diff -r 6a3248e22d58 -r c6424aebcf5e libidav/resource.c --- 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;