static size_t thex_upload_prepare_xml(char **data_ptr, const struct tth *tth, filesize_t filesize) { struct dime_record *dime; char buf[512]; size_t len, size; unsigned depth; depth = tt_good_depth(filesize); len = concat_strings(buf, sizeof buf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" "<!DOCTYPE hashtree S" /* NOTE: HIDE FROM METACONFIG */ "YSTEM \"" THEX_DOCTYPE "\">\r\n" "<hashtree>\r\n" "<file" " size=\"", filesize_to_string(filesize), "\"" " segmentsize=\"" THEX_SEGMENT_SIZE "\"/>\r\n" "<digest" " algorithm=\"" THEX_HASH_ALGO "\"" " outputsize=\"" THEX_HASH_SIZE "\"/>\r\n" "<serializedtree" " depth=\"", uint32_to_string(depth), "\"" " type=\"" THEX_TREE_TYPE "\"" " uri=\"", thex_upload_uuid(tth), "\"/>\r\n" "</hashtree>\r\n", (void *) 0); dime = dime_record_alloc(); dime_record_set_data(dime, buf, len); dime_record_set_type_mime(dime, "text/xml"); size = dime_create_record(dime, data_ptr, TRUE, FALSE); dime_record_free(&dime); return size; }
static size_t thex_upload_prepare_tree(char **data_ptr, const struct tth *tth, const struct tth *nodes, size_t n_nodes) { struct dime_record *dime; size_t size; dime = dime_record_alloc(); STATIC_ASSERT(TTH_RAW_SIZE == sizeof nodes[0]); dime_record_set_data(dime, nodes, n_nodes * TTH_RAW_SIZE); dime_record_set_type_uri(dime, THEX_TREE_TYPE); dime_record_set_id(dime, thex_upload_uuid(tth)); size = dime_create_record(dime, data_ptr, FALSE, TRUE); dime_record_free(&dime); return size; }
GSList * dime_parse_records(const char *data, size_t size) { const char * const data0 = data; GSList *list = NULL; for (;;) { struct dime_record *record; size_t ret; record = dime_record_alloc(); list = g_slist_prepend(list, record); ret = dime_parse_record_header(data, size, record); if (0 == ret) { goto error; } data += ret; size -= ret; if (data0 == data) { if (0 == (DIME_F_MB & record->flags)) { /* FIXME: Warning, no message begin flag */ goto error; } } if (DIME_F_ME & record->flags) { break; } } return g_slist_reverse(list); error: dime_list_free(&list); return NULL; }