dav/db.c

changeset 46
0542668d0f26
child 47
fbbbeed4ba8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dav/db.c	Fri Jun 13 13:52:59 2014 +0200
@@ -0,0 +1,146 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "db.h"
+
+#include <libidav/utils.h>
+
+
+#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
+
+#ifdef _WIN32
+#define ENV_HOME getenv("USERPROFILE")
+#else
+#define ENV_HOME getenv("HOME")
+#endif /* _WIN32 */
+
+UcxMap* load_db(char *name) {
+    char *dav_dir = util_concat_path(ENV_HOME, ".dav");
+    char *db_file = util_concat_path(dav_dir, name);
+    free(dav_dir);
+    
+    xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0);
+    if(!reader) {
+        fprintf(stderr, "Cannot open database file: %s\n", db_file);
+        free(db_file);
+        return NULL;
+    }
+    free(db_file);
+    
+    UcxMap *map = ucx_map_new(2048);
+    int error = 0;
+    while(xmlTextReaderRead(reader)) {
+        int type = xmlTextReaderNodeType(reader);
+        const xmlChar *name = xmlTextReaderConstName(reader);
+        
+        if(type == XML_READER_TYPE_ELEMENT) {
+            if(xstreq(name, "resource")) {
+                LocalResource *res = process_resource(reader);
+                if(res) {
+                    ucx_map_cstr_put(map, res->path, res);
+                } else {
+                    error = 1;
+                    break;
+                }
+            }
+        }
+    }
+    
+    xmlFreeTextReader(reader);
+    if(error) {
+        // TODO: free resources and map
+        return NULL;
+    } else {
+        return map;
+    }
+}
+
+LocalResource* process_resource(xmlTextReaderPtr reader) {
+    LocalResource *res = calloc(1, sizeof(LocalResource));
+    
+    int field = -1;
+    while(xmlTextReaderRead(reader)) {
+        int type = xmlTextReaderNodeType(reader);
+        const xmlChar *name = xmlTextReaderConstName(reader);
+        
+        if(type == XML_READER_TYPE_ELEMENT) {
+            if(xstreq(name, "path")) {
+                field = 0;
+            } else if(xstreq(name, "etag")) {
+                field = 1;
+            } else if(xstreq(name, "lastmodified")) {
+                field = 2;
+            } else if(xstreq(name, "size")) {
+                field = 3;
+            }
+        } else if(type == XML_READER_TYPE_TEXT) {
+            const xmlChar *value = xmlTextReaderConstValue(reader);
+            int b = 0;
+            switch(field) {
+                case 0: {
+                    res->name = strdup((char*)value);
+                    break;
+                }
+                case 1: {
+                    res->etag = strdup((char*)value);
+                    break;
+                }
+                case 2: {
+                    res->last_modified = util_parse_lastmodified((char*)value);
+                    break;
+                }
+                case 3: {
+                    res->size = atoi((char*)value);
+                    break;
+                }
+            }
+        } else if(XML_READER_TYPE_END_ELEMENT) {
+            if(xstreq(name, "resource")) {
+                break;
+            } else {
+                field = -1;
+            }
+        }
+    }
+    
+    if(!res->name || !res->path || res->last_modified == 0) {
+        // TODO: free res
+        return NULL;
+    } else {
+        return res;
+    }
+}
+
+int store_db(UcxMap *db, char *name) {
+    // TODO:
+    
+}

mercurial