dav/db.c

changeset 536
877f7c4a203b
parent 535
d814ee31c04f
child 537
abfc943f09ed
--- 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 <ucx/utils.h>
+
 #include <libidav/utils.h>
 
 #include <libxml/encoding.h>
@@ -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) {
+                // </parts>
+                break;
+            } else if(depth == 3) {
+                if(current_part) {
+                    if(!current_part->hash || !current_part->etag) {
+                        err = 1;
+                    }
+                }
+                // </part>
+                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;i<res->numparts;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;
+            }
+        }
+        
         // </resource>
         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);
+}

mercurial