source: trunk/packages/xen-common/xen-common/tools/vnet/libxutil/iostream.h @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 6.5 KB
Line 
1/*
2 * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#ifndef _XUTIL_IOSTREAM_H_
20#define _XUTIL_IOSTREAM_H_
21
22#include <stdarg.h>
23
24#ifdef __KERNEL__
25#include <linux/config.h>
26#include <linux/types.h>
27#include <linux/errno.h>
28#else
29#include <errno.h>
30#include <stdint.h>
31#include <stddef.h>
32#endif
33
34#include "allocate.h"
35
36/** End of input return value (for getc). */
37#define IOSTREAM_EOF -1
38
39/** An input/output abstraction.
40 */
41typedef struct IOStream IOStream;
42
43/** Record of the functions to use for operations on an
44 * IOStream implementation.
45 */
46typedef struct IOMethods {
47    /** Read function.  Called with the user data, buffer to read into
48     * and number of bytes to read.  Must return number of bytes read
49     * on success, less than zero on error.
50     */
51    int (*read)(IOStream *stream, void *buf, size_t n);
52
53    /** Write function. Called with user data, buffer to write and
54     * number of bytes to write. Must return number of bytes written on
55     * success, less than zero otherwise.
56     */
57    int (*write)(IOStream *stream, const void *buf, size_t n);
58
59    int (*flush)(IOStream *s);
60
61    int (*error)(IOStream *s);
62
63    int (*close)(IOStream *s);
64
65    void (*free)(IOStream *s);
66
67    void (*lock)(IOStream *s);
68    void (*unlock)(IOStream *s);
69
70} IOMethods;
71
72/** Abstract i/o object.
73 */
74struct IOStream {
75    /** Methods to use to implement operations. */
76    const IOMethods *methods;
77    /** Private state for the implementation. */
78    const void *data;
79    /** Flag indicating whether the stream is closed. */
80    int closed;
81    /** Number of bytes written. */
82    int written;
83    /** Number of bytes read. */
84    int read;
85    /** Flag indicating whether not to free when closed. */
86    int nofree;
87};
88
89
90/** IOStream version of stdin. */
91extern IOStream *iostdin;
92
93/** IOStream version of stdout, */
94extern IOStream *iostdout;
95
96/** IOStream version of stderr. */
97extern IOStream *iostderr;
98
99extern int IOStream_print(IOStream *io, const char *format, ...);
100extern int IOStream_vprint(IOStream *io, const char *format, va_list args);
101
102/** Read from a stream.
103 *
104 * @param stream input
105 * @param buf where to put input
106 * @param n number of bytes to read
107 * @return if ok, number of bytes read, otherwise negative error code
108 */
109static inline int IOStream_read(IOStream *stream, void *buf, size_t n){
110    int result;
111    if(stream->closed){
112        result = -EIO;
113        goto exit;
114    }
115    if(!stream->methods || !stream->methods->read){
116        result = -EINVAL;
117        goto exit;
118    }
119    result = (stream->methods->read)(stream, buf, n);
120    if(result > 0){
121        stream->read += result;
122    }
123  exit:
124    return result;
125}
126
127/** Write to a stream.
128 *
129 * @param stream input
130 * @param buf where to put input
131 * @param n number of bytes to write
132 * @return if ok, number of bytes written, otherwise negative error code
133 */
134static inline int IOStream_write(IOStream *stream, const void *buf, size_t n){
135    int result;
136    if(stream->closed){
137        result = -EIO;
138        goto exit;
139    }
140    if(!stream->methods || !stream->methods->write){
141        result = -EINVAL;
142        goto exit;
143    }
144    result = (stream->methods->write)(stream, buf, n);
145    if(result > 0){
146        stream->written += result;
147    }
148  exit:
149    return result;
150}
151
152/** Flush the stream.
153 *
154 * @param stream stream
155 * @return 0 on success, negative error code otherwise
156 */
157static inline int IOStream_flush(IOStream *stream){
158    int result = 0;
159    if(stream->closed){
160        result = -EIO;
161    } else if(stream->methods->flush){
162        result = (stream->methods->flush)(stream);
163    }
164    return result;
165}
166
167/** Check whether the stream has an error.
168 *
169 * @param stream to check
170 * @return 1 for error, 0 otherwise
171 */
172static inline int IOStream_error(IOStream *stream){
173    int err = 0;
174    if(stream->methods && stream->methods->error){
175       err = (stream->methods->error)(stream);
176    }
177    return err;
178}
179
180/** Close the stream.
181 *
182 * @param stream to close
183 * @return 0 on success, negative error code otherwise
184 */
185static inline int IOStream_close(IOStream *stream){
186    int err = 0;
187    if(!stream || stream->closed){
188        err = -EIO;
189        goto exit;
190    }
191    if(stream->methods && stream->methods->close){
192        err = (stream->methods->close)(stream);
193        stream->closed = 1;
194    }
195    if(stream->nofree) goto exit;
196    if(stream->methods && stream->methods->free){
197        (stream->methods->free)(stream);
198    }
199    *stream = (IOStream){};
200    deallocate(stream);
201  exit:
202    return err;
203}
204
205/** Test if the stream has been closed.
206 *
207 * @param stream to check
208 * @return 1 if closed, 0 otherwise
209 */
210static inline int IOStream_is_closed(IOStream *stream){
211    return stream->closed;
212}
213
214/** Print a character to a stream, like fputc().
215 *
216 * @param stream to print to
217 * @param c character to print
218 * @return result code from the print
219 */
220static inline int IOStream_putc(IOStream *stream, int c){
221    int err;
222    unsigned char b = (unsigned char)c;
223    err = IOStream_write(stream, &b, 1);
224    if(err < 1){
225        err = IOSTREAM_EOF;
226    } else {
227        err = b;
228    }
229    return err;
230}
231
232/** Read from a stream, like fgetc().
233 *
234 * @param stream to read from
235 * @return IOSTREAM_EOF on error, character read otherwise
236 */
237static inline int IOStream_getc(IOStream *stream){
238    int err, rc;
239    unsigned char b;
240
241    err = IOStream_read(stream, &b, 1);
242    if(err < 1){
243        rc = IOSTREAM_EOF;
244    } else {
245        rc = b;
246    }
247    return rc;
248}
249
250/** Get number of bytes read.
251 *
252 * @param stream to get from
253 * @return number of bytes read
254 */
255static inline int IOStream_get_read(IOStream *stream){
256    return stream->read;
257}
258
259/** Get number of bytes written.
260 *
261 * @param stream to get from
262 * @return number of bytes written
263 */
264static inline int IOStream_get_written(IOStream *stream){
265    return stream->written;
266}
267
268
269#endif /* ! _XUTIL_IOSTREAM_H_ */
Note: See TracBrowser for help on using the repository browser.