aboutsummaryrefslogtreecommitdiff
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)
downloadgnunet-f4771fcc1c3fda21a46d0cb85d8b29e012254696.tar.gz
gnunet-f4771fcc1c3fda21a46d0cb85d8b29e012254696.zip
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)
676 fn = get_serialization_file_name (h, ext, ent); 676 fn = get_serialization_file_name (h, ext, ent);
677 if (NULL == fn) 677 if (NULL == fn)
678 return NULL; 678 return NULL;
679 ret = GNUNET_BIO_read_open (fn); 679 ret = GNUNET_BIO_read_open_file (fn);
680 GNUNET_free (fn); 680 GNUNET_free (fn);
681 return ret; 681 return ret;
682} 682}
@@ -699,7 +699,7 @@ get_write_handle (struct GNUNET_FS_Handle *h, const char *ext, const char *ent)
699 fn = get_serialization_file_name (h, ext, ent); 699 fn = get_serialization_file_name (h, ext, ent);
700 if (NULL == fn) 700 if (NULL == fn)
701 return NULL; 701 return NULL;
702 ret = GNUNET_BIO_write_open (fn); 702 ret = GNUNET_BIO_write_open_file (fn);
703 GNUNET_break (NULL != ret); 703 GNUNET_break (NULL != ret);
704 GNUNET_free (fn); 704 GNUNET_free (fn);
705 return ret; 705 return ret;
@@ -727,7 +727,7 @@ get_write_handle_in_dir (struct GNUNET_FS_Handle *h,
727 fn = get_serialization_file_name_in_dir (h, ext, uni, ent); 727 fn = get_serialization_file_name_in_dir (h, ext, uni, ent);
728 if (NULL == fn) 728 if (NULL == fn)
729 return NULL; 729 return NULL;
730 ret = GNUNET_BIO_write_open (fn); 730 ret = GNUNET_BIO_write_open_file (fn);
731 GNUNET_free (fn); 731 GNUNET_free (fn);
732 return ret; 732 return ret;
733} 733}
@@ -839,7 +839,7 @@ write_start_time (struct GNUNET_BIO_WriteHandle *wh,
839 struct GNUNET_TIME_Relative dur; 839 struct GNUNET_TIME_Relative dur;
840 840
841 dur = GNUNET_TIME_absolute_get_duration (timestamp); 841 dur = GNUNET_TIME_absolute_get_duration (timestamp);
842 return GNUNET_BIO_write_int64 (wh, dur.rel_value_us); 842 return GNUNET_BIO_write_int64 (wh, "start time", dur.rel_value_us);
843} 843}
844 844
845 845
@@ -863,7 +863,8 @@ read_start_time (struct GNUNET_BIO_ReadHandle *rh,
863{ 863{
864 struct GNUNET_TIME_Relative dur; 864 struct GNUNET_TIME_Relative dur;
865 865
866 if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dur.rel_value_us)) 866 if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, "start time",
867 (int64_t *) &dur.rel_value_us))
867 return GNUNET_SYSERR; 868 return GNUNET_SYSERR;
868 *timestamp = GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), dur); 869 *timestamp = GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), dur);
869 return GNUNET_OK; 870 return GNUNET_OK;
@@ -937,10 +938,22 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
937 (GNUNET_OK != 938 (GNUNET_OK !=
938 GNUNET_BIO_read_string (rh, "fn", &ret->filename, 16 * 1024)) || 939 GNUNET_BIO_read_string (rh, "fn", &ret->filename, 16 * 1024)) ||
939 (GNUNET_OK != 940 (GNUNET_OK !=
940 GNUNET_BIO_read_int64 (rh, &ret->bo.expiration_time.abs_value_us)) || 941 GNUNET_BIO_read_int64 (
941 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &ret->bo.anonymity_level)) || 942 rh,
942 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &ret->bo.content_priority)) || 943 "expiration time",
943 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &ret->bo.replication_level))) 944 (int64_t *) &ret->bo.expiration_time.abs_value_us)) ||
945 (GNUNET_OK != GNUNET_BIO_read_int32 (
946 rh,
947 "anonymity level",
948 (int32_t *) &ret->bo.anonymity_level)) ||
949 (GNUNET_OK != GNUNET_BIO_read_int32 (
950 rh,
951 "content priority",
952 (int32_t *) &ret->bo.content_priority)) ||
953 (GNUNET_OK != GNUNET_BIO_read_int32 (
954 rh,
955 "replication level",
956 (int32_t *) &ret->bo.replication_level)))
944 { 957 {
945 GNUNET_break (0); 958 GNUNET_break (0);
946 goto cleanup; 959 goto cleanup;
@@ -948,7 +961,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
948 switch (b) 961 switch (b)
949 { 962 {
950 case 0: /* file-insert */ 963 case 0: /* file-insert */
951 if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) 964 if (GNUNET_OK != GNUNET_BIO_read_int64 (
965 rh,
966 "file size",
967 (int64_t *) &ret->data.file.file_size))
952 { 968 {
953 GNUNET_break (0); 969 GNUNET_break (0);
954 goto cleanup; 970 goto cleanup;
@@ -990,7 +1006,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
990 GNUNET_break (0); 1006 GNUNET_break (0);
991 goto cleanup; 1007 goto cleanup;
992 } 1008 }
993 if (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) 1009 if (GNUNET_OK != GNUNET_BIO_read_int64 (
1010 rh,
1011 "file size",
1012 (int64_t *) &ret->data.file.file_size))
994 { 1013 {
995 GNUNET_break (0); 1014 GNUNET_break (0);
996 goto cleanup; 1015 goto cleanup;
@@ -1010,7 +1029,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
1010 GNUNET_break (0); 1029 GNUNET_break (0);
1011 goto cleanup; 1030 goto cleanup;
1012 } 1031 }
1013 if ((GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) || 1032 if ((GNUNET_OK != GNUNET_BIO_read_int64 (
1033 rh,
1034 "file size",
1035 (int64_t *) &ret->data.file.file_size)) ||
1014 (GNUNET_OK != GNUNET_BIO_read (rh, 1036 (GNUNET_OK != GNUNET_BIO_read (rh,
1015 "fileid", 1037 "fileid",
1016 &ret->data.file.file_id, 1038 &ret->data.file.file_id,
@@ -1034,7 +1056,10 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
1034 GNUNET_break (0); 1056 GNUNET_break (0);
1035 goto cleanup; 1057 goto cleanup;
1036 } 1058 }
1037 if ((GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) || 1059 if ((GNUNET_OK != GNUNET_BIO_read_int64 (
1060 rh,
1061 "file size",
1062 (int64_t *) &ret->data.file.file_size)) ||
1038 (GNUNET_OK != GNUNET_BIO_read (rh, 1063 (GNUNET_OK != GNUNET_BIO_read (rh,
1039 "fileid", 1064 "fileid",
1040 &ret->data.file.file_id, 1065 &ret->data.file.file_id,
@@ -1054,11 +1079,18 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h,
1054 1079
1055 case 4: /* directory */ 1080 case 4: /* directory */
1056 ret->is_directory = GNUNET_YES; 1081 ret->is_directory = GNUNET_YES;
1057 if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dsize)) || 1082 if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, "dsize",
1083 (int32_t *) &dsize)) ||
1058 (GNUNET_OK != 1084 (GNUNET_OK !=
1059 GNUNET_BIO_read_int64 (rh, &ret->data.dir.contents_completed)) || 1085 GNUNET_BIO_read_int64 (
1086 rh,
1087 "contents completed",
1088 (int64_t *) &ret->data.dir.contents_completed)) ||
1060 (GNUNET_OK != 1089 (GNUNET_OK !=
1061 GNUNET_BIO_read_int64 (rh, &ret->data.dir.contents_size)) || 1090 GNUNET_BIO_read_int64 (
1091 rh,
1092 "contents size",
1093 (int64_t *)&ret->data.dir.contents_size)) ||
1062 (NULL == (ret->data.dir.dir_data = GNUNET_malloc_large (dsize))) || 1094 (NULL == (ret->data.dir.dir_data = GNUNET_malloc_large (dsize))) ||
1063 (GNUNET_OK != 1095 (GNUNET_OK !=
1064 GNUNET_BIO_read (rh, "dir-data", ret->data.dir.dir_data, dsize)) || 1096 GNUNET_BIO_read (rh, "dir-data", ret->data.dir.dir_data, dsize)) ||
@@ -1294,7 +1326,7 @@ copy_from_reader (struct GNUNET_BIO_WriteHandle *wh,
1294 GNUNET_free (emsg); 1326 GNUNET_free (emsg);
1295 return GNUNET_SYSERR; 1327 return GNUNET_SYSERR;
1296 } 1328 }
1297 if (GNUNET_OK != GNUNET_BIO_write (wh, buf, ret)) 1329 if (GNUNET_OK != GNUNET_BIO_write (wh, "copied from reader", buf, ret))
1298 return GNUNET_SYSERR; 1330 return GNUNET_SYSERR;
1299 off += ret; 1331 off += ret;
1300 } 1332 }
@@ -1353,19 +1385,34 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1353 skss = GNUNET_FS_uri_to_string (fi->sks_uri); 1385 skss = GNUNET_FS_uri_to_string (fi->sks_uri);
1354 else 1386 else
1355 skss = NULL; 1387 skss = NULL;
1356 if ((GNUNET_OK != GNUNET_BIO_write (wh, &b, sizeof(b))) || 1388 struct GNUNET_BIO_WriteSpec ws1[] = {
1357 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, fi->meta)) || 1389 GNUNET_BIO_write_spec_object ("b", &b, sizeof (b)),
1358 (GNUNET_OK != GNUNET_BIO_write_string (wh, ksks)) || 1390 GNUNET_BIO_write_spec_meta_data ("meta", fi->meta),
1359 (GNUNET_OK != GNUNET_BIO_write_string (wh, chks)) || 1391 GNUNET_BIO_write_spec_string ("ksks", ksks),
1360 (GNUNET_OK != GNUNET_BIO_write_string (wh, skss)) || 1392 GNUNET_BIO_write_spec_string ("chks", chks),
1393 GNUNET_BIO_write_spec_string ("skss", skss),
1394 GNUNET_BIO_write_spec_end (),
1395 };
1396 struct GNUNET_BIO_WriteSpec ws2[] = {
1397 GNUNET_BIO_write_spec_string ("emsg", fi->emsg),
1398 GNUNET_BIO_write_spec_string ("filename", fi->filename),
1399 GNUNET_BIO_write_spec_int64 (
1400 "expiration time",
1401 (int64_t *) &fi->bo.expiration_time.abs_value_us),
1402 GNUNET_BIO_write_spec_int32 (
1403 "anonymity level",
1404 (int32_t *) &fi->bo.anonymity_level),
1405 GNUNET_BIO_write_spec_int32 (
1406 "content priority",
1407 (int32_t *) &fi->bo.content_priority),
1408 GNUNET_BIO_write_spec_int32 (
1409 "replication level",
1410 (int32_t *) &fi->bo.replication_level),
1411 GNUNET_BIO_write_spec_end (),
1412 };
1413 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws1)) ||
1361 (GNUNET_OK != write_start_time (wh, fi->start_time)) || 1414 (GNUNET_OK != write_start_time (wh, fi->start_time)) ||
1362 (GNUNET_OK != GNUNET_BIO_write_string (wh, fi->emsg)) || 1415 (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws2)))
1363 (GNUNET_OK != GNUNET_BIO_write_string (wh, fi->filename)) ||
1364 (GNUNET_OK !=
1365 GNUNET_BIO_write_int64 (wh, fi->bo.expiration_time.abs_value_us)) ||
1366 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->bo.anonymity_level)) ||
1367 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->bo.content_priority)) ||
1368 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->bo.replication_level)))
1369 { 1416 {
1370 GNUNET_break (0); 1417 GNUNET_break (0);
1371 goto cleanup; 1418 goto cleanup;
@@ -1380,7 +1427,8 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1380 switch (b) 1427 switch (b)
1381 { 1428 {
1382 case 0: /* file-insert */ 1429 case 0: /* file-insert */
1383 if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size)) 1430 if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, "file size",
1431 fi->data.file.file_size))
1384 { 1432 {
1385 GNUNET_break (0); 1433 GNUNET_break (0);
1386 goto cleanup; 1434 goto cleanup;
@@ -1399,7 +1447,8 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1399 GNUNET_break (0); 1447 GNUNET_break (0);
1400 goto cleanup; 1448 goto cleanup;
1401 } 1449 }
1402 if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size)) 1450 if (GNUNET_OK != GNUNET_BIO_write_int64 (wh, "file size",
1451 fi->data.file.file_size))
1403 { 1452 {
1404 GNUNET_break (0); 1453 GNUNET_break (0);
1405 goto cleanup; 1454 goto cleanup;
@@ -1413,8 +1462,10 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1413 GNUNET_break (0); 1462 GNUNET_break (0);
1414 goto cleanup; 1463 goto cleanup;
1415 } 1464 }
1416 if ((GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size)) || 1465 if ((GNUNET_OK != GNUNET_BIO_write_int64 (wh, "file size",
1466 fi->data.file.file_size)) ||
1417 (GNUNET_OK != GNUNET_BIO_write (wh, 1467 (GNUNET_OK != GNUNET_BIO_write (wh,
1468 "file id",
1418 &fi->data.file.file_id, 1469 &fi->data.file.file_id,
1419 sizeof(struct GNUNET_HashCode)))) 1470 sizeof(struct GNUNET_HashCode))))
1420 { 1471 {
@@ -1427,19 +1478,24 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1427 if ((NULL != fi->data.dir.entries) && 1478 if ((NULL != fi->data.dir.entries) &&
1428 (NULL == fi->data.dir.entries->serialization)) 1479 (NULL == fi->data.dir.entries->serialization))
1429 GNUNET_FS_file_information_sync_ (fi->data.dir.entries); 1480 GNUNET_FS_file_information_sync_ (fi->data.dir.entries);
1430 if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, fi->data.dir.dir_size)) || 1481 struct GNUNET_BIO_WriteSpec ws[] = {
1431 (GNUNET_OK != 1482 GNUNET_BIO_write_spec_int32 ("dir size",
1432 GNUNET_BIO_write_int64 (wh, fi->data.dir.contents_completed)) || 1483 (int32_t *) &fi->data.dir.dir_size),
1433 (GNUNET_OK != 1484 GNUNET_BIO_write_spec_int64 (
1434 GNUNET_BIO_write_int64 (wh, fi->data.dir.contents_size)) || 1485 "contents completed",
1435 (GNUNET_OK != GNUNET_BIO_write (wh, 1486 (int64_t *) &fi->data.dir.contents_completed),
1436 fi->data.dir.dir_data, 1487 GNUNET_BIO_write_spec_int64 ("contents size",
1437 (uint32_t) fi->data.dir.dir_size)) || 1488 (int64_t *) &fi->data.dir.contents_size),
1438 (GNUNET_OK != 1489 GNUNET_BIO_write_spec_object ("dir data",
1439 GNUNET_BIO_write_string (wh, 1490 fi->data.dir.dir_data,
1440 (fi->data.dir.entries == NULL) 1491 (uint32_t) fi->data.dir.dir_size),
1441 ? NULL 1492 GNUNET_BIO_write_spec_string ("dir entries",
1442 : fi->data.dir.entries->serialization))) 1493 (fi->data.dir.entries == NULL)
1494 ? NULL
1495 : fi->data.dir.entries->serialization),
1496 GNUNET_BIO_write_spec_end (),
1497 };
1498 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
1443 { 1499 {
1444 GNUNET_break (0); 1500 GNUNET_break (0);
1445 goto cleanup; 1501 goto cleanup;
@@ -1453,6 +1509,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1453 if ((NULL != fi->next) && (NULL == fi->next->serialization)) 1509 if ((NULL != fi->next) && (NULL == fi->next->serialization))
1454 GNUNET_FS_file_information_sync_ (fi->next); 1510 GNUNET_FS_file_information_sync_ (fi->next);
1455 if (GNUNET_OK != GNUNET_BIO_write_string (wh, 1511 if (GNUNET_OK != GNUNET_BIO_write_string (wh,
1512 "serialization",
1456 (fi->next != NULL) 1513 (fi->next != NULL)
1457 ? fi->next->serialization 1514 ? fi->next->serialization
1458 : NULL)) 1515 : NULL))
@@ -1460,7 +1517,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1460 GNUNET_break (0); 1517 GNUNET_break (0);
1461 goto cleanup; 1518 goto cleanup;
1462 } 1519 }
1463 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 1520 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
1464 { 1521 {
1465 wh = NULL; 1522 wh = NULL;
1466 GNUNET_break (0); 1523 GNUNET_break (0);
@@ -1469,7 +1526,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi)
1469 return; /* done! */ 1526 return; /* done! */
1470cleanup: 1527cleanup:
1471 if (NULL != wh) 1528 if (NULL != wh)
1472 (void) GNUNET_BIO_write_close (wh); 1529 (void) GNUNET_BIO_write_close (wh, NULL);
1473 GNUNET_free_non_null (chks); 1530 GNUNET_free_non_null (chks);
1474 GNUNET_free_non_null (ksks); 1531 GNUNET_free_non_null (ksks);
1475 GNUNET_free_non_null (skss); 1532 GNUNET_free_non_null (skss);
@@ -1586,23 +1643,23 @@ deserialize_publish_file (void *cls, const char *filename)
1586 pc->serialization = get_serialization_short_name (filename); 1643 pc->serialization = get_serialization_short_name (filename);
1587 fi_root = NULL; 1644 fi_root = NULL;
1588 fi_pos = NULL; 1645 fi_pos = NULL;
1589 rh = GNUNET_BIO_read_open (filename); 1646 rh = GNUNET_BIO_read_open_file (filename);
1590 if (NULL == rh) 1647 if (NULL == rh)
1591 { 1648 {
1592 GNUNET_break (0); 1649 GNUNET_break (0);
1593 goto cleanup; 1650 goto cleanup;
1594 } 1651 }
1595 if ((GNUNET_OK != 1652 struct GNUNET_BIO_ReadSpec rs[] = {
1596 GNUNET_BIO_read_string (rh, "publish-nid", &pc->nid, 1024)) || 1653 GNUNET_BIO_read_spec_string ("publish-nid", &pc->nid, 1024),
1597 (GNUNET_OK != 1654 GNUNET_BIO_read_spec_string ("publish-nuid", &pc->nuid, 1024),
1598 GNUNET_BIO_read_string (rh, "publish-nuid", &pc->nuid, 1024)) || 1655 GNUNET_BIO_read_spec_int32 ("options", &options),
1599 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) || 1656 GNUNET_BIO_read_spec_int32 ("all done", &all_done),
1600 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &all_done)) || 1657 GNUNET_BIO_read_spec_int32 ("have ns", &have_ns),
1601 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &have_ns)) || 1658 GNUNET_BIO_read_spec_string ("publish-firoot", &fi_root, 128),
1602 (GNUNET_OK != 1659 GNUNET_BIO_read_spec_string ("publish-fipos", &fi_pos, 128),
1603 GNUNET_BIO_read_string (rh, "publish-firoot", &fi_root, 128)) || 1660 GNUNET_BIO_read_spec_end (),
1604 (GNUNET_OK != 1661 };
1605 GNUNET_BIO_read_string (rh, "publish-fipos", &fi_pos, 128)) || 1662 if ((GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs)) ||
1606 ((GNUNET_YES == have_ns) && 1663 ((GNUNET_YES == have_ns) &&
1607 (GNUNET_OK != GNUNET_BIO_read (rh, "publish-ns", &ns, sizeof(ns))))) 1664 (GNUNET_OK != GNUNET_BIO_read (rh, "publish-ns", &ns, sizeof(ns)))))
1608 { 1665 {
@@ -1729,26 +1786,29 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc)
1729 goto cleanup; 1786 goto cleanup;
1730 } 1787 }
1731 have_ns = (NULL != pc->ns) ? GNUNET_YES : GNUNET_NO; 1788 have_ns = (NULL != pc->ns) ? GNUNET_YES : GNUNET_NO;
1732 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nid)) || 1789 struct GNUNET_BIO_WriteSpec ws[] = {
1733 (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->nuid)) || 1790 GNUNET_BIO_write_spec_string ("nid", pc->nid),
1734 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->options)) || 1791 GNUNET_BIO_write_spec_string ("nuid", pc->nuid),
1735 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pc->all_done)) || 1792 GNUNET_BIO_write_spec_int32 ("options", (int32_t *) &pc->options),
1736 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, have_ns)) || 1793 GNUNET_BIO_write_spec_int32 ("all done", &pc->all_done),
1737 (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->fi->serialization)) || 1794 GNUNET_BIO_write_spec_int32 ("have ns", &have_ns),
1738 (GNUNET_OK != GNUNET_BIO_write_string (wh, 1795 GNUNET_BIO_write_spec_string ("serialization", pc->fi->serialization),
1739 (NULL == pc->fi_pos) 1796 GNUNET_BIO_write_spec_string ("pos serialization", (NULL == pc->fi_pos)
1740 ? NULL 1797 ? NULL
1741 : pc->fi_pos->serialization)) || 1798 : pc->fi_pos->serialization)
1799 };
1800 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)) ||
1742 ((NULL != pc->ns) && 1801 ((NULL != pc->ns) &&
1743 (GNUNET_OK != 1802 (GNUNET_OK !=
1744 GNUNET_BIO_write (wh, 1803 GNUNET_BIO_write (wh,
1804 "ns",
1745 pc->ns, 1805 pc->ns,
1746 sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey))))) 1806 sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)))))
1747 { 1807 {
1748 GNUNET_break (0); 1808 GNUNET_break (0);
1749 goto cleanup; 1809 goto cleanup;
1750 } 1810 }
1751 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 1811 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
1752 { 1812 {
1753 wh = NULL; 1813 wh = NULL;
1754 GNUNET_break (0); 1814 GNUNET_break (0);
@@ -1757,7 +1817,7 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc)
1757 return; 1817 return;
1758cleanup: 1818cleanup:
1759 if (NULL != wh) 1819 if (NULL != wh)
1760 (void) GNUNET_BIO_write_close (wh); 1820 (void) GNUNET_BIO_write_close (wh, NULL);
1761 GNUNET_FS_remove_sync_file_ (pc->h, 1821 GNUNET_FS_remove_sync_file_ (pc->h,
1762 GNUNET_FS_SYNC_PATH_MASTER_PUBLISH, 1822 GNUNET_FS_SYNC_PATH_MASTER_PUBLISH,
1763 pc->serialization); 1823 pc->serialization);
@@ -1797,25 +1857,34 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc)
1797 uris = GNUNET_FS_uri_to_string (uc->ksk_uri); 1857 uris = GNUNET_FS_uri_to_string (uc->ksk_uri);
1798 else 1858 else
1799 uris = NULL; 1859 uris = NULL;
1800 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uc->filename)) || 1860 struct GNUNET_BIO_WriteSpec ws1[] = {
1801 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, uc->file_size)) || 1861 GNUNET_BIO_write_spec_string ("filename", uc->filename),
1862 GNUNET_BIO_write_spec_int64 ("file size", (int64_t *) &uc->file_size),
1863 GNUNET_BIO_write_spec_end (),
1864 };
1865 struct GNUNET_BIO_WriteSpec ws2[] = {
1866 GNUNET_BIO_write_spec_int32 ("state", (int32_t *) &uc->state),
1867 GNUNET_BIO_write_spec_object ("hashkey", &uc->chk,
1868 sizeof (struct ContentHashKey)),
1869 GNUNET_BIO_write_spec_string ("uris", uris),
1870 GNUNET_BIO_write_spec_int32 ("ksk offset", (int32_t *) &uc->ksk_offset),
1871 GNUNET_BIO_write_spec_end (),
1872 };
1873 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws1)) ||
1802 (GNUNET_OK != write_start_time (wh, uc->start_time)) || 1874 (GNUNET_OK != write_start_time (wh, uc->start_time)) ||
1803 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->state)) || 1875 (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws2)) ||
1804 (GNUNET_OK !=
1805 GNUNET_BIO_write (wh, &uc->chk, sizeof(struct ContentHashKey))) ||
1806 (GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) ||
1807 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->ksk_offset)) ||
1808 ((uc->state == UNINDEX_STATE_FS_NOTIFY) && 1876 ((uc->state == UNINDEX_STATE_FS_NOTIFY) &&
1809 (GNUNET_OK != GNUNET_BIO_write (wh, 1877 (GNUNET_OK != GNUNET_BIO_write (wh,
1878 "file id",
1810 &uc->file_id, 1879 &uc->file_id,
1811 sizeof(struct GNUNET_HashCode)))) || 1880 sizeof(struct GNUNET_HashCode)))) ||
1812 ((uc->state == UNINDEX_STATE_ERROR) && 1881 ((uc->state == UNINDEX_STATE_ERROR) &&
1813 (GNUNET_OK != GNUNET_BIO_write_string (wh, uc->emsg)))) 1882 (GNUNET_OK != GNUNET_BIO_write_string (wh, "emsg", uc->emsg))))
1814 { 1883 {
1815 GNUNET_break (0); 1884 GNUNET_break (0);
1816 goto cleanup; 1885 goto cleanup;
1817 } 1886 }
1818 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 1887 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
1819 { 1888 {
1820 wh = NULL; 1889 wh = NULL;
1821 GNUNET_break (0); 1890 GNUNET_break (0);
@@ -1824,7 +1893,7 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc)
1824 return; 1893 return;
1825cleanup: 1894cleanup:
1826 if (NULL != wh) 1895 if (NULL != wh)
1827 (void) GNUNET_BIO_write_close (wh); 1896 (void) GNUNET_BIO_write_close (wh, NULL);
1828 GNUNET_FS_remove_sync_file_ (uc->h, 1897 GNUNET_FS_remove_sync_file_ (uc->h,
1829 GNUNET_FS_SYNC_PATH_MASTER_UNINDEX, 1898 GNUNET_FS_SYNC_PATH_MASTER_UNINDEX,
1830 uc->serialization); 1899 uc->serialization);
@@ -1845,15 +1914,20 @@ write_download_request (struct GNUNET_BIO_WriteHandle *wh,
1845 struct DownloadRequest *dr) 1914 struct DownloadRequest *dr)
1846{ 1915{
1847 unsigned int i; 1916 unsigned int i;
1848 1917 struct GNUNET_BIO_WriteSpec ws[] = {
1849 if ((GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->state)) || 1918 GNUNET_BIO_write_spec_int32 ("state", (int32_t *) &dr->state),
1850 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dr->offset)) || 1919 GNUNET_BIO_write_spec_int64 ("offset", (int64_t *) &dr->offset),
1851 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->num_children)) || 1920 GNUNET_BIO_write_spec_int32 ("num children", (int32_t *) &dr->num_children),
1852 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->depth))) 1921 GNUNET_BIO_write_spec_int32 ("depth", (int32_t *) &dr->depth),
1922 GNUNET_BIO_write_spec_end (),
1923 };
1924
1925 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
1853 return GNUNET_NO; 1926 return GNUNET_NO;
1854 if ((BRS_CHK_SET == dr->state) && 1927 if ((BRS_CHK_SET == dr->state) &&
1855 (GNUNET_OK != 1928 (GNUNET_OK !=
1856 GNUNET_BIO_write (wh, &dr->chk, sizeof(struct ContentHashKey)))) 1929 GNUNET_BIO_write (wh, "hashkey",
1930 &dr->chk, sizeof(struct ContentHashKey))))
1857 return GNUNET_NO; 1931 return GNUNET_NO;
1858 for (i = 0; i < dr->num_children; i++) 1932 for (i = 0; i < dr->num_children; i++)
1859 if (GNUNET_NO == write_download_request (wh, dr->children[i])) 1933 if (GNUNET_NO == write_download_request (wh, dr->children[i]))
@@ -1875,11 +1949,16 @@ read_download_request (struct GNUNET_BIO_ReadHandle *rh)
1875 unsigned int i; 1949 unsigned int i;
1876 1950
1877 dr = GNUNET_new (struct DownloadRequest); 1951 dr = GNUNET_new (struct DownloadRequest);
1878 if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->state)) || 1952 struct GNUNET_BIO_ReadSpec rs[] = {
1879 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dr->offset)) || 1953 GNUNET_BIO_read_spec_int32 ("state", (int32_t *) &dr->state),
1880 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->num_children)) || 1954 GNUNET_BIO_read_spec_int64 ("offset", (int64_t *) &dr->offset),
1955 GNUNET_BIO_read_spec_int32 ("num children", (int32_t *) &dr->num_children),
1956 GNUNET_BIO_read_spec_end (),
1957 };
1958 if ((GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs)) ||
1881 (dr->num_children > CHK_PER_INODE) || 1959 (dr->num_children > CHK_PER_INODE) ||
1882 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->depth)) || 1960 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "depth",
1961 (int32_t *) &dr->depth)) ||
1883 ((0 == dr->depth) && (dr->num_children > 0)) || 1962 ((0 == dr->depth) && (dr->num_children > 0)) ||
1884 ((dr->depth > 0) && (0 == dr->num_children))) 1963 ((dr->depth > 0) && (0 == dr->num_children)))
1885 { 1964 {
@@ -2005,7 +2084,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
2005 return; 2084 return;
2006 } 2085 }
2007 } 2086 }
2008 wh = GNUNET_BIO_write_open (fn); 2087 wh = GNUNET_BIO_write_open_file (fn);
2009 if (NULL == wh) 2088 if (NULL == wh)
2010 { 2089 {
2011 GNUNET_free (dc->serialization); 2090 GNUNET_free (dc->serialization);
@@ -2016,19 +2095,28 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
2016 GNUNET_assert ((GNUNET_YES == GNUNET_FS_uri_test_chk (dc->uri)) || 2095 GNUNET_assert ((GNUNET_YES == GNUNET_FS_uri_test_chk (dc->uri)) ||
2017 (GNUNET_YES == GNUNET_FS_uri_test_loc (dc->uri))); 2096 (GNUNET_YES == GNUNET_FS_uri_test_loc (dc->uri)));
2018 uris = GNUNET_FS_uri_to_string (dc->uri); 2097 uris = GNUNET_FS_uri_to_string (dc->uri);
2019 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) || 2098 struct GNUNET_BIO_WriteSpec ws1[] = {
2020 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, dc->meta)) || 2099 GNUNET_BIO_write_spec_string ("uris", uris),
2021 (GNUNET_OK != GNUNET_BIO_write_string (wh, dc->emsg)) || 2100 GNUNET_BIO_write_spec_meta_data ("metadata", dc->meta),
2022 (GNUNET_OK != GNUNET_BIO_write_string (wh, dc->filename)) || 2101 GNUNET_BIO_write_spec_string ("emsg", dc->emsg),
2023 (GNUNET_OK != GNUNET_BIO_write_string (wh, dc->temp_filename)) || 2102 GNUNET_BIO_write_spec_string ("filename", dc->filename),
2024 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->old_file_size)) || 2103 GNUNET_BIO_write_spec_string ("temp filename", dc->temp_filename),
2025 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->offset)) || 2104 GNUNET_BIO_write_spec_int64 ("old file size",
2026 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->length)) || 2105 (int64_t *) &dc->old_file_size),
2027 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, dc->completed)) || 2106 GNUNET_BIO_write_spec_int64 ("offset", (int64_t *) &dc->offset),
2107 GNUNET_BIO_write_spec_int64 ("length", (int64_t *) &dc->length),
2108 GNUNET_BIO_write_spec_int64 ("completed", (int64_t *) &dc->completed),
2109 GNUNET_BIO_write_spec_end (),
2110 };
2111 struct GNUNET_BIO_WriteSpec ws2[] = {
2112 GNUNET_BIO_write_spec_int32 ("anonymity", (int32_t *) &dc->anonymity),
2113 GNUNET_BIO_write_spec_int32 ("options", (int32_t *) &dc->options),
2114 GNUNET_BIO_write_spec_int32 ("has finished", (int32_t *) &dc->has_finished),
2115 GNUNET_BIO_write_spec_end (),
2116 };
2117 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws1)) ||
2028 (GNUNET_OK != write_start_time (wh, dc->start_time)) || 2118 (GNUNET_OK != write_start_time (wh, dc->start_time)) ||
2029 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dc->anonymity)) || 2119 (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws2)))
2030 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) dc->options)) ||
2031 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) dc->has_finished)))
2032 { 2120 {
2033 GNUNET_break (0); 2121 GNUNET_break (0);
2034 goto cleanup; 2122 goto cleanup;
@@ -2044,7 +2132,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
2044 } 2132 }
2045 GNUNET_free_non_null (uris); 2133 GNUNET_free_non_null (uris);
2046 uris = NULL; 2134 uris = NULL;
2047 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 2135 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
2048 { 2136 {
2049 wh = NULL; 2137 wh = NULL;
2050 GNUNET_break (0); 2138 GNUNET_break (0);
@@ -2054,7 +2142,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
2054 return; 2142 return;
2055cleanup: 2143cleanup:
2056 if (NULL != wh) 2144 if (NULL != wh)
2057 (void) GNUNET_BIO_write_close (wh); 2145 (void) GNUNET_BIO_write_close (wh, NULL);
2058 GNUNET_free_non_null (uris); 2146 GNUNET_free_non_null (uris);
2059 if (0 != unlink (fn)) 2147 if (0 != unlink (fn))
2060 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); 2148 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
@@ -2102,23 +2190,30 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
2102 goto cleanup; 2190 goto cleanup;
2103 } 2191 }
2104 uris = GNUNET_FS_uri_to_string (sr->uri); 2192 uris = GNUNET_FS_uri_to_string (sr->uri);
2105 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) || 2193 struct GNUNET_BIO_WriteSpec ws[] = {
2106 (GNUNET_OK != GNUNET_BIO_write_string (wh, 2194 GNUNET_BIO_write_spec_string ("uris", uris),
2107 (sr->download != NULL) 2195 GNUNET_BIO_write_spec_string ("download serialization",
2108 ? sr->download->serialization 2196 (sr->download != NULL)
2109 : NULL)) || 2197 ? sr->download->serialization
2110 (GNUNET_OK != 2198 : NULL),
2111 GNUNET_BIO_write_string (wh, 2199 GNUNET_BIO_write_spec_string ("update search serialization",
2112 (sr->update_search != NULL) 2200 (sr->update_search != NULL)
2113 ? sr->update_search->serialization 2201 ? sr->update_search->serialization
2114 : NULL)) || 2202 : NULL),
2115 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, sr->meta)) || 2203 GNUNET_BIO_write_spec_meta_data ("metadata", sr->meta),
2116 (GNUNET_OK != 2204 GNUNET_BIO_write_spec_object ("key", &sr->key,
2117 GNUNET_BIO_write (wh, &sr->key, sizeof(struct GNUNET_HashCode))) || 2205 sizeof(struct GNUNET_HashCode)),
2118 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->mandatory_missing)) || 2206 GNUNET_BIO_write_spec_int32 ("mandatory missing",
2119 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->optional_support)) || 2207 (int32_t *) &sr->mandatory_missing),
2120 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->availability_success)) || 2208 GNUNET_BIO_write_spec_int32 ("optional support",
2121 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->availability_trials))) 2209 (int32_t *) &sr->optional_support),
2210 GNUNET_BIO_write_spec_int32 ("availability success",
2211 (int32_t *) &sr->availability_success),
2212 GNUNET_BIO_write_spec_int32 ("availability trials",
2213 (int32_t *) &sr->availability_trials),
2214 GNUNET_BIO_write_spec_end (),
2215 };
2216 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
2122 { 2217 {
2123 GNUNET_break (0); 2218 GNUNET_break (0);
2124 goto cleanup; 2219 goto cleanup;
@@ -2126,13 +2221,14 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
2126 if ((NULL != sr->uri) && (GNUNET_FS_URI_KSK == sr->sc->uri->type) && 2221 if ((NULL != sr->uri) && (GNUNET_FS_URI_KSK == sr->sc->uri->type) &&
2127 (GNUNET_OK != 2222 (GNUNET_OK !=
2128 GNUNET_BIO_write (wh, 2223 GNUNET_BIO_write (wh,
2224 "keyword bitmap",
2129 sr->keyword_bitmap, 2225 sr->keyword_bitmap,
2130 (sr->sc->uri->data.ksk.keywordCount + 7) / 8))) 2226 (sr->sc->uri->data.ksk.keywordCount + 7) / 8)))
2131 { 2227 {
2132 GNUNET_break (0); 2228 GNUNET_break (0);
2133 goto cleanup; 2229 goto cleanup;
2134 } 2230 }
2135 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 2231 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
2136 { 2232 {
2137 wh = NULL; 2233 wh = NULL;
2138 GNUNET_break (0); 2234 GNUNET_break (0);
@@ -2143,7 +2239,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr)
2143cleanup: 2239cleanup:
2144 GNUNET_free_non_null (uris); 2240 GNUNET_free_non_null (uris);
2145 if (NULL != wh) 2241 if (NULL != wh)
2146 (void) GNUNET_BIO_write_close (wh); 2242 (void) GNUNET_BIO_write_close (wh, NULL);
2147 remove_sync_file_in_dir (sr->h, 2243 remove_sync_file_in_dir (sr->h,
2148 (NULL == sr->sc->psearch_result) 2244 (NULL == sr->sc->psearch_result)
2149 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH 2245 ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH
@@ -2188,19 +2284,21 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc)
2188 (GNUNET_YES == GNUNET_FS_uri_test_sks (sc->uri))); 2284 (GNUNET_YES == GNUNET_FS_uri_test_sks (sc->uri)));
2189 uris = GNUNET_FS_uri_to_string (sc->uri); 2285 uris = GNUNET_FS_uri_to_string (sc->uri);
2190 in_pause = (sc->task != NULL) ? 'r' : '\0'; 2286 in_pause = (sc->task != NULL) ? 'r' : '\0';
2191 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) || 2287 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, "uris", uris)) ||
2192 (GNUNET_OK != write_start_time (wh, sc->start_time)) || 2288 (GNUNET_OK != write_start_time (wh, sc->start_time)) ||
2193 (GNUNET_OK != GNUNET_BIO_write_string (wh, sc->emsg)) || 2289 (GNUNET_OK != GNUNET_BIO_write_string (wh, "emsg", sc->emsg)) ||
2194 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) sc->options)) || 2290 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "options",
2195 (GNUNET_OK != GNUNET_BIO_write (wh, &in_pause, sizeof(in_pause))) || 2291 (uint32_t) sc->options)) ||
2196 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sc->anonymity))) 2292 (GNUNET_OK != GNUNET_BIO_write (wh, "in pause",
2293 &in_pause, sizeof(in_pause))) ||
2294 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "anonymity", sc->anonymity)))
2197 { 2295 {
2198 GNUNET_break (0); 2296 GNUNET_break (0);
2199 goto cleanup; 2297 goto cleanup;
2200 } 2298 }
2201 GNUNET_free (uris); 2299 GNUNET_free (uris);
2202 uris = NULL; 2300 uris = NULL;
2203 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 2301 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
2204 { 2302 {
2205 wh = NULL; 2303 wh = NULL;
2206 GNUNET_break (0); 2304 GNUNET_break (0);
@@ -2209,7 +2307,7 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc)
2209 return; 2307 return;
2210cleanup: 2308cleanup:
2211 if (NULL != wh) 2309 if (NULL != wh)
2212 (void) GNUNET_BIO_write_close (wh); 2310 (void) GNUNET_BIO_write_close (wh, NULL);
2213 GNUNET_free_non_null (uris); 2311 GNUNET_free_non_null (uris);
2214 GNUNET_FS_remove_sync_file_ (sc->h, category, sc->serialization); 2312 GNUNET_FS_remove_sync_file_ (sc->h, category, sc->serialization);
2215 GNUNET_free (sc->serialization); 2313 GNUNET_free (sc->serialization);
@@ -2239,7 +2337,7 @@ deserialize_unindex_file (void *cls, const char *filename)
2239 uc = GNUNET_new (struct GNUNET_FS_UnindexContext); 2337 uc = GNUNET_new (struct GNUNET_FS_UnindexContext);
2240 uc->h = h; 2338 uc->h = h;
2241 uc->serialization = get_serialization_short_name (filename); 2339 uc->serialization = get_serialization_short_name (filename);
2242 rh = GNUNET_BIO_read_open (filename); 2340 rh = GNUNET_BIO_read_open_file (filename);
2243 if (NULL == rh) 2341 if (NULL == rh)
2244 { 2342 {
2245 GNUNET_break (0); 2343 GNUNET_break (0);
@@ -2248,14 +2346,17 @@ deserialize_unindex_file (void *cls, const char *filename)
2248 uris = NULL; 2346 uris = NULL;
2249 if ((GNUNET_OK != 2347 if ((GNUNET_OK !=
2250 GNUNET_BIO_read_string (rh, "unindex-fn", &uc->filename, 10 * 1024)) || 2348 GNUNET_BIO_read_string (rh, "unindex-fn", &uc->filename, 10 * 1024)) ||
2251 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &uc->file_size)) || 2349 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, "file size",
2350 (int64_t *) &uc->file_size)) ||
2252 (GNUNET_OK != read_start_time (rh, &uc->start_time)) || 2351 (GNUNET_OK != read_start_time (rh, &uc->start_time)) ||
2253 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &state)) || 2352 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "state",
2353 (int32_t *) &state)) ||
2254 (GNUNET_OK != 2354 (GNUNET_OK !=
2255 GNUNET_BIO_read (rh, "uri", &uc->chk, sizeof(struct ContentHashKey))) || 2355 GNUNET_BIO_read (rh, "uri", &uc->chk, sizeof(struct ContentHashKey))) ||
2256 (GNUNET_OK != 2356 (GNUNET_OK !=
2257 GNUNET_BIO_read_string (rh, "unindex-kskuri", &uris, 10 * 1024)) || 2357 GNUNET_BIO_read_string (rh, "unindex-kskuri", &uris, 10 * 1024)) ||
2258 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &uc->ksk_offset))) 2358 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "ksk offset",
2359 (int32_t *) &uc->ksk_offset)))
2259 { 2360 {
2260 GNUNET_free_non_null (uris); 2361 GNUNET_free_non_null (uris);
2261 GNUNET_break (0); 2362 GNUNET_break (0);
@@ -2443,7 +2544,7 @@ deserialize_search_result (void *cls, const char *filename)
2443 struct GNUNET_FS_SearchResult *sr; 2544 struct GNUNET_FS_SearchResult *sr;
2444 2545
2445 ser = get_serialization_short_name (filename); 2546 ser = get_serialization_short_name (filename);
2446 rh = GNUNET_BIO_read_open (filename); 2547 rh = GNUNET_BIO_read_open_file (filename);
2447 if (NULL == rh) 2548 if (NULL == rh)
2448 { 2549 {
2449 if (NULL != ser) 2550 if (NULL != ser)
@@ -2478,10 +2579,22 @@ deserialize_search_result (void *cls, const char *filename)
2478 "result-key", 2579 "result-key",
2479 &sr->key, 2580 &sr->key,
2480 sizeof(struct GNUNET_HashCode))) || 2581 sizeof(struct GNUNET_HashCode))) ||
2481 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->mandatory_missing)) || 2582 (GNUNET_OK != GNUNET_BIO_read_int32 (
2482 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->optional_support)) || 2583 rh,
2483 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->availability_success)) || 2584 "mandatory missing",
2484 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->availability_trials))) 2585 (int32_t *) &sr->mandatory_missing)) ||
2586 (GNUNET_OK != GNUNET_BIO_read_int32 (
2587 rh,
2588 "optional support",
2589 (int32_t *) &sr->optional_support)) ||
2590 (GNUNET_OK != GNUNET_BIO_read_int32 (
2591 rh,
2592 "availability success",
2593 (int32_t *) &sr->availability_success)) ||
2594 (GNUNET_OK != GNUNET_BIO_read_int32 (
2595 rh,
2596 "availability trials",
2597 (int32_t *) &sr->availability_trials)))
2485 { 2598 {
2486 GNUNET_break (0); 2599 GNUNET_break (0);
2487 goto cleanup; 2600 goto cleanup;
@@ -2741,7 +2854,7 @@ deserialize_subdownload (void *cls, const char *filename)
2741 struct GNUNET_BIO_ReadHandle *rh; 2854 struct GNUNET_BIO_ReadHandle *rh;
2742 2855
2743 ser = get_serialization_short_name (filename); 2856 ser = get_serialization_short_name (filename);
2744 rh = GNUNET_BIO_read_open (filename); 2857 rh = GNUNET_BIO_read_open_file (filename);
2745 if (NULL == rh) 2858 if (NULL == rh)
2746 { 2859 {
2747 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2860 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -2827,29 +2940,35 @@ deserialize_download (struct GNUNET_FS_Handle *h,
2827 dc->parent = parent; 2940 dc->parent = parent;
2828 dc->h = h; 2941 dc->h = h;
2829 dc->serialization = GNUNET_strdup (serialization); 2942 dc->serialization = GNUNET_strdup (serialization);
2943 struct GNUNET_BIO_ReadSpec rs[] = {
2944 GNUNET_BIO_read_spec_meta_data ("download-meta", &dc->meta),
2945 GNUNET_BIO_read_spec_string ("download-emsg", &dc->emsg, 10 * 1024),
2946 GNUNET_BIO_read_spec_string ("download-fn", &dc->filename, 10 * 1024),
2947 GNUNET_BIO_read_spec_string ("download-tfn",
2948 &dc->temp_filename, 10 * 1024),
2949 GNUNET_BIO_read_spec_int64 ("old file size",
2950 (int64_t *) &dc->old_file_size),
2951 GNUNET_BIO_read_spec_int64 ("offset",
2952 (int64_t *) &dc->offset),
2953 GNUNET_BIO_read_spec_int64 ("length",
2954 (int64_t *) &dc->length),
2955 GNUNET_BIO_read_spec_int64 ("completed",
2956 (int64_t *) &dc->completed),
2957 GNUNET_BIO_read_spec_end (),
2958 };
2830 if ((GNUNET_OK != 2959 if ((GNUNET_OK !=
2831 GNUNET_BIO_read_string (rh, "download-uri", &uris, 10 * 1024)) || 2960 GNUNET_BIO_read_string (rh, "download-uri", &uris, 10 * 1024)) ||
2832 (NULL == (dc->uri = GNUNET_FS_uri_parse (uris, &emsg))) || 2961 (NULL == (dc->uri = GNUNET_FS_uri_parse (uris, &emsg))) ||
2833 ((GNUNET_YES != GNUNET_FS_uri_test_chk (dc->uri)) && 2962 ((GNUNET_YES != GNUNET_FS_uri_test_chk (dc->uri)) &&
2834 (GNUNET_YES != GNUNET_FS_uri_test_loc (dc->uri))) || 2963 (GNUNET_YES != GNUNET_FS_uri_test_loc (dc->uri))) ||
2835 (GNUNET_OK != 2964 (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs)) ||
2836 GNUNET_BIO_read_meta_data (rh, "download-meta", &dc->meta)) ||
2837 (GNUNET_OK !=
2838 GNUNET_BIO_read_string (rh, "download-emsg", &dc->emsg, 10 * 1024)) ||
2839 (GNUNET_OK !=
2840 GNUNET_BIO_read_string (rh, "download-fn", &dc->filename, 10 * 1024)) ||
2841 (GNUNET_OK != GNUNET_BIO_read_string (rh,
2842 "download-tfn",
2843 &dc->temp_filename,
2844 10 * 1024)) ||
2845 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->old_file_size)) ||
2846 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->offset)) ||
2847 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->length)) ||
2848 (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dc->completed)) ||
2849 (GNUNET_OK != read_start_time (rh, &dc->start_time)) || 2965 (GNUNET_OK != read_start_time (rh, &dc->start_time)) ||
2850 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dc->anonymity)) || 2966 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "anonymity",
2851 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) || 2967 (int32_t *) &dc->anonymity)) ||
2852 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &status))) 2968 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "options",
2969 (int32_t *) &options)) ||
2970 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "status",
2971 (int32_t *) &status)))
2853 { 2972 {
2854 GNUNET_break (0); 2973 GNUNET_break (0);
2855 goto cleanup; 2974 goto cleanup;
@@ -2972,10 +3091,12 @@ deserialize_search (struct GNUNET_FS_Handle *h,
2972 (GNUNET_OK != read_start_time (rh, &sc->start_time)) || 3091 (GNUNET_OK != read_start_time (rh, &sc->start_time)) ||
2973 (GNUNET_OK != 3092 (GNUNET_OK !=
2974 GNUNET_BIO_read_string (rh, "search-emsg", &sc->emsg, 10 * 1024)) || 3093 GNUNET_BIO_read_string (rh, "search-emsg", &sc->emsg, 10 * 1024)) ||
2975 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &options)) || 3094 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "options",
3095 (int32_t *) &options)) ||
2976 (GNUNET_OK != 3096 (GNUNET_OK !=
2977 GNUNET_BIO_read (rh, "search-pause", &in_pause, sizeof(in_pause))) || 3097 GNUNET_BIO_read (rh, "search-pause", &in_pause, sizeof(in_pause))) ||
2978 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sc->anonymity))) 3098 (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "anonymity",
3099 (int32_t *) &sc->anonymity)))
2979 { 3100 {
2980 GNUNET_break (0); 3101 GNUNET_break (0);
2981 goto cleanup; 3102 goto cleanup;
@@ -3038,7 +3159,7 @@ deserialize_search_file (void *cls, const char *filename)
3038 if (S_ISDIR (buf.st_mode)) 3159 if (S_ISDIR (buf.st_mode))
3039 return GNUNET_OK; /* skip directories */ 3160 return GNUNET_OK; /* skip directories */
3040 ser = get_serialization_short_name (filename); 3161 ser = get_serialization_short_name (filename);
3041 rh = GNUNET_BIO_read_open (filename); 3162 rh = GNUNET_BIO_read_open_file (filename);
3042 if (NULL == rh) 3163 if (NULL == rh)
3043 { 3164 {
3044 if (NULL != ser) 3165 if (NULL != ser)
@@ -3081,7 +3202,7 @@ deserialize_download_file (void *cls, const char *filename)
3081 struct GNUNET_BIO_ReadHandle *rh; 3202 struct GNUNET_BIO_ReadHandle *rh;
3082 3203
3083 ser = get_serialization_short_name (filename); 3204 ser = get_serialization_short_name (filename);
3084 rh = GNUNET_BIO_read_open (filename); 3205 rh = GNUNET_BIO_read_open_file (filename);
3085 if (NULL == rh) 3206 if (NULL == rh)
3086 { 3207 {
3087 if (0 != unlink (filename)) 3208 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)
195 char *uris; 195 char *uris;
196 196
197 fn = get_update_information_directory (uig->h, &uig->ns); 197 fn = get_update_information_directory (uig->h, &uig->ns);
198 wh = GNUNET_BIO_write_open (fn); 198 wh = GNUNET_BIO_write_open_file (fn);
199 if (NULL == wh) 199 if (NULL == wh)
200 { 200 {
201 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 201 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -205,16 +205,22 @@ write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
205 GNUNET_free (fn); 205 GNUNET_free (fn);
206 return; 206 return;
207 } 207 }
208 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, uig->update_node_count)) 208 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh,
209 "fs-namespace-node-count",
210 uig->update_node_count))
209 goto END; 211 goto END;
210 for (i = 0; i < uig->update_node_count; i++) 212 for (i = 0; i < uig->update_node_count; i++)
211 { 213 {
212 n = uig->update_nodes[i]; 214 n = uig->update_nodes[i];
213 uris = GNUNET_FS_uri_to_string (n->uri); 215 uris = GNUNET_FS_uri_to_string (n->uri);
214 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, n->id)) || 216 struct GNUNET_BIO_WriteSpec ws[] = {
215 (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, n->md)) || 217 GNUNET_BIO_write_spec_string("fs-namespace-node-id", n->id),
216 (GNUNET_OK != GNUNET_BIO_write_string (wh, n->update)) || 218 GNUNET_BIO_write_spec_meta_data("fs-namespace-node-meta", n->md),
217 (GNUNET_OK != GNUNET_BIO_write_string (wh, uris))) 219 GNUNET_BIO_write_spec_string("fs-namespace-node-update", n->update),
220 GNUNET_BIO_write_spec_string("fs-namespace-uris", uris),
221 GNUNET_BIO_write_spec_end(),
222 };
223 if (GNUNET_OK != GNUNET_BIO_write_spec_commit(wh, ws))
218 { 224 {
219 GNUNET_free (uris); 225 GNUNET_free (uris);
220 break; 226 break;
@@ -222,7 +228,7 @@ write_update_information_graph (struct GNUNET_FS_UpdateInformationGraph *uig)
222 GNUNET_free (uris); 228 GNUNET_free (uris);
223 } 229 }
224END: 230END:
225 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 231 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
226 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 232 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
227 _ ("Failed to write `%s': %s\n"), 233 _ ("Failed to write `%s': %s\n"),
228 fn, 234 fn,
@@ -260,13 +266,14 @@ read_update_information_graph (struct GNUNET_FS_Handle *h,
260 GNUNET_free (fn); 266 GNUNET_free (fn);
261 return uig; 267 return uig;
262 } 268 }
263 rh = GNUNET_BIO_read_open (fn); 269 rh = GNUNET_BIO_read_open_file (fn);
264 if (NULL == rh) 270 if (NULL == rh)
265 { 271 {
266 GNUNET_free (fn); 272 GNUNET_free (fn);
267 return uig; 273 return uig;
268 } 274 }
269 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &count)) 275 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "fs-namespace-count",
276 (int32_t *) &count))
270 { 277 {
271 GNUNET_break (0); 278 GNUNET_break (0);
272 goto END; 279 goto END;
@@ -284,12 +291,14 @@ read_update_information_graph (struct GNUNET_FS_Handle *h,
284 for (i = 0; i < count; i++) 291 for (i = 0; i < count; i++)
285 { 292 {
286 n = GNUNET_new (struct NamespaceUpdateNode); 293 n = GNUNET_new (struct NamespaceUpdateNode);
287 if ((GNUNET_OK != 294 struct GNUNET_BIO_ReadSpec rs[] = {
288 GNUNET_BIO_read_string (rh, "identifier", &n->id, 1024)) || 295 GNUNET_BIO_read_spec_string("identifier", &n->id, 1024),
289 (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "meta", &n->md)) || 296 GNUNET_BIO_read_spec_meta_data("meta", &n->md),
290 (GNUNET_OK != 297 GNUNET_BIO_read_spec_string("update-id", &n->update, 1024),
291 GNUNET_BIO_read_string (rh, "update-id", &n->update, 1024)) || 298 GNUNET_BIO_read_spec_string("uri", &uris, 1024 * 2),
292 (GNUNET_OK != GNUNET_BIO_read_string (rh, "uri", &uris, 1024 * 2))) 299 GNUNET_BIO_read_spec_end(),
300 };
301 if (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs))
293 { 302 {
294 GNUNET_break (0); 303 GNUNET_break (0);
295 GNUNET_free_non_null (n->id); 304 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 ()
190 190
191 emsg = NULL; 191 emsg = NULL;
192 fn = get_state_file (); 192 fn = get_state_file ();
193 rh = GNUNET_BIO_read_open (fn); 193 rh = GNUNET_BIO_read_open_file (fn);
194 GNUNET_free (fn); 194 GNUNET_free (fn);
195 if (NULL == rh) 195 if (NULL == rh)
196 return; 196 return;
197 fn = NULL; 197 fn = NULL;
198 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &n)) 198 if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, "number of files",
199 (int32_t *) &n))
199 goto error; 200 goto error;
200 while (n-- > 0) 201 while (n-- > 0)
201 { 202 {
202 if ((GNUNET_OK != GNUNET_BIO_read_string (rh, "filename", &fn, 1024)) || 203 struct GNUNET_BIO_ReadSpec rs[] = {
203 (GNUNET_OK != 204 GNUNET_BIO_read_spec_string("filename", &fn, 1024),
204 GNUNET_BIO_read (rh, "id", &id, sizeof(struct GNUNET_HashCode)))) 205 GNUNET_BIO_read_spec_object("id", &id, sizeof(struct GNUNET_HashCode)),
206 GNUNET_BIO_read_spec_end(),
207 };
208 if (GNUNET_OK != GNUNET_BIO_read_spec_commit (rh, rs))
205 goto error; 209 goto error;
206 wi = GNUNET_new (struct WorkItem); 210 wi = GNUNET_new (struct WorkItem);
207 wi->id = id; 211 wi->id = id;
@@ -251,9 +255,13 @@ write_item (void *cls, const struct GNUNET_HashCode *key, void *value)
251 "Saving serialization ID of file `%s' with value `%s'\n", 255 "Saving serialization ID of file `%s' with value `%s'\n",
252 wi->filename, 256 wi->filename,
253 GNUNET_h2s (&wi->id)); 257 GNUNET_h2s (&wi->id));
254 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, wi->filename)) || 258 struct GNUNET_BIO_WriteSpec ws[] = {
255 (GNUNET_OK != 259 GNUNET_BIO_write_spec_string ("auto-share-write-item-filename",
256 GNUNET_BIO_write (wh, &wi->id, sizeof(struct GNUNET_HashCode)))) 260 wi->filename),
261 GNUNET_BIO_write_spec_object ("id", &wi->id, sizeof(struct GNUNET_HashCode)),
262 GNUNET_BIO_write_spec_end (),
263 };
264 if (GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws))
257 return GNUNET_SYSERR; /* write error, abort iteration */ 265 return GNUNET_SYSERR; /* write error, abort iteration */
258 return GNUNET_OK; 266 return GNUNET_OK;
259} 267}
@@ -271,7 +279,7 @@ save_state ()
271 279
272 n = GNUNET_CONTAINER_multihashmap_size (work_finished); 280 n = GNUNET_CONTAINER_multihashmap_size (work_finished);
273 fn = get_state_file (); 281 fn = get_state_file ();
274 wh = GNUNET_BIO_write_open (fn); 282 wh = GNUNET_BIO_write_open_file (fn);
275 if (NULL == wh) 283 if (NULL == wh)
276 { 284 {
277 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 285 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -280,9 +288,9 @@ save_state ()
280 GNUNET_free (fn); 288 GNUNET_free (fn);
281 return; 289 return;
282 } 290 }
283 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, n)) 291 if (GNUNET_OK != GNUNET_BIO_write_int32 (wh, "size of state", n))
284 { 292 {
285 (void) GNUNET_BIO_write_close (wh); 293 (void) GNUNET_BIO_write_close (wh, NULL);
286 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 294 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
287 _ ("Failed to save state to file %s\n"), 295 _ ("Failed to save state to file %s\n"),
288 fn); 296 fn);
@@ -290,7 +298,7 @@ save_state ()
290 return; 298 return;
291 } 299 }
292 (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, &write_item, wh); 300 (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, &write_item, wh);
293 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 301 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
294 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 302 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
295 _ ("Failed to save state to file %s\n"), 303 _ ("Failed to save state to file %s\n"),
296 fn); 304 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 ()
123 "INDEXDB"); 123 "INDEXDB");
124 return; 124 return;
125 } 125 }
126 wh = GNUNET_BIO_write_open (fn); 126 wh = GNUNET_BIO_write_open_file (fn);
127 if (NULL == wh) 127 if (NULL == wh)
128 { 128 {
129 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 129 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
@@ -134,11 +134,14 @@ write_index_list ()
134 } 134 }
135 for (pos = indexed_files_head; NULL != pos; pos = pos->next) 135 for (pos = indexed_files_head; NULL != pos; pos = pos->next)
136 if ((GNUNET_OK != GNUNET_BIO_write (wh, 136 if ((GNUNET_OK != GNUNET_BIO_write (wh,
137 "fs-indexing-file-id",
137 &pos->file_id, 138 &pos->file_id,
138 sizeof(struct GNUNET_HashCode))) || 139 sizeof(struct GNUNET_HashCode))) ||
139 (GNUNET_OK != GNUNET_BIO_write_string (wh, pos->filename))) 140 (GNUNET_OK != GNUNET_BIO_write_string (wh,
141 "fs-indexing-filename",
142 pos->filename)))
140 break; 143 break;
141 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 144 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
142 { 145 {
143 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 146 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
144 _ ("Error writing `%s'.\n"), 147 _ ("Error writing `%s'.\n"),
@@ -178,7 +181,7 @@ read_index_list ()
178 GNUNET_free (fn); 181 GNUNET_free (fn);
179 return; 182 return;
180 } 183 }
181 rh = GNUNET_BIO_read_open (fn); 184 rh = GNUNET_BIO_read_open_file (fn);
182 if (NULL == rh) 185 if (NULL == rh)
183 { 186 {
184 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 187 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 ()
1404 return; 1404 return;
1405 } 1405 }
1406 1406
1407 rh = GNUNET_BIO_read_open (filename); 1407 rh = GNUNET_BIO_read_open_file (filename);
1408 if (NULL == rh) 1408 if (NULL == rh)
1409 { 1409 {
1410 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1410 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1417,13 +1417,17 @@ load_hostlist_file ()
1417 } 1417 }
1418 1418
1419 counter = 0; 1419 counter = 0;
1420 struct GNUNET_BIO_ReadSpec rs[] = {
1421 GNUNET_BIO_read_spec_int32 ("times used", (int32_t *)&times_used),
1422 GNUNET_BIO_read_spec_int64 ("quality", (int64_t *) &quality),
1423 GNUNET_BIO_read_spec_int64 ("last used", (int64_t *) &last_used),
1424 GNUNET_BIO_read_spec_int64 ("created", (int64_t *) &created),
1425 GNUNET_BIO_read_spec_int32 ("hellos returned", (int32_t *) &hellos_returned),
1426 GNUNET_BIO_read_spec_end (),
1427 };
1420 while ((GNUNET_OK == GNUNET_BIO_read_string (rh, "url", &uri, MAX_URL_LEN)) && 1428 while ((GNUNET_OK == GNUNET_BIO_read_string (rh, "url", &uri, MAX_URL_LEN)) &&
1421 (NULL != uri) && 1429 (NULL != uri) &&
1422 (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &times_used)) && 1430 (GNUNET_OK == GNUNET_BIO_read_spec_commit (rh, rs)))
1423 (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) &&
1424 (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used)) &&
1425 (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created)) &&
1426 (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned)))
1427 { 1431 {
1428 hostlist = GNUNET_malloc (sizeof(struct Hostlist) + strlen (uri) + 1); 1432 hostlist = GNUNET_malloc (sizeof(struct Hostlist) + strlen (uri) + 1);
1429 hostlist->hello_count = hellos_returned; 1433 hostlist->hello_count = hellos_returned;
@@ -1494,7 +1498,7 @@ save_hostlist_file (int shutdown)
1494 GNUNET_free (filename); 1498 GNUNET_free (filename);
1495 return; 1499 return;
1496 } 1500 }
1497 wh = GNUNET_BIO_write_open (filename); 1501 wh = GNUNET_BIO_write_open_file (filename);
1498 if (NULL == wh) 1502 if (NULL == wh)
1499 { 1503 {
1500 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1504 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1521,14 +1525,21 @@ save_hostlist_file (int shutdown)
1521 } 1525 }
1522 if (GNUNET_YES == ok) 1526 if (GNUNET_YES == ok)
1523 { 1527 {
1524 if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pos->hostlist_uri)) || 1528 struct GNUNET_BIO_WriteSpec ws[] = {
1525 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->times_used)) || 1529 GNUNET_BIO_write_spec_string ("hostlist uri", pos->hostlist_uri),
1526 (GNUNET_OK != GNUNET_BIO_write_int64 (wh, pos->quality)) || 1530 GNUNET_BIO_write_spec_int32 ("times used", (int32_t *) &pos->times_used),
1527 (GNUNET_OK != 1531 GNUNET_BIO_write_spec_int64 ("quality", (int64_t *) &pos->quality),
1528 GNUNET_BIO_write_int64 (wh, pos->time_last_usage.abs_value_us)) || 1532 GNUNET_BIO_write_spec_int64 (
1529 (GNUNET_OK != 1533 "last usage",
1530 GNUNET_BIO_write_int64 (wh, pos->time_creation.abs_value_us)) || 1534 (int64_t *) &pos->time_last_usage.abs_value_us),
1531 (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->hello_count))) 1535 GNUNET_BIO_write_spec_int64 (
1536 "creation time",
1537 (int64_t *) &pos->time_creation.abs_value_us),
1538 GNUNET_BIO_write_spec_int32 ("hellos count",
1539 (int32_t *) &pos->hello_count),
1540 GNUNET_BIO_write_spec_end (),
1541 };
1542 if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
1532 { 1543 {
1533 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1544 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1534 _ ("Error writing hostlist URIs to file `%s'\n"), 1545 _ ("Error writing hostlist URIs to file `%s'\n"),
@@ -1548,7 +1559,7 @@ save_hostlist_file (int shutdown)
1548 counter, 1559 counter,
1549 GNUNET_YES); 1560 GNUNET_YES);
1550 1561
1551 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 1562 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
1552 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1563 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1553 _ ("Error writing hostlist URIs to file `%s'\n"), 1564 _ ("Error writing hostlist URIs to file `%s'\n"),
1554 filename); 1565 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"
42#endif 42#endif
43#endif 43#endif
44 44
45/****************************** READING API *******************************/
46
45/** 47/**
46 * Handle for buffered reading. 48 * Handle for buffered reading.
47 */ 49 */
@@ -55,11 +57,22 @@ struct GNUNET_BIO_ReadHandle;
55 * @return IO handle on success, NULL on error 57 * @return IO handle on success, NULL on error
56 */ 58 */
57struct GNUNET_BIO_ReadHandle * 59struct GNUNET_BIO_ReadHandle *
58GNUNET_BIO_read_open (const char *fn); 60GNUNET_BIO_read_open_file (const char *fn);
61
62
63/**
64 * Create a handle from an existing allocated buffer.
65 *
66 * @param buffer the buffer to use as source
67 * @param size the total size in bytes of the buffer
68 * @return IO handle on sucess, NULL on error
69 */
70struct GNUNET_BIO_ReadHandle *
71GNUNET_BIO_read_open_buffer (void *buffer, size_t size);
59 72
60 73
61/** 74/**
62 * Close an open file. Reports if any errors reading 75 * Close an open handle. Reports if any errors reading
63 * from the file were encountered. 76 * from the file were encountered.
64 * 77 *
65 * @param h file handle 78 * @param h file handle
@@ -71,51 +84,40 @@ GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, char **emsg);
71 84
72 85
73/** 86/**
74 * Read the contents of a binary file into a buffer. 87 * Read some contents into a buffer.
75 * 88 *
76 * @param h handle to an open file 89 * @param h the IO handle to read from
77 * @param what describes what is being read (for error message creation) 90 * @param what describes what is being read (for error message creation)
78 * @param result the buffer to write the result to 91 * @param result the buffer to write the result to
79 * @param len the number of bytes to read 92 * @param len the number of bytes to read
80 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 93 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
81 */ 94 */
82int 95int
83GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, const char *what, 96GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
84 void *result, size_t len); 97 const char *what,
98 void *result,
99 size_t len);
85 100
86 101
87/** 102/**
88 * Read the contents of a binary file into a buffer. 103 * Read 0-terminated string.
89 * 104 *
90 * @param h handle to an open file 105 * @param h the IO handle to read from
91 * @param file name of the source file
92 * @param line line number in the source file
93 * @param result the buffer to write the result to
94 * @param len the number of bytes to read
95 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
96 */
97int
98GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h,
99 const char *file, int line,
100 void *result, size_t len);
101
102/**
103 * Read 0-terminated string from a file.
104 *
105 * @param h handle to an open file
106 * @param what describes what is being read (for error message creation) 106 * @param what describes what is being read (for error message creation)
107 * @param result the buffer to store a pointer to the (allocated) string to 107 * @param result where to store the pointer to the (allocated) string
108 * (note that *result could be set to NULL as well) 108 * (note that *result could be set to NULL as well)
109 * @param max_length maximum allowed length for the string 109 * @param max_length maximum allowed length for the string
110 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 110 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
111 */ 111 */
112int 112int
113GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h, const char *what, 113GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
114 char **result, size_t max_length); 114 const char *what,
115 char **result,
116 size_t max_length);
115 117
116 118
117/** 119/**
118 * Read metadata container from a file. 120 * Read a metadata container.
119 * 121 *
120 * @param h handle to an open file 122 * @param h handle to an open file
121 * @param what describes what is being read (for error message creation) 123 * @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,
123 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 125 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
124 */ 126 */
125int 127int
126GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h, const char *what, 128GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
129 const char *what,
127 struct GNUNET_CONTAINER_MetaData **result); 130 struct GNUNET_CONTAINER_MetaData **result);
128 131
129 132
130/** 133/**
131 * Read a float. 134 * Read a float.
132 * 135 *
133 * @param h hande to open file 136 * @param h the IO handle to read from
137 * @param what describes what is being read (for error message creation)
134 * @param f address of float to read 138 * @param f address of float to read
135 */ 139 */
136#define GNUNET_BIO_read_float(h, f) (GNUNET_BIO_read_fn (h, __FILE__, __LINE__, \ 140int
137 f, sizeof(float))) 141GNUNET_BIO_read_float(struct GNUNET_BIO_ReadHandle *h,
142 const char *what,
143 float *f);
138 144
139 145
140/** 146/**
141 * Read a double. 147 * Read a double.
142 * 148 *
143 * @param h hande to open file 149 * @param h the IO handle to read from
150 * @param what describes what is being read (for error message creation)
144 * @param f address of double to read 151 * @param f address of double to read
145 */ 152 */
146#define GNUNET_BIO_read_double(h, f) (GNUNET_BIO_read_fn (h, __FILE__, __LINE__, \ 153int
147 f, sizeof(double))) 154GNUNET_BIO_read_double(struct GNUNET_BIO_ReadHandle *h,
155 const char *what,
156 double *f);
157
148 158
149 159
150/** 160/**
151 * Read an (u)int32_t. 161 * Read an (u)int32_t.
152 * 162 *
153 * @param h hande to open file 163 * @param h the IO handle to read from
154 * @param file name of the source file 164 * @param what describes what is being read (for error message creation)
155 * @param line line number in the code 165 * @param i where to store the data
156 * @param i address of 32-bit integer to read
157 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 166 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
158 */ 167 */
159int 168int
160GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, const char *file, 169GNUNET_BIO_read_int32 (struct GNUNET_BIO_ReadHandle *h,
161 int line, int32_t *i); 170 const char *what,
162 171 int32_t *i);
163 172
164/**
165 * Read an (u)int32_t.
166 *
167 * @param h hande to open file
168 * @param i address of 32-bit integer to read
169 */
170#define GNUNET_BIO_read_int32(h, i) GNUNET_BIO_read_int32__ (h, __FILE__, \
171 __LINE__, \
172 (int32_t *) i)
173 173
174 174
175/** 175/**
176 * Read an (u)int64_t. 176 * Read an (u)int64_t.
177 * 177 *
178 * @param h hande to open file 178 * @param h the IO handle to read from
179 * @param file name of the source file 179 * @param what describes what is being read (for error message creation)
180 * @param line line number in the code 180 * @param i where to store the data
181 * @param i address of 64-bit integer to read
182 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 181 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
183 */ 182 */
184int 183int
185GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, const char *file, 184GNUNET_BIO_read_int64 (struct GNUNET_BIO_ReadHandle *h,
186 int line, int64_t *i); 185 const char *what,
186 int64_t *i);
187 187
188 188
189/**
190 * Read an (u)int64_t.
191 *
192 * @param h hande to open file
193 * @param i address of 64-bit integer to read
194 */
195#define GNUNET_BIO_read_int64(h, i) GNUNET_BIO_read_int64__ (h, __FILE__, \
196 __LINE__, \
197 (int64_t *) i)
198 189
190/****************************** WRITING API *******************************/
199 191
200/** 192/**
201 * Handle for buffered writing. 193 * Handle for buffered writing.
@@ -205,108 +197,481 @@ struct GNUNET_BIO_WriteHandle;
205/** 197/**
206 * Open a file for writing. 198 * Open a file for writing.
207 * 199 *
208 * @param fn file name to be opened 200 * @param fn name of the file to be opened
209 * @return IO handle on success, NULL on error 201 * @return IO handle on success, NULL on error
210 */ 202 */
211struct GNUNET_BIO_WriteHandle * 203struct GNUNET_BIO_WriteHandle *
212GNUNET_BIO_write_open (const char *fn); 204GNUNET_BIO_write_open_file (const char *fn);
213 205
214 206
215/** 207/**
216 * Close an open file for writing. 208 * Create a handle backed by an in-memory buffer.
217 * 209 *
218 * @param h file handle 210 * @return IO handle on success, NULL on error
219 * @return GNUNET_OK on success, GNUNET_SYSERR otherwise 211 */
212struct GNUNET_BIO_WriteHandle *
213GNUNET_BIO_write_open_buffer (void);
214
215
216/**
217 * Force a file-based buffered writer to flush its buffer.
218 * If the handle does not use a file, this function returs #GNUNET_OK
219 * without doing anything.
220 *
221 * @param h the IO handle
222 * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned
223 * and the file is closed
220 */ 224 */
221int 225int
222GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h); 226GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h);
223 227
224 228
225/** 229/**
226 * Write a buffer to a file. 230 * Get the IO handle's contents.
231 * If the handle doesn't use an in-memory buffer, this function returns
232 * #GNUNET_SYSERR.
227 * 233 *
228 * @param h handle to open file 234 * @param h the IO handle
229 * @param buffer the data to write 235 * @param emsg set to the (allocated) error message
230 * @param n number of bytes to write 236 * if the handle has an error message the return value is #GNUNET_SYSERR
231 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 237 * @param contents where to store the pointer to the handle's contents
238 * @param size where to store the size of @e contents
239 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
232 */ 240 */
233int 241int
234GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, const void *buffer, 242GNUNET_BIO_get_buffer_contents (struct GNUNET_BIO_WriteHandle *h,
235 size_t n); 243 char **emsg,
244 void **contents,
245 size_t *size);
246
247
248/**
249 * Close an IO handle.
250 * If the handle was using a file, the file will be closed.
251 *
252 * @param h file handle
253 * @param emsg set to the (allocated) error message
254 * if the handle has an error message, the return value is #GNUNET_SYSERR
255 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
256 */
257int
258GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h, char **emsg);
236 259
237 260
238/** 261/**
239 * Force a buffered writer to flush its buffer 262 * Write a buffer to a handle.
240 * 263 *
241 * @param h the writer handle 264 * @param h the IO handle to write to
242 * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned and 265 * @param what what is being written (for error message creation)
243 * the file is closed 266 * @param buffer the data to write
267 * @param n number of bytes to write
268 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
244 */ 269 */
245int 270int
246GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h); 271GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
272 const char *what,
273 const void *buffer,
274 size_t n);
247 275
248 276
249/** 277/**
250 * Write a string to a file. 278 * Write a 0-terminated string.
251 * 279 *
252 * @param h handle to open file 280 * @param h the IO handle to write to
281 * @param what what is being written (for error message creation)
253 * @param s string to write (can be NULL) 282 * @param s string to write (can be NULL)
254 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 283 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
255 */ 284 */
256int 285int
257GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, const char *s); 286GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
287 const char *what,
288 const char *s);
258 289
259 290
260/** 291/**
261 * Write metadata container to a file. 292 * Write a metadata container.
262 * 293 *
263 * @param h handle to open file 294 * @param h the IO handle to write to
295 * @param what what is being written (for error message creation)
264 * @param m metadata to write 296 * @param m metadata to write
265 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 297 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
266 */ 298 */
267int 299int
268GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, 300GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
301 const char *what,
269 const struct GNUNET_CONTAINER_MetaData *m); 302 const struct GNUNET_CONTAINER_MetaData *m);
270 303
271 304
272/** 305/**
273 * Write a float. 306 * Write a float.
274 * 307 *
275 * @param h hande to open file 308 * @param h the IO handle to write to
309 * @param what what is being written (for error message creation)
276 * @param f float to write (must be a variable) 310 * @param f float to write (must be a variable)
277 */ 311 */
278#define GNUNET_BIO_write_float(h, f) GNUNET_BIO_write (h, &f, sizeof(float)) 312int
279 313GNUNET_BIO_write_float(struct GNUNET_BIO_WriteHandle *h,
314 const char *what,
315 float f);
280 316
281/** 317/**
282 * Write a double. 318 * Write a double.
283 * 319 *
284 * @param h hande to open file 320 * @param h the IO handle to write to
321 * @param what what is being written (for error message creation)
285 * @param f double to write (must be a variable) 322 * @param f double to write (must be a variable)
286 */ 323 */
287#define GNUNET_BIO_write_double(h, f) GNUNET_BIO_write (h, &f, sizeof(double)) 324int
325GNUNET_BIO_write_double(struct GNUNET_BIO_WriteHandle *h,
326 const char *what,
327 double f);
288 328
289 329
290/** 330/**
291 * Write an (u)int32_t. 331 * Write an (u)int32_t.
292 * 332 *
293 * @param h hande to open file 333 * @param h the IO handle to write to
334 * @param what what is being written (for error message creation)
294 * @param i 32-bit integer to write 335 * @param i 32-bit integer to write
295 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 336 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
296 */ 337 */
297int 338int
298GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h, int32_t i); 339GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h,
340 const char *what,
341 int32_t i);
299 342
300 343
301/** 344/**
302 * Write an (u)int64_t. 345 * Write an (u)int64_t.
303 * 346 *
304 * @param h hande to open file 347 * @param h the IO handle to write to
348 * @param what what is being written (for error message creation)
305 * @param i 64-bit integer to write 349 * @param i 64-bit integer to write
306 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 350 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
307 */ 351 */
308int 352int
309GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h, int64_t i); 353GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h,
354 const char *what,
355 int64_t i);
356
357
358/****************************** READ SPEC API ***************************/
359
360
361/**
362 * Function used to deserialize data read from @a h and store it into @a
363 * target.
364 *
365 * @param cls closure (can be NULL)
366 * @param h the IO handle to read from
367 * @param what what is being read (for error message creation)
368 * @param target where to store the data
369 * @param target_size how many bytes can be written in @a target
370 * can be 0 if the size is unknown or is not fixed
371 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
372 */
373typedef int
374(*GNUNET_BIO_ReadHandler)(void *cls,
375 struct GNUNET_BIO_ReadHandle *h,
376 const char *what,
377 void *target,
378 size_t target_size);
379
380
381/**
382 * Structure specifying a reading operation on an IO handle.
383 */
384struct GNUNET_BIO_ReadSpec
385{
386 /**
387 * Function performing data deserialization.
388 */
389 GNUNET_BIO_ReadHandler rh;
390
391 /**
392 * Closure for @e rh. Can be NULL.
393 */
394 void *cls;
395
396 /**
397 * What is being read (for error message creation)
398 */
399 const char *what;
400
401 /**
402 * Destination buffer. Can also be a pointer to a pointer, especially for
403 * dynamically allocated structures.
404 */
405 void *target;
406
407 /**
408 * Size of @e target. Can be 0 if unknown or not fixed.
409 */
410 size_t size;
411};
412
413
414/**
415 * End of specifications marker.
416 */
417#define GNUNET_BIO_read_spec_end() \
418 { NULL, NULL, NULL, NULL, 0 }
419
420
421/**
422 * Create the specification to read a certain amount of bytes.
423 *
424 * @param what describes what is being read (for error message creation)
425 * @param result the buffer to write the result to
426 * @param len the number of bytes to read
427 * @return the read spec
428 */
429struct GNUNET_BIO_ReadSpec
430GNUNET_BIO_read_spec_object (const char *what,
431 void *result,
432 size_t size);
433
434
435/**
436 * Create the specification to read a 0-terminated string.
437 *
438 * @param what describes what is being read (for error message creation)
439 * @param result where to store the pointer to the (allocated) string
440 * (note that *result could be set to NULL as well)
441 * @param max_length maximum allowed length for the string
442 * @return the read spec
443 */
444struct GNUNET_BIO_ReadSpec
445GNUNET_BIO_read_spec_string (const char *what,
446 char **result,
447 size_t max_length);
448
449
450/**
451 * Create the specification to read a metadata container.
452 *
453 * @param what describes what is being read (for error message creation)
454 * @param result the buffer to store a pointer to the (allocated) metadata
455 * @return the read spec
456 */
457struct GNUNET_BIO_ReadSpec
458GNUNET_BIO_read_spec_meta_data (const char *what,
459 struct GNUNET_CONTAINER_MetaData **result);
460
461
462/**
463 * Create the specification to read an (u)int32_t.
464 *
465 * @param what describes what is being read (for error message creation)
466 * @param i where to store the data
467 * @return the read spec
468 */
469struct GNUNET_BIO_ReadSpec
470GNUNET_BIO_read_spec_int32 (const char *what,
471 int32_t *i);
472
473
474/**
475 * Create the specification to read an (u)int64_t.
476 *
477 * @param what describes what is being read (for error message creation)
478 * @param i where to store the data
479 * @return the read spec
480 */
481struct GNUNET_BIO_ReadSpec
482GNUNET_BIO_read_spec_int64 (const char *what,
483 int64_t *i);
484
485
486/**
487 * Create the specification to read a float.
488 *
489 * @param what describes what is being read (for error message creation)
490 * @param f address of float to read
491 */
492struct GNUNET_BIO_ReadSpec
493GNUNET_BIO_read_spec_float(const char *what, float *f);
494
495
496/**
497 * Create the specification to read a double.
498 *
499 * @param what describes what is being read (for error message creation)
500 * @param f address of double to read
501 */
502struct GNUNET_BIO_ReadSpec
503GNUNET_BIO_read_spec_double(const char *what, double *f);
504
505
506/**
507 * Execute the read specifications in order.
508 *
509 * @param h the IO handle to read from
510 * @param rs array of read specs
511 * the last element must be #GNUNET_BIO_read_spec_end
512 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
513 */
514int
515GNUNET_BIO_read_spec_commit (struct GNUNET_BIO_ReadHandle *h,
516 struct GNUNET_BIO_ReadSpec *rs);
517
518
519/******************************* WRITE SPEC API *****************************/
520
521
522/**
523 * Function used to serialize data from a buffer and write it to @a h.
524 *
525 * @param cls closure (can be NULL)
526 * @param h the IO handle to write to
527 * @param what what is being written (for error message creation)
528 * @param source the data to write
529 * @param source_size how many bytes should be written
530 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
531 */
532typedef int
533(*GNUNET_BIO_WriteHandler) (void *cls,
534 struct GNUNET_BIO_WriteHandle *h,
535 const char *what,
536 void *source,
537 size_t source_size);
538
539
540/**
541 * Structure specifying a writing operation on an IO handle.
542 */
543struct GNUNET_BIO_WriteSpec
544{
545 /**
546 * Function performing data serialization.
547 */
548 GNUNET_BIO_WriteHandler wh;
549
550 /**
551 * Closure for @e rh. Can be NULL.
552 */
553 void *cls;
554
555 /**
556 * What is being read (for error message creation)
557 */
558 const char *what;
559
560 /**
561 * Source buffer. The data in this buffer will be written to the handle.
562 */
563 void *source;
564
565 /**
566 * Size of @e source. If it's smaller than the real size of @e source, only
567 * this many bytes will be written.
568 */
569 size_t source_size;
570};
571
572
573/**
574 * End of specifications marker.
575 */
576#define GNUNET_BIO_write_spec_end() \
577 { NULL, NULL, NULL, NULL, 0 }
578
579
580/**
581 * Create the specification to read some bytes.
582 *
583 * @param what describes what is being written (for error message creation)
584 * @param source the data to write
585 * @param size how many bytes should be written
586 * @return the write spec
587 */
588struct GNUNET_BIO_WriteSpec
589GNUNET_BIO_write_spec_object (const char *what,
590 void *source,
591 size_t size);
592
593
594/**
595 * Create the specification to write a 0-terminated string.
596 *
597 * @param what describes what is being read (for error message creation)
598 * @param s string to write (can be NULL)
599 * @return the read spec
600 */
601struct GNUNET_BIO_WriteSpec
602GNUNET_BIO_write_spec_string (const char *what,
603 const char *s);
604
605
606/**
607 * Create the specification to write a metadata container.
608 *
609 * @param what what is being written (for error message creation)
610 * @param m metadata to write
611 * @return the write spec
612 */
613struct GNUNET_BIO_WriteSpec
614GNUNET_BIO_write_spec_meta_data (const char *what,
615 const struct GNUNET_CONTAINER_MetaData *m);
616
617
618/**
619 * Create the specification to write an (u)int32_t.
620 *
621 * @param what describes what is being written (for error message creation)
622 * @param i pointer to a 32-bit integer
623 * @return the write spec
624 */
625struct GNUNET_BIO_WriteSpec
626GNUNET_BIO_write_spec_int32 (const char *what,
627 int32_t *i);
628
629
630/**
631 * Create the specification to write an (u)int64_t.
632 *
633 * @param what describes what is being written (for error message creation)
634 * @param i pointer to a 64-bit integer
635 * @return the write spec
636 */
637struct GNUNET_BIO_WriteSpec
638GNUNET_BIO_write_spec_int64 (const char *what,
639 int64_t *i);
640
641
642/**
643 * Create the specification to write a float.
644 *
645 * @param what describes what is being written (for error message creation)
646 * @param f pointer to a float
647 * @return the write spec
648 */
649struct GNUNET_BIO_WriteSpec
650GNUNET_BIO_write_spec_float(const char *what, float *f);
651
652
653/**
654 * Create the specification to write an double.
655 *
656 * @param what describes what is being written (for error message creation)
657 * @param f pointer to a double
658 * @return the write spec
659 */
660struct GNUNET_BIO_WriteSpec
661GNUNET_BIO_write_spec_double(const char *what, double *f);
662
663
664/**
665 * Execute the write specifications in order.
666 *
667 * @param h the IO handle to write to
668 * @param ws array of write specs
669 * the last element must be #GNUNET_BIO_write_spec_end
670 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
671 */
672int
673GNUNET_BIO_write_spec_commit (struct GNUNET_BIO_WriteHandle *h,
674 struct GNUNET_BIO_WriteSpec *ws);
310 675
311 676
312#if 0 /* keep Emacsens' auto-indent happy */ 677#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);
165 165
166 166
167/** 167/**
168 * Clear the buffer and return its contents.
169 * The caller is responsible to eventually #GNUNET_free
170 * the returned data.
171 *
172 * @param buf the buffer to reap the contents from
173 * @param size where to store the size of the returned data
174 * @returns the data contained in the string
175 */
176void *
177GNUNET_buffer_reap (struct GNUNET_Buffer *buf, size_t *size);
178
179
180/**
168 * Free the backing memory of the given buffer. 181 * Free the backing memory of the given buffer.
169 * Does not free the memory of the buffer control structure, 182 * Does not free the memory of the buffer control structure,
170 * which is typically stack-allocated. 183 * 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,
1001 if (NULL != lh) 1001 if (NULL != lh)
1002 GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof(uint64_t)); 1002 GNUNET_TESTBED_LOGGER_write (lh, &t, sizeof(uint64_t));
1003 if (NULL != histogram) 1003 if (NULL != histogram)
1004 GNUNET_BIO_write_int64 (histogram, t); 1004 GNUNET_BIO_write_int64 (histogram, "histogram-time", t);
1005 } 1005 }
1006#endif 1006#endif
1007 GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO); 1007 GNUNET_STATISTICS_update (stats, "# flood messages received", 1, GNUNET_NO);
@@ -1299,7 +1299,7 @@ shutdown_task (void *cls)
1299 } 1299 }
1300 if (NULL != histogram) 1300 if (NULL != histogram)
1301 { 1301 {
1302 GNUNET_BIO_write_close (histogram); 1302 GNUNET_BIO_write_close (histogram, NULL);
1303 histogram = NULL; 1303 histogram = NULL;
1304 } 1304 }
1305#endif 1305#endif
@@ -1453,7 +1453,7 @@ run (void *cls,
1453 GNUNET_assert ( 1453 GNUNET_assert (
1454 0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir)); 1454 0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir));
1455 GNUNET_free (histogram_dir); 1455 GNUNET_free (histogram_dir);
1456 histogram = GNUNET_BIO_write_open (histogram_fn); 1456 histogram = GNUNET_BIO_write_open_file (histogram_fn);
1457 if (NULL == histogram) 1457 if (NULL == histogram)
1458 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1458 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1459 "Unable to open histogram file `%s'\n", 1459 "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 ()
263 return; 263 return;
264 } 264 }
265 (void) GNUNET_DISK_directory_create_for_file (fn); 265 (void) GNUNET_DISK_directory_create_for_file (fn);
266 wh = GNUNET_BIO_write_open (fn); 266 wh = GNUNET_BIO_write_open_file (fn);
267 total = 0; 267 total = 0;
268 while (NULL != (se = sub_head)) 268 while (NULL != (se = sub_head))
269 { 269 {
@@ -290,10 +290,10 @@ save ()
290 msg->flags = 290 msg->flags =
291 htonl (pos->persistent ? GNUNET_STATISTICS_SETFLAG_PERSISTENT : 0); 291 htonl (pos->persistent ? GNUNET_STATISTICS_SETFLAG_PERSISTENT : 0);
292 msg->value = GNUNET_htonll (pos->value); 292 msg->value = GNUNET_htonll (pos->value);
293 if (GNUNET_OK != GNUNET_BIO_write (wh, msg, size)) 293 if (GNUNET_OK != GNUNET_BIO_write (wh, "statistics-save-msg", msg, size))
294 { 294 {
295 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn); 295 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "write", fn);
296 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 296 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
297 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", fn); 297 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", fn);
298 wh = NULL; 298 wh = NULL;
299 } 299 }
@@ -309,7 +309,7 @@ save ()
309 } 309 }
310 if (NULL != wh) 310 if (NULL != wh)
311 { 311 {
312 if (GNUNET_OK != GNUNET_BIO_write_close (wh)) 312 if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
313 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", fn); 313 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "close", fn);
314 if (0 == total) 314 if (0 == total)
315 GNUNET_break (0 == unlink (fn)); 315 GNUNET_break (0 == unlink (fn));
@@ -964,7 +964,7 @@ load ()
964 return; 964 return;
965 } 965 }
966 buf = GNUNET_malloc (fsize); 966 buf = GNUNET_malloc (fsize);
967 rh = GNUNET_BIO_read_open (fn); 967 rh = GNUNET_BIO_read_open_file (fn);
968 if (! rh) 968 if (! rh)
969 { 969 {
970 GNUNET_free (buf); 970 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,
85 85
86 ms = ntohs (msg->size) - sizeof(struct GNUNET_MessageHeader); 86 ms = ntohs (msg->size) - sizeof(struct GNUNET_MessageHeader);
87 GNUNET_BIO_write (bio, 87 GNUNET_BIO_write (bio,
88 "testbed-logger-handle-log-msg",
88 &msg[1], 89 &msg[1],
89 ms); 90 ms);
90 GNUNET_SERVICE_client_continue (client); 91 GNUNET_SERVICE_client_continue (client);
@@ -108,7 +109,7 @@ shutdown_task (void *cls)
108 return; 109 return;
109 } 110 }
110 GNUNET_break (GNUNET_OK == 111 GNUNET_break (GNUNET_OK ==
111 GNUNET_BIO_write_close (bio)); 112 GNUNET_BIO_write_close (bio, NULL));
112} 113}
113 114
114 115
@@ -202,7 +203,7 @@ logger_run (void *cls,
202 (intmax_t) pid); 203 (intmax_t) pid);
203 GNUNET_free (hname); 204 GNUNET_free (hname);
204 GNUNET_free (dir); 205 GNUNET_free (dir);
205 if (NULL == (bio = GNUNET_BIO_write_open (fn))) 206 if (NULL == (bio = GNUNET_BIO_write_open_file (fn)))
206 { 207 {
207 GNUNET_free (fn); 208 GNUNET_free (fn);
208 GNUNET_SCHEDULER_shutdown (); 209 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)
568 ld_cpu, ld_disk, mem_usage, nproc); 568 ld_cpu, ld_disk, mem_usage, nproc);
569 if (0 < nbs) 569 if (0 < nbs)
570 { 570 {
571 GNUNET_BIO_write (bw, str, nbs); 571 GNUNET_BIO_write (bw, "sample load task", str, nbs);
572 } 572 }
573 else 573 else
574 GNUNET_break (0); 574 GNUNET_break (0);
@@ -612,7 +612,7 @@ GST_stats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
612 hostname, (intmax_t) getpid ()); 612 hostname, (intmax_t) getpid ());
613 GNUNET_free (stats_dir); 613 GNUNET_free (stats_dir);
614 GNUNET_free (hostname); 614 GNUNET_free (hostname);
615 if (NULL == (bw = GNUNET_BIO_write_open (fn))) 615 if (NULL == (bw = GNUNET_BIO_write_open_file (fn)))
616 { 616 {
617 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 617 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
618 _ ("Cannot open %s for writing load statistics. " 618 _ ("Cannot open %s for writing load statistics. "
@@ -656,7 +656,7 @@ GST_stats_destroy ()
656 GNUNET_SCHEDULER_cancel (sample_load_task_id); 656 GNUNET_SCHEDULER_cancel (sample_load_task_id);
657 sample_load_task_id = NULL; 657 sample_load_task_id = NULL;
658 } 658 }
659 GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bw)); 659 GNUNET_break (GNUNET_OK == GNUNET_BIO_write_close (bw, NULL));
660 bw = NULL; 660 bw = NULL;
661} 661}
662 662
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 @@
48 48
49 49
50/** 50/**
51 * Enum used internally to know how buffering is handled.
52 *
53 * The idea is that by using an enum, BIO can be extended to support other
54 * kinds of "backend" for buffering (or just formatted I/O.)
55 */
56enum IOType
57{
58 /**
59 * The handle uses a file to read/write data.
60 */
61 IO_FILE = 0,
62
63 /**
64 * The data is stored entirely in memory.
65 */
66 IO_BUFFER,
67};
68
69
70/**
51 * Handle for buffered reading. 71 * Handle for buffered reading.
52 */ 72 */
53struct GNUNET_BIO_ReadHandle 73struct GNUNET_BIO_ReadHandle
54{ 74{
55 /** 75 /**
56 * Underlying file abstraction. 76 * The "backend" type.
77 */
78 enum IOType type;
79
80 /**
81 * Handle to a file on disk, if @e type is #IO_FILE.
57 */ 82 */
58 struct GNUNET_DISK_FileHandle *fd; 83 struct GNUNET_DISK_FileHandle *fd;
59 84
@@ -63,12 +88,12 @@ struct GNUNET_BIO_ReadHandle
63 char *emsg; 88 char *emsg;
64 89
65 /** 90 /**
66 * I/O buffer. Allocated at the end of the struct, do not free! 91 * I/O buffer. Do @b not free!
67 */ 92 */
68 char *buffer; 93 char *buffer;
69 94
70 /** 95 /**
71 * Number of bytes available in read @e buffer. 96 * Number of bytes available in @e buffer.
72 */ 97 */
73 size_t have; 98 size_t have;
74 99
@@ -91,7 +116,7 @@ struct GNUNET_BIO_ReadHandle
91 * @return IO handle on success, NULL on error 116 * @return IO handle on success, NULL on error
92 */ 117 */
93struct GNUNET_BIO_ReadHandle * 118struct GNUNET_BIO_ReadHandle *
94GNUNET_BIO_read_open (const char *fn) 119GNUNET_BIO_read_open_file (const char *fn)
95{ 120{
96 struct GNUNET_DISK_FileHandle *fd; 121 struct GNUNET_DISK_FileHandle *fd;
97 struct GNUNET_BIO_ReadHandle *h; 122 struct GNUNET_BIO_ReadHandle *h;
@@ -100,6 +125,7 @@ GNUNET_BIO_read_open (const char *fn)
100 if (NULL == fd) 125 if (NULL == fd)
101 return NULL; 126 return NULL;
102 h = GNUNET_malloc (sizeof(struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE); 127 h = GNUNET_malloc (sizeof(struct GNUNET_BIO_ReadHandle) + BIO_BUFFER_SIZE);
128 h->type = IO_FILE;
103 h->buffer = (char *) &h[1]; 129 h->buffer = (char *) &h[1];
104 h->size = BIO_BUFFER_SIZE; 130 h->size = BIO_BUFFER_SIZE;
105 h->fd = fd; 131 h->fd = fd;
@@ -108,11 +134,32 @@ GNUNET_BIO_read_open (const char *fn)
108 134
109 135
110/** 136/**
111 * Close an open file. Reports if any errors reading 137 * Create a handle from an existing allocated buffer.
138 *
139 * @param buffer the buffer to use as source
140 * @param size the total size in bytes of the buffer
141 * @return IO handle on sucess, NULL on error
142 */
143struct GNUNET_BIO_ReadHandle *
144GNUNET_BIO_read_open_buffer (void *buffer, size_t size)
145{
146 struct GNUNET_BIO_ReadHandle *h;
147
148 h = GNUNET_new (struct GNUNET_BIO_ReadHandle);
149 h->type = IO_BUFFER;
150 h->buffer = buffer;
151 h->size = size;
152 return h;
153}
154
155
156/**
157 * Close an open handle. Reports if any errors reading
112 * from the file were encountered. 158 * from the file were encountered.
113 * 159 *
114 * @param h file handle 160 * @param h file handle
115 * @param emsg set to the error message 161 * @param emsg set to the (allocated) error message
162 * if the handle has an error message, the return value is #GNUNET_SYSERR
116 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 163 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
117 */ 164 */
118int 165int
@@ -121,60 +168,63 @@ GNUNET_BIO_read_close (struct GNUNET_BIO_ReadHandle *h, char **emsg)
121 int err; 168 int err;
122 169
123 err = (NULL == h->emsg) ? GNUNET_OK : GNUNET_SYSERR; 170 err = (NULL == h->emsg) ? GNUNET_OK : GNUNET_SYSERR;
124 if (emsg != NULL) 171 if (NULL != emsg)
125 *emsg = h->emsg; 172 *emsg = h->emsg;
126 else 173 else
127 GNUNET_free_non_null (h->emsg); 174 GNUNET_free_non_null (h->emsg);
128 GNUNET_DISK_file_close (h->fd); 175 switch (h->type)
176 {
177 case IO_FILE:
178 GNUNET_DISK_file_close (h->fd);
179 break;
180 case IO_BUFFER:
181 break;
182 default:
183 break;
184 }
129 GNUNET_free (h); 185 GNUNET_free (h);
130 return err; 186 return err;
131} 187}
132 188
133 189
134/** 190/**
135 * Read the contents of a binary file into a buffer. 191 * Function used internally to read the contents of a file into a buffer.
136 * 192 *
137 * @param h handle to an open file 193 * @param h the IO handle to read from
138 * @param what describes what is being read (for error message creation) 194 * @param what describes what is being read (for error message creation)
139 * @param result the buffer to write the result to 195 * @param result the buffer to write the data to
140 * @param len the number of bytes to read 196 * @param len the number of bytes to read
141 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 197 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
142 */ 198 */
143int 199static int
144GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h, 200read_from_file (struct GNUNET_BIO_ReadHandle *h,
145 const char *what, 201 const char *what,
146 void *result, 202 char *result,
147 size_t len) 203 size_t len)
148{ 204{
149 char *dst = result; 205 size_t pos = 0;
150 size_t min; 206 size_t min;
151 size_t pos;
152 ssize_t ret; 207 ssize_t ret;
153 208
154 if (NULL != h->emsg)
155 return GNUNET_SYSERR;
156 pos = 0;
157 do 209 do
158 { 210 {
159 /* first, use buffer */
160 min = h->have - h->pos; 211 min = h->have - h->pos;
161 if (min > 0) 212 if (0 < min)
162 { 213 {
163 if (min > len - pos) 214 if (len - pos < min)
164 min = len - pos; 215 min = len - pos;
165 GNUNET_memcpy (&dst[pos], &h->buffer[h->pos], min); 216 GNUNET_memcpy (&result[pos], &h->buffer[h->pos], min);
166 h->pos += min; 217 h->pos += min;
167 pos += min; 218 pos += min;
168 } 219 }
169 if (pos == len) 220 if (len == pos)
170 return GNUNET_OK; /* done! */ 221 return GNUNET_OK;
171 GNUNET_assert (((off_t) h->have) == h->pos); 222 GNUNET_assert (((off_t) h->have) == h->pos);
172 /* fill buffer */
173 ret = GNUNET_DISK_file_read (h->fd, h->buffer, h->size); 223 ret = GNUNET_DISK_file_read (h->fd, h->buffer, h->size);
174 if (-1 == ret) 224 if (-1 == ret)
175 { 225 {
176 GNUNET_asprintf (&h->emsg, 226 GNUNET_asprintf (&h->emsg,
177 _ ("Error reading `%s': %s"), 227 _ ("Error reading `%s' from file: %s"),
178 what, 228 what,
179 strerror (errno)); 229 strerror (errno));
180 return GNUNET_SYSERR; 230 return GNUNET_SYSERR;
@@ -182,7 +232,7 @@ GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
182 if (0 == ret) 232 if (0 == ret)
183 { 233 {
184 GNUNET_asprintf (&h->emsg, 234 GNUNET_asprintf (&h->emsg,
185 _ ("Error reading `%s': %s"), 235 _ ("Error reading `%s' from file: %s"),
186 what, 236 what,
187 _ ("End of file")); 237 _ ("End of file"));
188 return GNUNET_SYSERR; 238 return GNUNET_SYSERR;
@@ -190,41 +240,84 @@ GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
190 h->pos = 0; 240 h->pos = 0;
191 h->have = ret; 241 h->have = ret;
192 } 242 }
193 while (pos < len); /* should always be true */ 243 while (pos < len);
194 return GNUNET_OK; 244 return GNUNET_OK;
195} 245}
196 246
197 247
198/** 248/**
199 * Read the contents of a binary file into a buffer. 249 * Function used internally to read the content of a buffer into a buffer.
200 * 250 *
201 * @param h handle to an open file 251 * @param h the IO handle to read from
202 * @param file name of the source file 252 * @param what describes what is being read (for error message creation)
203 * @param line line number in the source file 253 * @param result the buffer to write the result to
254 * @param len the number of bytes to read
255 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
256 */
257static int
258read_from_buffer (struct GNUNET_BIO_ReadHandle *h,
259 const char *what,
260 char *result,
261 size_t len)
262{
263 if (h->size < len || h->size - h->pos < len)
264 {
265 GNUNET_asprintf (&h->emsg,
266 _ ("Error while reading `%s' from buffer: %s"),
267 what,
268 _ ("Not enough data left"));
269 return GNUNET_SYSERR;
270 }
271 GNUNET_memcpy (result, h->buffer + h->pos, len);
272 h->pos += len;
273 return GNUNET_OK;
274}
275
276
277/**
278 * Read some contents into a buffer.
279 *
280 * @param h the IO handle to read from
281 * @param what describes what is being read (for error message creation)
204 * @param result the buffer to write the result to 282 * @param result the buffer to write the result to
205 * @param len the number of bytes to read 283 * @param len the number of bytes to read
206 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 284 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
207 */ 285 */
208int 286int
209GNUNET_BIO_read_fn (struct GNUNET_BIO_ReadHandle *h, 287GNUNET_BIO_read (struct GNUNET_BIO_ReadHandle *h,
210 const char *file, 288 const char *what,
211 int line, 289 void *result,
212 void *result, 290 size_t len)
213 size_t len)
214{ 291{
215 char what[PATH_MAX + 1024]; 292 char *dst = result;
216 293
217 GNUNET_snprintf (what, sizeof(what), "%s:%d", file, line); 294 if (NULL != h->emsg)
218 return GNUNET_BIO_read (h, what, result, len); 295 return GNUNET_SYSERR;
296
297 if (0 == len)
298 return GNUNET_OK;
299
300 switch (h->type)
301 {
302 case IO_FILE:
303 return read_from_file (h, what, dst, len);
304 case IO_BUFFER:
305 return read_from_buffer (h, what, dst, len);
306 default:
307 GNUNET_asprintf (&h->emsg,
308 _ ("Invalid handle type while reading `%s'"),
309 what);
310 return GNUNET_SYSERR;
311 }
219} 312}
220 313
221 314
222/** 315/**
223 * Read 0-terminated string from a file. 316 * Read 0-terminated string.
224 * 317 *
225 * @param h handle to an open file 318 * @param h the IO handle to read from
226 * @param what describes what is being read (for error message creation) 319 * @param what describes what is being read (for error message creation)
227 * @param result the buffer to store a pointer to the (allocated) string to 320 * @param result where to store the pointer to the (allocated) string
228 * (note that *result could be set to NULL as well) 321 * (note that *result could be set to NULL as well)
229 * @param max_length maximum allowed length for the string 322 * @param max_length maximum allowed length for the string
230 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure 323 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
@@ -238,10 +331,21 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
238 char *buf; 331 char *buf;
239 uint32_t big; 332 uint32_t big;
240 333
241 if (GNUNET_OK != GNUNET_BIO_read_int32 (h, &big)) 334 if (GNUNET_OK != GNUNET_BIO_read_int32 (h,
335 _ ("string length"),
336 (int32_t *) &big))
242 { 337 {
243 GNUNET_free_non_null (h->emsg); 338 char *tmp = h->emsg;
244 GNUNET_asprintf (&h->emsg, _ ("Error reading length of string `%s'"), what); 339 if (NULL != tmp)
340 GNUNET_asprintf (&h->emsg,
341 _ ("%s (while reading `%s')"),
342 tmp,
343 what);
344 else
345 GNUNET_asprintf (&h->emsg,
346 _ ("Error reading length of string `%s'"),
347 what);
348 GNUNET_free_non_null (tmp);
245 return GNUNET_SYSERR; 349 return GNUNET_SYSERR;
246 } 350 }
247 if (0 == big) 351 if (0 == big)
@@ -274,7 +378,7 @@ GNUNET_BIO_read_string (struct GNUNET_BIO_ReadHandle *h,
274 378
275 379
276/** 380/**
277 * Read metadata container from a file. 381 * Read a metadata container.
278 * 382 *
279 * @param h handle to an open file 383 * @param h handle to an open file
280 * @param what describes what is being read (for error message creation) 384 * @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,
290 char *buf; 394 char *buf;
291 struct GNUNET_CONTAINER_MetaData *meta; 395 struct GNUNET_CONTAINER_MetaData *meta;
292 396
293 if (GNUNET_OK != GNUNET_BIO_read_int32 (h, (int32_t *) &size)) 397 if (GNUNET_OK != GNUNET_BIO_read_int32 (h,
398 _ ("metadata length"),
399 (int32_t *) &size))
294 return GNUNET_SYSERR; 400 return GNUNET_SYSERR;
295 if (size == 0) 401 if (0 == size)
296 { 402 {
297 *result = NULL; 403 *result = NULL;
298 return GNUNET_OK; 404 return GNUNET_OK;
299 } 405 }
300 if (size > MAX_META_DATA) 406 if (MAX_META_DATA < size)
301 { 407 {
302 GNUNET_asprintf (&h->emsg, 408 GNUNET_asprintf (
303 _ ("Serialized metadata `%s' larger than allowed (%u>%u)"), 409 &h->emsg,
304 what, 410 _ ("Serialized metadata `%s' larger than allowed (%u > %u)"),
305 size, 411 what,
306 MAX_META_DATA); 412 size,
413 MAX_META_DATA);
307 return GNUNET_SYSERR; 414 return GNUNET_SYSERR;
308 } 415 }
309 buf = GNUNET_malloc (size); 416 buf = GNUNET_malloc (size);
@@ -316,7 +423,7 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
316 if (NULL == meta) 423 if (NULL == meta)
317 { 424 {
318 GNUNET_free (buf); 425 GNUNET_free (buf);
319 GNUNET_asprintf (&h->emsg, _ ("Metadata `%s' failed to deserialize"), what); 426 GNUNET_asprintf (&h->emsg, _ ("Failed to deserialize metadata `%s'"), what);
320 return GNUNET_SYSERR; 427 return GNUNET_SYSERR;
321 } 428 }
322 GNUNET_free (buf); 429 GNUNET_free (buf);
@@ -324,25 +431,56 @@ GNUNET_BIO_read_meta_data (struct GNUNET_BIO_ReadHandle *h,
324 return GNUNET_OK; 431 return GNUNET_OK;
325} 432}
326 433
434/**
435 * Read a float.
436 *
437 * @param h the IO handle to read from
438 * @param what describes what is being read (for error message creation)
439 * @param f address of float to read
440 */
441int
442GNUNET_BIO_read_float(struct GNUNET_BIO_ReadHandle *h,
443 const char *what,
444 float *f)
445{
446 int32_t *i = (int32_t *) f;
447 return GNUNET_BIO_read_int32 (h, what, i);
448}
449
450
451/**
452 * Read a double.
453 *
454 * @param h the IO handle to read from
455 * @param what describes what is being read (for error message creation)
456 * @param f address of double to read
457 */
458int
459GNUNET_BIO_read_double(struct GNUNET_BIO_ReadHandle *h,
460 const char *what,
461 double *f)
462{
463 int64_t *i = (int64_t *) f;
464 return GNUNET_BIO_read_int64 (h, what, i);
465}
466
327 467
328/** 468/**
329 * Read an (u)int32_t. 469 * Read an (u)int32_t.
330 * 470 *
331 * @param h hande to open file 471 * @param h the IO handle to read from
332 * @param file name of the source file 472 * @param what describes what is being read (for error message creation)
333 * @param line line number in the source file 473 * @param i where to store the data
334 * @param i address of 32-bit integer to read
335 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 474 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
336 */ 475 */
337int 476int
338GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h, 477GNUNET_BIO_read_int32 (struct GNUNET_BIO_ReadHandle *h,
339 const char *file, 478 const char *what,
340 int line, 479 int32_t *i)
341 int32_t *i)
342{ 480{
343 int32_t big; 481 int32_t big;
344 482
345 if (GNUNET_OK != GNUNET_BIO_read_fn (h, file, line, &big, sizeof(int32_t))) 483 if (GNUNET_OK != GNUNET_BIO_read (h, what, &big, sizeof(int32_t)))
346 return GNUNET_SYSERR; 484 return GNUNET_SYSERR;
347 *i = ntohl (big); 485 *i = ntohl (big);
348 return GNUNET_OK; 486 return GNUNET_OK;
@@ -352,21 +490,19 @@ GNUNET_BIO_read_int32__ (struct GNUNET_BIO_ReadHandle *h,
352/** 490/**
353 * Read an (u)int64_t. 491 * Read an (u)int64_t.
354 * 492 *
355 * @param h hande to open file 493 * @param h the IO handle to read from
356 * @param file name of the source file 494 * @param what describes what is being read (for error message creation)
357 * @param line line number in the source file 495 * @param i where to store the data
358 * @param i address of 64-bit integer to read
359 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 496 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
360 */ 497 */
361int 498int
362GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h, 499GNUNET_BIO_read_int64 (struct GNUNET_BIO_ReadHandle *h,
363 const char *file, 500 const char *what,
364 int line, 501 int64_t *i)
365 int64_t *i)
366{ 502{
367 int64_t big; 503 int64_t big;
368 504
369 if (GNUNET_OK != GNUNET_BIO_read_fn (h, file, line, &big, sizeof(int64_t))) 505 if (GNUNET_OK != GNUNET_BIO_read (h, what, &big, sizeof(int64_t)))
370 return GNUNET_SYSERR; 506 return GNUNET_SYSERR;
371 *i = GNUNET_ntohll (big); 507 *i = GNUNET_ntohll (big);
372 return GNUNET_OK; 508 return GNUNET_OK;
@@ -379,17 +515,29 @@ GNUNET_BIO_read_int64__ (struct GNUNET_BIO_ReadHandle *h,
379struct GNUNET_BIO_WriteHandle 515struct GNUNET_BIO_WriteHandle
380{ 516{
381 /** 517 /**
382 * Underlying file handle. 518 * The "backend" type.
519 */
520 enum IOType type;
521
522 /**
523 * Handle to a file on disk, if @e type is #IO_FILE.
383 */ 524 */
384 struct GNUNET_DISK_FileHandle *fd; 525 struct GNUNET_DISK_FileHandle *fd;
385 526
386 /** 527 /**
387 * I/O buffer. Do not free, allocated at the end of the struct. 528 * Error message, NULL if there were no errors.
388 */ 529 */
389 char *buffer; 530 char *emsg;
531
532 /**
533 * I/O buffer.
534 * This field is a void * because it is used to hold pointers to allocated
535 * structures or arrays and will be casted to the appropriate type.
536 */
537 void *buffer;
390 538
391 /** 539 /**
392 * Number of bytes already in @e buffer. 540 * Number of bytes available in @e buffer.
393 */ 541 */
394 size_t have; 542 size_t have;
395 543
@@ -403,25 +551,26 @@ struct GNUNET_BIO_WriteHandle
403/** 551/**
404 * Open a file for writing. 552 * Open a file for writing.
405 * 553 *
406 * @param fn file name to be opened 554 * @param fn name of the file to be opened
407 * @return IO handle on success, NULL on error 555 * @return IO handle on success, NULL on error
408 */ 556 */
409struct GNUNET_BIO_WriteHandle * 557struct GNUNET_BIO_WriteHandle *
410GNUNET_BIO_write_open (const char *fn) 558GNUNET_BIO_write_open_file (const char *fn)
411{ 559{
412 struct GNUNET_DISK_FileHandle *fd; 560 struct GNUNET_DISK_FileHandle *fd;
413 struct GNUNET_BIO_WriteHandle *h; 561 struct GNUNET_BIO_WriteHandle *h;
414 562
415 fd = 563 fd =
416 GNUNET_DISK_file_open (fn, 564 GNUNET_DISK_file_open (fn,
417 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_TRUNCATE 565 GNUNET_DISK_OPEN_WRITE
566 | GNUNET_DISK_OPEN_TRUNCATE
418 | GNUNET_DISK_OPEN_CREATE, 567 | GNUNET_DISK_OPEN_CREATE,
419 GNUNET_DISK_PERM_USER_READ 568 GNUNET_DISK_PERM_USER_READ
420 | GNUNET_DISK_PERM_USER_WRITE); 569 | GNUNET_DISK_PERM_USER_WRITE);
421 if (NULL == fd) 570 if (NULL == fd)
422 return NULL; 571 return NULL;
423 h = GNUNET_malloc (sizeof(struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE); 572 h = GNUNET_malloc (sizeof(struct GNUNET_BIO_WriteHandle) + BIO_BUFFER_SIZE);
424 h->buffer = (char *) &h[1]; 573 h->buffer = &h[1];
425 h->size = BIO_BUFFER_SIZE; 574 h->size = BIO_BUFFER_SIZE;
426 h->fd = fd; 575 h->fd = fd;
427 return h; 576 return h;
@@ -429,42 +578,94 @@ GNUNET_BIO_write_open (const char *fn)
429 578
430 579
431/** 580/**
432 * Close an open file for writing. 581 * Create a handle backed by an in-memory buffer.
582 *
583 * @return IO handle on success, NULL on error
584 */
585struct GNUNET_BIO_WriteHandle *
586GNUNET_BIO_write_open_buffer (void)
587{
588 struct GNUNET_BIO_WriteHandle *h;
589
590 h = GNUNET_new (struct GNUNET_BIO_WriteHandle);
591 h->type = IO_BUFFER;
592 h->buffer = (void *) GNUNET_malloc (sizeof (struct GNUNET_Buffer));
593 return h;
594}
595
596
597/**
598 * Close an IO handle.
599 * If the handle was using a file, the file will be closed.
433 * 600 *
434 * @param h file handle 601 * @param h file handle
602 * @param emsg set to the (allocated) error message
603 * if the handle has an error message, the return value is #GNUNET_SYSERR
435 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 604 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
436 */ 605 */
437int 606int
438GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h) 607GNUNET_BIO_write_close (struct GNUNET_BIO_WriteHandle *h, char **emsg)
439{ 608{
440 int ret; 609 int err;
441 610
442 ret = GNUNET_SYSERR; 611 err = (NULL == h->emsg) ? GNUNET_OK : GNUNET_SYSERR;
443 if ((NULL != h->fd) && (GNUNET_OK == (ret = GNUNET_BIO_flush (h)))) 612 if (NULL != emsg)
444 GNUNET_DISK_file_close (h->fd); 613 *emsg = h->emsg;
614 else
615 GNUNET_free_non_null (h->emsg);
616 switch (h->type)
617 {
618 case IO_FILE:
619 if (NULL == h->fd)
620 return GNUNET_SYSERR;
621 if (GNUNET_OK != GNUNET_BIO_flush (h))
622 {
623 if (NULL != emsg)
624 *emsg = h->emsg;
625 else
626 GNUNET_free_non_null (h->emsg);
627 err = GNUNET_SYSERR;
628 }
629 else
630 {
631 GNUNET_DISK_file_close (h->fd);
632 }
633 break;
634 case IO_BUFFER:
635 GNUNET_buffer_clear ((struct GNUNET_Buffer *) h->buffer);
636 GNUNET_free (h->buffer);
637 break;
638 }
445 GNUNET_free (h); 639 GNUNET_free (h);
446 return ret; 640 return err;
447} 641}
448 642
449 643
450/** 644/**
451 * Force a buffered writer to flush its buffer 645 * Force a file-based buffered writer to flush its buffer.
646 * If the handle does not use a file, this function returs #GNUNET_OK
647 * without doing anything.
452 * 648 *
453 * @param h the writer handle 649 * @param h the IO handle
454 * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned and 650 * @return #GNUNET_OK upon success. Upon failure #GNUNET_SYSERR is returned
455 * the file is closed 651 * and the file is closed
456 */ 652 */
457int 653int
458GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h) 654GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h)
459{ 655{
460 ssize_t ret; 656 ssize_t ret;
461 657
658 if (IO_FILE != h->type)
659 return GNUNET_OK;
660
462 ret = GNUNET_DISK_file_write (h->fd, h->buffer, h->have); 661 ret = GNUNET_DISK_file_write (h->fd, h->buffer, h->have);
463 if (ret != (ssize_t) h->have) 662 if (ret != (ssize_t) h->have)
464 { 663 {
465 GNUNET_DISK_file_close (h->fd); 664 GNUNET_DISK_file_close (h->fd);
466 h->fd = NULL; 665 h->fd = NULL;
467 return GNUNET_SYSERR; /* error */ 666 GNUNET_free_non_null (h->emsg);
667 GNUNET_asprintf (&h->emsg, _ ("Unable to flush buffer to file"));
668 return GNUNET_SYSERR;
468 } 669 }
469 h->have = 0; 670 h->have = 0;
470 return GNUNET_OK; 671 return GNUNET_OK;
@@ -472,96 +673,213 @@ GNUNET_BIO_flush (struct GNUNET_BIO_WriteHandle *h)
472 673
473 674
474/** 675/**
475 * Write a buffer to a file. 676 * Get the IO handle's contents.
677 * If the handle doesn't use an in-memory buffer, this function returns
678 * #GNUNET_SYSERR.
476 * 679 *
477 * @param h handle to open file 680 * @param h the IO handle
478 * @param buffer the data to write 681 * @param emsg set to the (allocated) error message
479 * @param n number of bytes to write 682 * if the handle has an error message the return value is #GNUNET_SYSERR
480 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 683 * @param contents where to store the pointer to the handle's contents
684 * @param size where to store the size of @e contents
685 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
481 */ 686 */
482int 687int
483GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h, 688GNUNET_BIO_get_buffer_contents (struct GNUNET_BIO_WriteHandle *h,
484 const void *buffer, 689 char **emsg,
485 size_t n) 690 void **contents,
691 size_t *size)
692{
693 if (IO_BUFFER != h->type)
694 return GNUNET_SYSERR;
695 if (NULL == contents || NULL == size)
696 return GNUNET_SYSERR;
697 int ret = (NULL != h->emsg) ? GNUNET_SYSERR : GNUNET_OK;
698 if (NULL != emsg)
699 *emsg = h->emsg;
700 else
701 GNUNET_free_non_null (h->emsg);
702 *contents = GNUNET_buffer_reap ((struct GNUNET_Buffer *) h->buffer, size);
703 return ret;
704}
705
706
707/**
708 * Function used internally to write the contents of a buffer into a file.
709 *
710 * @param h the IO handle to write to
711 * @param what describes what is being written (for error message creation)
712 * @param source the buffer to write
713 * @param len the number of bytes to write
714 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
715 */
716static int
717write_to_file (struct GNUNET_BIO_WriteHandle *h,
718 const char *what,
719 const char *source,
720 size_t len)
486{ 721{
487 const char *src = buffer;
488 size_t min; 722 size_t min;
489 size_t pos; 723 size_t pos = 0;
724 char *buffer = (char *) h->buffer;
490 725
491 if (NULL == h->fd) 726 if (NULL == h->fd)
727 {
728 GNUNET_asprintf (&h->emsg,
729 _ ("Error while writing `%s' to file: %s"),
730 what,
731 _ ("No associated file"));
492 return GNUNET_SYSERR; 732 return GNUNET_SYSERR;
493 pos = 0; 733 }
734
494 do 735 do
495 { 736 {
496 /* first, just use buffer */
497 min = h->size - h->have; 737 min = h->size - h->have;
498 if (min > n - pos) 738 if (len - pos < min)
499 min = n - pos; 739 min = len - pos;
500 GNUNET_memcpy (&h->buffer[h->have], &src[pos], min); 740 GNUNET_memcpy (&buffer[h->have], &source[pos], min);
501 pos += min; 741 pos += min;
502 h->have += min; 742 h->have += min;
503 if (pos == n) 743 if (len == pos)
504 return GNUNET_OK; /* done */ 744 return GNUNET_OK;
505 GNUNET_assert (h->have == h->size); 745 GNUNET_assert (h->have == h->size);
506 if (GNUNET_OK != GNUNET_BIO_flush (h)) 746 if (GNUNET_OK != GNUNET_BIO_flush (h))
507 return GNUNET_SYSERR; /* error */ 747 {
748 char *tmp = h->emsg;
749 GNUNET_asprintf (&h->emsg,
750 _ ("Error while writing `%s' to file: %s"),
751 what,
752 tmp);
753 GNUNET_free_non_null (tmp);
754 return GNUNET_SYSERR;
755 }
508 } 756 }
509 while (pos < n); /* should always be true */ 757 while (pos < len);
510 GNUNET_break (0); 758 GNUNET_break (0);
511 return GNUNET_OK; 759 return GNUNET_OK;
512} 760}
513 761
514 762
515/** 763/**
516 * Write a string to a file. 764 * Function used internally to write the contents of a buffer to another buffer.
765 *
766 * @param h the IO handle to write to
767 * @param what describes what is being written (for error message creation)
768 * @param source the buffer to write
769 * @param len the number of bytes to write
770 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
771 */
772static int
773write_to_buffer (struct GNUNET_BIO_WriteHandle *h,
774 const char *what,
775 const char *source,
776 size_t len)
777{
778 GNUNET_buffer_write ((struct GNUNET_Buffer *) h->buffer, source, len);
779 h->have += len;
780 return GNUNET_OK;
781}
782
783
784/**
785 * Write a buffer to a handle.
786 *
787 * @param h the IO handle to write to
788 * @param what what is being written (for error message creation)
789 * @param buffer the data to write
790 * @param n number of bytes to write
791 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
792 */
793int
794GNUNET_BIO_write (struct GNUNET_BIO_WriteHandle *h,
795 const char *what,
796 const void *buffer,
797 size_t n)
798{
799 const char *src = buffer;
800
801 if (NULL != h->emsg)
802 return GNUNET_SYSERR;
803
804 if (0 == n)
805 return GNUNET_OK;
806
807 switch (h->type)
808 {
809 case IO_FILE:
810 return write_to_file (h, what, src, n);
811 case IO_BUFFER:
812 return write_to_buffer (h, what, src, n);
813 default:
814 GNUNET_asprintf (&h->emsg,
815 _ ("Invalid handle type while writing `%s'"),
816 what);
817 return GNUNET_SYSERR;
818 }
819}
820
821
822/**
823 * Write a 0-terminated string.
517 * 824 *
518 * @param h handle to open file 825 * @param h the IO handle to write to
826 * @param what what is being written (for error message creation)
519 * @param s string to write (can be NULL) 827 * @param s string to write (can be NULL)
520 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 828 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
521 */ 829 */
522int 830int
523GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h, const char *s) 831GNUNET_BIO_write_string (struct GNUNET_BIO_WriteHandle *h,
832 const char *what,
833 const char *s)
524{ 834{
525 uint32_t slen; 835 uint32_t slen;
526 836
527 slen = (uint32_t) ((s == NULL) ? 0 : strlen (s) + 1); 837 slen = (uint32_t) ((s == NULL) ? 0 : strlen (s) + 1);
528 if (GNUNET_OK != GNUNET_BIO_write_int32 (h, slen)) 838 if (GNUNET_OK != GNUNET_BIO_write_int32 (h, _ ("string length"), slen))
529 return GNUNET_SYSERR; 839 return GNUNET_SYSERR;
530 if (0 != slen) 840 if (0 != slen)
531 return GNUNET_BIO_write (h, s, slen - 1); 841 return GNUNET_BIO_write (h, what, s, slen - 1);
532 return GNUNET_OK; 842 return GNUNET_OK;
533} 843}
534 844
535 845
536/** 846/**
537 * Write metadata container to a file. 847 * Write a metadata container.
538 * 848 *
539 * @param h handle to open file 849 * @param h the IO handle to write to
850 * @param what what is being written (for error message creation)
540 * @param m metadata to write 851 * @param m metadata to write
541 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 852 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
542 */ 853 */
543int 854int
544GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h, 855GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
856 const char *what,
545 const struct GNUNET_CONTAINER_MetaData *m) 857 const struct GNUNET_CONTAINER_MetaData *m)
546{ 858{
547 ssize_t size; 859 ssize_t size;
548 char *buf; 860 char *buf;
549 861
550 if (m == NULL) 862 if (m == NULL)
551 return GNUNET_BIO_write_int32 (h, 0); 863 return GNUNET_BIO_write_int32 (h, _ ("metadata length"), 0);
552 buf = NULL; 864 buf = NULL;
553 size = GNUNET_CONTAINER_meta_data_serialize ( 865 size = GNUNET_CONTAINER_meta_data_serialize (
554 m, 866 m,
555 &buf, 867 &buf,
556 MAX_META_DATA, 868 MAX_META_DATA,
557 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); 869 GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
558 if (size == -1) 870 if (-1 == size)
559 { 871 {
560 GNUNET_free (buf); 872 GNUNET_free (buf);
873 GNUNET_free_non_null (h->emsg);
874 GNUNET_asprintf (&h->emsg,
875 _ ("Failed to serialize metadata `%s'"),
876 what);
561 return GNUNET_SYSERR; 877 return GNUNET_SYSERR;
562 } 878 }
563 if ((GNUNET_OK != GNUNET_BIO_write_int32 (h, (uint32_t) size)) || 879 if ((GNUNET_OK != GNUNET_BIO_write_int32 (h,
564 (GNUNET_OK != GNUNET_BIO_write (h, buf, size))) 880 _ ("metadata length"),
881 (uint32_t) size))
882 || (GNUNET_OK != GNUNET_BIO_write (h, what, buf, size)))
565 { 883 {
566 GNUNET_free (buf); 884 GNUNET_free (buf);
567 return GNUNET_SYSERR; 885 return GNUNET_SYSERR;
@@ -572,36 +890,669 @@ GNUNET_BIO_write_meta_data (struct GNUNET_BIO_WriteHandle *h,
572 890
573 891
574/** 892/**
893 * Write a float.
894 *
895 * @param h the IO handle to write to
896 * @param what what is being written (for error message creation)
897 * @param f float to write
898 */
899int
900GNUNET_BIO_write_float(struct GNUNET_BIO_WriteHandle *h,
901 const char *what,
902 float f)
903{
904 int32_t i = f;
905 return GNUNET_BIO_write_int32 (h, what, i);
906}
907
908
909/**
910 * Write a double.
911 *
912 * @param h the IO handle to write to
913 * @param what what is being written (for error message creation)
914 * @param f double to write
915 */
916int
917GNUNET_BIO_write_double(struct GNUNET_BIO_WriteHandle *h,
918 const char *what,
919 double f)
920{
921 int64_t i = f;
922 return GNUNET_BIO_write_int64 (h, what, i);
923}
924
925
926/**
575 * Write an (u)int32_t. 927 * Write an (u)int32_t.
576 * 928 *
577 * @param h hande to open file 929 * @param h the IO handle to write to
930 * @param what what is being written (for error message creation)
578 * @param i 32-bit integer to write 931 * @param i 32-bit integer to write
579 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 932 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
580 */ 933 */
581int 934int
582GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h, int32_t i) 935GNUNET_BIO_write_int32 (struct GNUNET_BIO_WriteHandle *h,
936 const char *what,
937 int32_t i)
583{ 938{
584 int32_t big; 939 int32_t big;
585 940
586 big = htonl (i); 941 big = htonl (i);
587 return GNUNET_BIO_write (h, &big, sizeof(int32_t)); 942 return GNUNET_BIO_write (h, what, &big, sizeof(int32_t));
588} 943}
589 944
590 945
591/** 946/**
592 * Write an (u)int64_t. 947 * Write an (u)int64_t.
593 * 948 *
594 * @param h hande to open file 949 * @param h the IO handle to write to
950 * @param what what is being written (for error message creation)
595 * @param i 64-bit integer to write 951 * @param i 64-bit integer to write
596 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error 952 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
597 */ 953 */
598int 954int
599GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h, int64_t i) 955GNUNET_BIO_write_int64 (struct GNUNET_BIO_WriteHandle *h,
956 const char *what,
957 int64_t i)
600{ 958{
601 int64_t big; 959 int64_t big;
602 960
603 big = GNUNET_htonll (i); 961 big = GNUNET_htonll (i);
604 return GNUNET_BIO_write (h, &big, sizeof(int64_t)); 962 return GNUNET_BIO_write (h, what, &big, sizeof(int64_t));
963}
964
965
966/**
967 * Function used internally to read some bytes from within a read spec.
968 *
969 * @param cls ignored, always NULL
970 * @param h the IO handle to read from
971 * @param what what is being read (for error message creation)
972 * @param target where to store the data
973 * @param target_size how many bytes to read
974 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
975 */
976static int
977read_spec_handler_object (void *cls,
978 struct GNUNET_BIO_ReadHandle *h,
979 const char *what,
980 void *target,
981 size_t target_size)
982{
983 return GNUNET_BIO_read (h, what, target, target_size);
984}
985
986
987/**
988 * Create the specification to read a certain amount of bytes.
989 *
990 * @param what describes what is being read (for error message creation)
991 * @param result the buffer to write the result to
992 * @param len the number of bytes to read
993 * @return the read spec
994 */
995struct GNUNET_BIO_ReadSpec
996GNUNET_BIO_read_spec_object (const char *what,
997 void *result,
998 size_t len)
999{
1000 struct GNUNET_BIO_ReadSpec rs = {
1001 .rh = &read_spec_handler_object,
1002 .cls = NULL,
1003 .what = what,
1004 .target = result,
1005 .size = len,
1006 };
1007
1008 return rs;
1009}
1010
1011
1012/**
1013 * Function used interally to read a string from within a read spec.
1014 *
1015 * @param cls ignored, always NULL
1016 * @param h the IO handle to read from
1017 * @param what what is being read (for error message creation)
1018 * @param target where to store the data
1019 * @param target_size how many bytes to read
1020 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1021 */
1022static int
1023read_spec_handler_string (void *cls,
1024 struct GNUNET_BIO_ReadHandle *h,
1025 const char *what,
1026 void *target,
1027 size_t target_size)
1028{
1029 char **result = target;
1030 return GNUNET_BIO_read_string (h, what, result, target_size);
1031}
1032
1033
1034/**
1035 * Create the specification to read a 0-terminated string.
1036 *
1037 * @param what describes what is being read (for error message creation)
1038 * @param result where to store the pointer to the (allocated) string
1039 * (note that *result could be set to NULL as well)
1040 * @param max_length maximum allowed length for the string
1041 * @return the read spec
1042 */
1043struct GNUNET_BIO_ReadSpec
1044GNUNET_BIO_read_spec_string (const char *what,
1045 char **result,
1046 size_t max_length)
1047{
1048 struct GNUNET_BIO_ReadSpec rs = {
1049 .rh = &read_spec_handler_string,
1050 .cls = NULL,
1051 .target = result,
1052 .size = max_length,
1053 };
1054
1055 return rs;
1056}
1057
1058
1059/**
1060 * Function used internally to read a metadata container from within a read
1061 * spec.
1062 *
1063 * @param cls ignored, always NULL
1064 * @param h the IO handle to read from
1065 * @param what what is being read (for error message creation)
1066 * @param target where to store the data
1067 * @param target_size ignored
1068 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
1069 */
1070static int
1071read_spec_handler_meta_data (void *cls,
1072 struct GNUNET_BIO_ReadHandle *h,
1073 const char *what,
1074 void *target,
1075 size_t target_size)
1076{
1077 struct GNUNET_CONTAINER_MetaData **result = target;
1078 return GNUNET_BIO_read_meta_data (h, what, result);
1079}
1080
1081
1082/**
1083 * Create the specification to read a metadata container.
1084 *
1085 * @param what describes what is being read (for error message creation)
1086 * @param result the buffer to store a pointer to the (allocated) metadata
1087 * @return the read spec
1088 */
1089struct GNUNET_BIO_ReadSpec
1090GNUNET_BIO_read_spec_meta_data (const char *what,
1091 struct GNUNET_CONTAINER_MetaData **result)
1092{
1093 struct GNUNET_BIO_ReadSpec rs = {
1094 .rh = &read_spec_handler_meta_data,
1095 .cls = NULL,
1096 .target = result,
1097 .size = 0,
1098 };
1099
1100 return rs;
1101}
1102
1103
1104/**
1105 * Function used internally to read an (u)int32_t from within a read spec.
1106 *
1107 * @param cls ignored, always NULL
1108 * @param h the IO handle to read from
1109 * @param what what is being read (for error message creation)
1110 * @param target where to store the data
1111 * @param target_size ignored
1112 * @retun #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1113 */
1114static int
1115read_spec_handler_int32 (void *cls,
1116 struct GNUNET_BIO_ReadHandle *h,
1117 const char *what,
1118 void *target,
1119 size_t target_size)
1120{
1121 int32_t *result = target;
1122 return GNUNET_BIO_read_int32 (h, what, result);
1123}
1124
1125
1126/**
1127 * Create the specification to read an (u)int32_t.
1128 *
1129 * @param what describes what is being read (for error message creation)
1130 * @param i where to store the data
1131 * @return the read spec
1132 */
1133struct GNUNET_BIO_ReadSpec
1134GNUNET_BIO_read_spec_int32 (const char *what,
1135 int32_t *i)
1136{
1137 struct GNUNET_BIO_ReadSpec rs = {
1138 .rh = &read_spec_handler_int32,
1139 .cls = NULL,
1140 .target = i,
1141 .size = 0,
1142 };
1143
1144 return rs;
1145}
1146
1147
1148/**
1149 * Function used internally to read an (u)int64_t from within a read spec.
1150 *
1151 * @param cls ignored, always NULL
1152 * @param h the IO handle to read from
1153 * @param what what is being read (for error message creation)
1154 * @param target where to store the data
1155 * @param target_size ignored
1156 * @retun #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1157 */
1158static int
1159read_spec_handler_int64 (void *cls,
1160 struct GNUNET_BIO_ReadHandle *h,
1161 const char *what,
1162 void *target,
1163 size_t target_size)
1164{
1165 int64_t *result = target;
1166 return GNUNET_BIO_read_int64 (h, what, result);
1167}
1168
1169
1170/**
1171 * Create the specification to read an (u)int64_t.
1172 *
1173 * @param what describes what is being read (for error message creation)
1174 * @param i where to store the data
1175 * @return the read spec
1176 */
1177struct GNUNET_BIO_ReadSpec
1178GNUNET_BIO_read_spec_int64 (const char *what,
1179 int64_t *i)
1180{
1181 struct GNUNET_BIO_ReadSpec rs = {
1182 .rh = &read_spec_handler_int64,
1183 .cls = NULL,
1184 .target = i,
1185 .size = 0,
1186 };
1187
1188 return rs;
1189}
1190
1191
1192/**
1193 * Create the specification to read a float.
1194 *
1195 * @param what describes what is being read (for error message creation)
1196 * @param f address of float to read
1197 */
1198struct GNUNET_BIO_ReadSpec
1199GNUNET_BIO_read_spec_float(const char *what, float *f)
1200{
1201 struct GNUNET_BIO_ReadSpec rs = {
1202 .rh = &read_spec_handler_int32,
1203 .cls = NULL,
1204 .target = (int32_t *) f,
1205 .size = 0,
1206 };
1207
1208 return rs;
1209}
1210
1211
1212/**
1213 * Create the specification to read a double.
1214 *
1215 * @param what describes what is being read (for error message creation)
1216 * @param f address of double to read
1217 */
1218struct GNUNET_BIO_ReadSpec
1219GNUNET_BIO_read_spec_double(const char *what, double *f)
1220{
1221 struct GNUNET_BIO_ReadSpec rs = {
1222 .rh = &read_spec_handler_int64,
1223 .cls = NULL,
1224 .target = (int64_t *) f,
1225 .size = 0,
1226 };
1227
1228 return rs;
1229}
1230
1231
1232/**
1233 * Execute the read specifications in order.
1234 *
1235 * @param h the IO handle to read from
1236 * @param rs array of read specs
1237 * the last element must be #GNUNET_BIO_read_spec_end
1238 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1239 */
1240int
1241GNUNET_BIO_read_spec_commit (struct GNUNET_BIO_ReadHandle *h,
1242 struct GNUNET_BIO_ReadSpec *rs)
1243{
1244 int ret = GNUNET_OK;
1245
1246 for (size_t i=0; NULL!=rs[i].rh; ++i)
1247 {
1248 ret = rs[i].rh (rs[i].cls, h, rs[i].what, rs[i].target, rs[i].size);
1249 if (GNUNET_OK != ret)
1250 return ret;
1251 }
1252
1253 return ret;
1254}
1255
1256
1257/**
1258 * Function used internally to write some bytes from within a write spec.
1259 *
1260 * @param cls ignored, always NULL
1261 * @param h the IO handle to write to
1262 * @param what what is being written (for error message creation)
1263 * @param source the data to write
1264 * @param source_size how many bytes to write
1265 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1266 */
1267static int
1268write_spec_handler_object (void *cls,
1269 struct GNUNET_BIO_WriteHandle *h,
1270 const char *what,
1271 void *source,
1272 size_t source_size)
1273{
1274 return GNUNET_BIO_write (h, what, source, source_size);
1275}
1276
1277
1278/**
1279 * Create the specification to read some bytes.
1280 *
1281 * @param what describes what is being written (for error message creation)
1282 * @param source the data to write
1283 * @param size how many bytes should be written
1284 * @return the write spec
1285 */
1286struct GNUNET_BIO_WriteSpec
1287GNUNET_BIO_write_spec_object (const char *what,
1288 void *source,
1289 size_t size)
1290{
1291 struct GNUNET_BIO_WriteSpec ws = {
1292 .wh = &write_spec_handler_object,
1293 .cls = NULL,
1294 .what = what,
1295 .source = source,
1296 .source_size = size,
1297 };
1298
1299 return ws;
1300}
1301
1302
1303/**
1304 * Function used internally to write a 0-terminated string from within a write
1305 * spec.
1306 *
1307 * @param cls ignored, always NULL
1308 * @param h the IO handle to write to
1309 * @param what what is being written (for error message creation)
1310 * @param source the data to write
1311 * @param source_size ignored
1312 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1313 */
1314static int
1315write_spec_handler_string (void *cls,
1316 struct GNUNET_BIO_WriteHandle *h,
1317 const char *what,
1318 void *source,
1319 size_t source_size)
1320{
1321 const char *s = source;
1322 return GNUNET_BIO_write_string (h, what, s);
1323}
1324
1325
1326/**
1327 * Create the specification to write a 0-terminated string.
1328 *
1329 * @param what describes what is being read (for error message creation)
1330 * @param s string to write (can be NULL)
1331 * @return the read spec
1332 */
1333struct GNUNET_BIO_WriteSpec
1334GNUNET_BIO_write_spec_string (const char *what,
1335 const char *s)
1336{
1337 struct GNUNET_BIO_WriteSpec ws = {
1338 .wh = &write_spec_handler_string,
1339 .cls = NULL,
1340 .what = what,
1341 .source = (void *) s,
1342 .source_size = 0,
1343 };
1344
1345 return ws;
1346}
1347
1348
1349/**
1350 * Function used internally to write a metadata container from within a write
1351 * spec.
1352 *
1353 * @param cls ignored, always NULL
1354 * @param h the IO handle to write to
1355 * @param what what is being written (for error message creation)
1356 * @param source the data to write
1357 * @param source_size ignored
1358 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1359 */
1360static int
1361write_spec_handler_meta_data (void *cls,
1362 struct GNUNET_BIO_WriteHandle *h,
1363 const char *what,
1364 void *source,
1365 size_t source_size)
1366{
1367 const struct GNUNET_CONTAINER_MetaData *m = source;
1368 return GNUNET_BIO_write_meta_data (h, what, m);
1369}
1370
1371
1372/**
1373 * Create the specification to write a metadata container.
1374 *
1375 * @param what what is being written (for error message creation)
1376 * @param m metadata to write
1377 * @return the write spec
1378 */
1379struct GNUNET_BIO_WriteSpec
1380GNUNET_BIO_write_spec_meta_data (const char *what,
1381 const struct GNUNET_CONTAINER_MetaData *m)
1382{
1383 struct GNUNET_BIO_WriteSpec ws = {
1384 .wh = &write_spec_handler_meta_data,
1385 .cls = NULL,
1386 .what = what,
1387 .source = (void *) m,
1388 .source_size = 0,
1389 };
1390
1391 return ws;
1392}
1393
1394
1395/**
1396 * Function used internally to write an (u)int32_t from within a write spec.
1397 *
1398 * @param cls ignored, always NULL
1399 * @param h the IO handle to write to
1400 * @param what what is being written (for error message creation)
1401 * @param source the data to write
1402 * @param source_size ignored
1403 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1404 */
1405static int
1406write_spec_handler_int32 (void *cls,
1407 struct GNUNET_BIO_WriteHandle *h,
1408 const char *what,
1409 void *source,
1410 size_t source_size)
1411{
1412 int32_t i = *(int32_t *) source;
1413 return GNUNET_BIO_write_int32 (h, what, i);
1414}
1415
1416
1417/**
1418 * Create the specification to write an (u)int32_t.
1419 *
1420 * @param what describes what is being written (for error message creation)
1421 * @param i pointer to a 32-bit integer
1422 * @return the write spec
1423 */
1424struct GNUNET_BIO_WriteSpec
1425GNUNET_BIO_write_spec_int32 (const char *what,
1426 int32_t *i)
1427{
1428 struct GNUNET_BIO_WriteSpec ws = {
1429 .wh = &write_spec_handler_int32,
1430 .cls = NULL,
1431 .what = what,
1432 .source = i,
1433 .source_size = 0,
1434 };
1435
1436 return ws;
1437}
1438
1439
1440/**
1441 * Function used internally to write an (u)int64_t from within a write spec.
1442 *
1443 * @param cls ignored, always NULL
1444 * @param h the IO handle to write to
1445 * @param what what is being written (for error message creation)
1446 * @param source the data to write
1447 * @param source_size ignored
1448 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1449 */
1450static int
1451write_spec_handler_int64 (void *cls,
1452 struct GNUNET_BIO_WriteHandle *h,
1453 const char *what,
1454 void *source,
1455 size_t source_size)
1456{
1457 int64_t i = *(int64_t *) source;
1458 return GNUNET_BIO_write_int64 (h, what, i);
1459}
1460
1461
1462/**
1463 * Create the specification to write an (u)int64_t.
1464 *
1465 * @param what describes what is being written (for error message creation)
1466 * @param i pointer to a 64-bit integer
1467 * @return the write spec
1468 */
1469struct GNUNET_BIO_WriteSpec
1470GNUNET_BIO_write_spec_int64 (const char *what,
1471 int64_t *i)
1472{
1473 struct GNUNET_BIO_WriteSpec ws = {
1474 .wh = &write_spec_handler_int64,
1475 .cls = NULL,
1476 .what = what,
1477 .source = i,
1478 .source_size = 0,
1479 };
1480
1481 return ws;
1482}
1483
1484
1485/**
1486 * Create the specification to write a float.
1487 *
1488 * @param what describes what is being written (for error message creation)
1489 * @param f pointer to a float
1490 * @return the write spec
1491 */
1492struct GNUNET_BIO_WriteSpec
1493GNUNET_BIO_write_spec_float(const char *what, float *f)
1494{
1495 struct GNUNET_BIO_WriteSpec ws = {
1496 .wh = &write_spec_handler_int32,
1497 .cls = NULL,
1498 .what = what,
1499 .source = (int32_t *) f,
1500 .source_size = 0,
1501 };
1502
1503 return ws;
1504}
1505
1506
1507/**
1508 * Create the specification to write an double.
1509 *
1510 * @param what describes what is being written (for error message creation)
1511 * @param f pointer to a double
1512 * @return the write spec
1513 */
1514struct GNUNET_BIO_WriteSpec
1515GNUNET_BIO_write_spec_double(const char *what, double *f)
1516{
1517 struct GNUNET_BIO_WriteSpec ws = {
1518 .wh = &write_spec_handler_int64,
1519 .cls = NULL,
1520 .what = what,
1521 .source = (int64_t *) f,
1522 .source_size = 0,
1523 };
1524
1525 return ws;
1526}
1527
1528
1529/**
1530 * Execute the write specifications in order.
1531 *
1532 * @param h the IO handle to write to
1533 * @param ws array of write specs
1534 * the last element must be #GNUNET_BIO_write_spec_end
1535 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
1536 */
1537int
1538GNUNET_BIO_write_spec_commit (struct GNUNET_BIO_WriteHandle *h,
1539 struct GNUNET_BIO_WriteSpec *ws)
1540{
1541 int ret = GNUNET_OK;
1542
1543 for (size_t i=0; NULL!=ws[i].wh; ++i)
1544 {
1545 ret = ws[i].wh (ws[i].cls, h, ws[i].what, ws[i].source, ws[i].source_size);
1546 if (GNUNET_OK != ret)
1547 return ret;
1548 }
1549
1550 /* If it's a file-based handle, the flush makes sure that the data in the
1551 buffer is actualy written to the disk. */
1552 if (IO_FILE == h->type)
1553 ret = GNUNET_BIO_flush (h);
1554
1555 return ret;
605} 1556}
606 1557
607 1558
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)
130 buf->mem[buf->position++] = '\0'; 130 buf->mem[buf->position++] = '\0';
131 } 131 }
132 res = buf->mem; 132 res = buf->mem;
133 *buf = (struct GNUNET_Buffer) { 0 }; 133 memset (buf, 0, sizeof (struct GNUNET_Buffer));
134 return res;
135}
136
137
138/**
139 * Clear the buffer and return its contents.
140 * The caller is responsible to eventually #GNUNET_free
141 * the returned data.
142 *
143 * @param buf the buffer to reap the contents from
144 * @param size where to store the size of the returned data
145 * @returns the data contained in the string
146 */
147void *
148GNUNET_buffer_reap (struct GNUNET_Buffer *buf, size_t *size)
149{
150 *size = buf->position;
151 void *res = buf->mem;
152 memset (buf, 0, sizeof (struct GNUNET_Buffer));
134 return res; 153 return res;
135} 154}
136 155
@@ -144,7 +163,7 @@ void
144GNUNET_buffer_clear (struct GNUNET_Buffer *buf) 163GNUNET_buffer_clear (struct GNUNET_Buffer *buf)
145{ 164{
146 GNUNET_free_non_null (buf->mem); 165 GNUNET_free_non_null (buf->mem);
147 *buf = (struct GNUNET_Buffer) { 0 }; 166 memset (buf, 0, sizeof (struct GNUNET_Buffer));
148} 167}
149 168
150 169
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 @@
30#define TESTSTRING "testString" 30#define TESTSTRING "testString"
31#define TESTNUMBER64 ((int64_t) 100000L) 31#define TESTNUMBER64 ((int64_t) 100000L)
32 32
33
33static int 34static int
34test_normal_rw () 35test_normal_rw (void)
35{ 36{
36 char *msg; 37 struct GNUNET_BIO_WriteHandle *wh;
37 int64_t testNum; 38 struct GNUNET_BIO_ReadHandle *rh;
38 char *readResultString; 39 void *buffer;
39 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 40 size_t buffer_size = 0;
40 struct GNUNET_BIO_WriteHandle *fileW; 41 char *filename = GNUNET_DISK_mktemp ("gnunet-bio");
41 struct GNUNET_BIO_ReadHandle *fileR; 42 struct GNUNET_CONTAINER_MetaData *mdW;
42 struct GNUNET_CONTAINER_MetaData *metaDataW; 43 struct GNUNET_CONTAINER_MetaData *mdR = NULL;
43 struct GNUNET_CONTAINER_MetaData *metaDataR; 44 char *rString = NULL;
44 45 int64_t wNum = TESTNUMBER64;
45 metaDataW = GNUNET_CONTAINER_meta_data_create (); 46 int64_t rNum = 0;
46 metaDataR = NULL; 47
47 GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW); 48 mdW = GNUNET_CONTAINER_meta_data_create ();
48 49 GNUNET_CONTAINER_meta_data_add_publication_date (mdW);
49 fileW = GNUNET_BIO_write_open (fileName); 50
50 GNUNET_assert (NULL != fileW); 51 struct GNUNET_BIO_WriteSpec ws[] = {
51 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, TESTSTRING)); 52 GNUNET_BIO_write_spec_string ("test-normal-rw-string", TESTSTRING),
52 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_meta_data (fileW, metaDataW)); 53 GNUNET_BIO_write_spec_meta_data ("test-normal-rw-metadata", mdW),
53 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int64 (fileW, TESTNUMBER64)); 54 GNUNET_BIO_write_spec_int64 ("test-normal-rw-int64", &wNum),
54 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 55 GNUNET_BIO_write_spec_end(),
55 56 };
56 fileR = GNUNET_BIO_read_open (fileName); 57
57 GNUNET_assert (NULL != fileR); 58 struct GNUNET_BIO_ReadSpec rs[] = {
58 readResultString = NULL; 59 GNUNET_BIO_read_spec_string ("test-normal-rw-string", &rString, 200),
59 GNUNET_assert (GNUNET_OK == 60 GNUNET_BIO_read_spec_meta_data ("test-normal-rw-metadata", &mdR),
60 GNUNET_BIO_read_string (fileR, "Read string error", 61 GNUNET_BIO_read_spec_int64 ("test-normal-rw-int64", &rNum),
61 &readResultString, 200)); 62 GNUNET_BIO_read_spec_end(),
62 GNUNET_assert (NULL != readResultString); 63 };
63 GNUNET_assert (0 == strcmp (TESTSTRING, readResultString)); 64
64 GNUNET_free (readResultString); 65 /* I/O on file */
66 wh = GNUNET_BIO_write_open_file (filename);
67 GNUNET_assert (NULL != wh);
68 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_spec_commit (wh, ws));
69 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
70
71 rh = GNUNET_BIO_read_open_file (filename);
72 GNUNET_assert (NULL != rh);
73 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_spec_commit (rh, rs));
74 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
75 GNUNET_assert (0 == strcmp (TESTSTRING, rString));
76 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_meta_data_test_equal (mdR, mdW));
77 GNUNET_assert (wNum == rNum);
78
79 GNUNET_CONTAINER_meta_data_destroy (mdR);
80 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
81 GNUNET_free(filename);
82
83 /* I/O on buffer */
84 wh = GNUNET_BIO_write_open_buffer ();
85 GNUNET_assert (NULL != wh);
86 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_spec_commit (wh, ws));
65 GNUNET_assert (GNUNET_OK == 87 GNUNET_assert (GNUNET_OK ==
66 GNUNET_BIO_read_meta_data (fileR, "Read meta error", 88 GNUNET_BIO_get_buffer_contents (wh,
67 &metaDataR)); 89 NULL,
68 GNUNET_assert (GNUNET_YES == 90 &buffer,
69 GNUNET_CONTAINER_meta_data_test_equal (metaDataR, metaDataW)); 91 &buffer_size));
70 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_int64 (fileR, &testNum)); 92 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
71 GNUNET_BIO_read_close (fileR, &msg); 93
72 GNUNET_CONTAINER_meta_data_destroy (metaDataW); 94 rh = GNUNET_BIO_read_open_buffer (buffer, buffer_size);
73 GNUNET_CONTAINER_meta_data_destroy (metaDataR); 95 GNUNET_assert (NULL != rh);
74 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 96 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_spec_commit (rh, rs));
75 GNUNET_free (fileName); 97 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
98 GNUNET_assert (0 == strcmp (TESTSTRING, rString));
99 GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_meta_data_test_equal (mdR, mdW));
100 GNUNET_assert (wNum == rNum);
101
102 GNUNET_free (buffer);
103
104 GNUNET_CONTAINER_meta_data_destroy (mdW);
105 GNUNET_CONTAINER_meta_data_destroy (mdR);
76 return 0; 106 return 0;
77} 107}
78 108
79 109
80static int 110static int
81test_nullstring_rw () 111test_nullstring_rw (void)
82{ 112{
83 char *msg; 113 struct GNUNET_BIO_WriteHandle *wh;
84 char *readResultString = (char *) "not null"; 114 struct GNUNET_BIO_ReadHandle *rh;
85 struct GNUNET_BIO_WriteHandle *fileW; 115 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
86 struct GNUNET_BIO_ReadHandle *fileR; 116 char *rString = "not null";
87 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 117
88 118 wh = GNUNET_BIO_write_open_file (filename);
89 fileW = GNUNET_BIO_write_open (fileName); 119 GNUNET_assert (NULL != wh);
90 GNUNET_assert (NULL != fileW); 120 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (wh,
91 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, NULL)); 121 "test-nullstring-rw",
92 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 122 NULL));
93 123 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
94 fileR = GNUNET_BIO_read_open (fileName); 124
95 GNUNET_assert (NULL != fileR); 125 rh = GNUNET_BIO_read_open_file (filename);
96 GNUNET_assert (GNUNET_OK == 126 GNUNET_assert (NULL != rh);
97 GNUNET_BIO_read_string (fileR, "Read string error", 127 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_string (rh,
98 &readResultString, 200)); 128 "test-nullstring-rw",
99 GNUNET_assert (NULL == readResultString); 129 &rString, 200));
100 GNUNET_BIO_read_close (fileR, &msg); 130 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
101 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 131
102 GNUNET_free (fileName); 132 GNUNET_assert (NULL == rString);
103 133
134 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
135 GNUNET_free (filename);
104 return 0; 136 return 0;
105} 137}
106 138
107 139
108static int 140static int
109test_emptystring_rw () 141test_emptystring_rw (void)
110{ 142{
111 char *msg; 143 struct GNUNET_BIO_WriteHandle *wh;
112 char *readResultString; 144 struct GNUNET_BIO_ReadHandle *rh;
113 struct GNUNET_BIO_WriteHandle *fileW; 145 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
114 struct GNUNET_BIO_ReadHandle *fileR; 146 char *rString = NULL;
115 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 147
116 148 wh = GNUNET_BIO_write_open_file (filename);
117 fileW = GNUNET_BIO_write_open (fileName); 149 GNUNET_assert (NULL != wh);
118 GNUNET_assert (NULL != fileW); 150 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (wh,
119 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, "")); 151 "test-emptystring-rw",
120 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 152 ""));
121 153 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
122 fileR = GNUNET_BIO_read_open (fileName); 154
123 GNUNET_assert (NULL != fileR); 155 rh = GNUNET_BIO_read_open_file (filename);
124 readResultString = NULL; 156 GNUNET_assert (NULL != rh);
125 GNUNET_assert (GNUNET_OK == 157 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_string (rh,
126 GNUNET_BIO_read_string (fileR, "Read string error", 158 "test-emptystring-rw",
127 &readResultString, 200)); 159 &rString, 200));
128 GNUNET_free (readResultString); 160 GNUNET_assert (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL));
129 GNUNET_BIO_read_close (fileR, &msg); 161
130 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 162 GNUNET_free (rString);
131 GNUNET_free (fileName); 163
164 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
165 GNUNET_free (filename);
132 return 0; 166 return 0;
133} 167}
134 168
135 169
136static int 170static int
137test_bigstring_rw () 171test_bigstring_rw (void)
138{ 172{
139 char *msg; 173 struct GNUNET_BIO_WriteHandle *wh;
140 char *readResultString; 174 struct GNUNET_BIO_ReadHandle *rh;
141 struct GNUNET_BIO_WriteHandle *fileW; 175 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
142 struct GNUNET_BIO_ReadHandle *fileR; 176 char *rString = NULL;
143 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 177
144 178 wh = GNUNET_BIO_write_open_file (filename);
145 fileW = GNUNET_BIO_write_open (fileName); 179 GNUNET_assert (NULL != wh);
146 GNUNET_assert (NULL != fileW); 180 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (wh,
147 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_string (fileW, TESTSTRING)); 181 "test-bigstring-rw",
148 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 182 TESTSTRING));
149 183 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
150 fileR = GNUNET_BIO_read_open (fileName); 184
151 GNUNET_assert (NULL != fileR); 185 rh = GNUNET_BIO_read_open_file (filename);
152 readResultString = NULL; 186 GNUNET_assert (NULL != rh);
153 GNUNET_assert (GNUNET_SYSERR == 187 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_string (rh,
154 GNUNET_BIO_read_string (fileR, "Read string error", 188 "test-bigstring-rw",
155 &readResultString, 1)); 189 &rString, 1));
156 GNUNET_assert (NULL == readResultString); 190 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
157 msg = NULL; 191
158 GNUNET_BIO_read_close (fileR, &msg); 192 GNUNET_assert (NULL == rString);
159 GNUNET_free (msg); 193
160 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 194 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
161 GNUNET_free (fileName); 195 GNUNET_free (filename);
162 return 0; 196 return 0;
163} 197}
164 198
165 199
166static int 200static int
167test_bigmeta_rw () 201test_bigmeta_rw (void)
168{ 202{
169 char *msg;
170 static char meta[1024 * 1024 * 10]; 203 static char meta[1024 * 1024 * 10];
171 struct GNUNET_BIO_WriteHandle *fileW; 204 struct GNUNET_BIO_WriteHandle *wh;
172 struct GNUNET_BIO_ReadHandle *fileR; 205 struct GNUNET_BIO_ReadHandle *rh;
173 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 206 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
174 struct GNUNET_CONTAINER_MetaData *metaDataR; 207 struct GNUNET_CONTAINER_MetaData *mdR = NULL;
175 208
176 memset (meta, 'b', sizeof(meta)); 209 memset (meta, 'b', sizeof (meta));
177 meta[sizeof(meta) - 1] = '\0'; 210 meta[sizeof (meta) - 1] = '\0';
178 fileW = GNUNET_BIO_write_open (fileName); 211
179 GNUNET_assert (NULL != fileW); 212 wh = GNUNET_BIO_write_open_file (filename);
180 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, sizeof(meta))); 213 GNUNET_assert (NULL != wh);
181 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write (fileW, meta, sizeof(meta))); 214 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
182 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 215 "test-bigmeta-rw-int32",
183 216 sizeof (meta)));
184 fileR = GNUNET_BIO_read_open (fileName); 217 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write (wh,
185 GNUNET_assert (NULL != fileR); 218 "test-bigmeta-rw-bytes",
186 metaDataR = NULL; 219 meta,
220 sizeof (meta)));
221 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
222
223 rh = GNUNET_BIO_read_open_file (filename);
224 GNUNET_assert (NULL != rh);
187 GNUNET_assert (GNUNET_SYSERR == 225 GNUNET_assert (GNUNET_SYSERR ==
188 GNUNET_BIO_read_meta_data (fileR, "Read meta error", 226 GNUNET_BIO_read_meta_data (rh,
189 &metaDataR)); 227 "test-bigmeta-rw-metadata",
190 msg = NULL; 228 &mdR));
191 GNUNET_BIO_read_close (fileR, &msg); 229 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
192 GNUNET_free (msg); 230
193 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 231 GNUNET_assert (NULL == mdR);
194 GNUNET_assert (NULL == metaDataR); 232
195 GNUNET_free (fileName); 233 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
234 GNUNET_free (filename);
196 return 0; 235 return 0;
197} 236}
198 237
199 238
200static int 239static int
201test_directory_r () 240test_directory_r (void)
202{ 241{
203#ifdef __linux__ 242#ifdef LINUX
204 char *msg; 243 struct GNUNET_BIO_ReadHandle *rh;
205 char readResult[200]; 244 char rString[200];
206 struct GNUNET_BIO_ReadHandle *fileR; 245
207 246 rh = GNUNET_BIO_read_open_file ("/dev");
208 fileR = GNUNET_BIO_read_open ("/dev"); 247 GNUNET_assert (NULL != rh);
209 GNUNET_assert (NULL != fileR); 248 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read (rh,
210 GNUNET_assert (GNUNET_SYSERR == 249 "test-directory-r",
211 GNUNET_BIO_read (fileR, "Read error", readResult, 250 rString,
212 sizeof(readResult))); 251 sizeof (rString)));
213 msg = NULL; 252 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
214 GNUNET_BIO_read_close (fileR, &msg);
215 GNUNET_free (msg);
216#endif 253#endif
217 return 0; 254 return 0;
218} 255}
219 256
220 257
221static int 258static int
222test_nullfile_rw () 259test_nullfile_rw (void)
223{ 260{
224 static char fileNameNO[102401]; 261 static char filename[102401];
225 struct GNUNET_BIO_WriteHandle *fileWNO; 262 struct GNUNET_BIO_WriteHandle *wh;
226 struct GNUNET_BIO_ReadHandle *fileRNO; 263 struct GNUNET_BIO_ReadHandle *rh;
227 264
228 memset (fileNameNO, 'a', sizeof(fileNameNO)); 265 memset (filename, 'a', sizeof (filename));
229 fileNameNO[sizeof(fileNameNO) - 1] = '\0'; 266 filename[sizeof (filename) - 1] = '\0';
230 267
231 GNUNET_log_skip (1, GNUNET_NO); 268 GNUNET_log_skip (2, GNUNET_NO);
232 fileWNO = GNUNET_BIO_write_open (fileNameNO); 269 wh = GNUNET_BIO_write_open_file (filename);
233 GNUNET_log_skip (0, GNUNET_YES); 270 GNUNET_log_skip (0, GNUNET_YES);
234 GNUNET_assert (NULL == fileWNO); 271 GNUNET_assert (NULL == wh);
235 272
236 GNUNET_log_skip (1, GNUNET_NO); 273 GNUNET_log_skip (2, GNUNET_NO);
237 fileRNO = GNUNET_BIO_read_open (fileNameNO); 274 rh = GNUNET_BIO_read_open_file (filename);
238 GNUNET_log_skip (0, GNUNET_YES); 275 GNUNET_log_skip (0, GNUNET_YES);
239 GNUNET_assert (NULL == fileRNO); 276 GNUNET_assert (NULL == rh);
277
240 return 0; 278 return 0;
241} 279}
242 280
243 281
244static int 282static int
245test_fullfile_rw () 283test_fullfile_rw (void)
246{ 284{
247#ifdef __linux__ 285#ifdef LINUX
248 /* /dev/full only seems to exist on Linux */ 286 /* /dev/full doesn't exist on every platform */
249 char *msg; 287 struct GNUNET_BIO_WriteHandle *wh;
250 int64_t testNum; 288 struct GNUNET_BIO_ReadHandle *rh;
251 char *readResultString; 289 char *rString = NULL;
252 char readResult[200]; 290 char rResult[200];
253 struct GNUNET_BIO_WriteHandle *fileW; 291 struct GNUNET_CONTAINER_MetaData *mdW;
254 struct GNUNET_BIO_ReadHandle *fileR; 292 struct GNUNET_CONTAINER_MetaData *mdR = NULL;
255 struct GNUNET_CONTAINER_MetaData *metaDataW; 293
256 struct GNUNET_CONTAINER_MetaData *metaDataR; 294 mdW = GNUNET_CONTAINER_meta_data_create ();
257 295 GNUNET_CONTAINER_meta_data_add_publication_date (mdW);
258 metaDataW = GNUNET_CONTAINER_meta_data_create (); 296
259 GNUNET_CONTAINER_meta_data_add_publication_date (metaDataW); 297 struct GNUNET_BIO_WriteSpec ws[] = {
260 298 GNUNET_BIO_write_spec_object ("test-fullfile-rw-bytes",
261 fileW = GNUNET_BIO_write_open ("/dev/full"); 299 TESTSTRING,
262 GNUNET_assert (NULL != fileW); 300 strlen (TESTSTRING)),
263 (void) GNUNET_BIO_write (fileW, TESTSTRING, strlen (TESTSTRING)); 301 GNUNET_BIO_write_spec_string ("test-fullfile-rw-string",
264 (void) GNUNET_BIO_write_string (fileW, TESTSTRING); 302 TESTSTRING),
265 (void) GNUNET_BIO_write_meta_data (fileW, metaDataW); 303 GNUNET_BIO_write_spec_meta_data ("test-fullfile-rw-metadata",
266 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (fileW)); 304 mdW),
267 GNUNET_CONTAINER_meta_data_destroy (metaDataW); 305 GNUNET_BIO_write_spec_end (),
268 306 };
269 fileW = GNUNET_BIO_write_open ("/dev/full"); 307
270 GNUNET_assert (NULL != fileW); 308 struct GNUNET_BIO_ReadSpec rs[] = {
271 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (fileW)); 309 GNUNET_BIO_read_spec_object ("test-fullfile-rw-bytes",
272 310 rResult,
273 fileR = GNUNET_BIO_read_open ("/dev/null"); 311 sizeof (rResult)),
274 GNUNET_assert (NULL != fileR); 312 GNUNET_BIO_read_spec_string ("test-fullfile-rw-string",
275 GNUNET_assert (GNUNET_SYSERR == 313 &rString,
276 GNUNET_BIO_read (fileR, "Read error", readResult, 314 200),
277 sizeof(readResult))); 315 GNUNET_BIO_read_spec_meta_data ("test-fullfile-rw-metadata",
278 readResultString = NULL; 316 &mdR),
279 GNUNET_assert (GNUNET_SYSERR == 317 GNUNET_BIO_read_spec_end(),
280 GNUNET_BIO_read_string (fileR, "Read string error", 318 };
281 &readResultString, 200)); 319
282 GNUNET_assert (NULL == readResultString); 320 wh = GNUNET_BIO_write_open_file ("/dev/full");
283 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_int64 (fileR, &testNum)); 321 GNUNET_assert (NULL != wh);
284 metaDataR = NULL; 322 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_spec_commit (wh, ws));
285 GNUNET_assert (GNUNET_SYSERR == 323 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_write_close (wh, NULL));
286 GNUNET_BIO_read_meta_data (fileR, "Read meta error", 324
287 &metaDataR)); 325 rh = GNUNET_BIO_read_open_file ("/dev/null");
288 msg = NULL; 326 GNUNET_assert (NULL != rh);
289 GNUNET_BIO_read_close (fileR, &msg); 327 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_spec_commit (rh, rs));
290 GNUNET_free (msg); 328 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
291 GNUNET_assert (NULL == metaDataR); 329
330 GNUNET_assert (NULL == rString);
331 GNUNET_assert (NULL == mdR);
292#endif 332#endif
293 return 0; 333 return 0;
294} 334}
295 335
296 336
297static int 337static int
298test_fakestring_rw () 338test_fakestring_rw (void)
299{ 339{
300 char *msg; 340 struct GNUNET_BIO_WriteHandle *wh;
301 int32_t tmpInt = 2; 341 struct GNUNET_BIO_ReadHandle *rh;
302 char *readResult; 342 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
303 struct GNUNET_BIO_WriteHandle *fileW; 343 char *rString = NULL;
304 struct GNUNET_BIO_ReadHandle *fileR; 344
305 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 345 wh = GNUNET_BIO_write_open_file (filename);
306 346 GNUNET_assert (NULL != wh);
307 fileW = GNUNET_BIO_write_open (fileName); 347 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
308 GNUNET_assert (NULL != fileW); 348 "test-fakestring-rw-int32",
309 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, tmpInt)); 349 2));
310 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 350 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
311 351
312 fileR = GNUNET_BIO_read_open (fileName); 352 rh = GNUNET_BIO_read_open_file (filename);
313 GNUNET_assert (NULL != fileR); 353 GNUNET_assert (NULL != rh);
314 GNUNET_assert (GNUNET_SYSERR == 354 GNUNET_assert (GNUNET_SYSERR ==
315 GNUNET_BIO_read_string (fileR, "Read string error", 355 GNUNET_BIO_read_string (rh,
316 &readResult, 200)); 356 "test-fakestring-rw-string",
317 msg = NULL; 357 &rString, 200));
318 GNUNET_BIO_read_close (fileR, &msg); 358 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
319 GNUNET_free (msg); 359
320 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 360 GNUNET_assert (NULL == rString);
321 GNUNET_free (fileName); 361
362 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
363 GNUNET_free (filename);
322 return 0; 364 return 0;
323} 365}
324 366
325 367
326static int 368static int
327test_fakemeta_rw () 369test_fakemeta_rw (void)
328{ 370{
329 char *msg; 371 struct GNUNET_BIO_WriteHandle *wh;
330 int32_t tmpInt = 2; 372 struct GNUNET_BIO_ReadHandle *rh;
331 struct GNUNET_BIO_WriteHandle *fileW; 373 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
332 struct GNUNET_BIO_ReadHandle *fileR; 374 struct GNUNET_CONTAINER_MetaData *mdR = NULL;
333 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 375
334 struct GNUNET_CONTAINER_MetaData *metaDataR; 376 wh = GNUNET_BIO_write_open_file (filename);
335 377 GNUNET_assert (NULL != wh);
336 fileW = GNUNET_BIO_write_open (fileName); 378 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
337 GNUNET_assert (NULL != fileW); 379 "test-fakestring-rw-int32",
338 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, tmpInt)); 380 2));
339 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 381 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
340 382
341 fileR = GNUNET_BIO_read_open (fileName); 383 rh = GNUNET_BIO_read_open_file (filename);
342 GNUNET_assert (NULL != fileR); 384 GNUNET_assert (NULL != rh);
343 metaDataR = NULL;
344 GNUNET_assert (GNUNET_SYSERR == 385 GNUNET_assert (GNUNET_SYSERR ==
345 GNUNET_BIO_read_meta_data (fileR, "Read meta error", 386 GNUNET_BIO_read_meta_data (rh,
346 &metaDataR)); 387 "test-fakestring-rw-metadata",
347 GNUNET_assert (NULL == metaDataR); 388 &mdR));
348 msg = NULL; 389 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
349 GNUNET_BIO_read_close (fileR, &msg); 390
350 GNUNET_free (msg); 391 GNUNET_assert (NULL == mdR);
351 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 392
352 GNUNET_free (fileName); 393 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
394 GNUNET_free (filename);
353 return 0; 395 return 0;
354} 396}
355 397
356 398
357static int 399static int
358test_fakebigmeta_rw () 400test_fakebigmeta_rw (void)
359{ 401{
360 char *msg; 402 struct GNUNET_BIO_WriteHandle *wh;
361 int32_t tmpInt = 1024 * 1024 * 10; 403 struct GNUNET_BIO_ReadHandle *rh;
362 struct GNUNET_BIO_WriteHandle *fileW; 404 char *filename = GNUNET_DISK_mktemp ("gnunet_bio");
363 struct GNUNET_BIO_ReadHandle *fileR; 405 struct GNUNET_CONTAINER_MetaData *mdR = NULL;
364 char *fileName = GNUNET_DISK_mktemp ("gnunet_bio"); 406 int32_t wNum = 1024 * 1024 * 10;
365 struct GNUNET_CONTAINER_MetaData *metaDataR; 407
366 408 wh = GNUNET_BIO_write_open_file (filename);
367 fileW = GNUNET_BIO_write_open (fileName); 409 GNUNET_assert (NULL != wh);
368 GNUNET_assert (NULL != fileW); 410 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (wh,
369 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_int32 (fileW, tmpInt)); 411 "test-fakebigmeta-rw-int32",
370 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (fileW)); 412 wNum));
371 413 GNUNET_assert (GNUNET_OK == GNUNET_BIO_write_close (wh, NULL));
372 fileR = GNUNET_BIO_read_open (fileName); 414
373 GNUNET_assert (NULL != fileR); 415 rh = GNUNET_BIO_read_open_file (filename);
374 metaDataR = NULL; 416 GNUNET_assert (NULL != rh);
375 GNUNET_assert (GNUNET_SYSERR == 417 GNUNET_assert (GNUNET_SYSERR ==
376 GNUNET_BIO_read_meta_data (fileR, "Read meta error", 418 GNUNET_BIO_read_meta_data (rh,
377 &metaDataR)); 419 "test-fakebigmeta-rw-metadata",
378 msg = NULL; 420 &mdR));
379 GNUNET_BIO_read_close (fileR, &msg); 421 GNUNET_assert (GNUNET_SYSERR == GNUNET_BIO_read_close (rh, NULL));
380 GNUNET_free (msg); 422
381 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (fileName)); 423 GNUNET_assert (NULL == mdR);
382 GNUNET_assert (NULL == metaDataR); 424
383 GNUNET_free (fileName); 425 GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (filename));
426 GNUNET_free (filename);
384 return 0; 427 return 0;
385} 428}
386 429
387 430
388static int 431static int
389check_string_rw () 432check_string_rw (void)
390{ 433{
391 GNUNET_assert (0 == test_nullstring_rw ()); 434 GNUNET_assert (0 == test_nullstring_rw ());
392 GNUNET_assert (0 == test_emptystring_rw ()); 435 GNUNET_assert (0 == test_emptystring_rw ());
@@ -397,7 +440,7 @@ check_string_rw ()
397 440
398 441
399static int 442static int
400check_metadata_rw () 443check_metadata_rw (void)
401{ 444{
402 GNUNET_assert (0 == test_fakebigmeta_rw ()); 445 GNUNET_assert (0 == test_fakebigmeta_rw ());
403 GNUNET_assert (0 == test_fakemeta_rw ()); 446 GNUNET_assert (0 == test_fakemeta_rw ());
@@ -407,7 +450,7 @@ check_metadata_rw ()
407 450
408 451
409static int 452static int
410check_file_rw () 453check_file_rw (void)
411{ 454{
412 GNUNET_assert (0 == test_normal_rw ()); 455 GNUNET_assert (0 == test_normal_rw ());
413 GNUNET_assert (0 == test_nullfile_rw ()); 456 GNUNET_assert (0 == test_nullfile_rw ());