diff -r d814ee31c04f -r 877f7c4a203b dav/db.c --- a/dav/db.c Sat Mar 23 10:04:18 2019 +0100 +++ b/dav/db.c Tue Mar 26 17:30:34 2019 +0100 @@ -33,6 +33,8 @@ #include "db.h" +#include + #include #include @@ -106,6 +108,78 @@ } } +void process_parts(xmlTextReaderPtr reader, LocalResource *res) { + UcxList *parts = NULL; + + FilePart *current_part = NULL; + + size_t count = 0; + int field = -1; + int err = 0; + while(xmlTextReaderRead(reader)) { + int type = xmlTextReaderNodeType(reader); + const xmlChar *name = xmlTextReaderConstName(reader); + int depth = xmlTextReaderDepth(reader); + + int part = TRUE; + if(type == XML_READER_TYPE_ELEMENT) { + if(depth == 3 && xstreq(name, "part")) { + current_part = calloc(1, sizeof(FilePart)); + current_part->block = count; + parts = ucx_list_append(parts, current_part); + count++; + } else if(depth == 4) { + if(xstreq(name, "hash")) { + field = 0; + } else if(xstreq(name, "etag")) { + field = 1; + } + } + } else if(type == XML_READER_TYPE_END_ELEMENT) { + if(depth == 2) { + // + break; + } else if(depth == 3) { + if(current_part) { + if(!current_part->hash || !current_part->etag) { + err = 1; + } + } + // + current_part = NULL; + } + field = -1; + } else if(type == XML_READER_TYPE_TEXT && depth == 5 && current_part) { + const char *text = (const char*)xmlTextReaderConstValue(reader); + if(field == 0) { + current_part->hash = strdup(text); + } else if(field = 1) { + current_part->etag = strdup(text); + } + } + } + + if(err) { + ucx_list_free_content(parts, (ucx_destructor)filepart_free); + ucx_list_free(parts); + return; + } + + FilePart *file_parts = calloc(count, sizeof(FilePart)); + size_t i = 0; + UCX_FOREACH(elm, parts) { + FilePart *p = elm->data; + file_parts[i] = *p; + free(p); + i++; + } + + ucx_list_free(parts); + + res->parts = file_parts; + res->numparts = count; +} + LocalResource* process_resource(xmlTextReaderPtr reader) { LocalResource *res = calloc(1, sizeof(LocalResource)); @@ -141,6 +215,8 @@ res->skipped = TRUE; } else if(xstreq(name, "tags-updated")) { res->tags_updated = TRUE; + } else if(xstreq(name, "parts")) { + process_parts(reader, res); } } else if(type == XML_READER_TYPE_TEXT) { const xmlChar *value = xmlTextReaderConstValue(reader); @@ -441,6 +517,47 @@ } } + if(res->numparts > 0) { + r = xmlTextWriterStartElement(writer, BAD_CAST "parts"); + if(r < 0) { + xmlFreeTextWriter(writer); + return -1; + } + for(size_t i=0;inumparts;i++) { + FilePart p = res->parts[i]; + r = xmlTextWriterStartElement(writer, BAD_CAST "part"); + if(r < 0) { + xmlFreeTextWriter(writer); + return -1; + } + + if(p.hash) { + r = xmlTextWriterWriteElement(writer, BAD_CAST "hash", BAD_CAST p.hash); + if(r < 0) { + xmlFreeTextWriter(writer); + return -1; + } + } + if(p.etag) { + r = xmlTextWriterWriteElement(writer, BAD_CAST "etag", BAD_CAST p.etag); + if(r < 0) { + xmlFreeTextWriter(writer); + return -1; + } + } + r = xmlTextWriterEndElement(writer); + if(r < 0) { + xmlFreeTextWriter(writer); + return -1; + } + } + r = xmlTextWriterEndElement(writer); + if(r < 0) { + xmlFreeTextWriter(writer); + return -1; + } + } + // xmlTextWriterEndElement(writer); } @@ -517,3 +634,13 @@ } free(res); } + +void filepart_free(FilePart *part) { + if(part->etag) { + free(part->etag); + } + if(part->hash) { + free(part->hash); + } + free(part); +}