2005-01-26 Moritz Schulte <moritz@g10code.com>
[gnupg.git] / common / estream.h
1 /* estream.h - Extended stream I/O/ Library
2    Copyright (C) 2004 g10 Code GmbH
3
4    This file is part of Libestream.
5  
6    Libestream is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published
8    by the Free Software Foundation; either version 2 of the License,
9    or (at your option) any later version.
10  
11    Libestream is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15  
16    You should have received a copy of the GNU General Public License
17    along with Libestream; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #ifndef ESTREAM_H
22 #define ESTREAM_H
23
24 #include <sys/types.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27
28 \f
29 /* Forward declaration for the (opaque) internal type.  */
30 struct estream_internal;
31
32 /* The definition of this struct is entirely private.  You must not
33    use it for anything.  It is only here so some functions can be
34    implemented as macros.  */
35 struct es__stream
36 {
37   /* The layout of this struct must never change.  It may be grown,
38      but only if all functions which access the new members are
39      versioned.  */
40
41   /* A pointer to the stream buffer.  */
42   unsigned char *buffer;
43
44   /* The size of the buffer in bytes.  */
45   size_t buffer_size;
46
47   /* The length of the usable data in the buffer, only valid when in
48      read mode (see flags).  */
49   size_t data_len;
50
51   /* The current position of the offset pointer, valid in read and
52      write mode.  */
53   size_t data_offset;
54
55   size_t data_flushed;
56   unsigned char *unread_buffer;
57   size_t unread_buffer_size;
58
59   /* The number of unread bytes.  */
60   size_t unread_data_len;
61
62   /* Various flags.  */
63 #define ES__FLAG_WRITING        (1 << 0)
64   unsigned int flags;
65
66   /* A pointer to our internal data for this stream.  */
67   struct estream_internal *intern;
68 };
69
70 /* The opaque type for an estream.  */
71 typedef struct es__stream *estream_t;
72
73 \f
74 typedef ssize_t (*es_cookie_read_function_t) (void *cookie,
75                                               char *buffer, size_t size);
76 typedef ssize_t (*es_cookie_write_function_t) (void *cookie,
77                                                const char *buffer,
78                                                size_t size);
79 typedef int (*es_cookie_seek_function_t) (void *cookie,
80                                           off_t *pos, int whence);
81 typedef int (*es_cookie_close_function_t) (void *cookie);
82
83 typedef struct es_cookie_io_functions
84 {
85   es_cookie_read_function_t func_read;
86   es_cookie_write_function_t func_write;
87   es_cookie_seek_function_t func_seek;
88   es_cookie_close_function_t func_close;
89 } es_cookie_io_functions_t;
90
91 \f
92 #ifndef ES__RESTRICT
93 #  if defined __GNUC__ && defined __GNUC_MINOR__
94 #    if  (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 92))
95 #      define ES__RESTRICT __restrict__
96 #    endif
97 #  endif
98 #endif
99 #ifndef ES__RESTRICT
100 #  define ES__RESTRICT
101 #endif
102
103 int es_init (void);
104
105 estream_t es_fopen (const char *ES__RESTRICT path,
106                     const char *ES__RESTRICT mode);
107 estream_t es_mopen (unsigned char *ES__RESTRICT data,
108                     size_t data_n, size_t data_len,
109                     unsigned int grow,
110                     void *(*func_realloc) (void *mem, size_t size),
111                     void (*func_free) (void *mem),
112                     const char *ES__RESTRICT mode);
113 estream_t es_open_memstream (char **ptr, size_t *size);
114 estream_t es_fdopen (int filedes, const char *mode);
115 estream_t es_freopen (const char *ES__RESTRICT path,
116                       const char *ES__RESTRICT mode,
117                       estream_t ES__RESTRICT stream);
118 estream_t es_fopencookie (void *ES__RESTRICT cookie,
119                           const char *ES__RESTRICT mode,
120                           es_cookie_io_functions_t functions);
121 int es_fclose (estream_t stream);
122 int es_fileno (estream_t stream);
123 int es_fileno_unlocked (estream_t stream);
124
125 void es_flockfile (estream_t stream);
126 int es_ftrylockfile (estream_t stream);
127 void es_funlockfile (estream_t stream);
128
129 int es_feof (estream_t stream);
130 int es_feof_unlocked (estream_t stream);
131 int es_ferror (estream_t stream);
132 int es_ferror_unlocked (estream_t stream);
133 void es_clearerr (estream_t stream);
134 void es_clearerr_unlocked (estream_t stream);
135
136 int es_fflush (estream_t stream);
137 int es_fseek (estream_t stream, long int offset, int whence);
138 int es_fseeko (estream_t stream, off_t offset, int whence);
139 long int es_ftell (estream_t stream);
140 off_t es_ftello (estream_t stream);
141 void es_rewind (estream_t stream);
142
143 int es_fgetc (estream_t stream);
144 int es_fputc (int c, estream_t stream);
145
146 int _es_getc_underflow (estream_t stream);
147 int _es_putc_overflow (int c, estream_t stream);
148
149 #define es_getc_unlocked(stream)                                \
150   (((! ((stream)->flags & 1))                                   \
151     && ((stream)->data_offset < (stream)->data_len)             \
152     && (! (stream)->unread_data_len))                           \
153   ? ((int) (stream)->buffer[((stream)->data_offset)++])         \
154   : _es_getc_underflow ((stream)))
155
156 #define es_putc_unlocked(c, stream)                             \
157   ((((stream)->flags & 1)                                       \
158     && ((stream)->data_offset < (stream)->buffer_size)          \
159     && (c != '\n'))                                             \
160   ? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c))) \
161   : _es_putc_overflow ((c), (stream)))
162
163 #define es_getc(stream)    es_fgetc (stream)
164 #define es_putc(c, stream) es_fputc (c, stream)
165
166 int es_ungetc (int c, estream_t stream);
167
168 int es_read (estream_t ES__RESTRICT stream,
169              char *ES__RESTRICT buffer, size_t bytes_to_read,
170              size_t *ES__RESTRICT bytes_read);
171 int es_write (estream_t ES__RESTRICT stream,
172               const char *ES__RESTRICT buffer, size_t bytes_to_write,
173               size_t *ES__RESTRICT bytes_written);
174
175 size_t es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems,
176                  estream_t ES__RESTRICT stream);
177 size_t es_fwrite (const void *ES__RESTRICT ptr, size_t size, size_t memb,
178                   estream_t ES__RESTRICT stream);
179
180 char *es_fgets (char *ES__RESTRICT s, int n, estream_t ES__RESTRICT stream);
181 int es_fputs (const char *ES__RESTRICT s, estream_t ES__RESTRICT stream);
182
183 ssize_t es_getline (char *ES__RESTRICT *ES__RESTRICT lineptr,
184                     size_t *ES__RESTRICT n,
185                     estream_t stream);
186
187 int es_fprintf (estream_t ES__RESTRICT stream,
188                 const char *ES__RESTRICT format, ...);
189 int es_vfprintf (estream_t ES__RESTRICT stream,
190                  const char *ES__RESTRICT format, va_list ap);
191
192 int es_setvbuf (estream_t ES__RESTRICT stream,
193                 char *ES__RESTRICT buf, int mode, size_t size);
194 void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf);
195
196 estream_t es_tmpfile (void);
197
198 void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
199 void *es_opaque_get (estream_t stream);
200
201 #endif