2 This file is part of GNUnet.
3 (C) 2006, 2009 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
24 * @brief functions for buffering IO
25 * @author Christian Grothoff
28 #include "gnunet_bio_lib.h"
32 * Handle for buffered reading.
34 struct GNUNET_BIO_ReadHandle
40 * Open a file for reading.
42 * @param fn file name to be opened
43 * @return IO handle on success, NULL on error
45 struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn)
52 * Close an open file. Reports if any errors reading
53 * from the file were encountered.
55 * @param h file handle
56 * @param emsg set to the error message
57 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
59 int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
67 * Read the contents of a binary file into a buffer.
69 * @param h handle to an open file
70 * @param what describes what is being read (for error message creation)
71 * @param result the buffer to write the result to
72 * @param len the number of bytes to read
73 * @return len on success, GNUNET_SYSERR on failure
75 ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
84 * Read 0-terminated string from a file.
86 * @param h handle to an open file
87 * @param what describes what is being read (for error message creation)
88 * @param result the buffer to store a pointer to the (allocated) string to
89 * (note that *result could be set to NULL as well)
90 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
92 int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
100 * Read metadata container from a file.
102 * @param h handle to an open file
103 * @param what describes what is being read (for error message creation)
104 * @param result the buffer to store a pointer to the (allocated) metadata
105 * @return GNUNET_OK on success, GNUNET_SYSERR on failure
107 int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
109 struct GNUNET_CONTAINER_MetaData **result)
115 * Read an (u)int32_t.
117 * @param h hande to open file
118 * @param what describes what is being read (for error message creation)
119 * @param i address of 32-bit integer to read
120 * @return GNUNET_OK on success, GNUNET_SYSERR on error
122 int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
128 * Read an (u)int64_t.
130 * @param h hande to open file
131 * @param what describes what is being read (for error message creation)
132 * @param i address of 64-bit integer to read
133 * @return GNUNET_OK on success, GNUNET_SYSERR on error
135 int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
140 * Handle for buffered writing.
142 struct GNUNET_BIO_WriteHandle
148 * Open a file for writing.
150 * @param fn file name to be opened
151 * @return IO handle on success, NULL on error
153 struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn)
160 * Close an open file for writing.
162 * @param h file handle
163 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
165 int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
169 * Write a buffer to a file.
171 * @param h handle to open file
172 * @param buffer the data to write
173 * @param n number of bytes to write
174 * @return GNUNET_OK on success, GNUNET_SYSERR on error
176 ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
182 * Write a string to a file.
184 * @param h handle to open file
185 * @param s string to write (can be NULL)
186 * @return GNUNET_OK on success, GNUNET_SYSERR on error
188 int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
195 * Write metadata container to a file.
197 * @param h handle to open file
198 * @param m metadata to write
199 * @return GNUNET_OK on success, GNUNET_SYSERR on error
201 int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
202 const struct GNUNET_CONTAINER_MetaData *m);
209 * @param h hande to open file
210 * @param f float to write (must be a variable)
212 #define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, &f, sizeof(float)))
219 * @param h hande to open file
220 * @param f double to write (must be a variable)
222 #define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double)))
226 * Write an (u)int32_t.
228 * @param h hande to open file
229 * @param i address of 32-bit integer to write
230 * @return GNUNET_OK on success, GNUNET_SYSERR on error
232 int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h,
237 * Write an (u)int64_t.
239 * @param h hande to open file
240 * @param i address of 64-bit integer to write
241 * @return GNUNET_OK on success, GNUNET_SYSERR on error
243 int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h,
259 write_buffered (WriteBuffer * wb, const void *s, unsigned int size)
271 /* first, just use buffer */
272 min = wb->size - wb->have;
273 if (min > size - pos)
275 memcpy (&wb->buffer[wb->have], &src[pos], min);
280 GNUNET_GE_ASSERT (NULL, wb->have == wb->size);
281 ret = WRITE (wb->fd, wb->buffer, wb->size);
290 while (pos < size); /* should always be true */
295 WRITEINT (WriteBuffer * wb, int val)
299 write_buffered (wb, &big, sizeof (int));
303 WRITELONG (WriteBuffer * wb, long long val)
306 big = GNUNET_htonll (val);
307 write_buffered (wb, &big, sizeof (long long));
311 writeURI (WriteBuffer * wb, const struct GNUNET_ECRS_URI *uri)
316 buf = GNUNET_ECRS_uri_to_string (uri);
319 write_buffered (wb, buf, size);
324 WRITESTRING (WriteBuffer * wb, const char *name)
326 GNUNET_GE_BREAK (NULL, name != NULL);
327 WRITEINT (wb, strlen (name));
328 write_buffered (wb, name, strlen (name));
332 writeMetaData (struct GNUNET_GE_Context *ectx,
333 WriteBuffer * wb, const struct GNUNET_MetaData *meta)
338 size = GNUNET_meta_data_get_serialized_size (meta,
339 GNUNET_SERIALIZE_FULL
341 GNUNET_SERIALIZE_NO_COMPRESS);
342 if (size > 1024 * 1024)
344 buf = GNUNET_malloc (size);
345 GNUNET_meta_data_serialize (ectx,
349 GNUNET_SERIALIZE_PART |
350 GNUNET_SERIALIZE_NO_COMPRESS);
352 write_buffered (wb, buf, size);
358 writeFileInfo (struct GNUNET_GE_Context *ectx, WriteBuffer * wb,
359 const GNUNET_ECRS_FileInfo * fi)
361 writeMetaData (ectx, wb, fi->meta);
362 writeURI (wb, fi->uri);
378 read_buffered (ReadBuffer * rb, void *d, unsigned int size)
390 /* first, use buffer */
391 min = rb->have - rb->pos;
394 if (min > size - pos)
396 memcpy (&dst[pos], &rb->buffer[rb->pos], min);
401 return pos; /* done! */
402 GNUNET_GE_ASSERT (NULL, rb->have == rb->pos);
404 ret = READ (rb->fd, rb->buffer, rb->size);
416 while (pos < size); /* should always be true */
422 read_int (ReadBuffer * rb, int *val)
426 if (sizeof (int) != read_buffered (rb, &big, sizeof (int)))
427 return GNUNET_SYSERR;
433 read_uint (ReadBuffer * rb, unsigned int *val)
437 if (sizeof (unsigned int) !=
438 read_buffered (rb, &big, sizeof (unsigned int)))
439 return GNUNET_SYSERR;
444 #define READINT(a) if (GNUNET_OK != read_int(rb, (int*) &a)) return GNUNET_SYSERR;
447 read_long (ReadBuffer * rb, long long *val)
451 if (sizeof (long long) != read_buffered (rb, &big, sizeof (long long)))
452 return GNUNET_SYSERR;
453 *val = GNUNET_ntohll (big);
457 #define READLONG(a) if (GNUNET_OK != read_long(rb, (long long*) &a)) return GNUNET_SYSERR;
459 static struct GNUNET_ECRS_URI *
460 read_uri (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
463 struct GNUNET_ECRS_URI *ret;
466 if (GNUNET_OK != read_uint (rb, &size))
468 buf = GNUNET_malloc (size + 1);
470 if (size != read_buffered (rb, buf, size))
475 ret = GNUNET_ECRS_string_to_uri (ectx, buf);
476 GNUNET_GE_BREAK (ectx, ret != NULL);
481 #define READURI(u) if (NULL == (u = read_uri(ectx, rb))) return GNUNET_SYSERR;
484 read_string (ReadBuffer * rb, unsigned int maxLen)
489 if (GNUNET_OK != read_uint (rb, &big))
493 buf = GNUNET_malloc (big + 1);
495 if (big != read_buffered (rb, buf, big))
503 #define READSTRING(c, max) if (NULL == (c = read_string(rb, max))) return GNUNET_SYSERR;
506 * Read file info from file.
508 * @return GNUNET_OK on success, GNUNET_SYSERR on error
510 static struct GNUNET_MetaData *
511 read_meta (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
515 struct GNUNET_MetaData *meta;
517 if (read_uint (rb, &size) != GNUNET_OK)
519 GNUNET_GE_BREAK (ectx, 0);
522 if (size > 1024 * 1024)
524 GNUNET_GE_BREAK (ectx, 0);
527 buf = GNUNET_malloc (size);
528 if (size != read_buffered (rb, buf, size))
531 GNUNET_GE_BREAK (ectx, 0);
534 meta = GNUNET_meta_data_deserialize (ectx, buf, size);
538 GNUNET_GE_BREAK (ectx, 0);