changes to support UTF-8 encoding from
[webpac] / openisis / lio.h
1 /*
2         openisis - an open implementation of the CDS/ISIS database
3         Version 0.8.x (patchlevel see file Version)
4         Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
5
6         This library is free software; you can redistribute it and/or
7         modify it under the terms of the GNU Lesser General Public
8         License as published by the Free Software Foundation; either
9         version 2.1 of the License, or (at your option) any later version.
10
11         This library is distributed in the hope that it will be useful,
12         but 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 Lesser General Public
17         License along with this library; if not, write to the Free Software
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20         see README for more information
21 EOH */
22 #ifndef LIO_H
23
24 /*
25         $Id: lio.h,v 1.22 2003/05/29 18:02:54 kripke Exp $
26         I/O support for the openisis library.
27         Provides non-blocking, look-ahead network streams and other nice stuff.
28 */
29
30 #include "luti.h"
31 #include "lll.h"
32
33
34 /* ************************************************************
35         time
36 */
37
38 /* struct wrapper just for struct Tm *Time */ 
39 typedef struct Tm {
40         lll   millis;
41 }       Tm;
42
43 /**
44         set Tm to current time, return difference in millis
45 */
46 extern int timeUpd ( Tm * );
47 /**
48         print generalized time yyyyMMddHHmmss + 0 byte to buffer
49         if Tm is 0, current time is used
50         if Tm.millis is 0, Tm is updated
51         return buffer, which must have 15 bytes
52 */
53 extern char *timeGtf ( char *buf, Tm * );
54 /**
55         like timeAsc, but with additional 3 digits millis
56         return buffer, which must have 18 bytes
57 */
58 extern char *timeGtfm ( char *buf, Tm * );
59 /**
60         nanosl
61 */
62 extern void timeSleep ( Tm * );
63
64
65 /* ************************************************************
66         system files
67 */
68
69 /**
70         system file is a non-negative 32bit int including status bits.
71         main status bits are LIO_IN and LIO_OUT,
72         which are set by open and cleared by close.
73
74         negative values are reserved for use by non-system based streams.
75 */
76 #define LIO_WANT  0xfff00000 /* what we want: open flags */
77 #define LIO_FD    0x0000ffff /* what we get: system fd */
78 #define LIO_STAT  0x000f0000 /* how it's going: it's status */
79
80 /* status flags */
81 #define LIO_IN    0x00010000 /* support input */
82 #define LIO_OUT   0x00020000 /* support output */
83 #define LIO_INOUT 0x00030000 /* support both */
84 #define LIO_ISOPEN( file ) (LIO_INOUT & (file))
85
86 /* common requirements that are also used by non-system streams. */
87 #define LIO_RD    0x00100000 /* shall be opened for input */
88 #define LIO_WR    0x00200000 /* shall be opened for output */
89 #define LIO_RDWR  0x00300000 /* shall be opened for both */
90 #define LIO_SYNC  0x00400000 /* with WR: syncing output */
91 #define LIO_NBLK  0x00800000 /* non blocking IO (not used) */
92
93 /* system files only. */
94 #define LIO_CREAT 0x01000000 /* with WR: shall be created */
95 #define LIO_TRY   0x01000000 /* w/o  WR: do not complain if open fails */
96 #define LIO_TRUNC 0x02000000 /* with WR: shall be truncated */
97 #define LIO_SEEK  0x04000000 /* random access (with WR: else append mode) */
98 #define LIO_SOCK  0x08000000 /* is a socket (support shutdown) */
99
100 /* locking */
101 #define LIO_TLOCK 0x10000000 /* try locking (EX with WR) */
102 #define LIO_WLOCK 0x20000000 /* lock waiting (EX with WR) */
103 #define LIO_FLOCK 0x30000000 /* any locking is set */
104
105
106 /** create a new fid based on name and flags.
107         name may be &i to use fd i, esp. for i=0,1 or 2.
108         @return non-negative file or some error code
109 */
110 extern int lio_open ( const char *name, int flags );
111 extern int lio_close ( int *file, int flags );
112 extern int lio_size ( int file );
113 extern unsigned lio_time ( int file ); /* mtime sec */
114
115 extern int lio_in;
116 extern int lio_out;
117 extern int lio_err;
118
119
120 /*
121         Like the syscalls, this returns the number of bytes on success.
122         Unlike the syscalls, it returns 0 rather than an error
123         when no bytes are available after interrupt (EINTR)
124         or on non-blocking IO (EAGAIN); i.e. you may try later.
125         On error, a negative value is returned.
126         On errors that render the file unusable,
127         it is closed for input or output, resp.
128         These are most errors but EFAULT (bad buf)
129         and ESPIPE (which clears the SEEK bit).
130         For files that do not have the SEEK bit set,
131         EOF is considered such an error and -LERR_EOF is returned.
132         If you want to stream a disk file like 'tail -f', set the SEEK bit.
133 */
134 extern int lio_read ( int *file, void *buf, unsigned count );
135 extern int lio_write ( int *file, const void *buf, unsigned count );
136 extern int lio_pread ( int *file, void *buf, unsigned count, int offset );
137 extern int lio_pwrite ( int *file, const void *buf, unsigned count, int offset );
138 extern int lio_seek ( int *file, int offset );
139 extern int lio_trunc ( int *file, int offset );
140 /**
141         open, sync or close a memory mapping
142
143         @param file pointer to open file handle to map.
144                 if file is NULL, *map is unmapped (and set to NULL)
145                 else if *map is NULL, length bytes are mapped
146                 else *map is synced (flushed)
147         @param length number of bytes to map; if 0, size will be used
148         @return mapped length; if <= 0, *map is set to 0, else to memory region
149 */
150 extern int lio_mmap ( int *file, void **map, int length );
151
152
153 /** slurp in a whole file at once.
154         @param buf points to buffer of size sz.
155                 lio_slurp will allocate one, if *buf is NULL
156         @param sz maximum number of bytes to read
157         @param name of file to slurp
158         @param opt if != 0, do not complain on failure
159         @return number of bytes read or negative on error
160 */
161 extern int lio_slurp ( char **buf, int sz, const char *name, int opt );
162
163
164
165 /* ************************************************************
166         streams
167 */
168
169 /** an I/O buffered stream similar to stdio's FILE.
170         Unlike FILE with it's stupid ungetc,
171         it supports efficient scanning of the whole input buffer without
172         actually consuming it.
173         Also unlike at least Linux' glibc's stdio, access is not interlocked.
174         The buffer is typically used for input OR output.
175         However, for internal pipes, the same buffer is used from both ends.
176
177         High level access functions like printf operate directly on the buffer
178         and call the stream function on buffer underflow or overflow
179         (or explicit flush).
180 */
181 typedef int lio_sfunc ( struct Ios *s, int op );
182
183 enum {
184         LIO_BUFSIZ = 8192
185 };
186
187 typedef struct Buf {
188         /* struct Buf     *nxt; chain -- not used */
189         short           fill; /* total #bytes in the buffer */
190         short           done; /* #bytes done */
191         unsigned char   c[LIO_BUFSIZ]; /* actual buffer may be longer */
192 } Buf;
193 /* fill - done is the number of available bytes */
194 #define LIO_BAVAIL( b )  ((b)->fill - (b)->done)
195 #define LIO_BINIT( b ) do { \
196         /*(b)->nxt = 0;*/ (b)->fill = 0; (b)->done = 0; \
197         } while (0)
198 #define LIO_BINITIALIZER { 0,0,"" }
199
200 typedef struct Ios {
201         lio_sfunc  *func;
202         const char *name; /* stream's name */
203         int         file; /* file "id" and flags as above */
204         int         pos;  /* logical position of buffer start within stream */
205         Buf         b;
206 }       Ios;
207
208 #define LIO_SISOPEN( s ) LIO_ISOPEN( (s)->file )
209 #define LIO_SAVAIL( s )  LIO_BAVAIL( &(s)->b )
210 #define LIO_SINIT( s, fun, nam, fil ) do { \
211         (s)->func = fun; (s)->name = nam; (s)->file = fil; \
212         (s)->pos = 0; \
213         LIO_BINIT( &(s)->b ); \
214         } while (0)
215 #define LIO_STDINIT( s, nam, fil ) LIO_SINIT( s, lio_stdio, nam, fil )
216 #define LIO_SINITIALIZER( fun, nam, fil ) { fun, nam, fil, 0, LIO_BINITIALIZER }
217 #define LIO_STDINITIALIZER( nam, fil ) LIO_SINITIALIZER( lio_stdio, nam, fil )
218         
219
220 /** stream operations.
221 */
222 enum {
223         LIO_SSIZE,  /* tell the size of the stream structure */
224         LIO_SOPEN,  /* initialize the structure */
225         LIO_SCLOSE, /* close */
226         LIO_SPURGE, /* kill the done bytes. return fill buffer size */
227         LIO_SFILL,  /* try to refill the buffer (poll input). return # new bytes */
228         LIO_SFLUSH, /* try to flush the buffer. return # bytes written */
229         LIO_SPUSH   /* push input stream: munge prefilled input */
230 };
231
232 /**
233         "abstract" base implementation of stream.
234         not very useful in itself, but used by derived impl.
235 */
236 extern int ioStream ( Ios *s, int op );
237
238 /**
239         stream func based on system file to mimic stdio.
240         on LIO_SOPEN, the fid is set by lio_open based on name.
241         other ops used the correponding lio system call.
242 */
243 extern int ioStdio ( Ios *s, int op );
244
245 #define LIO_OPEN( s )  (s)->func( (s), LIO_SOPEN )
246 #define LIO_CLOSE( s ) (s)->func( (s), LIO_SCLOSE )
247 #define LIO_FILL( s )  (s)->func( (s), LIO_SFILL )
248 #define LIO_FLUSH( s ) (s)->func( (s), LIO_SFLUSH )
249
250
251
252
253 /* ************************************************************
254         inter process communication
255 */
256
257 extern CLockFunc *lio_lock;
258 #define LIO_LOCK() (NULL != lio_lock && lio_lock(OPENISIS_LOCK))
259 #define LIO_RELE() (NULL != lio_lock && lio_lock(OPENISIS_RELE))
260 #define LIO_WAIT( c ) (NULL != lio_lock && lio_lock(OPENISIS_WAIT \
261         | (OPENISIS_COND & (c))))
262 #define LIO_WAKE( c ) (NULL != lio_lock && lio_lock(OPENISIS_WAKE \
263         | (OPENISIS_COND & (c))))
264
265 #define LIO_H
266 #endif /* LIO_H */