libidav/resource.c

changeset 139
c6424aebcf5e
parent 135
664aeaec8d25
child 140
0a06bed068a1
--- a/libidav/resource.c	Thu Jul 09 17:22:55 2015 +0200
+++ b/libidav/resource.c	Fri Oct 02 13:18:17 2015 +0200
@@ -39,6 +39,7 @@
 #include "ucx/utils.h"
 
 #include "resource.h"
+#include "davqlexec.h"
 
 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
 
@@ -236,18 +237,26 @@
 
 char* resource_get_property(DavResource *res, char *ns, char *name) {
     UcxKey key = dav_property_key(ns, name);
-    DavResourceData *data = (DavResourceData*)res->data;
-    char *property = ucx_map_get(data->properties, key);
+    char *property = resource_get_property_k(res, key);
     free(key.data);
     return property;
 }
 
+char* resource_get_property_k(DavResource *res, UcxKey key) {
+    DavResourceData *data = (DavResourceData*)res->data;
+    return ucx_map_get(data->properties, key);
+}
+
 UcxKey dav_property_key(char *ns, char *name) {
+    return dav_property_key_a(ucx_default_allocator(), ns, name);
+}
+
+UcxKey dav_property_key_a(UcxAllocator *a, char *ns, char *name) {
     sstr_t ns_str = sstr(ns);
     sstr_t name_str = sstr(name);
     
     sstr_t key;
-    key = sstrcat(4, ns_str, S("\0"), name_str, S("\0"));
+    key = sstrcat_a(a, 4, ns_str, S("\0"), name_str, S("\0"));
     
     return ucx_key(key.ptr, key.length);
 }
@@ -271,6 +280,111 @@
     child->parent = parent;
 }
 
+static int resource_cmp(DavResource *res1, DavResource *res2, DavOrderCriterion *cr) {
+    if(!(res1 && res2)) {
+        return 0;
+    }
+    
+    int ret;
+    if(cr->type == 0) {
+        switch(cr->column.resprop) {
+            case DAVQL_RES_NAME: {
+                ret = strcmp(res1->name, res2->name);
+                break;
+            }
+            case DAVQL_RES_PATH: {
+                ret = strcmp(res1->path, res2->path);
+                break;
+            }
+            case DAVQL_RES_HREF: {
+                ret = strcmp(res1->href, res2->href);
+                break;
+            }
+            case DAVQL_RES_CONTENTLENGTH: {
+                int c = res1->contentlength == res2->contentlength;
+                ret = c ? 0 : (res1->contentlength < res2->contentlength?-1:1);
+                break;
+            }
+            case DAVQL_RES_CONTENTTYPE: {
+                ret = strcmp(res1->contenttype, res2->contenttype);
+                break;
+            }
+            case DAVQL_RES_CREATIONDATE: {
+                int c = res1->creationdate == res2->creationdate;
+                ret = c ? 0 : (res1->creationdate < res2->creationdate?-1:1);
+                break;
+            }
+            case DAVQL_RES_LASTMODIFIED: {
+                int c = res1->lastmodified == res2->lastmodified;
+                ret = c ? 0 : (res1->lastmodified < res2->lastmodified?-1:1);
+                break;
+            }
+            case DAVQL_RES_ISCOLLECTION: {
+                int c = res1->iscollection == res2->iscollection;
+                ret = c ? 0 : (res1->iscollection < res2->iscollection?-1:1);
+                break;
+            }
+            default: ret = 0;
+        }
+    } else if(cr->type == 1) {
+        char *value1 = resource_get_property_k(res1, cr->column.property);
+        char *value2 = resource_get_property_k(res2, cr->column.property);
+        if(!value1) {
+            ret = value2 ? -1 : 0;
+        } else if(!value2) {
+            ret = value1 ? 1 : 0;
+        } else {
+            ret = strcmp(value1, value2);
+        }
+    } else {
+        return 0;
+    }
+    
+    return cr->descending ? -ret : ret;
+}
+
+void resource_add_ordered_child(DavResource *parent, DavResource *child, UcxList *ordercr) {
+    if(!ordercr) {
+        resource_add_child(parent, child);
+        return;
+    }
+    
+    child->parent = parent;
+    
+    if(!parent->children) {
+        child->next = NULL;
+        child->prev = NULL;
+        parent->children = child;
+    } else {
+        DavResource *resource = parent->children;
+        while(resource) {
+            int r = 0;
+            UCX_FOREACH(elm, ordercr) {
+                DavOrderCriterion *cr = elm->data;
+                r = resource_cmp(child, resource, cr);
+                if(r != 0) {
+                    break;
+                }
+            }
+            
+            if(r < 0 || !resource->next) {
+                // insert child before resource
+                child->prev = resource->prev;
+                child->next = resource;
+                if(resource->prev) {
+                    resource->prev->next = child;
+                } else {
+                    parent->children = child;
+                }
+                resource->prev = child;
+                break;
+            } else {
+                resource = resource->next;
+            }
+        }
+    }
+}
+
 char* dav_get_property(DavResource *res, char *name) {
     char *pns;
     char *pname;

mercurial