aboutsummaryrefslogtreecommitdiff
path: root/src/util/bio.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-24 09:26:47 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-24 09:26:47 +0000
commitda7cc55488f90b3294dbb7aa186184e6e8501d7e (patch)
tree642f70be79ca8f2cbdbb3579d213086f3a25a4bf /src/util/bio.c
parent2518cfc0a86865ebe4d0550e0013ed52a494231b (diff)
downloadgnunet-da7cc55488f90b3294dbb7aa186184e6e8501d7e.tar.gz
gnunet-da7cc55488f90b3294dbb7aa186184e6e8501d7e.zip
hxing
Diffstat (limited to 'src/util/bio.c')
-rw-r--r--src/util/bio.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/src/util/bio.c b/src/util/bio.c
new file mode 100644
index 000000000..060b6f94b
--- /dev/null
+++ b/src/util/bio.c
@@ -0,0 +1,545 @@
1/*
2 This file is part of GNUnet.
3 (C) 2006, 2009 Christian Grothoff (and other contributing authors)
4
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.
9
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.
14
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.
19*/
20
21
22/**
23 * @file util/bio.c
24 * @brief functions for buffering IO
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_bio_lib.h"
29
30
31/**
32 * Handle for buffered reading.
33 */
34struct GNUNET_BIO_ReadHandle
35{
36};
37
38
39/**
40 * Open a file for reading.
41 *
42 * @param fn file name to be opened
43 * @return IO handle on success, NULL on error
44 */
45struct GNUNET_BIO_ReadHandle *GNUNET_BIO_read_open (const char *fn)
46{
47 return NULL;
48}
49
50
51/**
52 * Close an open file. Reports if any errors reading
53 * from the file were encountered.
54 *
55 * @param h file handle
56 * @param emsg set to the error message
57 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
58 */
59int GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h,
60 char **emsg)
61{
62 return GNUNET_SYSERR;
63}
64
65
66/**
67 * Read the contents of a binary file into a buffer.
68 *
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
74 */
75ssize_t GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
76 const char *what,
77 void *result,
78 size_t len)
79{
80}
81
82
83/**
84 * Read 0-terminated string from a file.
85 *
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
91 */
92int GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
93 const char *what,
94 char **result)
95{
96}
97
98
99/**
100 * Read metadata container from a file.
101 *
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
106 */
107int GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
108 const char *what,
109 struct GNUNET_CONTAINER_MetaData **result)
110{
111}
112
113
114/**
115 * Read an (u)int32_t.
116 *
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
121 */
122int GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
123 const char *what,
124 int32_t *i);
125
126
127/**
128 * Read an (u)int64_t.
129 *
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
134 */
135int GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
136 const char *what,
137 int64_t *i);
138
139/**
140 * Handle for buffered writing.
141 */
142struct GNUNET_BIO_WriteHandle
143{
144};
145
146
147/**
148 * Open a file for writing.
149 *
150 * @param fn file name to be opened
151 * @return IO handle on success, NULL on error
152 */
153struct GNUNET_BIO_WriteHandle *GNUNET_BIO_write_open (const char *fn)
154{
155 return NULL;
156}
157
158
159/**
160 * Close an open file for writing.
161 *
162 * @param h file handle
163 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
164 */
165int GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
166
167
168/**
169 * Write a buffer to a file.
170 *
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
175 */
176ssize_t GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
177 const void *buffer,
178 size_t n);
179
180
181/**
182 * Write a string to a file.
183 *
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
187 */
188int GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
189 const char *s);
190
191
192
193
194/**
195 * Write metadata container to a file.
196 *
197 * @param h handle to open file
198 * @param m metadata to write
199 * @return GNUNET_OK on success, GNUNET_SYSERR on error
200 */
201int GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
202 const struct GNUNET_CONTAINER_MetaData *m);
203
204
205
206/**
207 * Write a float.
208 *
209 * @param h hande to open file
210 * @param f float to write (must be a variable)
211 */
212#define GNUNET_BIO_write_float(h, f) (sizeof(float) == GNUNET_BIO_write (h, &f, sizeof(float)))
213
214
215
216/**
217 * Write a double.
218 *
219 * @param h hande to open file
220 * @param f double to write (must be a variable)
221 */
222#define GNUNET_BIO_write_float(h, f) (sizeof(double) == GNUNET_BIO_write (h, &f, sizeof(double)))
223
224
225/**
226 * Write an (u)int32_t.
227 *
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
231 */
232int GNUNET_BIO_write_int32 (struct GNUNET_BIO_ReadHandle *h,
233 int32_t i);
234
235
236/**
237 * Write an (u)int64_t.
238 *
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
242 */
243int GNUNET_BIO_write_int64 (struct GNUNET_BIO_ReadHandle *h,
244 int64_t i);
245
246
247
248
249
250typedef struct
251{
252 int fd;
253 unsigned int have;
254 unsigned int size;
255 char *buffer;
256} WriteBuffer;
257
258static void
259write_buffered (WriteBuffer * wb, const void *s, unsigned int size)
260{
261 const char *src = s;
262 unsigned int min;
263 unsigned int pos;
264 int ret;
265
266 if (wb->fd == -1)
267 return;
268 pos = 0;
269 do
270 {
271 /* first, just use buffer */
272 min = wb->size - wb->have;
273 if (min > size - pos)
274 min = size - pos;
275 memcpy (&wb->buffer[wb->have], &src[pos], min);
276 pos += min;
277 wb->have += min;
278 if (pos == size)
279 return; /* done */
280 GNUNET_GE_ASSERT (NULL, wb->have == wb->size);
281 ret = WRITE (wb->fd, wb->buffer, wb->size);
282 if (ret != wb->size)
283 {
284 CLOSE (wb->fd);
285 wb->fd = -1;
286 return; /* error */
287 }
288 wb->have = 0;
289 }
290 while (pos < size); /* should always be true */
291}
292
293
294static void
295WRITEINT (WriteBuffer * wb, int val)
296{
297 int big;
298 big = htonl (val);
299 write_buffered (wb, &big, sizeof (int));
300}
301
302static void
303WRITELONG (WriteBuffer * wb, long long val)
304{
305 long long big;
306 big = GNUNET_htonll (val);
307 write_buffered (wb, &big, sizeof (long long));
308}
309
310static void
311writeURI (WriteBuffer * wb, const struct GNUNET_ECRS_URI *uri)
312{
313 char *buf;
314 unsigned int size;
315
316 buf = GNUNET_ECRS_uri_to_string (uri);
317 size = strlen (buf);
318 WRITEINT (wb, size);
319 write_buffered (wb, buf, size);
320 GNUNET_free (buf);
321}
322
323static void
324WRITESTRING (WriteBuffer * wb, const char *name)
325{
326 GNUNET_GE_BREAK (NULL, name != NULL);
327 WRITEINT (wb, strlen (name));
328 write_buffered (wb, name, strlen (name));
329}
330
331static void
332writeMetaData (struct GNUNET_GE_Context *ectx,
333 WriteBuffer * wb, const struct GNUNET_MetaData *meta)
334{
335 unsigned int size;
336 char *buf;
337
338 size = GNUNET_meta_data_get_serialized_size (meta,
339 GNUNET_SERIALIZE_FULL
340 |
341 GNUNET_SERIALIZE_NO_COMPRESS);
342 if (size > 1024 * 1024)
343 size = 1024 * 1024;
344 buf = GNUNET_malloc (size);
345 GNUNET_meta_data_serialize (ectx,
346 meta,
347 buf,
348 size,
349 GNUNET_SERIALIZE_PART |
350 GNUNET_SERIALIZE_NO_COMPRESS);
351 WRITEINT (wb, size);
352 write_buffered (wb, buf, size);
353 GNUNET_free (buf);
354}
355
356
357static void
358writeFileInfo (struct GNUNET_GE_Context *ectx, WriteBuffer * wb,
359 const GNUNET_ECRS_FileInfo * fi)
360{
361 writeMetaData (ectx, wb, fi->meta);
362 writeURI (wb, fi->uri);
363}
364
365
366
367
368typedef struct
369{
370 int fd;
371 unsigned int have;
372 unsigned int size;
373 unsigned int pos;
374 char *buffer;
375} ReadBuffer;
376
377static int
378read_buffered (ReadBuffer * rb, void *d, unsigned int size)
379{
380 char *dst = d;
381 unsigned int min;
382 unsigned int pos;
383 int ret;
384
385 if (rb->fd == -1)
386 return -1;
387 pos = 0;
388 do
389 {
390 /* first, use buffer */
391 min = rb->have - rb->pos;
392 if (min > 0)
393 {
394 if (min > size - pos)
395 min = size - pos;
396 memcpy (&dst[pos], &rb->buffer[rb->pos], min);
397 rb->pos += min;
398 pos += min;
399 }
400 if (pos == size)
401 return pos; /* done! */
402 GNUNET_GE_ASSERT (NULL, rb->have == rb->pos);
403 /* fill buffer */
404 ret = READ (rb->fd, rb->buffer, rb->size);
405 if (ret == -1)
406 {
407 CLOSE (rb->fd);
408 rb->fd = -1;
409 return -1;
410 }
411 if (ret == 0)
412 return 0;
413 rb->pos = 0;
414 rb->have = ret;
415 }
416 while (pos < size); /* should always be true */
417 return pos;
418}
419
420
421static int
422read_int (ReadBuffer * rb, int *val)
423{
424 int big;
425
426 if (sizeof (int) != read_buffered (rb, &big, sizeof (int)))
427 return GNUNET_SYSERR;
428 *val = ntohl (big);
429 return GNUNET_OK;
430}
431
432static unsigned int
433read_uint (ReadBuffer * rb, unsigned int *val)
434{
435 unsigned int big;
436
437 if (sizeof (unsigned int) !=
438 read_buffered (rb, &big, sizeof (unsigned int)))
439 return GNUNET_SYSERR;
440 *val = ntohl (big);
441 return GNUNET_OK;
442}
443
444#define READINT(a) if (GNUNET_OK != read_int(rb, (int*) &a)) return GNUNET_SYSERR;
445
446static int
447read_long (ReadBuffer * rb, long long *val)
448{
449 long long big;
450
451 if (sizeof (long long) != read_buffered (rb, &big, sizeof (long long)))
452 return GNUNET_SYSERR;
453 *val = GNUNET_ntohll (big);
454 return GNUNET_OK;
455}
456
457#define READLONG(a) if (GNUNET_OK != read_long(rb, (long long*) &a)) return GNUNET_SYSERR;
458
459static struct GNUNET_ECRS_URI *
460read_uri (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
461{
462 char *buf;
463 struct GNUNET_ECRS_URI *ret;
464 unsigned int size;
465
466 if (GNUNET_OK != read_uint (rb, &size))
467 return NULL;
468 buf = GNUNET_malloc (size + 1);
469 buf[size] = '\0';
470 if (size != read_buffered (rb, buf, size))
471 {
472 GNUNET_free (buf);
473 return NULL;
474 }
475 ret = GNUNET_ECRS_string_to_uri (ectx, buf);
476 GNUNET_GE_BREAK (ectx, ret != NULL);
477 GNUNET_free (buf);
478 return ret;
479}
480
481#define READURI(u) if (NULL == (u = read_uri(ectx, rb))) return GNUNET_SYSERR;
482
483static char *
484read_string (ReadBuffer * rb, unsigned int maxLen)
485{
486 char *buf;
487 unsigned int big;
488
489 if (GNUNET_OK != read_uint (rb, &big))
490 return NULL;
491 if (big > maxLen)
492 return NULL;
493 buf = GNUNET_malloc (big + 1);
494 buf[big] = '\0';
495 if (big != read_buffered (rb, buf, big))
496 {
497 GNUNET_free (buf);
498 return NULL;
499 }
500 return buf;
501}
502
503#define READSTRING(c, max) if (NULL == (c = read_string(rb, max))) return GNUNET_SYSERR;
504
505/**
506 * Read file info from file.
507 *
508 * @return GNUNET_OK on success, GNUNET_SYSERR on error
509 */
510static struct GNUNET_MetaData *
511read_meta (struct GNUNET_GE_Context *ectx, ReadBuffer * rb)
512{
513 unsigned int size;
514 char *buf;
515 struct GNUNET_MetaData *meta;
516
517 if (read_uint (rb, &size) != GNUNET_OK)
518 {
519 GNUNET_GE_BREAK (ectx, 0);
520 return NULL;
521 }
522 if (size > 1024 * 1024)
523 {
524 GNUNET_GE_BREAK (ectx, 0);
525 return NULL;
526 }
527 buf = GNUNET_malloc (size);
528 if (size != read_buffered (rb, buf, size))
529 {
530 GNUNET_free (buf);
531 GNUNET_GE_BREAK (ectx, 0);
532 return NULL;
533 }
534 meta = GNUNET_meta_data_deserialize (ectx, buf, size);
535 if (meta == NULL)
536 {
537 GNUNET_free (buf);
538 GNUNET_GE_BREAK (ectx, 0);
539 return NULL;
540 }
541 GNUNET_free (buf);
542 return meta;
543}
544
545/* end of bio.c */