summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessio Vanni <vannilla@firemail.cc>2020-05-14 16:03:10 +0200
committerChristian Grothoff <christian@grothoff.org>2020-05-19 02:41:47 +0200
commitf4771fcc1c3fda21a46d0cb85d8b29e012254696 (patch)
tree012df74ed2cf44cb20605b239e1b88dab6edc645
parent6a52ce5f9bc35a852b215e7073f3a0d2665ca8de (diff)
Improved BIO API
BIO now supports reading from and writing to in-memory buffers. For reading, an allocated buffer (array) and a size is passed as arguments to the function opening the handle. For writing, a GNUNET_Buffer is created and used internally. The buffer contents can be extracted using the relevant function. There is a new API in addition to the existing read/write: this new API is more "declarative" in nature and is meant to mimic APIs like GNUNET_SQ. The read/write operations are defined in an array of specs which are then "commited" in a single (non-atomic) operation, rather than explicitly executing multiple function calls and checking their return value. Also there are small changes to GNUNET_Buffer to account for BIO's new features. Signed-off-by: Christian Grothoff <christian@grothoff.org>
-rw-r--r--src/fs/fs_api.c447
-rw-r--r--src/fs/fs_namespace.c39
-rw-r--r--src/fs/gnunet-auto-share.c32
-rw-r--r--src/fs/gnunet-service-fs_indexing.c11
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_client.c43
-rw-r--r--src/include/gnunet_bio_lib.h559
-rw-r--r--src/include/gnunet_buffer_lib.h13
-rw-r--r--src/nse/gnunet-service-nse.c6
-rw-r--r--src/statistics/gnunet-service-statistics.c10
-rw-r--r--src/testbed-logger/gnunet-service-testbed-logger.c5
-rw-r--r--src/testbed/gnunet-service-testbed_cpustatus.c6
-rw-r--r--src/util/bio.c1219
-rw-r--r--src/util/buffer.c23
-rw-r--r--src/util/test_bio.c601
14 files changed, 2279 insertions, 735 deletions
diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c
index e04a93f9c..39e3add63 100644
--- a/src/fs/fs_api.c
+++ b/src/fs/fs_api.c
@@ -676,7 +676,7 @@ get_read_handle (struct GNUNET_FS_Handle *h, const char *ext, const char *ent)
fn = get_serialization_file_name (h, ext, ent);
if (NULL == fn)
return NULL;
- ret = GNUNET_BIO_read_open (fn);
+ ret = GNUNET_BIO_read_open_file (fn);
GNUNET_free (fn);
return ret;
}
@@ -699,7 +699,7 @@ get_write_handle (struct GNUNET_FS_Handle *h, const char *ext, const char *ent)
fn = get_serialization_file_name (h, ext, ent);
if (NULL == fn)
return NULL;
- ret = GNUNET_BIO_write_open (fn);
+ ret = GNUNET_BIO_write_open_file (fn);
GNUNET_break (NULL != ret);
GNUNET_free (fn);
return ret;
@@ -727,7 +727,7 @@ get_write_handle_in_dir (struct GNUNET_FS_Handle *h,
fn = get_serialization_file_name_in_dir (h, ext, uni, ent);
if (NULL == fn)
return NULL;
- ret = GNUNET_BIO_write_open (fn);
+ ret = GNUNET_BIO_write_open_file (fn);
GNUNET_free (fn);
return ret;
}
@@ -839,7 +839,7 @@ write_start_time (struct GNUNET_BIO_WriteHandle *wh,
struct GNUNET_TIME_Relative dur;
dur = GNUNET_TIME_absolute_get_duration (timestamp);
- return GNUNET_BIO_write_int64 (wh, dur.rel_value_us);
+ return GNUNET_BIO_write_int64 (wh, "start time", dur.rel_value_us);
}
@@ -863,7 +863,8 @@ read_start_time (struct GNUNET_BIO_ReadHandle *rh,
{
struct GNUNET_TIME_Relative dur;
- if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dur.rel_value_us))
+ if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, "start time",
+ (int64_t *) &dur.rel_value_us))
return GNUNET_SYSERR;
*timestamp = GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), dur);
return GNUNET_OK;
@@ -937,10 +938,22 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
(GNUNET_OK !=
GNUNET_BIO_read_string (rh, "fn", &ret->filename, 16 * 1024)) ||
(GNUNET_OK !=
- GNUNET_BIO_read_int64 (rh, &ret->bo.expiration_time.abs_value_us)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &ret->bo.anonymity_level)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &ret->bo.content_priority)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &ret->bo.replication_level)))
+ GNUNET_BIO_read_int64 (
+ rh,
+ "expiration time",
+ (int64_t *) &ret->bo.expiration_time.abs_value_us)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "anonymity level",
+ (int32_t *) &ret->bo.anonymity_level)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "content priority",
+ (int32_t *) &ret->bo.content_priority)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "replication level",
+ (int32_t *) &ret->bo.replication_level)))
{
GNUNET_break (0);
goto cleanup;
@@ -948,7 +961,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
switch (b)
{
case 0: /* file-insert */
- if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size))
+ if (GNUNET_OK != GNUNET_BIO_read_int64 (
+ rh,
+ "file size",
+ (int64_t *) &ret->data.file.file_size))
{
GNUNET_break (0);
goto cleanup;
@@ -990,7 +1006,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
GNUNET_break (0);
goto cleanup;
}
- if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size))
+ if (GNUNET_OK != GNUNET_BIO_read_int64 (
+ rh,
+ "file size",
+ (int64_t *) &ret->data.file.file_size))
{
GNUNET_break (0);
goto cleanup;
@@ -1010,7 +1029,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
GNUNET_break (0);
goto cleanup;
}
- if ((GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) ||
+ if ((GNUNET_OK != GNUNET_BIO_read_int64 (
+ rh,
+ "file size",
+ (int64_t *) &ret->data.file.file_size)) ||
(GNUNET_OK != GNUNET_BIO_read (rh,
"fileid",
&ret->data.file.file_id,
@@ -1034,7 +1056,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
GNUNET_break (0);
goto cleanup;
}
- if ((GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) ||
+ if ((GNUNET_OK != GNUNET_BIO_read_int64 (
+ rh,
+ "file size",
+ (int64_t *) &ret->data.file.file_size)) ||
(GNUNET_OK != GNUNET_BIO_read (rh,
"fileid",
&ret->data.file.file_id,
@@ -1054,11 +1079,18 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
case 4: /* directory */
ret->is_directory = GNUNET_YES;
- if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dsize)) ||
+ if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, "dsize",
+ (int32_t *) &dsize)) ||
(GNUNET_OK !=
- GNUNET_BIO_read_int64 (rh, &ret->data.dir.contents_completed)) ||
+ GNUNET_BIO_read_int64 (
+ rh,
+ "contents completed",
+ (int64_t *) &ret->data.dir.contents_completed)) ||
(GNUNET_OK !=
- GNUNET_BIO_read_int64 (rh, &ret->data.dir.contents_size)) ||
+ GNUNET_BIO_read_int64 (
+ rh,
+ "contents size",
+ (int64_t *)&ret->data.dir.contents_size)) ||
(NULL == (ret->data.dir.dir_data = GNUNET_malloc_large (dsize))) ||
(GNUNET_OK !=
GNUNET_BIO_read (rh, "dir-data", ret->data.dir.dir_data, dsize)) ||
@@ -1294,7 +1326,7 @@ copy_from_reader (struct GNUNET_BIO_WriteHandle *wh,
GNUNET_free (emsg);
return GNUNET_SYSERR;
}
- if (GNUNET_OK != GNUNET_BIO_write (wh, buf, ret))
+ if (GNUNET_OK != GNUNET_BIO_write (wh, "copied from reader", buf, ret))
return GNUNET_SYSERR;
off += ret;
}
@@ -1353,19 +1385,34 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
skss = GNUNET_FS_uri_to_string (fi->sks_uri);
else
skss = NULL;
- if ((GNUNET_OK != GNUNET_BIO_write (wh, &b, sizeof(b))) ||
- (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, fi->meta)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, ksks)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, chks)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, skss)) ||
+ struct GNUNET_BIO_WriteSpec ws1[] = {
+ GNUNET_BIO_write_spec_object ("b", &b, sizeof (b)),
+ GNUNET_BIO_write_spec_meta_data ("meta", fi->meta),
+ GNUNET_BIO_write_spec_string ("ksks", ksks),
+ GNUNET_BIO_write_spec_string ("chks", chks),
+ GNUNET_BIO_write_spec_string ("skss", skss),
+ GNUNET_BIO_write_spec_end (),
+ };
+ struct GNUNET_BIO_WriteSpec ws2[] = {
+ GNUNET_BIO_write_spec_string ("emsg", fi->emsg),
+ GNUNET_BIO_write_spec_string ("filename", fi->filename),
+ GNUNET_BIO_write_spec_int64 (
+ "expiration time",
+ (int64_t *) &fi->bo.expiration_time.abs_value_us),
+ GNUNET_BIO_write_spec_int32 (
+ "anonymity level",
+ (int32_t *) &fi->bo.anonymity_level),
+ GNUNET_BIO_write_spec_int32 (
+ "content priority",
+ (int32_t *) &fi->bo.content_priority),
+ GNUNET_BIO_write_spec_int32 (
+ "replication level",
+ (int32_t *) &fi->bo.replication_level),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws1)) ||
(GNUNET_OK != write_start_time (wh, fi->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, fi->emsg)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, fi->filename)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_int64 (wh, fi->bo.expiration_time.abs_value_us)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->bo.anonymity_level)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->bo.content_priority)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->bo.replication_level)))
+ (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws2)))
{
GNUNET_break (0);
goto cleanup;
@@ -1380,7 +1427,8 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
switch (b)
{
case 0: /* file-insert */
- if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size))
+ if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, "file size",
+ fi->data.file.file_size))
{
GNUNET_break (0);
goto cleanup;
@@ -1399,7 +1447,8 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
GNUNET_break (0);
goto cleanup;
}
- if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size))
+ if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, "file size",
+ fi->data.file.file_size))
{
GNUNET_break (0);
goto cleanup;
@@ -1413,8 +1462,10 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
GNUNET_break (0);
goto cleanup;
}
- if ((GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size)) ||
+ if ((GNUNET_OK != GNUNET_BIO_write_int64 (wh, "file size",
+ fi->data.file.file_size)) ||
(GNUNET_OK != GNUNET_BIO_write (wh,
+ "file id",
&fi->data.file.file_id,
sizeof(struct GNUNET_HashCode))))
{
@@ -1427,19 +1478,24 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
if ((NULL != fi->data.dir.entries) &&
(NULL == fi->data.dir.entries->serialization))
GNUNET_FS_file_information_sync_ (fi->data.dir.entries);
- if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->data.dir.dir_size)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_int64 (wh, fi->data.dir.contents_completed)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_int64 (wh, fi->data.dir.contents_size)) ||
- (GNUNET_OK != GNUNET_BIO_write (wh,
- fi->data.dir.dir_data,
- (uint32_t) fi->data.dir.dir_size)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_string (wh,
- (fi->data.dir.entries == NULL)
- ? NULL
- : fi->data.dir.entries->serialization)))
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_int32 ("dir size",
+ (int32_t *) &fi->data.dir.dir_size),
+ GNUNET_BIO_write_spec_int64 (
+ "contents completed",
+ (int64_t *) &fi->data.dir.contents_completed),
+ GNUNET_BIO_write_spec_int64 ("contents size",
+ (int64_t *) &fi->data.dir.contents_size),
+ GNUNET_BIO_write_spec_object ("dir data",
+ fi->data.dir.dir_data,
+ (uint32_t) fi->data.dir.dir_size),
+ GNUNET_BIO_write_spec_string ("dir entries",
+ (fi->data.dir.entries == NULL)
+ ? NULL
+ : fi->data.dir.entries->serialization),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
{
GNUNET_break (0);
goto cleanup;
@@ -1453,6 +1509,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
if ((NULL != fi->next) && (NULL == fi->next->serialization))
GNUNET_FS_file_information_sync_ (fi->next);
if (GNUNET_OK != GNUNET_BIO_write_string (wh,
+ "serialization",
(fi->next != NULL)
? fi->next->serialization
: NULL))
@@ -1460,7 +1517,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
GNUNET_break (0);
goto cleanup;
}
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
wh = NULL;
GNUNET_break (0);
@@ -1469,7 +1526,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
return; /* done! */
cleanup:
if (NULL != wh)
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
GNUNET_free_non_null (chks);
GNUNET_free_non_null (ksks);
GNUNET_free_non_null (skss);
@@ -1586,23 +1643,23 @@ deserialize_publish_file (void *cls, const char *filename)
pc->serialization = get_serialization_short_name (filename);
fi_root = NULL;
fi_pos = NULL;
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
GNUNET_break (0);
goto cleanup;
}
- if ((GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "publish-nid", &pc->nid, 1024)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &all_done)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &have_ns)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128)) ||
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_string ("publish-nid", &pc->nid, 1024),
+ GNUNET_BIO_read_spec_string ("publish-nuid", &pc->nuid, 1024),
+ GNUNET_BIO_read_spec_int32 ("options", &options),
+ GNUNET_BIO_read_spec_int32 ("all done", &all_done),
+ GNUNET_BIO_read_spec_int32 ("have ns", &have_ns),
+ GNUNET_BIO_read_spec_string ("publish-firoot", &fi_root, 128),
+ GNUNET_BIO_read_spec_string ("publish-fipos", &fi_pos, 128),
+ GNUNET_BIO_read_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs)) ||
((GNUNET_YES == have_ns) &&
(GNUNET_OK != GNUNET_BIO_read (rh, "publish-ns", &ns, sizeof(ns)))))
{
@@ -1729,26 +1786,29 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc)
goto cleanup;
}
have_ns = (NULL != pc->ns) ? GNUNET_YES : GNUNET_NO;
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nid)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nuid)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->options)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->all_done)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, have_ns)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->fi->serialization)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh,
- (NULL == pc->fi_pos)
- ? NULL
- : pc->fi_pos->serialization)) ||
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_string ("nid", pc->nid),
+ GNUNET_BIO_write_spec_string ("nuid", pc->nuid),
+ GNUNET_BIO_write_spec_int32 ("options", (int32_t *) &pc->options),
+ GNUNET_BIO_write_spec_int32 ("all done", &pc->all_done),
+ GNUNET_BIO_write_spec_int32 ("have ns", &have_ns),
+ GNUNET_BIO_write_spec_string ("serialization", pc->fi->serialization),
+ GNUNET_BIO_write_spec_string ("pos serialization", (NULL == pc->fi_pos)
+ ? NULL
+ : pc->fi_pos->serialization)
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)) ||
((NULL != pc->ns) &&
(GNUNET_OK !=
GNUNET_BIO_write (wh,
+ "ns",
pc->ns,
sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)))))
{
GNUNET_break (0);
goto cleanup;
}
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
wh = NULL;
GNUNET_break (0);
@@ -1757,7 +1817,7 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc)
return;
cleanup:
if (NULL != wh)
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
GNUNET_FS_remove_sync_file_ (pc->h,
GNUNET_FS_SYNC_PATH_MASTER_PUBLISH,
pc->serialization);
@@ -1797,25 +1857,34 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc)
uris = GNUNET_FS_uri_to_string (uc->ksk_uri);
else
uris = NULL;
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uc->filename)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, uc->file_size)) ||
+ struct GNUNET_BIO_WriteSpec ws1[] = {
+ GNUNET_BIO_write_spec_string ("filename", uc->filename),
+ GNUNET_BIO_write_spec_int64 ("file size", (int64_t *) &uc->file_size),
+ GNUNET_BIO_write_spec_end (),
+ };
+ struct GNUNET_BIO_WriteSpec ws2[] = {
+ GNUNET_BIO_write_spec_int32 ("state", (int32_t *) &uc->state),
+ GNUNET_BIO_write_spec_object ("hashkey", &uc->chk,
+ sizeof (struct ContentHashKey)),
+ GNUNET_BIO_write_spec_string ("uris", uris),
+ GNUNET_BIO_write_spec_int32 ("ksk offset", (int32_t *) &uc->ksk_offset),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws1)) ||
(GNUNET_OK != write_start_time (wh, uc->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->state)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write (wh, &uc->chk, sizeof(struct ContentHashKey))) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->ksk_offset)) ||
+ (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws2)) ||
((uc->state == UNINDEX_STATE_FS_NOTIFY) &&
(GNUNET_OK != GNUNET_BIO_write (wh,
+ "file id",
&uc->file_id,
sizeof(struct GNUNET_HashCode)))) ||
((uc->state == UNINDEX_STATE_ERROR) &&
- (GNUNET_OK != GNUNET_BIO_write_string (wh, uc->emsg))))
+ (GNUNET_OK != GNUNET_BIO_write_string (wh, "emsg", uc->emsg))))
{
GNUNET_break (0);
goto cleanup;
}
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
wh = NULL;
GNUNET_break (0);
@@ -1824,7 +1893,7 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc)
return;
cleanup:
if (NULL != wh)
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
GNUNET_FS_remove_sync_file_ (uc->h,
GNUNET_FS_SYNC_PATH_MASTER_UNINDEX,
uc->serialization);
@@ -1845,15 +1914,20 @@ write_download_request (struct GNUNET_BIO_WriteHandle *wh,
struct DownloadRequest *dr)
{
unsigned int i;
-
- if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->state)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dr->offset)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->num_children)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->depth)))
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_int32 ("state", (int32_t *) &dr->state),
+ GNUNET_BIO_write_spec_int64 ("offset", (int64_t *) &dr->offset),
+ GNUNET_BIO_write_spec_int32 ("num children", (int32_t *) &dr->num_children),
+ GNUNET_BIO_write_spec_int32 ("depth", (int32_t *) &dr->depth),
+ GNUNET_BIO_write_spec_end (),
+ };
+
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
return GNUNET_NO;
if ((BRS_CHK_SET == dr->state) &&
(GNUNET_OK !=
- GNUNET_BIO_write (wh, &dr->chk, sizeof(struct ContentHashKey))))
+ GNUNET_BIO_write (wh, "hashkey",
+ &dr->chk, sizeof(struct ContentHashKey))))
return GNUNET_NO;
for (i = 0; i < dr->num_children; i++)
if (GNUNET_NO == write_download_request (wh, dr->children[i]))
@@ -1875,11 +1949,16 @@ read_download_request (struct GNUNET_BIO_ReadHandle *rh)
unsigned int i;
dr = GNUNET_new (struct DownloadRequest);
- if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->state)) ||
- (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dr->offset)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->num_children)) ||
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_int32 ("state", (int32_t *) &dr->state),
+ GNUNET_BIO_read_spec_int64 ("offset", (int64_t *) &dr->offset),
+ GNUNET_BIO_read_spec_int32 ("num children", (int32_t *) &dr->num_children),
+ GNUNET_BIO_read_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs)) ||
(dr->num_children > CHK_PER_INODE) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->depth)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "depth",
+ (int32_t *) &dr->depth)) ||
((0 == dr->depth) && (dr->num_children > 0)) ||
((dr->depth > 0) && (0 == dr->num_children)))
{
@@ -2005,7 +2084,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
return;
}
}
- wh = GNUNET_BIO_write_open (fn);
+ wh = GNUNET_BIO_write_open_file (fn);
if (NULL == wh)
{
GNUNET_free (dc->serialization);
@@ -2016,19 +2095,28 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
GNUNET_assert ((GNUNET_YES == GNUNET_FS_uri_test_chk (dc->uri)) ||
(GNUNET_YES == GNUNET_FS_uri_test_loc (dc->uri)));
uris = GNUNET_FS_uri_to_string (dc->uri);
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) ||
- (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, dc->meta)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, dc->emsg)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, dc->filename)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, dc->temp_filename)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->old_file_size)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->offset)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->length)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->completed)) ||
+ struct GNUNET_BIO_WriteSpec ws1[] = {
+ GNUNET_BIO_write_spec_string ("uris", uris),
+ GNUNET_BIO_write_spec_meta_data ("metadata", dc->meta),
+ GNUNET_BIO_write_spec_string ("emsg", dc->emsg),
+ GNUNET_BIO_write_spec_string ("filename", dc->filename),
+ GNUNET_BIO_write_spec_string ("temp filename", dc->temp_filename),
+ GNUNET_BIO_write_spec_int64 ("old file size",
+ (int64_t *) &dc->old_file_size),
+ GNUNET_BIO_write_spec_int64 ("offset", (int64_t *) &dc->offset),
+ GNUNET_BIO_write_spec_int64 ("length", (int64_t *) &dc->length),
+ GNUNET_BIO_write_spec_int64 ("completed", (int64_t *) &dc->completed),
+ GNUNET_BIO_write_spec_end (),
+ };
+ struct GNUNET_BIO_WriteSpec ws2[] = {
+ GNUNET_BIO_write_spec_int32 ("anonymity", (int32_t *) &dc->anonymity),
+ GNUNET_BIO_write_spec_int32 ("options", (int32_t *) &dc->options),
+ GNUNET_BIO_write_spec_int32 ("has finished", (int32_t *) &dc->has_finished),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws1)) ||
(GNUNET_OK != write_start_time (wh, dc->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dc->anonymity)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) dc->options)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) dc->has_finished)))
+ (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws2)))
{
GNUNET_break (0);
goto cleanup;
@@ -2044,7 +2132,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
}
GNUNET_free_non_null (uris);
uris = NULL;
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
wh = NULL;
GNUNET_break (0);
@@ -2054,7 +2142,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
return;
cleanup:
if (NULL != wh)
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
GNUNET_free_non_null (uris);
if (0 != unlink (fn))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
@@ -2102,23 +2190,30 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
goto cleanup;
}
uris = GNUNET_FS_uri_to_string (sr->uri);
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh,
- (sr->download != NULL)
- ? sr->download->serialization
- : NULL)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_string (wh,
- (sr->update_search != NULL)
- ? sr->update_search->serialization
- : NULL)) ||
- (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, sr->meta)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write (wh, &sr->key, sizeof(struct GNUNET_HashCode))) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->mandatory_missing)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->optional_support)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->availability_success)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->availability_trials)))
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_string ("uris", uris),
+ GNUNET_BIO_write_spec_string ("download serialization",
+ (sr->download != NULL)
+ ? sr->download->serialization
+ : NULL),
+ GNUNET_BIO_write_spec_string ("update search serialization",
+ (sr->update_search != NULL)
+ ? sr->update_search->serialization
+ : NULL),
+ GNUNET_BIO_write_spec_meta_data ("metadata", sr->meta),
+ GNUNET_BIO_write_spec_object ("key", &sr->key,
+ sizeof(struct GNUNET_HashCode)),
+ GNUNET_BIO_write_spec_int32 ("mandatory missing",
+ (int32_t *) &sr->mandatory_missing),
+ GNUNET_BIO_write_spec_int32 ("optional support",
+ (int32_t *) &sr->optional_support),
+ GNUNET_BIO_write_spec_int32 ("availability success",
+ (int32_t *) &sr->availability_success),
+ GNUNET_BIO_write_spec_int32 ("availability trials",
+ (int32_t *) &sr->availability_trials),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
{
GNUNET_break (0);
goto cleanup;
@@ -2126,13 +2221,14 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
if ((NULL != sr->uri) && (GNUNET_FS_URI_KSK == sr->sc->uri->type) &&
(GNUNET_OK !=
GNUNET_BIO_write (wh,
+ "keyword bitmap",
sr->keyword_bitmap,
(sr->sc->uri->data.ksk.keywordCount + 7) / 8)))
{
GNUNET_break (0);
goto cleanup;
}
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
wh = NULL;
GNUNET_break (0);
@@ -2143,7 +2239,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
cleanup:
GNUNET_free_non_null (uris);
if (NULL != wh)
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
remove_sync_file_in_dir (sr->h,
(NULL == sr->sc->psearch_result)
? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
@@ -2188,19 +2284,21 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc)
(GNUNET_YES == GNUNET_FS_uri_test_sks (sc->uri)));
uris = GNUNET_FS_uri_to_string (sc->uri);
in_pause = (sc->task != NULL) ? 'r' : '\0';
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) ||
+ if ((GNUNET_OK != GNUNET_BIO_write_string (wh, "uris", uris)) ||
(GNUNET_OK != write_start_time (wh, sc->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, sc->emsg)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) sc->options)) ||
- (GNUNET_OK != GNUNET_BIO_write (wh, &in_pause, sizeof(in_pause))) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sc->anonymity)))
+ (GNUNET_OK != GNUNET_BIO_write_string (wh, "emsg", sc->emsg)) ||
+ (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "options",
+ (uint32_t) sc->options)) ||
+ (GNUNET_OK != GNUNET_BIO_write (wh, "in pause",
+ &in_pause, sizeof(in_pause))) ||
+ (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "anonymity", sc->anonymity)))
{
GNUNET_break (0);
goto cleanup;
}
GNUNET_free (uris);
uris = NULL;
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
wh = NULL;
GNUNET_break (0);
@@ -2209,7 +2307,7 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc)
return;
cleanup:
if (NULL != wh)
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
GNUNET_free_non_null (uris);
GNUNET_FS_remove_sync_file_ (sc->h, category, sc->serialization);
GNUNET_free (sc->serialization);
@@ -2239,7 +2337,7 @@ deserialize_unindex_file (void *cls, const char *filename)
uc = GNUNET_new (struct GNUNET_FS_UnindexContext);
uc->h = h;
uc->serialization = get_serialization_short_name (filename);
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
GNUNET_break (0);
@@ -2248,14 +2346,17 @@ deserialize_unindex_file (void *cls, const char *filename)
uris = NULL;
if ((GNUNET_OK !=
GNUNET_BIO_read_string (rh, "unindex-fn", &uc->filename, 10 * 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &uc->file_size)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int64 (rh, "file size",
+ (int64_t *) &uc->file_size)) ||
(GNUNET_OK != read_start_time (rh, &uc->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &state)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "state",
+ (int32_t *) &state)) ||
(GNUNET_OK !=
GNUNET_BIO_read (rh, "uri", &uc->chk, sizeof(struct ContentHashKey))) ||
(GNUNET_OK !=
GNUNET_BIO_read_string (rh, "unindex-kskuri", &uris, 10 * 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &uc->ksk_offset)))
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "ksk offset",
+ (int32_t *) &uc->ksk_offset)))
{
GNUNET_free_non_null (uris);
GNUNET_break (0);
@@ -2443,7 +2544,7 @@ deserialize_search_result (void *cls, const char *filename)
struct GNUNET_FS_SearchResult *sr;
ser = get_serialization_short_name (filename);
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
if (NULL != ser)
@@ -2478,10 +2579,22 @@ deserialize_search_result (void *cls, const char *filename)
"result-key",
&sr->key,
sizeof(struct GNUNET_HashCode))) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->mandatory_missing)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->optional_support)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->availability_success)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->availability_trials)))
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "mandatory missing",
+ (int32_t *) &sr->mandatory_missing)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "optional support",
+ (int32_t *) &sr->optional_support)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "availability success",
+ (int32_t *) &sr->availability_success)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (
+ rh,
+ "availability trials",
+ (int32_t *) &sr->availability_trials)))
{
GNUNET_break (0);
goto cleanup;
@@ -2741,7 +2854,7 @@ deserialize_subdownload (void *cls, const char *filename)
struct GNUNET_BIO_ReadHandle *rh;
ser = get_serialization_short_name (filename);
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -2827,29 +2940,35 @@ deserialize_download (struct GNUNET_FS_Handle *h,
dc->parent = parent;
dc->h = h;
dc->serialization = GNUNET_strdup (serialization);
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_meta_data ("download-meta", &dc->meta),
+ GNUNET_BIO_read_spec_string ("download-emsg", &dc->emsg, 10 * 1024),
+ GNUNET_BIO_read_spec_string ("download-fn", &dc->filename, 10 * 1024),
+ GNUNET_BIO_read_spec_string ("download-tfn",
+ &dc->temp_filename, 10 * 1024),
+ GNUNET_BIO_read_spec_int64 ("old file size",
+ (int64_t *) &dc->old_file_size),
+ GNUNET_BIO_read_spec_int64 ("offset",
+ (int64_t *) &dc->offset),
+ GNUNET_BIO_read_spec_int64 ("length",
+ (int64_t *) &dc->length),
+ GNUNET_BIO_read_spec_int64 ("completed",
+ (int64_t *) &dc->completed),
+ GNUNET_BIO_read_spec_end (),
+ };
if ((GNUNET_OK !=
GNUNET_BIO_read_string (rh, "download-uri", &uris, 10 * 1024)) ||
(NULL == (dc->uri = GNUNET_FS_uri_parse (uris, &emsg))) ||
((GNUNET_YES != GNUNET_FS_uri_test_chk (dc->uri)) &&
(GNUNET_YES != GNUNET_FS_uri_test_loc (dc->uri))) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_meta_data (rh, "download-meta", &dc->meta)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "download-emsg", &dc->emsg, 10 * 1024)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "download-fn", &dc->filename, 10 * 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_string (rh,
- "download-tfn",
- &dc->temp_filename,
- 10 * 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->old_file_size)) ||
- (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->offset)) ||
- (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->length)) ||
- (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->completed)) ||
+ (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs)) ||
(GNUNET_OK != read_start_time (rh, &dc->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dc->anonymity)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &status)))
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "anonymity",
+ (int32_t *) &dc->anonymity)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "options",
+ (int32_t *) &options)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "status",
+ (int32_t *) &status)))
{
GNUNET_break (0);
goto cleanup;
@@ -2972,10 +3091,12 @@ deserialize_search (struct GNUNET_FS_Handle *h,
(GNUNET_OK != read_start_time (rh, &sc->start_time)) ||
(GNUNET_OK !=
GNUNET_BIO_read_string (rh, "search-emsg", &sc->emsg, 10 * 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "options",
+ (int32_t *) &options)) ||
(GNUNET_OK !=
GNUNET_BIO_read (rh, "search-pause", &in_pause, sizeof(in_pause))) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sc->anonymity)))
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "anonymity",
+ (int32_t *) &sc->anonymity)))
{
GNUNET_break (0);
goto cleanup;
@@ -3038,7 +3159,7 @@ deserialize_search_file (void *cls, const char *filename)
if (S_ISDIR (buf.st_mode))
return GNUNET_OK; /* skip directories */
ser = get_serialization_short_name (filename);
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
if (NULL != ser)
@@ -3081,7 +3202,7 @@ deserialize_download_file (void *cls, const char *filename)
struct GNUNET_BIO_ReadHandle *rh;
ser = get_serialization_short_name (filename);
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
if (0 != unlink (filename))
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
index 6ede02afd..f098032d7 100644
--- a/src/fs/fs_namespace.c
+++ b/src/fs/fs_namespace.c
@@ -195,7 +195,7 @@ write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
char *uris;
fn = get_update_information_directory (uig->h, &uig->ns);
- wh = GNUNET_BIO_write_open (fn);
+ wh = GNUNET_BIO_write_open_file (fn);
if (NULL == wh)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -205,16 +205,22 @@ write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
GNUNET_free (fn);
return;
}
- if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, uig->update_node_count))
+ if (GNUNET_OK != GNUNET_BIO_write_int32 (wh,
+ "fs-namespace-node-count",
+ uig->update_node_count))
goto END;
for (i = 0; i < uig->update_node_count; i++)
{
n = uig->update_nodes[i];
uris = GNUNET_FS_uri_to_string (n->uri);
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) ||
- (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, n->update)) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, uris)))
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_string("fs-namespace-node-id", n->id),
+ GNUNET_BIO_write_spec_meta_data("fs-namespace-node-meta", n->md),
+ GNUNET_BIO_write_spec_string("fs-namespace-node-update", n->update),
+ GNUNET_BIO_write_spec_string("fs-namespace-uris", uris),
+ GNUNET_BIO_write_spec_end(),
+ };
+ if (GNUNET_OK != GNUNET_BIO_write_spec_commit(wh, ws))
{
GNUNET_free (uris);
break;
@@ -222,7 +228,7 @@ write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
GNUNET_free (uris);
}
END:
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_ ("Failed to write `%s': %s\n"),
fn,
@@ -260,13 +266,14 @@ read_update_information_graph (struct GNUNET_FS_Handle *h,
GNUNET_free (fn);
return uig;
}
- rh = GNUNET_BIO_read_open (fn);
+ rh = GNUNET_BIO_read_open_file (fn);
if (NULL == rh)
{
GNUNET_free (fn);
return uig;
}
- if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count))
+ if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "fs-namespace-count",
+ (int32_t *) &count))
{
GNUNET_break (0);
goto END;
@@ -284,12 +291,14 @@ read_update_information_graph (struct GNUNET_FS_Handle *h,
for (i = 0; i < count; i++)
{
n = GNUNET_new (struct NamespaceUpdateNode);
- if ((GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read_string (rh, "update-id", &n->update, 1024)) ||
- (GNUNET_OK != GNUNET_BIO_read_string (rh, "uri", &uris, 1024 * 2)))
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_string("identifier", &n->id, 1024),
+ GNUNET_BIO_read_spec_meta_data("meta", &n->md),
+ GNUNET_BIO_read_spec_string("update-id", &n->update, 1024),
+ GNUNET_BIO_read_spec_string("uri", &uris, 1024 * 2),
+ GNUNET_BIO_read_spec_end(),
+ };
+ if (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs))
{
GNUNET_break (0);
GNUNET_free_non_null (n->id);
diff --git a/src/fs/gnunet-auto-share.c b/src/fs/gnunet-auto-share.c
index 13bc908e8..3aed0268b 100644
--- a/src/fs/gnunet-auto-share.c
+++ b/src/fs/gnunet-auto-share.c
@@ -190,18 +190,22 @@ load_state ()
emsg = NULL;
fn = get_state_file ();
- rh = GNUNET_BIO_read_open (fn);
+ rh = GNUNET_BIO_read_open_file (fn);
GNUNET_free (fn);
if (NULL == rh)
return;
fn = NULL;
- if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &n))
+ if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "number of files",
+ (int32_t *) &n))
goto error;
while (n-- > 0)
{
- if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "filename", &fn, 1024)) ||
- (GNUNET_OK !=
- GNUNET_BIO_read (rh, "id", &id, sizeof(struct GNUNET_HashCode))))
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_string("filename", &fn, 1024),
+ GNUNET_BIO_read_spec_object("id", &id, sizeof(struct GNUNET_HashCode)),
+ GNUNET_BIO_read_spec_end(),
+ };
+ if (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs))
goto error;
wi = GNUNET_new (struct WorkItem);
wi->id = id;
@@ -251,9 +255,13 @@ write_item (void *cls, const struct GNUNET_HashCode *key, void *value)
"Saving serialization ID of file `%s' with value `%s'\n",
wi->filename,
GNUNET_h2s (&wi->id));
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, wi->filename)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write (wh, &wi->id, sizeof(struct GNUNET_HashCode))))
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_string ("auto-share-write-item-filename",
+ wi->filename),
+ GNUNET_BIO_write_spec_object ("id", &wi->id, sizeof(struct GNUNET_HashCode)),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws))
return GNUNET_SYSERR; /* write error, abort iteration */
return GNUNET_OK;
}
@@ -271,7 +279,7 @@ save_state ()
n = GNUNET_CONTAINER_multihashmap_size (work_finished);
fn = get_state_file ();
- wh = GNUNET_BIO_write_open (fn);
+ wh = GNUNET_BIO_write_open_file (fn);
if (NULL == wh)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -280,9 +288,9 @@ save_state ()
GNUNET_free (fn);
return;
}
- if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, n))
+ if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "size of state", n))
{
- (void) GNUNET_BIO_write_close (wh);
+ (void) GNUNET_BIO_write_close (wh, NULL);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_ ("Failed to save state to file %s\n"),
fn);
@@ -290,7 +298,7 @@ save_state ()
return;
}
(void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, &write_item, wh);
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_ ("Failed to save state to file %s\n"),
fn);
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index 98fca3ec5..f4d560176 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -123,7 +123,7 @@ write_index_list ()
"INDEXDB");
return;
}
- wh = GNUNET_BIO_write_open (fn);
+ wh = GNUNET_BIO_write_open_file (fn);
if (NULL == wh)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -134,11 +134,14 @@ write_index_list ()
}
for (pos = indexed_files_head; NULL != pos; pos = pos->next)
if ((GNUNET_OK != GNUNET_BIO_write (wh,
+ "fs-indexing-file-id",
&pos->file_id,
sizeof(struct GNUNET_HashCode))) ||
- (GNUNET_OK != GNUNET_BIO_write_string (wh, pos->filename)))
+ (GNUNET_OK != GNUNET_BIO_write_string (wh,
+ "fs-indexing-filename",
+ pos->filename)))
break;
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
_ ("Error writing `%s'.\n"),
@@ -178,7 +181,7 @@ read_index_list ()
GNUNET_free (fn);
return;
}
- rh = GNUNET_BIO_read_open (fn);
+ rh = GNUNET_BIO_read_open_file (fn);
if (NULL == rh)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
diff --git a/src/hostlist/gnunet-daemon-hostlist_client.c b/src/hostlist/gnunet-daemon-hostlist_client.c
index a5ff9f9fa..c2e8f5d88 100644
--- a/src/hostlist/gnunet-daemon-hostlist_client.c
+++ b/src/hostlist/gnunet-daemon-hostlist_client.c
@@ -1404,7 +1404,7 @@ load_hostlist_file ()
return;
}
- rh = GNUNET_BIO_read_open (filename);
+ rh = GNUNET_BIO_read_open_file (filename);
if (NULL == rh)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1417,13 +1417,17 @@ load_hostlist_file ()
}
counter = 0;
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_int32 ("times used", (int32_t *)&times_used),
+ GNUNET_BIO_read_spec_int64 ("quality", (int64_t *) &quality),
+ GNUNET_BIO_read_spec_int64 ("last used", (int64_t *) &last_used),
+ GNUNET_BIO_read_spec_int64 ("created", (int64_t *) &created),
+ GNUNET_BIO_read_spec_int32 ("hellos returned", (int32_t *) &hellos_returned),
+ GNUNET_BIO_read_spec_end (),
+ };
while ((GNUNET_OK == GNUNET_BIO_read_string (rh, "url", &uri, MAX_URL_LEN)) &&
(NULL != uri) &&
- (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &times_used)) &&
- (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) &&
- (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used)) &&
- (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created)) &&
- (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned)))
+ (GNUNET_OK == GNUNET_BIO_read_spec_commit (rh, rs)))
{
hostlist = GNUNET_malloc (sizeof(struct Hostlist) + strlen (uri) + 1);
hostlist->hello_count = hellos_returned;
@@ -1494,7 +1498,7 @@ save_hostlist_file (int shutdown)
GNUNET_free (filename);
return;
}
- wh = GNUNET_BIO_write_open (filename);
+ wh = GNUNET_BIO_write_open_file (filename);
if (NULL == wh)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1521,14 +1525,21 @@ save_hostlist_file (int shutdown)
}
if (GNUNET_YES == ok)
{
- if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pos->hostlist_uri)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->times_used)) ||
- (GNUNET_OK != GNUNET_BIO_write_int64 (wh, pos->quality)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_int64 (wh, pos->time_last_usage.abs_value_us)) ||
- (GNUNET_OK !=
- GNUNET_BIO_write_int64 (wh, pos->time_creation.abs_value_us)) ||
- (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->hello_count)))
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_string ("hostlist uri", pos->hostlist_uri),
+ GNUNET_BIO_write_spec_int32 ("times used", (int32_t *) &pos->times_used),
+ GNUNET_BIO_write_spec_int64 ("quality", (int64_t *) &pos->quality),
+ GNUNET_BIO_write_spec_int64 (
+ "last usage",
+ (int64_t *) &pos->time_last_usage.abs_value_us),
+ GNUNET_BIO_write_spec_int64 (
+ "creation time",
+ (int64_t *) &pos->time_creation.abs_value_us),
+ GNUNET_BIO_write_spec_int32 ("hellos count",
+ (int32_t *) &pos->hello_count),
+ GNUNET_BIO_write_spec_end (),
+ };
+ if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_ ("Error writing hostlist URIs to file `%s'\n"),
@@ -1548,7 +1559,7 @@ save_hostlist_file (int shutdown)
counter,
GNUNET_YES);
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_ ("Error writing hostlist URIs to file `%s'\n"),
filename);
diff --git a/src/include/gnunet_bio_lib.h b/src/include/gnunet_bio_lib.h
index 2f715ec97..687334c1c 100644
--- a/src/include/gnunet_bio_lib.h
+++ b/src/include/gnunet_bio_lib.h
@@ -42,6 +42,8 @@ extern "C"
#endif
#endif
+/****************************** READING API *******************************/
+
/**
* Handle for buffered reading.
*/
@@ -55,11 +57,22 @@ struct GNUNET_BIO_ReadHandle;
* @return IO handle on success, NULL on error
*/
struct GNUNET_BIO_ReadHandle *
-GNUNET_BIO_read_open (const char *fn);
+GNUNET_BIO_read_open_file (const char *fn);
+
+
+/**
+ * Create a handle from an existing allocated buffer.
+ *
+ * @param buffer the buffer to use as source
+ * @param size the total size in bytes of the buffer
+ * @return IO handle on sucess, NULL on error
+ */
+struct GNUNET_BIO_ReadHandle *
+GNUNET_BIO_read_open_buffer (void *buffer, size_t size);
/**
- * Close an open file. Reports if any errors reading
+ * Close an open handle. Reports if any errors reading
* from the file were encountered.
*
* @param h file handle
@@ -71,51 +84,40 @@ GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, char **emsg);
/**
- * Read the contents of a binary file into a buffer.
+ * Read some contents into a buffer.
*
- * @param h handle to an open file
+ * @param h the IO handle to read from
* @param what describes what is being read (for error message creation)
* @param result the buffer to write the result to
* @param len the number of bytes to read
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
int
-GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, const char *what,
- void *result, size_t len);
+GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *result,
+ size_t len);
/**
- * Read the contents of a binary file into a buffer.
+ * Read 0-terminated string.
*
- * @param h handle to an open file
- * @param file name of the source file
- * @param line line number in the source file
- * @param result the buffer to write the result to
- * @param len the number of bytes to read
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
- */
-int
-GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h,
- const char *file, int line,
- void *result, size_t len);
-
-/**
- * Read 0-terminated string from a file.
- *
- * @param h handle to an open file
+ * @param h the IO handle to read from
* @param what describes what is being read (for error message creation)
- * @param result the buffer to store a pointer to the (allocated) string to
+ * @param result where to store the pointer to the (allocated) string
* (note that *result could be set to NULL as well)
* @param max_length maximum allowed length for the string
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
int
-GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, const char *what,
- char **result, size_t max_length);
+GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ char **result,
+ size_t max_length);
/**
- * Read metadata container from a file.
+ * Read a metadata container.
*
* @param h handle to an open file
* @param what describes what is being read (for error message creation)
@@ -123,79 +125,69 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, const char *what,
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
int
-GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what,
+GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
struct GNUNET_CONTAINER_MetaData **result);
/**
* Read a float.
*
- * @param h hande to open file
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
* @param f address of float to read
*/
-#define GNUNET_BIO_read_float(h, f) (GNUNET_BIO_read_fn (h, __FILE__, __LINE__, \
- f, sizeof(float)))
+int
+GNUNET_BIO_read_float(struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ float *f);
/**
* Read a double.
*
- * @param h hande to open file
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
* @param f address of double to read
*/
-#define GNUNET_BIO_read_double(h, f) (GNUNET_BIO_read_fn (h, __FILE__, __LINE__, \
- f, sizeof(double)))
+int
+GNUNET_BIO_read_double(struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ double *f);
+
/**
* Read an (u)int32_t.
*
- * @param h hande to open file
- * @param file name of the source file
- * @param line line number in the code
- * @param i address of 32-bit integer to read
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, const char *file,
- int line, int32_t *i);
-
+GNUNET_BIO_read_int32 (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ int32_t *i);
-/**
- * Read an (u)int32_t.
- *
- * @param h hande to open file
- * @param i address of 32-bit integer to read
- */
-#define GNUNET_BIO_read_int32(h, i) GNUNET_BIO_read_int32__ (h, __FILE__, \
- __LINE__, \
- (int32_t *) i)
/**
* Read an (u)int64_t.
*
- * @param h hande to open file
- * @param file name of the source file
- * @param line line number in the code
- * @param i address of 64-bit integer to read
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, const char *file,
- int line, int64_t *i);
+GNUNET_BIO_read_int64 (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ int64_t *i);
-/**
- * Read an (u)int64_t.
- *
- * @param h hande to open file
- * @param i address of 64-bit integer to read
- */
-#define GNUNET_BIO_read_int64(h, i) GNUNET_BIO_read_int64__ (h, __FILE__, \
- __LINE__, \
- (int64_t *) i)
+/****************************** WRITING API *******************************/
/**
* Handle for buffered writing.
@@ -205,108 +197,481 @@ struct GNUNET_BIO_WriteHandle;
/**
* Open a file for writing.
*
- * @param fn file name to be opened
+ * @param fn name of the file to be opened
* @return IO handle on success, NULL on error
*/
struct GNUNET_BIO_WriteHandle *
-GNUNET_BIO_write_open (const char *fn);
+GNUNET_BIO_write_open_file (const char *fn);
/**
- * Close an open file for writing.
+ * Create a handle backed by an in-memory buffer.
*
- * @param h file handle
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ * @return IO handle on success, NULL on error
+ */
+struct GNUNET_BIO_WriteHandle *
+GNUNET_BIO_write_open_buffer (void);
+
+
+/**
+ * Force a file-based buffered writer to flush its buffer.
+ * If the handle does not use a file, this function returs #GNUNET_OK
+ * without doing anything.
+ *
+ * @param h the IO handle
+ * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned
+ * and the file is closed
*/
int
-GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h);
+GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h);
/**
- * Write a buffer to a file.
+ * Get the IO handle's contents.
+ * If the handle doesn't use an in-memory buffer, this function returns
+ * #GNUNET_SYSERR.
*
- * @param h handle to open file
- * @param buffer the data to write
- * @param n number of bytes to write
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ * @param h the IO handle
+ * @param emsg set to the (allocated) error message
+ * if the handle has an error message the return value is #GNUNET_SYSERR
+ * @param contents where to store the pointer to the handle's contents
+ * @param size where to store the size of @e contents
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
int
-GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, const void *buffer,
- size_t n);
+GNUNET_BIO_get_buffer_contents (struct GNUNET_BIO_WriteHandle *h,
+ char **emsg,
+ void **contents,
+ size_t *size);
+
+
+/**
+ * Close an IO handle.
+ * If the handle was using a file, the file will be closed.
+ *
+ * @param h file handle
+ * @param emsg set to the (allocated) error message
+ * if the handle has an error message, the return value is #GNUNET_SYSERR
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h, char **emsg);
/**
- * Force a buffered writer to flush its buffer
+ * Write a buffer to a handle.
*
- * @param h the writer handle
- * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned and
- * the file is closed
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param buffer the data to write
+ * @param n number of bytes to write
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h);
+GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ const void *buffer,
+ size_t n);
/**
- * Write a string to a file.
+ * Write a 0-terminated string.
*
- * @param h handle to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param s string to write (can be NULL)
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, const char *s);
+GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ const char *s);
/**
- * Write metadata container to a file.
+ * Write a metadata container.
*
- * @param h handle to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param m metadata to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
const struct GNUNET_CONTAINER_MetaData *m);
/**
* Write a float.
*
- * @param h hande to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param f float to write (must be a variable)
*/
-#define GNUNET_BIO_write_float(h, f) GNUNET_BIO_write (h, &f, sizeof(float))
-
+int
+GNUNET_BIO_write_float(struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ float f);
/**
* Write a double.
*
- * @param h hande to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param f double to write (must be a variable)
*/
-#define GNUNET_BIO_write_double(h, f) GNUNET_BIO_write (h, &f, sizeof(double))
+int
+GNUNET_BIO_write_double(struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ double f);
/**
* Write an (u)int32_t.
*
- * @param h hande to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param i 32-bit integer to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h, int32_t i);
+GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ int32_t i);
/**
* Write an (u)int64_t.
*
- * @param h hande to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param i 64-bit integer to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h, int64_t i);
+GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ int64_t i);
+
+
+/****************************** READ SPEC API ***************************/
+
+
+/**
+ * Function used to deserialize data read from @a h and store it into @a
+ * target.
+ *
+ * @param cls closure (can be NULL)
+ * @param h the IO handle to read from
+ * @param what what is being read (for error message creation)
+ * @param target where to store the data
+ * @param target_size how many bytes can be written in @a target
+ * can be 0 if the size is unknown or is not fixed
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+typedef int
+(*GNUNET_BIO_ReadHandler)(void *cls,
+ struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *target,
+ size_t target_size);
+
+
+/**
+ * Structure specifying a reading operation on an IO handle.
+ */
+struct GNUNET_BIO_ReadSpec
+{
+ /**
+ * Function performing data deserialization.
+ */
+ GNUNET_BIO_ReadHandler rh;
+
+ /**
+ * Closure for @e rh. Can be NULL.
+ */
+ void *cls;
+
+ /**
+ * What is being read (for error message creation)
+ */
+ const char *what;
+
+ /**
+ * Destination buffer. Can also be a pointer to a pointer, especially for
+ * dynamically allocated structures.
+ */
+ void *target;
+
+ /**
+ * Size of @e target. Can be 0 if unknown or not fixed.
+ */
+ size_t size;
+};
+
+
+/**
+ * End of specifications marker.
+ */
+#define GNUNET_BIO_read_spec_end() \
+ { NULL, NULL, NULL, NULL, 0 }
+
+
+/**
+ * Create the specification to read a certain amount of bytes.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to write the result to
+ * @param len the number of bytes to read
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_object (const char *what,
+ void *result,
+ size_t size);
+
+
+/**
+ * Create the specification to read a 0-terminated string.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param result where to store the pointer to the (allocated) string
+ * (note that *result could be set to NULL as well)
+ * @param max_length maximum allowed length for the string
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_string (const char *what,
+ char **result,
+ size_t max_length);
+
+
+/**
+ * Create the specification to read a metadata container.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to store a pointer to the (allocated) metadata
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_meta_data (const char *what,
+ struct GNUNET_CONTAINER_MetaData **result);
+
+
+/**
+ * Create the specification to read an (u)int32_t.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_int32 (const char *what,
+ int32_t *i);
+
+
+/**
+ * Create the specification to read an (u)int64_t.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_int64 (const char *what,
+ int64_t *i);
+
+
+/**
+ * Create the specification to read a float.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param f address of float to read
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_float(const char *what, float *f);
+
+
+/**
+ * Create the specification to read a double.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param f address of double to read
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_double(const char *what, double *f);
+
+
+/**
+ * Execute the read specifications in order.
+ *
+ * @param h the IO handle to read from
+ * @param rs array of read specs
+ * the last element must be #GNUNET_BIO_read_spec_end
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_BIO_read_spec_commit (struct GNUNET_BIO_ReadHandle *h,
+ struct GNUNET_BIO_ReadSpec *rs);
+
+
+/******************************* WRITE SPEC API *****************************/
+
+
+/**
+ * Function used to serialize data from a buffer and write it to @a h.
+ *
+ * @param cls closure (can be NULL)
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param source the data to write
+ * @param source_size how many bytes should be written
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+typedef int
+(*GNUNET_BIO_WriteHandler) (void *cls,
+ struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ void *source,
+ size_t source_size);
+
+
+/**
+ * Structure specifying a writing operation on an IO handle.
+ */
+struct GNUNET_BIO_WriteSpec
+{
+ /**
+ * Function performing data serialization.
+ */
+ GNUNET_BIO_WriteHandler wh;
+
+ /**
+ * Closure for @e rh. Can be NULL.
+ */
+ void *cls;
+
+ /**
+ * What is being read (for error message creation)
+ */
+ const char *what;
+
+ /**
+ * Source buffer. The data in this buffer will be written to the handle.
+ */
+ void *source;
+
+ /**
+ * Size of @e source. If it's smaller than the real size of @e source, only
+ * this many bytes will be written.
+ */
+ size_t source_size;
+};
+
+
+/**
+ * End of specifications marker.
+ */
+#define GNUNET_BIO_write_spec_end() \
+ { NULL, NULL, NULL, NULL, 0 }
+
+
+/**
+ * Create the specification to read some bytes.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param source the data to write
+ * @param size how many bytes should be written
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_object (const char *what,
+ void *source,
+ size_t size);
+
+
+/**
+ * Create the specification to write a 0-terminated string.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param s string to write (can be NULL)
+ * @return the read spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_string (const char *what,
+ const char *s);
+
+
+/**
+ * Create the specification to write a metadata container.
+ *
+ * @param what what is being written (for error message creation)
+ * @param m metadata to write
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_meta_data (const char *what,
+ const struct GNUNET_CONTAINER_MetaData *m);
+
+
+/**
+ * Create the specification to write an (u)int32_t.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param i pointer to a 32-bit integer
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_int32 (const char *what,
+ int32_t *i);
+
+
+/**
+ * Create the specification to write an (u)int64_t.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param i pointer to a 64-bit integer
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_int64 (const char *what,
+ int64_t *i);
+
+
+/**
+ * Create the specification to write a float.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param f pointer to a float
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_float(const char *what, float *f);
+
+
+/**
+ * Create the specification to write an double.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param f pointer to a double
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_double(const char *what, double *f);
+
+
+/**
+ * Execute the write specifications in order.
+ *
+ * @param h the IO handle to write to
+ * @param ws array of write specs
+ * the last element must be #GNUNET_BIO_write_spec_end
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_BIO_write_spec_commit (struct GNUNET_BIO_WriteHandle *h,
+ struct GNUNET_BIO_WriteSpec *ws);
#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_buffer_lib.h b/src/include/gnunet_buffer_lib.h
index c0ae06d77..e23536ab2 100644
--- a/src/include/gnunet_buffer_lib.h
+++ b/src/include/gnunet_buffer_lib.h
@@ -165,6 +165,19 @@ GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf);
/**
+ * Clear the buffer and return its contents.
+ * The caller is responsible to eventually #GNUNET_free
+ * the returned data.
+ *
+ * @param buf the buffer to reap the contents from
+ * @param size where to store the size of the returned data
+ * @returns the data contained in the string
+ */
+void *
+GNUNET_buffer_reap (struct GNUNET_Buffer *buf, size_t *size);
+
+
+/**
* Free the backing memory of the given buffer.
* Does not free the memory of the buffer control structure,
* which is typically stack-allocated.
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index 793f60694..411f533a5 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -1001,7 +1001,7 @@ handle_p2p_estimate (void *cls,
if (NULL != lh)
GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof(uint64_t));
if (NULL != histogram)
- GNUNET_BIO_write_int64 (histogram, t);
+ GNUNET_BIO_write_int64 (histogram, "histogram-time", t);
}
#endif
GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
@@ -1299,7 +1299,7 @@ shutdown_task (void *cls)
}
if (NULL != histogram)
{
- GNUNET_BIO_write_close (histogram);
+ GNUNET_BIO_write_close (histogram, NULL);
histogram = NULL;
}
#endif
@@ -1453,7 +1453,7 @@ run (void *cls,
GNUNET_assert (
0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
GNUNET_free (histogram_dir);
- histogram = GNUNET_BIO_write_open (histogram_fn);
+ histogram = GNUNET_BIO_write_open_file (histogram_fn);
if (NULL == histogram)
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unable to open histogram file `%s'\n",
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
index 5d58c3743..d40f74aaf 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -263,7 +263,7 @@ save ()
return;
}
(void) GNUNET_DISK_directory_create_for_file (fn);
- wh = GNUNET_BIO_write_open (fn);
+ wh = GNUNET_BIO_write_open_file (fn);
total = 0;
while (NULL != (se = sub_head))
{
@@ -290,10 +290,10 @@ save ()
msg->flags =
htonl (pos->persistent ? GNUNET_STATISTICS_SETFLAG_PERSISTENT : 0);
msg->value = GNUNET_htonll (pos->value);
- if (GNUNET_OK != GNUNET_BIO_write (wh, msg, size))
+ if (GNUNET_OK != GNUNET_BIO_write (wh, "statistics-save-msg", msg, size))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", fn);
wh = NULL;
}
@@ -309,7 +309,7 @@ save ()
}
if (NULL != wh)
{
- if (GNUNET_OK != GNUNET_BIO_write_close (wh))
+ if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", fn);
if (0 == total)
GNUNET_break (0 == unlink (fn));
@@ -964,7 +964,7 @@ load ()
return;
}
buf = GNUNET_malloc (fsize);
- rh = GNUNET_BIO_read_open (fn);
+ rh = GNUNET_BIO_read_open_file (fn);
if (! rh)
{
GNUNET_free (buf);
diff --git a/src/testbed-logger/gnunet-service-testbed-logger.c b/src/testbed-logger/gnunet-service-testbed-logger.c
index 4e0a3cd34..81652fa4f 100644
--- a/src/testbed-logger/gnunet-service-testbed-logger.c
+++ b/src/testbed-logger/gnunet-service-testbed-logger.c
@@ -85,6 +85,7 @@ handle_log_msg (void *cls,
ms = ntohs (msg->size) - sizeof(struct GNUNET_MessageHeader);
GNUNET_BIO_write (bio,
+ "testbed-logger-handle-log-msg",
&msg[1],
ms);
GNUNET_SERVICE_client_continue (client);
@@ -108,7 +109,7 @@ shutdown_task (void *cls)
return;
}
GNUNET_break (GNUNET_OK ==
- GNUNET_BIO_write_close (bio));
+ GNUNET_BIO_write_close (bio, NULL));
}
@@ -202,7 +203,7 @@ logger_run (void *cls,
(intmax_t) pid);
GNUNET_free (hname);
GNUNET_free (dir);
- if (NULL == (bio = GNUNET_BIO_write_open (fn)))
+ if (NULL == (bio = GNUNET_BIO_write_open_file (fn)))
{
GNUNET_free (fn);
GNUNET_SCHEDULER_shutdown ();
diff --git a/src/testbed/gnunet-service-testbed_cpustatus.c b/src/testbed/gnunet-service-testbed_cpustatus.c
index e96449def..2d490ba8c 100644
--- a/src/testbed/gnunet-service-testbed_cpustatus.c
+++ b/src/testbed/gnunet-service-testbed_cpustatus.c
@@ -568,7 +568,7 @@ sample_load_task (void *cls)
ld_cpu, ld_disk, mem_usage, nproc);
if (0 < nbs)
{
- GNUNET_BIO_write (bw, str, nbs);
+ GNUNET_BIO_write (bw, "sample load task", str, nbs);
}
else
GNUNET_break (0);
@@ -612,7 +612,7 @@ GST_stats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
hostname, (intmax_t) getpid ());
GNUNET_free (stats_dir);
GNUNET_free (hostname);
- if (NULL == (bw = GNUNET_BIO_write_open (fn)))
+ if (NULL == (bw = GNUNET_BIO_write_open_file (fn)))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
_ ("Cannot open %s for writing load statistics. "
@@ -656,7 +656,7 @@ GST_stats_destroy ()
GNUNET_SCHEDULER_cancel (sample_load_task_id);
sample_load_task_id = NULL;
}
- GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bw));
+ GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bw, NULL));
bw = NULL;
}
diff --git a/src/util/bio.c b/src/util/bio.c
index e05258f73..ce15f073b 100644
--- a/src/util/bio.c
+++ b/src/util/bio.c
@@ -48,12 +48,37 @@
/**
+ * Enum used internally to know how buffering is handled.
+ *
+ * The idea is that by using an enum, BIO can be extended to support other
+ * kinds of "backend" for buffering (or just formatted I/O.)
+ */
+enum IOType
+{
+ /**
+ * The handle uses a file to read/write data.
+ */
+ IO_FILE = 0,
+
+ /**
+ * The data is stored entirely in memory.
+ */
+ IO_BUFFER,
+};
+
+
+/**
* Handle for buffered reading.
*/
struct GNUNET_BIO_ReadHandle
{
/**
- * Underlying file abstraction.
+ * The "backend" type.
+ */
+ enum IOType type;
+
+ /**
+ * Handle to a file on disk, if @e type is #IO_FILE.
*/
struct GNUNET_DISK_FileHandle *fd;
@@ -63,12 +88,12 @@ struct GNUNET_BIO_ReadHandle
char *emsg;
/**
- * I/O buffer. Allocated at the end of the struct, do not free!
+ * I/O buffer. Do @b not free!
*/
char *buffer;
/**
- * Number of bytes available in read @e buffer.
+ * Number of bytes available in @e buffer.
*/
size_t have;
@@ -91,7 +116,7 @@ struct GNUNET_BIO_ReadHandle
* @return IO handle on success, NULL on error
*/
struct GNUNET_BIO_ReadHandle *
-GNUNET_BIO_read_open (const char *fn)
+GNUNET_BIO_read_open_file (const char *fn)
{
struct GNUNET_DISK_FileHandle *fd;
struct GNUNET_BIO_ReadHandle *h;
@@ -100,6 +125,7 @@ GNUNET_BIO_read_open (const char *fn)
if (NULL == fd)
return NULL;
h = GNUNET_malloc (sizeof(struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE);
+ h->type = IO_FILE;
h->buffer = (char *) &h[1];
h->size = BIO_BUFFER_SIZE;
h->fd = fd;
@@ -108,11 +134,32 @@ GNUNET_BIO_read_open (const char *fn)
/**
- * Close an open file. Reports if any errors reading
+ * Create a handle from an existing allocated buffer.
+ *
+ * @param buffer the buffer to use as source
+ * @param size the total size in bytes of the buffer
+ * @return IO handle on sucess, NULL on error
+ */
+struct GNUNET_BIO_ReadHandle *
+GNUNET_BIO_read_open_buffer (void *buffer, size_t size)
+{
+ struct GNUNET_BIO_ReadHandle *h;
+
+ h = GNUNET_new (struct GNUNET_BIO_ReadHandle);
+ h->type = IO_BUFFER;
+ h->buffer = buffer;
+ h->size = size;
+ return h;
+}
+
+
+/**
+ * Close an open handle. Reports if any errors reading
* from the file were encountered.
*
* @param h file handle
- * @param emsg set to the error message
+ * @param emsg set to the (allocated) error message
+ * if the handle has an error message, the return value is #GNUNET_SYSERR
* @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
int
@@ -121,60 +168,63 @@ GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, char **emsg)
int err;
err = (NULL == h->emsg) ? GNUNET_OK : GNUNET_SYSERR;
- if (emsg != NULL)
+ if (NULL != emsg)
*emsg = h->emsg;
else
GNUNET_free_non_null (h->emsg);
- GNUNET_DISK_file_close (h->fd);
+ switch (h->type)
+ {
+ case IO_FILE:
+ GNUNET_DISK_file_close (h->fd);
+ break;
+ case IO_BUFFER:
+ break;
+ default:
+ break;
+ }
GNUNET_free (h);
return err;
}
/**
- * Read the contents of a binary file into a buffer.
+ * Function used internally to read the contents of a file into a buffer.
*
- * @param h handle to an open file
+ * @param h the IO handle to read from
* @param what describes what is being read (for error message creation)
- * @param result the buffer to write the result to
+ * @param result the buffer to write the data to
* @param len the number of bytes to read
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
-int
-GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
- const char *what,
- void *result,
- size_t len)
+static int
+read_from_file (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ char *result,
+ size_t len)
{
- char *dst = result;
+ size_t pos = 0;
size_t min;
- size_t pos;
ssize_t ret;
- if (NULL != h->emsg)
- return GNUNET_SYSERR;
- pos = 0;
do
{
- /* first, use buffer */
min = h->have - h->pos;
- if (min > 0)
+ if (0 < min)
{
- if (min > len - pos)
+ if (len - pos < min)
min = len - pos;
- GNUNET_memcpy (&dst[pos], &h->buffer[h->pos], min);
+ GNUNET_memcpy (&result[pos], &h->buffer[h->pos], min);
h->pos += min;
pos += min;
}
- if (pos == len)
- return GNUNET_OK; /* done! */
+ if (len == pos)
+ return GNUNET_OK;
GNUNET_assert (((off_t) h->have) == h->pos);
- /* fill buffer */
ret = GNUNET_DISK_file_read (h->fd, h->buffer, h->size);
if (-1 == ret)
{
GNUNET_asprintf (&h->emsg,
- _ ("Error reading `%s': %s"),
+ _ ("Error reading `%s' from file: %s"),
what,
strerror (errno));
return GNUNET_SYSERR;
@@ -182,7 +232,7 @@ GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
if (0 == ret)
{
GNUNET_asprintf (&h->emsg,
- _ ("Error reading `%s': %s"),
+ _ ("Error reading `%s' from file: %s"),
what,
_ ("End of file"));
return GNUNET_SYSERR;
@@ -190,41 +240,84 @@ GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
h->pos = 0;
h->have = ret;
}
- while (pos < len); /* should always be true */
+ while (pos < len);
return GNUNET_OK;
}
/**
- * Read the contents of a binary file into a buffer.
+ * Function used internally to read the content of a buffer into a buffer.
*
- * @param h handle to an open file
- * @param file name of the source file
- * @param line line number in the source file
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to write the result to
+ * @param len the number of bytes to read
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+read_from_buffer (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ char *result,
+ size_t len)
+{
+ if (h->size < len || h->size - h->pos < len)
+ {
+ GNUNET_asprintf (&h->emsg,
+ _ ("Error while reading `%s' from buffer: %s"),
+ what,
+ _ ("Not enough data left"));
+ return GNUNET_SYSERR;
+ }
+ GNUNET_memcpy (result, h->buffer + h->pos, len);
+ h->pos += len;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Read some contents into a buffer.
+ *
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
* @param result the buffer to write the result to
* @param len the number of bytes to read
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
int
-GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h,
- const char *file,
- int line,
- void *result,
- size_t len)
+GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *result,
+ size_t len)
{
- char what[PATH_MAX + 1024];
+ char *dst = result;
- GNUNET_snprintf (what, sizeof(what), "%s:%d", file, line);
- return GNUNET_BIO_read (h, what, result, len);
+ if (NULL != h->emsg)
+ return GNUNET_SYSERR;
+
+ if (0 == len)
+ return GNUNET_OK;
+
+ switch (h->type)
+ {
+ case IO_FILE:
+ return read_from_file (h, what, dst, len);
+ case IO_BUFFER:
+ return read_from_buffer (h, what, dst, len);
+ default:
+ GNUNET_asprintf (&h->emsg,
+ _ ("Invalid handle type while reading `%s'"),
+ what);
+ return GNUNET_SYSERR;
+ }
}
/**
- * Read 0-terminated string from a file.
+ * Read 0-terminated string.
*
- * @param h handle to an open file
+ * @param h the IO handle to read from
* @param what describes what is being read (for error message creation)
- * @param result the buffer to store a pointer to the (allocated) string to
+ * @param result where to store the pointer to the (allocated) string
* (note that *result could be set to NULL as well)
* @param max_length maximum allowed length for the string
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
@@ -238,10 +331,21 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
char *buf;
uint32_t big;
- if (GNUNET_OK != GNUNET_BIO_read_int32 (h, &big))
+ if (GNUNET_OK != GNUNET_BIO_read_int32 (h,
+ _ ("string length"),
+ (int32_t *) &big))
{
- GNUNET_free_non_null (h->emsg);
- GNUNET_asprintf (&h->emsg, _ ("Error reading length of string `%s'"), what);
+ char *tmp = h->emsg;
+ if (NULL != tmp)
+ GNUNET_asprintf (&h->emsg,
+ _ ("%s (while reading `%s')"),
+ tmp,
+ what);
+ else
+ GNUNET_asprintf (&h->emsg,
+ _ ("Error reading length of string `%s'"),
+ what);
+ GNUNET_free_non_null (tmp);
return GNUNET_SYSERR;
}
if (0 == big)
@@ -274,7 +378,7 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
/**
- * Read metadata container from a file.
+ * Read a metadata container.
*
* @param h handle to an open file
* @param what describes what is being read (for error message creation)
@@ -290,20 +394,23 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
char *buf;
struct GNUNET_CONTAINER_MetaData *meta;
- if (GNUNET_OK != GNUNET_BIO_read_int32 (h, (int32_t *) &size))
+ if (GNUNET_OK != GNUNET_BIO_read_int32 (h,
+ _ ("metadata length"),
+ (int32_t *) &size))
return GNUNET_SYSERR;
- if (size == 0)
+ if (0 == size)
{
*result = NULL;
return GNUNET_OK;
}
- if (size > MAX_META_DATA)
+ if (MAX_META_DATA < size)
{
- GNUNET_asprintf (&h->emsg,
- _ ("Serialized metadata `%s' larger than allowed (%u>%u)"),
- what,
- size,
- MAX_META_DATA);
+ GNUNET_asprintf (
+ &h->emsg,
+ _ ("Serialized metadata `%s' larger than allowed (%u > %u)"),
+ what,
+ size,
+ MAX_META_DATA);
return GNUNET_SYSERR;
}
buf = GNUNET_malloc (size);
@@ -316,7 +423,7 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
if (NULL == meta)
{
GNUNET_free (buf);
- GNUNET_asprintf (&h->emsg, _ ("Metadata `%s' failed to deserialize"), what);
+ GNUNET_asprintf (&h->emsg, _ ("Failed to deserialize metadata `%s'"), what);
return GNUNET_SYSERR;
}
GNUNET_free (buf);
@@ -324,25 +431,56 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
return GNUNET_OK;
}
+/**
+ * Read a float.
+ *
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param f address of float to read
+ */
+int
+GNUNET_BIO_read_float(struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ float *f)
+{
+ int32_t *i = (int32_t *) f;
+ return GNUNET_BIO_read_int32 (h, what, i);
+}
+
+
+/**
+ * Read a double.
+ *
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param f address of double to read
+ */
+int
+GNUNET_BIO_read_double(struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ double *f)
+{
+ int64_t *i = (int64_t *) f;
+ return GNUNET_BIO_read_int64 (h, what, i);
+}
+
/**
* Read an (u)int32_t.
*
- * @param h hande to open file
- * @param file name of the source file
- * @param line line number in the source file
- * @param i address of 32-bit integer to read
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
- const char *file,
- int line,
- int32_t *i)
+GNUNET_BIO_read_int32 (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ int32_t *i)
{
int32_t big;
- if (GNUNET_OK != GNUNET_BIO_read_fn (h, file, line, &big, sizeof(int32_t)))
+ if (GNUNET_OK != GNUNET_BIO_read (h, what, &big, sizeof(int32_t)))
return GNUNET_SYSERR;
*i = ntohl (big);
return GNUNET_OK;
@@ -352,21 +490,19 @@ GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
/**
* Read an (u)int64_t.
*
- * @param h hande to open file
- * @param file name of the source file
- * @param line line number in the source file
- * @param i address of 64-bit integer to read
+ * @param h the IO handle to read from
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
- const char *file,
- int line,
- int64_t *i)
+GNUNET_BIO_read_int64 (struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ int64_t *i)
{
int64_t big;
- if (GNUNET_OK != GNUNET_BIO_read_fn (h, file, line, &big, sizeof(int64_t)))
+ if (GNUNET_OK != GNUNET_BIO_read (h, what, &big, sizeof(int64_t)))
return GNUNET_SYSERR;
*i = GNUNET_ntohll (big);
return GNUNET_OK;
@@ -379,17 +515,29 @@ GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
struct GNUNET_BIO_WriteHandle
{
/**
- * Underlying file handle.
+ * The "backend" type.
+ */
+ enum IOType type;
+
+ /**
+ * Handle to a file on disk, if @e type is #IO_FILE.
*/
struct GNUNET_DISK_FileHandle *fd;
/**
- * I/O buffer. Do not free, allocated at the end of the struct.
+ * Error message, NULL if there were no errors.
*/
- char *buffer;
+ char *emsg;
+
+ /**
+ * I/O buffer.
+ * This field is a void * because it is used to hold pointers to allocated
+ * structures or arrays and will be casted to the appropriate type.
+ */
+ void *buffer;
/**
- * Number of bytes already in @e buffer.
+ * Number of bytes available in @e buffer.
*/
size_t have;
@@ -403,25 +551,26 @@ struct GNUNET_BIO_WriteHandle
/**
* Open a file for writing.
*
- * @param fn file name to be opened
+ * @param fn name of the file to be opened
* @return IO handle on success, NULL on error
*/
struct GNUNET_BIO_WriteHandle *
-GNUNET_BIO_write_open (const char *fn)
+GNUNET_BIO_write_open_file (const char *fn)
{
struct GNUNET_DISK_FileHandle *fd;
struct GNUNET_BIO_WriteHandle *h;
fd =
GNUNET_DISK_file_open (fn,
- GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE
+ GNUNET_DISK_OPEN_WRITE
+ | GNUNET_DISK_OPEN_TRUNCATE
| GNUNET_DISK_OPEN_CREATE,
GNUNET_DISK_PERM_USER_READ
| GNUNET_DISK_PERM_USER_WRITE);
if (NULL == fd)
return NULL;
h = GNUNET_malloc (sizeof(struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE);
- h->buffer = (char *) &h[1];
+ h->buffer = &h[1];
h->size = BIO_BUFFER_SIZE;
h->fd = fd;
return h;
@@ -429,42 +578,94 @@ GNUNET_BIO_write_open (const char *fn)
/**
- * Close an open file for writing.
+ * Create a handle backed by an in-memory buffer.
+ *
+ * @return IO handle on success, NULL on error
+ */
+struct GNUNET_BIO_WriteHandle *
+GNUNET_BIO_write_open_buffer (void)
+{
+ struct GNUNET_BIO_WriteHandle *h;
+
+ h = GNUNET_new (struct GNUNET_BIO_WriteHandle);
+ h->type = IO_BUFFER;
+ h->buffer = (void *) GNUNET_malloc (sizeof (struct GNUNET_Buffer));
+ return h;
+}
+
+
+/**
+ * Close an IO handle.
+ * If the handle was using a file, the file will be closed.
*
* @param h file handle
+ * @param emsg set to the (allocated) error message
+ * if the handle has an error message, the return value is #GNUNET_SYSERR
* @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
int
-GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h)
+GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h, char **emsg)
{
- int ret;
+ int err;
- ret = GNUNET_SYSERR;
- if ((NULL != h->fd) && (GNUNET_OK == (ret = GNUNET_BIO_flush (h))))
- GNUNET_DISK_file_close (h->fd);
+ err = (NULL == h->emsg) ? GNUNET_OK : GNUNET_SYSERR;
+ if (NULL != emsg)
+ *emsg = h->emsg;
+ else
+ GNUNET_free_non_null (h->emsg);
+ switch (h->type)
+ {
+ case IO_FILE:
+ if (NULL == h->fd)
+ return GNUNET_SYSERR;
+ if (GNUNET_OK != GNUNET_BIO_flush (h))
+ {
+ if (NULL != emsg)
+ *emsg = h->emsg;
+ else
+ GNUNET_free_non_null (h->emsg);
+ err = GNUNET_SYSERR;
+ }
+ else
+ {
+ GNUNET_DISK_file_close (h->fd);
+ }
+ break;
+ case IO_BUFFER:
+ GNUNET_buffer_clear ((struct GNUNET_Buffer *) h->buffer);
+ GNUNET_free (h->buffer);
+ break;
+ }
GNUNET_free (h);
- return ret;
+ return err;
}
/**
- * Force a buffered writer to flush its buffer
+ * Force a file-based buffered writer to flush its buffer.
+ * If the handle does not use a file, this function returs #GNUNET_OK
+ * without doing anything.
*
- * @param h the writer handle
- * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned and
- * the file is closed
+ * @param h the IO handle
+ * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned
+ * and the file is closed
*/
int
GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h)
{
ssize_t ret;
+ if (IO_FILE != h->type)
+ return GNUNET_OK;
+
ret = GNUNET_DISK_file_write (h->fd, h->buffer, h->have);
if (ret != (ssize_t) h->have)
{
GNUNET_DISK_file_close (h->fd);
h->fd = NULL;
- return GNUNET_SYSERR; /* error */
+ GNUNET_free_non_null (h->emsg);
+ GNUNET_asprintf (&h->emsg, _ ("Unable to flush buffer to file"));
+ return GNUNET_SYSERR;
}
h->have = 0;
return GNUNET_OK;
@@ -472,96 +673,213 @@ GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h)
/**
- * Write a buffer to a file.
+ * Get the IO handle's contents.
+ * If the handle doesn't use an in-memory buffer, this function returns
+ * #GNUNET_SYSERR.
*
- * @param h handle to open file
- * @param buffer the data to write
- * @param n number of bytes to write
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ * @param h the IO handle
+ * @param emsg set to the (allocated) error message
+ * if the handle has an error message the return value is #GNUNET_SYSERR
+ * @param contents where to store the pointer to the handle's contents
+ * @param size where to store the size of @e contents
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
*/
int
-GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
- const void *buffer,
- size_t n)
+GNUNET_BIO_get_buffer_contents (struct GNUNET_BIO_WriteHandle *h,
+ char **emsg,
+ void **contents,
+ size_t *size)
+{
+ if (IO_BUFFER != h->type)
+ return GNUNET_SYSERR;
+ if (NULL == contents || NULL == size)
+ return GNUNET_SYSERR;
+ int ret = (NULL != h->emsg) ? GNUNET_SYSERR : GNUNET_OK;
+ if (NULL != emsg)
+ *emsg = h->emsg;
+ else
+ GNUNET_free_non_null (h->emsg);
+ *contents = GNUNET_buffer_reap ((struct GNUNET_Buffer *) h->buffer, size);
+ return ret;
+}
+
+
+/**
+ * Function used internally to write the contents of a buffer into a file.
+ *
+ * @param h the IO handle to write to
+ * @param what describes what is being written (for error message creation)
+ * @param source the buffer to write
+ * @param len the number of bytes to write
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_to_file (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ const char *source,
+ size_t len)
{
- const char *src = buffer;
size_t min;
- size_t pos;
+ size_t pos = 0;
+ char *buffer = (char *) h->buffer;
if (NULL == h->fd)
+ {
+ GNUNET_asprintf (&h->emsg,
+ _ ("Error while writing `%s' to file: %s"),
+ what,
+ _ ("No associated file"));
return GNUNET_SYSERR;
- pos = 0;
+ }
+
do
{
- /* first, just use buffer */
min = h->size - h->have;
- if (min > n - pos)
- min = n - pos;
- GNUNET_memcpy (&h->buffer[h->have], &src[pos], min);
+ if (len - pos < min)
+ min = len - pos;
+ GNUNET_memcpy (&buffer[h->have], &source[pos], min);
pos += min;
h->have += min;
- if (pos == n)
- return GNUNET_OK; /* done */
+ if (len == pos)
+ return GNUNET_OK;
GNUNET_assert (h->have == h->size);
if (GNUNET_OK != GNUNET_BIO_flush (h))
- return GNUNET_SYSERR; /* error */
+ {
+ char *tmp = h->emsg;
+ GNUNET_asprintf (&h->emsg,
+ _ ("Error while writing `%s' to file: %s"),
+ what,
+ tmp);
+ GNUNET_free_non_null (tmp);
+ return GNUNET_SYSERR;
+ }
}
- while (pos < n); /* should always be true */
+ while (pos < len);
GNUNET_break (0);
return GNUNET_OK;
}
/**
- * Write a string to a file.
+ * Function used internally to write the contents of a buffer to another buffer.
+ *
+ * @param h the IO handle to write to
+ * @param what describes what is being written (for error message creation)
+ * @param source the buffer to write
+ * @param len the number of bytes to write
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_to_buffer (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ const char *source,
+ size_t len)
+{
+ GNUNET_buffer_write ((struct GNUNET_Buffer *) h->buffer, source, len);
+ h->have += len;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Write a buffer to a handle.
+ *
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param buffer the data to write
+ * @param n number of bytes to write
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ const void *buffer,
+ size_t n)
+{
+ const char *src = buffer;
+
+ if (NULL != h->emsg)
+ return GNUNET_SYSERR;
+
+ if (0 == n)
+ return GNUNET_OK;
+
+ switch (h->type)
+ {
+ case IO_FILE:
+ return write_to_file (h, what, src, n);
+ case IO_BUFFER:
+ return write_to_buffer (h, what, src, n);
+ default:
+ GNUNET_asprintf (&h->emsg,
+ _ ("Invalid handle type while writing `%s'"),
+ what);
+ return GNUNET_SYSERR;
+ }
+}
+
+
+/**
+ * Write a 0-terminated string.
*
- * @param h handle to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param s string to write (can be NULL)
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, const char *s)
+GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ const char *s)
{
uint32_t slen;
slen = (uint32_t) ((s == NULL) ? 0 : strlen (s) + 1);
- if (GNUNET_OK != GNUNET_BIO_write_int32 (h, slen))
+ if (GNUNET_OK != GNUNET_BIO_write_int32 (h, _ ("string length"), slen))
return GNUNET_SYSERR;
if (0 != slen)
- return GNUNET_BIO_write (h, s, slen - 1);
+ return GNUNET_BIO_write (h, what, s, slen - 1);
return GNUNET_OK;
}
/**
- * Write metadata container to a file.
+ * Write a metadata container.
*
- * @param h handle to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param m metadata to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
const struct GNUNET_CONTAINER_MetaData *m)
{
ssize_t size;
char *buf;
if (m == NULL)
- return GNUNET_BIO_write_int32 (h, 0);
+ return GNUNET_BIO_write_int32 (h, _ ("metadata length"), 0);
buf = NULL;
size = GNUNET_CONTAINER_meta_data_serialize (
m,
&buf,
MAX_META_DATA,
GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
- if (size == -1)
+ if (-1 == size)
{
GNUNET_free (buf);
+ GNUNET_free_non_null (h->emsg);
+ GNUNET_asprintf (&h->emsg,
+ _ ("Failed to serialize metadata `%s'"),
+ what);
return GNUNET_SYSERR;
}
- if ((GNUNET_OK != GNUNET_BIO_write_int32 (h, (uint32_t) size)) ||
- (GNUNET_OK != GNUNET_BIO_write (h, buf, size)))
+ if ((GNUNET_OK != GNUNET_BIO_write_int32 (h,
+ _ ("metadata length"),
+ (uint32_t) size))
+ || (GNUNET_OK != GNUNET_BIO_write (h, what, buf, size)))
{
GNUNET_free (buf);
return GNUNET_SYSERR;
@@ -572,36 +890,669 @@ GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
/**
+ * Write a float.
+ *
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param f float to write
+ */
+int
+GNUNET_BIO_write_float(struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ float f)
+{
+ int32_t i = f;
+ return GNUNET_BIO_write_int32 (h, what, i);
+}
+
+
+/**
+ * Write a double.
+ *
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param f double to write
+ */
+int
+GNUNET_BIO_write_double(struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ double f)
+{
+ int64_t i = f;
+ return GNUNET_BIO_write_int64 (h, what, i);
+}
+
+
+/**
* Write an (u)int32_t.
*
- * @param h hande to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param i 32-bit integer to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h, int32_t i)
+GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ int32_t i)
{
int32_t big;
big = htonl (i);
- return GNUNET_BIO_write (h, &big, sizeof(int32_t));
+ return GNUNET_BIO_write (h, what, &big, sizeof(int32_t));
}
/**
* Write an (u)int64_t.
*
- * @param h hande to open file
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
* @param i 64-bit integer to write
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
int
-GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h, int64_t i)
+GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ int64_t i)
{
int64_t big;
big = GNUNET_htonll (i);
- return GNUNET_BIO_write (h, &big, sizeof(int64_t));
+ return GNUNET_BIO_write (h, what, &big, sizeof(int64_t));
+}
+
+
+/**
+ * Function used internally to read some bytes from within a read spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to read from
+ * @param what what is being read (for error message creation)
+ * @param target where to store the data
+ * @param target_size how many bytes to read
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+read_spec_handler_object (void *cls,
+ struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *target,
+ size_t target_size)
+{
+ return GNUNET_BIO_read (h, what, target, target_size);
+}
+
+
+/**
+ * Create the specification to read a certain amount of bytes.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to write the result to
+ * @param len the number of bytes to read
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_object (const char *what,
+ void *result,
+ size_t len)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_object,
+ .cls = NULL,
+ .what = what,
+ .target = result,
+ .size = len,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Function used interally to read a string from within a read spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to read from
+ * @param what what is being read (for error message creation)
+ * @param target where to store the data
+ * @param target_size how many bytes to read
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+read_spec_handler_string (void *cls,
+ struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *target,
+ size_t target_size)
+{
+ char **result = target;
+ return GNUNET_BIO_read_string (h, what, result, target_size);
+}
+
+
+/**
+ * Create the specification to read a 0-terminated string.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param result where to store the pointer to the (allocated) string
+ * (note that *result could be set to NULL as well)
+ * @param max_length maximum allowed length for the string
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_string (const char *what,
+ char **result,
+ size_t max_length)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_string,
+ .cls = NULL,
+ .target = result,
+ .size = max_length,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Function used internally to read a metadata container from within a read
+ * spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to read from
+ * @param what what is being read (for error message creation)
+ * @param target where to store the data
+ * @param target_size ignored
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+static int
+read_spec_handler_meta_data (void *cls,
+ struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *target,
+ size_t target_size)
+{
+ struct GNUNET_CONTAINER_MetaData **result = target;
+ return GNUNET_BIO_read_meta_data (h, what, result);
+}
+
+
+/**
+ * Create the specification to read a metadata container.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param result the buffer to store a pointer to the (allocated) metadata
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_meta_data (const char *what,
+ struct GNUNET_CONTAINER_MetaData **result)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_meta_data,
+ .cls = NULL,
+ .target = result,
+ .size = 0,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Function used internally to read an (u)int32_t from within a read spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to read from
+ * @param what what is being read (for error message creation)
+ * @param target where to store the data
+ * @param target_size ignored
+ * @retun #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+read_spec_handler_int32 (void *cls,
+ struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *target,
+ size_t target_size)
+{
+ int32_t *result = target;
+ return GNUNET_BIO_read_int32 (h, what, result);
+}
+
+
+/**
+ * Create the specification to read an (u)int32_t.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_int32 (const char *what,
+ int32_t *i)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_int32,
+ .cls = NULL,
+ .target = i,
+ .size = 0,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Function used internally to read an (u)int64_t from within a read spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to read from
+ * @param what what is being read (for error message creation)
+ * @param target where to store the data
+ * @param target_size ignored
+ * @retun #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+read_spec_handler_int64 (void *cls,
+ struct GNUNET_BIO_ReadHandle *h,
+ const char *what,
+ void *target,
+ size_t target_size)
+{
+ int64_t *result = target;
+ return GNUNET_BIO_read_int64 (h, what, result);
+}
+
+
+/**
+ * Create the specification to read an (u)int64_t.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param i where to store the data
+ * @return the read spec
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_int64 (const char *what,
+ int64_t *i)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_int64,
+ .cls = NULL,
+ .target = i,
+ .size = 0,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Create the specification to read a float.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param f address of float to read
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_float(const char *what, float *f)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_int32,
+ .cls = NULL,
+ .target = (int32_t *) f,
+ .size = 0,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Create the specification to read a double.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param f address of double to read
+ */
+struct GNUNET_BIO_ReadSpec
+GNUNET_BIO_read_spec_double(const char *what, double *f)
+{
+ struct GNUNET_BIO_ReadSpec rs = {
+ .rh = &read_spec_handler_int64,
+ .cls = NULL,
+ .target = (int64_t *) f,
+ .size = 0,
+ };
+
+ return rs;
+}
+
+
+/**
+ * Execute the read specifications in order.
+ *
+ * @param h the IO handle to read from
+ * @param rs array of read specs
+ * the last element must be #GNUNET_BIO_read_spec_end
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_BIO_read_spec_commit (struct GNUNET_BIO_ReadHandle *h,
+ struct GNUNET_BIO_ReadSpec *rs)
+{
+ int ret = GNUNET_OK;
+
+ for (size_t i=0; NULL!=rs[i].rh; ++i)
+ {
+ ret = rs[i].rh (rs[i].cls, h, rs[i].what, rs[i].target, rs[i].size);
+ if (GNUNET_OK != ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+
+/**
+ * Function used internally to write some bytes from within a write spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param source the data to write
+ * @param source_size how many bytes to write
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_spec_handler_object (void *cls,
+ struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ void *source,
+ size_t source_size)
+{
+ return GNUNET_BIO_write (h, what, source, source_size);
+}
+
+
+/**
+ * Create the specification to read some bytes.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param source the data to write
+ * @param size how many bytes should be written
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_object (const char *what,
+ void *source,
+ size_t size)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_object,
+ .cls = NULL,
+ .what = what,
+ .source = source,
+ .source_size = size,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Function used internally to write a 0-terminated string from within a write
+ * spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param source the data to write
+ * @param source_size ignored
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_spec_handler_string (void *cls,
+ struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ void *source,
+ size_t source_size)
+{
+ const char *s = source;
+ return GNUNET_BIO_write_string (h, what, s);
+}
+
+
+/**
+ * Create the specification to write a 0-terminated string.
+ *
+ * @param what describes what is being read (for error message creation)
+ * @param s string to write (can be NULL)
+ * @return the read spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_string (const char *what,
+ const char *s)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_string,
+ .cls = NULL,
+ .what = what,
+ .source = (void *) s,
+ .source_size = 0,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Function used internally to write a metadata container from within a write
+ * spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param source the data to write
+ * @param source_size ignored
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_spec_handler_meta_data (void *cls,
+ struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ void *source,
+ size_t source_size)
+{
+ const struct GNUNET_CONTAINER_MetaData *m = source;
+ return GNUNET_BIO_write_meta_data (h, what, m);
+}
+
+
+/**
+ * Create the specification to write a metadata container.
+ *
+ * @param what what is being written (for error message creation)
+ * @param m metadata to write
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_meta_data (const char *what,
+ const struct GNUNET_CONTAINER_MetaData *m)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_meta_data,
+ .cls = NULL,
+ .what = what,
+ .source = (void *) m,
+ .source_size = 0,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Function used internally to write an (u)int32_t from within a write spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param source the data to write
+ * @param source_size ignored
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_spec_handler_int32 (void *cls,
+ struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ void *source,
+ size_t source_size)
+{
+ int32_t i = *(int32_t *) source;
+ return GNUNET_BIO_write_int32 (h, what, i);
+}
+
+
+/**
+ * Create the specification to write an (u)int32_t.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param i pointer to a 32-bit integer
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_int32 (const char *what,
+ int32_t *i)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_int32,
+ .cls = NULL,
+ .what = what,
+ .source = i,
+ .source_size = 0,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Function used internally to write an (u)int64_t from within a write spec.
+ *
+ * @param cls ignored, always NULL
+ * @param h the IO handle to write to
+ * @param what what is being written (for error message creation)
+ * @param source the data to write
+ * @param source_size ignored
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+static int
+write_spec_handler_int64 (void *cls,
+ struct GNUNET_BIO_WriteHandle *h,
+ const char *what,
+ void *source,
+ size_t source_size)
+{
+ int64_t i = *(int64_t *) source;
+ return GNUNET_BIO_write_int64 (h, what, i);
+}
+
+
+/**
+ * Create the specification to write an (u)int64_t.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param i pointer to a 64-bit integer
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_int64 (const char *what,
+ int64_t *i)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_int64,
+ .cls = NULL,
+ .what = what,
+ .source = i,
+ .source_size = 0,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Create the specification to write a float.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param f pointer to a float
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_float(const char *what, float *f)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_int32,
+ .cls = NULL,
+ .what = what,
+ .source = (int32_t *) f,
+ .source_size = 0,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Create the specification to write an double.
+ *
+ * @param what describes what is being written (for error message creation)
+ * @param f pointer to a double
+ * @return the write spec
+ */
+struct GNUNET_BIO_WriteSpec
+GNUNET_BIO_write_spec_double(const char *what, double *f)
+{
+ struct GNUNET_BIO_WriteSpec ws = {
+ .wh = &write_spec_handler_int64,
+ .cls = NULL,
+ .what = what,
+ .source = (int64_t *) f,
+ .source_size = 0,
+ };
+
+ return ws;
+}
+
+
+/**
+ * Execute the write specifications in order.
+ *
+ * @param h the IO handle to write to
+ * @param ws array of write specs
+ * the last element must be #GNUNET_BIO_write_spec_end
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_BIO_write_spec_commit (struct GNUNET_BIO_WriteHandle *h,
+ struct GNUNET_BIO_WriteSpec *ws)
+{
+ int ret = GNUNET_OK;
+
+ for (size_t i=0; NULL!=ws[i].wh; ++i)
+ {
+ ret = ws[i].wh (ws[i].cls, h, ws[i].what, ws[i].source, ws[i].source_size);
+ if (GNUNET_OK != ret)
+ return ret;
+ }
+
+ /* If it's a file-based handle, the flush makes sure that the data in the
+ buffer is actualy written to the disk. */
+ if (IO_FILE == h->type)
+ ret = GNUNET_BIO_flush (h);
+
+ return ret;
}
diff --git a/src/util/buffer.c b/src/util/buffer.c
index dabf630c7..c865f6307 100644
--- a/src/util/buffer.c
+++ b/src/util/buffer.c
@@ -130,7 +130,26 @@ GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf)
buf->mem[buf->position++] = '\0';
}
res = buf->mem;
- *buf = (struct GNUNET_Buffer) { 0 };
+ memset (buf, 0, sizeof (struct GNUNET_Buffer));
+ return res;
+}
+
+
+/**
+ * Clear the buffer and return its contents.
+ * The caller is responsible to eventually #GNUNET_free
+ * the returned data.
+ *
+ * @param buf the buffer to reap the contents from
+ * @param size where to store the size of the returned data
+ * @returns the data contained in the string
+ */
+void *
+GNUNET_buffer_reap (struct GNUNET_Buffer *buf, size_t *size)
+{
+ *size = buf->position;
+ void *res = buf->mem;
+ memset (buf, 0, sizeof (struct GNUNET_Buffer));
return res;
}
@@ -144,7 +163,7 @@ void
GNUNET_buffer_clear (struct GNUNET_Buffer *buf)
{
GNUNET_free_non_null (buf->mem);
- *buf = (struct GNUNET_Buffer) { 0 };
+ memset (buf, 0, sizeof (struct GNUNET_Buffer));
}
diff --git a/src/util/test_bio.c b/src/util/test_bio.c
index 53b45c23a..0c8453121 100644
--- a/src/util/test_bio.c
+++ b/src/util/test_bio.c
@@ -30,363 +30,406 @@
#define TESTSTRING "testString"
#define TESTNUMBER64 ((int64_t) 100000L)
+
static int
-test_normal_rw ()
+test_normal_rw (void)
{
- char *msg;
- int64_t testNum;
- char *readResultString;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- struct GNUNET_CONTAINER_MetaData *metaDataW;
- struct GNUNET_CONTAINER_MetaData *metaDataR;
-
- metaDataW = GNUNET_CONTAINER_meta_data_create ();
- metaDataR = NULL;
- GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW);
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, TESTSTRING));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_meta_data (fileW, metaDataW));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int64 (fileW, TESTNUMBER64));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- readResultString = NULL;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_BIO_read_string (fileR, "Read string error",
- &readResultString, 200));
- GNUNET_assert (NULL != readResultString);
- GNUNET_assert (0 == strcmp (TESTSTRING, readResultString));
- GNUNET_free (readResultString);
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ void *buffer;
+ size_t buffer_size = 0;
+ char *filename = GNUNET_DISK_mktemp ("gnunet-bio");
+ struct GNUNET_CONTAINER_MetaData *mdW;
+ struct GNUNET_CONTAINER_MetaData *mdR = NULL;
+ char *rString = NULL;
+ int64_t wNum = TESTNUMBER64;
+ int64_t rNum = 0;
+
+ mdW = GNUNET_CONTAINER_meta_data_create ();
+ GNUNET_CONTAINER_meta_data_add_publication_date (mdW);
+
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_string ("test-normal-rw-string", TESTSTRING),
+ GNUNET_BIO_write_spec_meta_data ("test-normal-rw-metadata", mdW),
+ GNUNET_BIO_write_spec_int64 ("test-normal-rw-int64", &wNum),
+ GNUNET_BIO_write_spec_end(),
+ };
+
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_string ("test-normal-rw-string", &rString, 200),
+ GNUNET_BIO_read_spec_meta_data ("test-normal-rw-metadata", &mdR),
+ GNUNET_BIO_read_spec_int64 ("test-normal-rw-int64", &rNum),
+ GNUNET_BIO_read_spec_end(),
+ };
+
+ /* I/O on file */
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_spec_commit (wh, ws));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_spec_commit (rh, rs));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
+ GNUNET_assert (0 == strcmp (TESTSTRING, rString));
+ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_meta_data_test_equal (mdR, mdW));
+ GNUNET_assert (wNum == rNum);
+
+ GNUNET_CONTAINER_meta_data_destroy (mdR);
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free(filename);
+
+ /* I/O on buffer */
+ wh = GNUNET_BIO_write_open_buffer ();
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_spec_commit (wh, ws));
GNUNET_assert (GNUNET_OK ==
- GNUNET_BIO_read_meta_data (fileR, "Read meta error",
- &metaDataR));
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_meta_data_test_equal (metaDataR, metaDataW));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_int64 (fileR, &testNum));
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_CONTAINER_meta_data_destroy (metaDataW);
- GNUNET_CONTAINER_meta_data_destroy (metaDataR);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_free (fileName);
+ GNUNET_BIO_get_buffer_contents (wh,
+ NULL,
+ &buffer,
+ &buffer_size));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_buffer (buffer, buffer_size);
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_spec_commit (rh, rs));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
+ GNUNET_assert (0 == strcmp (TESTSTRING, rString));
+ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_meta_data_test_equal (mdR, mdW));
+ GNUNET_assert (wNum == rNum);
+
+ GNUNET_free (buffer);
+
+ GNUNET_CONTAINER_meta_data_destroy (mdW);
+ GNUNET_CONTAINER_meta_data_destroy (mdR);
return 0;
}
static int
-test_nullstring_rw ()
+test_nullstring_rw (void)
{
- char *msg;
- char *readResultString = (char *) "not null";
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, NULL));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- GNUNET_assert (GNUNET_OK ==
- GNUNET_BIO_read_string (fileR, "Read string error",
- &readResultString, 200));
- GNUNET_assert (NULL == readResultString);
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_free (fileName);
-
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ char *rString = "not null";
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (wh,
+ "test-nullstring-rw",
+ NULL));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_string (rh,
+ "test-nullstring-rw",
+ &rString, 200));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == rString);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-test_emptystring_rw ()
+test_emptystring_rw (void)
{
- char *msg;
- char *readResultString;
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, ""));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- readResultString = NULL;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_BIO_read_string (fileR, "Read string error",
- &readResultString, 200));
- GNUNET_free (readResultString);
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_free (fileName);
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ char *rString = NULL;
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (wh,
+ "test-emptystring-rw",
+ ""));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_string (rh,
+ "test-emptystring-rw",
+ &rString, 200));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_free (rString);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-test_bigstring_rw ()
+test_bigstring_rw (void)
{
- char *msg;
- char *readResultString;
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, TESTSTRING));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- readResultString = NULL;
- GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_string (fileR, "Read string error",
- &readResultString, 1));
- GNUNET_assert (NULL == readResultString);
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_free (fileName);
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ char *rString = NULL;
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (wh,
+ "test-bigstring-rw",
+ TESTSTRING));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_string (rh,
+ "test-bigstring-rw",
+ &rString, 1));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == rString);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-test_bigmeta_rw ()
+test_bigmeta_rw (void)
{
- char *msg;
static char meta[1024 * 1024 * 10];
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
- struct GNUNET_CONTAINER_MetaData *metaDataR;
-
- memset (meta, 'b', sizeof(meta));
- meta[sizeof(meta) - 1] = '\0';
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, sizeof(meta)));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write (fileW, meta, sizeof(meta)));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- metaDataR = NULL;
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ struct GNUNET_CONTAINER_MetaData *mdR = NULL;
+
+ memset (meta, 'b', sizeof (meta));
+ meta[sizeof (meta) - 1] = '\0';
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
+ "test-bigmeta-rw-int32",
+ sizeof (meta)));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write (wh,
+ "test-bigmeta-rw-bytes",
+ meta,
+ sizeof (meta)));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_meta_data (fileR, "Read meta error",
- &metaDataR));
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_assert (NULL == metaDataR);
- GNUNET_free (fileName);
+ GNUNET_BIO_read_meta_data (rh,
+ "test-bigmeta-rw-metadata",
+ &mdR));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == mdR);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-test_directory_r ()
+test_directory_r (void)
{
-#ifdef __linux__
- char *msg;
- char readResult[200];
- struct GNUNET_BIO_ReadHandle *fileR;
-
- fileR = GNUNET_BIO_read_open ("/dev");
- GNUNET_assert (NULL != fileR);
- GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read (fileR, "Read error", readResult,
- sizeof(readResult)));
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
+#ifdef LINUX
+ struct GNUNET_BIO_ReadHandle *rh;
+ char rString[200];
+
+ rh = GNUNET_BIO_read_open_file ("/dev");
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read (rh,
+ "test-directory-r",
+ rString,
+ sizeof (rString)));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
#endif
return 0;
}
static int
-test_nullfile_rw ()
+test_nullfile_rw (void)
{
- static char fileNameNO[102401];
- struct GNUNET_BIO_WriteHandle *fileWNO;
- struct GNUNET_BIO_ReadHandle *fileRNO;
+ static char filename[102401];
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
- memset (fileNameNO, 'a', sizeof(fileNameNO));
- fileNameNO[sizeof(fileNameNO) - 1] = '\0';
+ memset (filename, 'a', sizeof (filename));
+ filename[sizeof (filename) - 1] = '\0';
- GNUNET_log_skip (1, GNUNET_NO);
- fileWNO = GNUNET_BIO_write_open (fileNameNO);
+ GNUNET_log_skip (2, GNUNET_NO);
+ wh = GNUNET_BIO_write_open_file (filename);
GNUNET_log_skip (0, GNUNET_YES);
- GNUNET_assert (NULL == fileWNO);
+ GNUNET_assert (NULL == wh);
- GNUNET_log_skip (1, GNUNET_NO);
- fileRNO = GNUNET_BIO_read_open (fileNameNO);
+ GNUNET_log_skip (2, GNUNET_NO);
+ rh = GNUNET_BIO_read_open_file (filename);
GNUNET_log_skip (0, GNUNET_YES);
- GNUNET_assert (NULL == fileRNO);
+ GNUNET_assert (NULL == rh);
+
return 0;
}
static int
-test_fullfile_rw ()
+test_fullfile_rw (void)
{
-#ifdef __linux__
- /* /dev/full only seems to exist on Linux */
- char *msg;
- int64_t testNum;
- char *readResultString;
- char readResult[200];
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- struct GNUNET_CONTAINER_MetaData *metaDataW;
- struct GNUNET_CONTAINER_MetaData *metaDataR;
-
- metaDataW = GNUNET_CONTAINER_meta_data_create ();
- GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW);
-
- fileW = GNUNET_BIO_write_open ("/dev/full");
- GNUNET_assert (NULL != fileW);
- (void) GNUNET_BIO_write (fileW, TESTSTRING, strlen (TESTSTRING));
- (void) GNUNET_BIO_write_string (fileW, TESTSTRING);
- (void) GNUNET_BIO_write_meta_data (fileW, metaDataW);
- GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (fileW));
- GNUNET_CONTAINER_meta_data_destroy (metaDataW);
-
- fileW = GNUNET_BIO_write_open ("/dev/full");
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open ("/dev/null");
- GNUNET_assert (NULL != fileR);
- GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read (fileR, "Read error", readResult,
- sizeof(readResult)));
- readResultString = NULL;
- GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_string (fileR, "Read string error",
- &readResultString, 200));
- GNUNET_assert (NULL == readResultString);
- GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_int64 (fileR, &testNum));
- metaDataR = NULL;
- GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_meta_data (fileR, "Read meta error",
- &metaDataR));
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
- GNUNET_assert (NULL == metaDataR);
+#ifdef LINUX
+ /* /dev/full doesn't exist on every platform */
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *rString = NULL;
+ char rResult[200];
+ struct GNUNET_CONTAINER_MetaData *mdW;
+ struct GNUNET_CONTAINER_MetaData *mdR = NULL;
+
+ mdW = GNUNET_CONTAINER_meta_data_create ();
+ GNUNET_CONTAINER_meta_data_add_publication_date (mdW);
+
+ struct GNUNET_BIO_WriteSpec ws[] = {
+ GNUNET_BIO_write_spec_object ("test-fullfile-rw-bytes",
+ TESTSTRING,
+ strlen (TESTSTRING)),
+ GNUNET_BIO_write_spec_string ("test-fullfile-rw-string",
+ TESTSTRING),
+ GNUNET_BIO_write_spec_meta_data ("test-fullfile-rw-metadata",
+ mdW),
+ GNUNET_BIO_write_spec_end (),
+ };
+
+ struct GNUNET_BIO_ReadSpec rs[] = {
+ GNUNET_BIO_read_spec_object ("test-fullfile-rw-bytes",
+ rResult,
+ sizeof (rResult)),
+ GNUNET_BIO_read_spec_string ("test-fullfile-rw-string",
+ &rString,
+ 200),
+ GNUNET_BIO_read_spec_meta_data ("test-fullfile-rw-metadata",
+ &mdR),
+ GNUNET_BIO_read_spec_end(),
+ };
+
+ wh = GNUNET_BIO_write_open_file ("/dev/full");
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_spec_commit (wh, ws));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file ("/dev/null");
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_spec_commit (rh, rs));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == rString);
+ GNUNET_assert (NULL == mdR);
#endif
return 0;
}
static int
-test_fakestring_rw ()
+test_fakestring_rw (void)
{
- char *msg;
- int32_t tmpInt = 2;
- char *readResult;
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, tmpInt));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ char *rString = NULL;
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
+ "test-fakestring-rw-int32",
+ 2));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_string (fileR, "Read string error",
- &readResult, 200));
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_free (fileName);
+ GNUNET_BIO_read_string (rh,
+ "test-fakestring-rw-string",
+ &rString, 200));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == rString);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-test_fakemeta_rw ()
+test_fakemeta_rw (void)
{
- char *msg;
- int32_t tmpInt = 2;
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
- struct GNUNET_CONTAINER_MetaData *metaDataR;
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, tmpInt));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- metaDataR = NULL;
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ struct GNUNET_CONTAINER_MetaData *mdR = NULL;
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
+ "test-fakestring-rw-int32",
+ 2));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_meta_data (fileR, "Read meta error",
- &metaDataR));
- GNUNET_assert (NULL == metaDataR);
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_free (fileName);
+ GNUNET_BIO_read_meta_data (rh,
+ "test-fakestring-rw-metadata",
+ &mdR));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == mdR);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-test_fakebigmeta_rw ()
+test_fakebigmeta_rw (void)
{
- char *msg;
- int32_t tmpInt = 1024 * 1024 * 10;
- struct GNUNET_BIO_WriteHandle *fileW;
- struct GNUNET_BIO_ReadHandle *fileR;
- char *fileName = GNUNET_DISK_mktemp ("gnunet_bio");
- struct GNUNET_CONTAINER_MetaData *metaDataR;
-
- fileW = GNUNET_BIO_write_open (fileName);
- GNUNET_assert (NULL != fileW);
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, tmpInt));
- GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW));
-
- fileR = GNUNET_BIO_read_open (fileName);
- GNUNET_assert (NULL != fileR);
- metaDataR = NULL;
+ struct GNUNET_BIO_WriteHandle *wh;
+ struct GNUNET_BIO_ReadHandle *rh;
+ char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
+ struct GNUNET_CONTAINER_MetaData *mdR = NULL;
+ int32_t wNum = 1024 * 1024 * 10;
+
+ wh = GNUNET_BIO_write_open_file (filename);
+ GNUNET_assert (NULL != wh);
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
+ "test-fakebigmeta-rw-int32",
+ wNum));
+ GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
+
+ rh = GNUNET_BIO_read_open_file (filename);
+ GNUNET_assert (NULL != rh);
GNUNET_assert (GNUNET_SYSERR ==
- GNUNET_BIO_read_meta_data (fileR, "Read meta error",
- &metaDataR));
- msg = NULL;
- GNUNET_BIO_read_close (fileR, &msg);
- GNUNET_free (msg);
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName));
- GNUNET_assert (NULL == metaDataR);
- GNUNET_free (fileName);
+ GNUNET_BIO_read_meta_data (rh,
+ "test-fakebigmeta-rw-metadata",
+ &mdR));
+ GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
+
+ GNUNET_assert (NULL == mdR);
+
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
+ GNUNET_free (filename);
return 0;
}
static int
-check_string_rw ()
+check_string_rw (void)
{
GNUNET_assert (0 == test_nullstring_rw ());
GNUNET_assert (0 == test_emptystring_rw ());
@@ -397,7 +440,7 @@ check_string_rw ()
static int
-check_metadata_rw ()
+check_metadata_rw (void)
{
GNUNET_assert (0 == test_fakebigmeta_rw ());
GNUNET_assert (0 == test_fakemeta_rw ());
@@ -407,7 +450,7 @@ check_metadata_rw ()
static int
-check_file_rw ()
+check_file_rw (void)
{
GNUNET_assert (0 == test_normal_rw ());
GNUNET_assert (0 == test_nullfile_rw ());