libidav/davqlexec.c

changeset 747
efbd59642577
parent 739
bba6a6e221b4
child 755
283d3d7a657a
--- a/libidav/davqlexec.c	Sun Apr 16 14:12:24 2023 +0200
+++ b/libidav/davqlexec.c	Fri Apr 21 21:25:32 2023 +0200
@@ -31,8 +31,12 @@
 #include <string.h>
 #include <inttypes.h>
 
-#include <ucx/utils.h>
-#include <ucx/map.h>
+#include <cx/utils.h>
+#include <cx/map.h>
+#include <cx/hash_map.h>
+#include <cx/printf.h>
+#include <cx/basic_mempool.h>
+
 #include "davqlexec.h"
 #include "utils.h"
 #include "methods.h"
@@ -46,9 +50,16 @@
     }
     args->first = NULL;
     
+    if(!st->args) {
+        args->first = NULL;
+        args->current = NULL;
+        return args;
+    }
+    
     DavQLArg *cur = NULL;
-    UCX_FOREACH(elm, st->args) {
-        intptr_t type = (intptr_t)elm->data;
+    CxIterator i = cxListIterator(st->args);
+    cx_foreach(void*, data, i) {
+        intptr_t type = (intptr_t)data;
         DavQLArg *arg = calloc(1, sizeof(DavQLArg));
         if(!arg) {
             dav_ql_free_arglist(args);
@@ -167,8 +178,9 @@
     return result;
 }
 
-sstr_t dav_format_string(UcxAllocator *a, sstr_t fstr, DavQLArgList *ap, davqlerror_t *error) {
-    UcxBuffer *buf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND);
+cxmutstr dav_format_string(const CxAllocator *a, cxstring fstr, DavQLArgList *ap, davqlerror_t *error) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 128, a, CX_BUFFER_AUTO_EXTEND);
     
     int placeholder = 0;
     for(int i=0;i<fstr.length;i++) {
@@ -176,24 +188,24 @@
         if(placeholder) {
             if(c == '%') {
                 // no placeholder, %% transposes to %
-                ucx_buffer_putc(buf, c);
+                cxBufferPut(&buf, c);
             } else {
                 // detect placeholder type and insert arg
                 int err = 0;
                 switch(c) {
                     case 's': {
                         char *arg = dav_ql_getarg_str(ap);
-                        ucx_buffer_puts(buf, arg);
+                        cxBufferPutString(&buf, arg);
                         break;
                     }
                     case 'd': {
                         int arg = dav_ql_getarg_int(ap);
-                        ucx_bprintf(buf, "%d", arg);
+                        cx_bprintf(&buf, "%d", arg);
                         break;
                     }
                     case 'u': {
                         unsigned int arg = dav_ql_getarg_uint(ap);
-                        ucx_bprintf(buf, "%u", arg);
+                        cx_bprintf(&buf, "%u", arg);
                         break;
                     }
                     case 't': {
@@ -207,11 +219,8 @@
                     }
                 }
                 if(err) {
-                    ucx_buffer_free(buf);
-                    sstr_t n;
-                    n.ptr = NULL;
-                    n.length = 0;
-                    return n;
+                    cxBufferDestroy(&buf);
+                    return (cxmutstr){NULL,0};
                 }
             }
             placeholder = 0;
@@ -219,29 +228,32 @@
             if(c == '%') {
                 placeholder = 1;
             } else {
-                ucx_buffer_putc(buf, c);
+                cxBufferPut(&buf, c);
             }
         }
     }
+    if(cxBufferPut(&buf, '\0')) {
+        *error = DAVQL_OOM;
+        cxBufferDestroy(&buf);
+        return (cxmutstr){NULL, 0};
+    }
     *error = DAVQL_OK;
     
-    sstr_t ret = sstrdup_a(a, sstrn(buf->space, buf->size));
-    ucx_buffer_free(buf);
-    return ret;
+    return cx_mutstrn(buf.space, buf.size-1);
 }
 
-static int fl_add_properties(DavSession *sn, UcxMempool *mp, UcxMap *map, DavQLExpression *expression) {
+static int fl_add_properties(DavSession *sn, const CxAllocator *a, CxMap *map, DavQLExpression *expression) {
     if(!expression) {
         return 0;
     }
     
     if(expression->type == DAVQL_IDENTIFIER) {
-        DavProperty *property = ucx_mempool_malloc(mp, sizeof(DavProperty));
+        DavProperty *property = cxMalloc(a, sizeof(DavProperty));
 
         char *name;
         DavNamespace *ns = dav_get_property_namespace(
                 sn->context,
-                sstrdup_a(mp->allocator, expression->srctext).ptr,
+                cx_strdup_a(a, expression->srctext).ptr,
                 &name);
         if(!ns) {
             return -1;
@@ -251,16 +263,16 @@
         property->name = name;
         property->value = NULL;
         
-        ucx_map_sstr_put(map, expression->srctext, property);
+        cxMapPut(map, cx_hash_key(expression->srctext.ptr, expression->srctext.length), property);
     }
     
     if(expression->left) {
-        if(fl_add_properties(sn, mp, map, expression->left)) {
+        if(fl_add_properties(sn, a, map, expression->left)) {
             return -1;
         }
     }
     if(expression->right) {
-        if(fl_add_properties(sn, mp, map, expression->right)) {
+        if(fl_add_properties(sn, a, map, expression->right)) {
             return -1;
         }
     }
@@ -268,170 +280,170 @@
     return 0;
 }
 
-static UcxBuffer* fieldlist2propfindrequest(DavSession *sn, UcxMempool *mp, UcxList *fields, int *isallprop) {
-    UcxMap *properties = ucx_map_new(32);
+static CxBuffer* fieldlist2propfindrequest(DavSession *sn, const CxAllocator *a, CxList *fields, int *isallprop) {
+    CxMap *properties = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32);
     *isallprop = 0;
     
-    UCX_FOREACH(elm, fields) {
-        DavQLField *field = elm->data;
-        if(!sstrcmp(field->name, S("*"))) {
-            ucx_map_free(properties);
+    CxIterator i = cxListIterator(fields);
+    cx_foreach(DavQLField*, field, i) {
+        if(!cx_strcmp(field->name, CX_STR("*"))) {
+            cxMapDestroy(properties);
             *isallprop = 1;
             return create_allprop_propfind_request();
-        } else if(!sstrcmp(field->name, S("-"))) {
-            ucx_map_free(properties);
+        } else if(!cx_strcmp(field->name, CX_STR("-"))) {
+            cxMapDestroy(properties);
             return create_propfind_request(sn, NULL, "propfind", 0);
         } else {
-            if(fl_add_properties(sn, mp, properties, field->expr)) {
+            if(fl_add_properties(sn, a, properties, field->expr)) {
                 // TODO: set error
-                ucx_map_free(properties);
+                cxMapDestroy(properties);
                 return NULL;
             }
         }
     }
     
-    UcxMapIterator i = ucx_map_iterator(properties);
-    UcxKey key;
-    DavProperty *value;
-    UcxList *list = NULL;
-    UCX_MAP_FOREACH(key, value, i) {
-        list = ucx_list_append(list, value);
+    i = cxMapIteratorValues(properties);
+    CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS);
+    cx_foreach(DavProperty*, value, i) {
+        cxListAdd(list, value);
     }
     
-    UcxBuffer *reqbuf = create_propfind_request(sn, list, "propfind", 0);
-    ucx_list_free(list);
-    ucx_map_free(properties);
+    CxBuffer *reqbuf = create_propfind_request(sn, list, "propfind", 0);
+    cxListDestroy(list);
+    cxMapDestroy(properties);
     return reqbuf;
 }
 
-static int reset_properties(DavSession *sn, DavResult *result, DavResource *res, UcxList *fields) {
-    UcxMap *new_properties = ucx_map_new_a(sn->mp->allocator, 32);
+static int reset_properties(DavSession *sn, DavResult *result, DavResource *res, CxList *fields) {
+    CxMap *new_properties = cxHashMapCreate(sn->mp->allocator, CX_STORE_POINTERS, 32);
     DavResourceData *data = (DavResourceData*)res->data;
     
     // add basic properties
     void *value;
     
-    sstr_t cl_keystr = dav_property_key("DAV:", "getcontentlength");
-    UcxKey cl_key = ucx_key(cl_keystr.ptr, cl_keystr.length);
-    value = ucx_map_get(data->properties, cl_key);
+    cxmutstr cl_keystr = dav_property_key("DAV:", "getcontentlength");
+    CxHashKey cl_key = cx_hash_key(cl_keystr.ptr, cl_keystr.length);
+    value = cxMapGet(data->properties, cl_key);
     if(value) {
-        ucx_map_put(new_properties, cl_key, value);
+        cxMapPut(new_properties, cl_key, value);
     }
     
-    sstr_t cd_keystr = dav_property_key("DAV:", "creationdate");
-    UcxKey cd_key = ucx_key(cd_keystr.ptr, cd_keystr.length);
-    value = ucx_map_get(data->properties, cd_key);
+    cxmutstr cd_keystr = dav_property_key("DAV:", "creationdate");
+    CxHashKey cd_key = cx_hash_key(cd_keystr.ptr, cd_keystr.length);
+    value = cxMapGet(data->properties, cd_key);
     if(value) {
-        ucx_map_put(new_properties, cd_key, value);
+        cxMapPut(new_properties, cd_key, value);
     }
     
-    sstr_t lm_keystr = dav_property_key("DAV:", "getlastmodified");
-    UcxKey lm_key = ucx_key(lm_keystr.ptr, lm_keystr.length);
-    value = ucx_map_get(data->properties, lm_key);
+    cxmutstr lm_keystr = dav_property_key("DAV:", "getlastmodified");
+    CxHashKey lm_key = cx_hash_key(lm_keystr.ptr, lm_keystr.length);
+    value = cxMapGet(data->properties, lm_key);
     if(value) {
-        ucx_map_put(new_properties, lm_key, value);
+        cxMapPut(new_properties, lm_key, value);
     }
     
-    sstr_t ct_keystr = dav_property_key("DAV:", "getcontenttype");
-    UcxKey ct_key = ucx_key(ct_keystr.ptr, ct_keystr.length);
-    value = ucx_map_get(data->properties, ct_key);
+    cxmutstr ct_keystr = dav_property_key("DAV:", "getcontenttype");
+    CxHashKey ct_key = cx_hash_key(ct_keystr.ptr, ct_keystr.length);
+    value = cxMapGet(data->properties, ct_key);
     if(value) {
-        ucx_map_put(new_properties, ct_key, value);
+        cxMapPut(new_properties, ct_key, value);
     }
     
-    sstr_t rt_keystr = dav_property_key("DAV:", "resourcetype");
-    UcxKey rt_key = ucx_key(rt_keystr.ptr, rt_keystr.length);
-    value = ucx_map_get(data->properties, rt_key);
+    cxmutstr rt_keystr = dav_property_key("DAV:", "resourcetype");
+    CxHashKey rt_key = cx_hash_key(rt_keystr.ptr, rt_keystr.length);
+    value = cxMapGet(data->properties, rt_key);
     if(value) {
-        ucx_map_put(new_properties, rt_key, value);
+        cxMapPut(new_properties, rt_key, value);
     }
     
-    sstr_t cn_keystr = dav_property_key(DAV_NS, "crypto-name");
-    UcxKey cn_key = ucx_key(cn_keystr.ptr, cn_keystr.length);
-    value = ucx_map_get(data->properties, cn_key);
+    cxmutstr cn_keystr = dav_property_key(DAV_NS, "crypto-name");
+    CxHashKey cn_key = cx_hash_key(cn_keystr.ptr, cn_keystr.length);
+    value = cxMapGet(data->properties, cn_key);
     if(value) {
-        ucx_map_put(new_properties, cn_key, value);
+        cxMapPut(new_properties, cn_key, value);
     }
     
-    sstr_t ck_keystr = dav_property_key(DAV_NS, "crypto-key");
-    UcxKey ck_key = ucx_key(ck_keystr.ptr, ck_keystr.length);
-    value = ucx_map_get(data->properties, ck_key);
+    cxmutstr ck_keystr = dav_property_key(DAV_NS, "crypto-key");
+    CxHashKey ck_key = cx_hash_key(ck_keystr.ptr, ck_keystr.length);
+    value = cxMapGet(data->properties, ck_key);
     if(value) {
-        ucx_map_put(new_properties, ck_key, value);
+        cxMapPut(new_properties, ck_key, value);
     }
     
-    sstr_t ch_keystr = dav_property_key(DAV_NS, "crypto-hash");
-    UcxKey ch_key = ucx_key(ch_keystr.ptr, ch_keystr.length);
-    value = ucx_map_get(data->properties, ch_key);
+    cxmutstr ch_keystr = dav_property_key(DAV_NS, "crypto-hash");
+    CxHashKey ch_key = cx_hash_key(ch_keystr.ptr, ch_keystr.length);
+    value = cxMapGet(data->properties, ch_key);
     if(value) {
-        ucx_map_put(new_properties, ch_key, value);
+        cxMapPut(new_properties, ch_key, value);
     }
     
     // add properties from field list
-    UCX_FOREACH(elm, fields) {
-        DavCompiledField *field = elm->data;
-        DavQLStackObj field_result;
-        if(!dav_exec_expr(field->code, res, &field_result)) {
-            sstr_t str;
-            str.ptr = NULL;
-            str.length = 0;
-            DavXmlNode *node = NULL;
-            if(field_result.type == 0) {
-                str = ucx_asprintf(
-                        sn->mp->allocator,
-                        "%d",
-                        field_result.data.integer);
-            } else if(field_result.type == 1) {
-                if(field_result.data.string) {
-                    str = sstrdup_a(sn->mp->allocator, sstrn(
-                            field_result.data.string,
-                            field_result.length));
+    if(fields) {
+        CxIterator i = cxListIterator(fields);
+        cx_foreach(DavCompiledField*, field, i) {
+            DavQLStackObj field_result;
+            if(!dav_exec_expr(field->code, res, &field_result)) {
+                cxmutstr str;
+                str.ptr = NULL;
+                str.length = 0;
+                DavXmlNode *node = NULL;
+                if(field_result.type == 0) {
+                    str = cx_asprintf_a(
+                            sn->mp->allocator,
+                            "%" PRId64,
+                            field_result.data.integer);
+                } else if(field_result.type == 1) {
+                    if(field_result.data.string) {
+                        str = cx_strdup_a(sn->mp->allocator, cx_strn(
+                                field_result.data.string,
+                                field_result.length));
+                    }
+                } else if(field_result.type == 2) {
+                    node = dav_copy_node(field_result.data.node);
+                } else {
+                    // unknown type
+                    // TODO: error
+                    resource_free_properties(sn, new_properties);
+                    return -1;
                 }
-            } else if(field_result.type == 2) {
-                node = dav_copy_node(field_result.data.node);
+                if(str.ptr) {
+                    node = dav_session_malloc(sn, sizeof(DavXmlNode));
+                    memset(node, 0, sizeof(DavXmlNode));
+                    node->type = DAV_XML_TEXT;
+                    node->content = str.ptr;
+                    node->contentlength = str.length;
+                }
+                if(node) {
+                    cxmutstr key = dav_property_key(field->ns, field->name);
+
+                    DavNamespace *namespace = dav_session_malloc(sn, sizeof(DavNamespace));
+                    namespace->prefix = NULL;
+                    namespace->name = dav_session_strdup(sn, field->ns);
+
+                    DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty));
+                    prop->name = dav_session_strdup(sn, field->name);
+                    prop->ns = namespace;
+                    prop->value = node;
+
+                    cxMapPut(new_properties, cx_hash_key(key.ptr, key.length), prop);
+                    free(key.ptr);
+                }
             } else {
-                // unknown type
                 // TODO: error
                 resource_free_properties(sn, new_properties);
                 return -1;
             }
-            if(str.ptr) {
-                node = dav_session_malloc(sn, sizeof(DavXmlNode));
-                memset(node, 0, sizeof(DavXmlNode));
-                node->type = DAV_XML_TEXT;
-                node->content = str.ptr;
-                node->contentlength = str.length;
-            }
-            if(node) {
-                sstr_t key = dav_property_key(field->ns, field->name);
-                
-                DavNamespace *namespace = dav_session_malloc(sn, sizeof(DavNamespace));
-                namespace->prefix = NULL;
-                namespace->name = dav_session_strdup(sn, field->ns);
-
-                DavProperty *prop = dav_session_malloc(sn, sizeof(DavProperty));
-                prop->name = dav_session_strdup(sn, field->name);
-                prop->ns = namespace;
-                prop->value = node;
-                
-                ucx_map_sstr_put(new_properties, key, prop);
-                free(key.ptr);
-            }
-        } else {
-            // TODO: error
-            resource_free_properties(sn, new_properties);
-            return -1;
         }
     }
     
-    ucx_map_remove(data->properties, cl_key);
-    ucx_map_remove(data->properties, cd_key);
-    ucx_map_remove(data->properties, lm_key);
-    ucx_map_remove(data->properties, ct_key);
-    ucx_map_remove(data->properties, rt_key);
-    ucx_map_remove(data->properties, cn_key);
-    ucx_map_remove(data->properties, ck_key);
-    ucx_map_remove(data->properties, ch_key);
+    cxMapRemove(data->properties, cl_key);
+    cxMapRemove(data->properties, cd_key);
+    cxMapRemove(data->properties, lm_key);
+    cxMapRemove(data->properties, ct_key);
+    cxMapRemove(data->properties, rt_key);
+    cxMapRemove(data->properties, cn_key);
+    cxMapRemove(data->properties, ck_key);
+    cxMapRemove(data->properties, ch_key);
     
     resource_free_properties(sn, data->properties);
     data->properties = new_properties;
@@ -452,7 +464,7 @@
  * execute a davql select statement
  */
 DavResult dav_exec_select(DavSession *sn, DavQLStatement *st, va_list ap) {
-    UcxMempool *mp = ucx_mempool_new(128);
+    CxMempool *mp = cxBasicMempoolCreate(128);
     DavResult result;
     result.result = NULL;
     result.status = 1;
@@ -461,157 +473,158 @@
     if(!args) {
         return result;
     }
-    ucx_mempool_reg_destr(mp, args, (ucx_destructor)dav_ql_free_arglist);
+    util_regdestr(mp, args, (cx_destructor_func)dav_ql_free_arglist);
     
     int isallprop;
-    UcxBuffer *rqbuf = fieldlist2propfindrequest(sn, mp, st->fields, &isallprop);
+    CxBuffer *rqbuf = fieldlist2propfindrequest(sn, mp->allocator, st->fields, &isallprop);
     if(!rqbuf) {
-        ucx_mempool_destroy(mp);
+        cxMempoolDestroy(mp);
         return result;
     }
-    ucx_mempool_reg_destr(mp, rqbuf, (ucx_destructor)ucx_buffer_free);
+    util_regdestr(mp, rqbuf, (cx_destructor_func)cxBufferFree);
     
     // compile field list
-    UcxList *cfieldlist = NULL;
-    UCX_FOREACH(elm, st->fields) {
-        DavQLField *field = elm->data;
-        if(sstrcmp(field->name, S("*")) && sstrcmp(field->name, S("-"))) {
-            // compile field expression
-            UcxBuffer *code = dav_compile_expr(
+    CxList *cfieldlist = cxLinkedListCreate(mp->allocator, NULL, CX_STORE_POINTERS);
+    if(st->fields) {
+        CxIterator i = cxListIterator(st->fields);
+        cx_foreach(DavQLField*, field, i) {
+            if(cx_strcmp(field->name, CX_STR("*")) && cx_strcmp(field->name, CX_STR("-"))) {
+                // compile field expression
+                CxBuffer *code = dav_compile_expr(
+                        sn->context,
+                        mp->allocator,
+                        field->expr,
+                        args);
+                if(!code) {
+                    // TODO: set error string
+                    return result;
+                }
+                DavCompiledField *cfield = cxMalloc(
+                        mp->allocator,
+                        sizeof(DavCompiledField));
+
+                char *ns;
+                char *name;
+                dav_get_property_namespace_str(
                     sn->context,
-                    mp->allocator,
-                    field->expr,
-                    args);
-            if(!code) {
-                // TODO: set error string
-                return result;
-            }
-            ucx_mempool_reg_destr(mp, code, (ucx_destructor)ucx_buffer_free);
-            DavCompiledField *cfield = ucx_mempool_malloc(
-                    mp,
-                    sizeof(DavCompiledField));
-            
-            char *ns;
-            char *name;
-            dav_get_property_namespace_str(
-                sn->context,
-                sstrdup_a(mp->allocator, field->name).ptr,
-                &ns,
-                &name);
-            if(!ns || !name) {
-                // TODO: set error string
-                return result;
-            }
-            cfield->ns = ns;
-            cfield->name = name;
-            cfield->code = code;
-            cfieldlist = ucx_list_append_a(mp->allocator, cfieldlist, cfield);
-        } 
+                    cx_strdup_a(mp->allocator, field->name).ptr,
+                    &ns,
+                    &name);
+                if(!ns || !name) {
+                    // TODO: set error string
+                    return result;
+                }
+                cfield->ns = ns;
+                cfield->name = name;
+                cfield->code = code;
+                cxListAdd(cfieldlist, cfield);
+            } 
+        }
     }
     
     // get path string
     davqlerror_t error;
-    sstr_t path = dav_format_string(mp->allocator, st->path, args, &error);
+    cxmutstr path = dav_format_string(mp->allocator, st->path, args, &error);
     if(error) {
         // TODO: cleanup
-        ucx_mempool_destroy(mp);
+        cxMempoolDestroy(mp);
         return result;
     }
     
     int depth = st->depth == DAV_DEPTH_PLACEHOLDER ?
             dav_ql_getarg_int(args) : st->depth;
     
-    UcxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, args);
+    CxBuffer *where = dav_compile_expr(sn->context, mp->allocator, st->where, args);
     if(st->where && !where) {
         // TODO: cleanup
-        ucx_mempool_destroy(mp);
+        cxMempoolDestroy(mp);
         return result;
     }
-    if(where) {
-        ucx_mempool_reg_destr(mp, where, (ucx_destructor)ucx_buffer_free);
-    }
     
     // compile order criterion
-    UcxList *ordercr = NULL;
-    UCX_FOREACH(elm, st->orderby) {
-        DavQLOrderCriterion *oc = elm->data;
-        DavQLExpression *column = oc->column;
-        //printf("%.*s %s\n", column->srctext.length, column->srctext.ptr, oc->descending ? "desc" : "asc");
-        if(column->type == DAVQL_IDENTIFIER) {
-            // TODO: remove code duplication (add_cmd)
-            davqlresprop_t resprop;
-            sstr_t propertyname = sstrchr(column->srctext, ':');
-            if(propertyname.length > 0) {
-                char *ns;
-                char *name;
-                dav_get_property_namespace_str(
-                        sn->context,
-                        sstrdup_a(mp->allocator, column->srctext).ptr,
-                        &ns,
-                        &name);
-                if(ns && name) {
-                    DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion));
-                    cr->type = 1;
-                    sstr_t keystr = dav_property_key_a(mp->allocator, ns, name);
-                    cr->column.property = ucx_key(keystr.ptr, keystr.length);
-                    cr->descending = oc->descending;
-                    ordercr = ucx_list_append_a(mp->allocator, ordercr, cr);
+    CxList *ordercr = NULL;
+    if(st->orderby) {
+        ordercr = cxLinkedListCreate(mp->allocator, NULL, sizeof(DavOrderCriterion));
+        CxIterator i = cxListIterator(st->orderby);
+        cx_foreach(DavQLOrderCriterion*, oc, i) {
+            DavQLExpression *column = oc->column;
+            //printf("%.*s %s\n", column->srctext.length, column->srctext.ptr, oc->descending ? "desc" : "asc");
+            if(column->type == DAVQL_IDENTIFIER) {
+                // TODO: remove code duplication (add_cmd)
+                davqlresprop_t resprop;
+                cxstring propertyname = cx_strchr(column->srctext, ':');
+                if(propertyname.length > 0) {
+                    char *ns;
+                    char *name;
+                    dav_get_property_namespace_str(
+                            sn->context,
+                            cx_strdup_a(mp->allocator, column->srctext).ptr,
+                            &ns,
+                            &name);
+                    if(ns && name) {
+                        DavOrderCriterion cr;
+                        cr.type = 1;
+                        cxmutstr keystr = dav_property_key_a(mp->allocator, ns, name);
+                        cr.column.property = cx_hash_key(keystr.ptr, keystr.length);
+                        cr.descending = oc->descending;
+                        cxListAdd(ordercr, &cr);
+                    } else {
+                        // error
+                        // TODO: cleanup
+                        cxMempoolDestroy(mp);
+                        return result;
+                    }
+                } else if(dav_identifier2resprop(column->srctext, &resprop)) {
+                    DavOrderCriterion cr;
+                    cr.type = 0;
+                    cr.column.resprop = resprop;
+                    cr.descending = oc->descending;
+                    cxListAdd(ordercr, &cr);
                 } else {
                     // error
                     // TODO: cleanup
-                    ucx_mempool_destroy(mp);
+                    cxMempoolDestroy(mp);
                     return result;
                 }
-            } else if(dav_identifier2resprop(column->srctext, &resprop)) {
-                DavOrderCriterion *cr = ucx_mempool_malloc(mp, sizeof(DavOrderCriterion));
-                cr->type = 0;
-                cr->column.resprop = resprop;
-                cr->descending = oc->descending;
-                ordercr = ucx_list_append_a(mp->allocator, ordercr, cr);
+
+            } else if(column->type == DAVQL_NUMBER) {
+                // TODO: implement
+                fprintf(stderr, "order by number not supported\n");
+                return result;
             } else {
-                // error
+                // something is broken
                 // TODO: cleanup
-                ucx_mempool_destroy(mp);
+                cxMempoolDestroy(mp);
                 return result;
             }
-            
-        } else if(column->type == DAVQL_NUMBER) {
-            // TODO: implement
-            fprintf(stderr, "order by number not supported\n");
-            return result;
-        } else {
-            // something is broken
-            // TODO: cleanup
-            ucx_mempool_destroy(mp);
-            return result;
         }
     }
     
     DavResource *selroot = dav_resource_new(sn, path.ptr);
     
-    UcxList *stack = NULL; // stack with DavResource* elements
+    CxList *stack = cxLinkedListCreateSimple(sizeof(DavQLRes));
     // initialize the stack with the requested resource
-    DavQLRes *res = ucx_mempool_malloc(mp, sizeof(DavQLRes));
-    res->resource = selroot;
-    res->depth = 0;
-    stack = ucx_list_prepend(stack, res);
+    DavQLRes res;
+    res.resource = selroot;
+    res.depth = 0;
+    cxListInsert(stack, 0, &res);
     
     // reuseable response buffer
-    UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
+    CxBuffer *rpbuf = cxBufferCreate(NULL, 4096, mp->allocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     if(!rpbuf) {
         // TODO: cleanup
-        ucx_mempool_destroy(mp);
+        cxMempoolDestroy(mp);
         return result;
     }
-    ucx_mempool_reg_destr(mp, rpbuf, (ucx_destructor)ucx_buffer_free);
     
     result.result = selroot;
     result.status = 0;
     
     // do a propfind request for each resource on the stack
-    while(stack) {
-        DavQLRes *sr = stack->data; // get first element from the stack
-        stack = ucx_list_remove(stack, stack); // remove first element
+    while(stack->size > 0) {
+        DavQLRes *sr = cxListAt(stack, 0); // get first element from the stack
+        cxListRemove(stack, 0);
+        cxListRemove(stack, 0); // remove first element
         DavResource *root = sr->resource;
         
         util_set_url(sn, dav_resource_get_href(sr->resource));
@@ -672,7 +685,7 @@
                         result.result = NULL;
                         result.status = -1;
                         dav_resource_free_all(selroot);
-                        ucx_list_free(stack);
+                        cxListDestroy(stack);
                         break;
                     }
                 } else {
@@ -691,12 +704,10 @@
                                 if(child->iscollection &&
                                     (depth < 0 || depth > sr->depth+1))
                                 {
-                                    DavQLRes *rs = ucx_mempool_malloc(
-                                            mp,
-                                            sizeof(DavQLRes));
-                                    rs->resource = child;
-                                    rs->depth = sr->depth + 1;
-                                    stack = ucx_list_prepend(stack, rs);
+                                    DavQLRes rs;
+                                    rs.resource = child;
+                                    rs.depth = sr->depth + 1;
+                                    cxListInsert(stack, 0, &rs);
                                 }
                             } else {
                                 dav_resource_free(child);
@@ -717,10 +728,10 @@
         }
         
         // reset response buffer
-        ucx_buffer_seek(rpbuf, SEEK_SET, 0);
+        cxBufferSeek(rpbuf, SEEK_SET, 0);
     }
     
-    ucx_mempool_destroy(mp);
+    cxMempoolDestroy(mp);
     return result;
 }
 
@@ -738,22 +749,22 @@
     return count;
 }
 
-int dav_identifier2resprop(sstr_t src, davqlresprop_t *prop) {
-    if(!sstrcmp(src, S("name"))) {
+int dav_identifier2resprop(cxstring src, davqlresprop_t *prop) {
+    if(!cx_strcmp(src, CX_STR("name"))) {
         *prop = DAVQL_RES_NAME;
-    } else if(!sstrcmp(src, S("path"))) {
+    } else if(!cx_strcmp(src, CX_STR("path"))) {
         *prop = DAVQL_RES_PATH;
-    } else if(!sstrcmp(src, S("href"))) {
+    } else if(!cx_strcmp(src, CX_STR("href"))) {
         *prop = DAVQL_RES_HREF;
-    } else if(!sstrcmp(src, S("contentlength"))) {
+    } else if(!cx_strcmp(src, CX_STR("contentlength"))) {
         *prop = DAVQL_RES_CONTENTLENGTH;
-    } else if(!sstrcmp(src, S("contenttype"))) {
+    } else if(!cx_strcmp(src, CX_STR("contenttype"))) {
         *prop = DAVQL_RES_CONTENTTYPE;
-    } else if(!sstrcmp(src, S("creationdate"))) {
+    } else if(!cx_strcmp(src, CX_STR("creationdate"))) {
         *prop = DAVQL_RES_CREATIONDATE;
-    } else if(!sstrcmp(src, S("lastmodified"))) {
+    } else if(!cx_strcmp(src, CX_STR("lastmodified"))) {
         *prop = DAVQL_RES_LASTMODIFIED;
-    } else if(!sstrcmp(src, S("iscollection"))) {
+    } else if(!cx_strcmp(src, CX_STR("iscollection"))) {
         *prop = DAVQL_RES_ISCOLLECTION;
     } else {
         return 0;
@@ -761,7 +772,7 @@
     return 1;
 }
 
-static int add_cmd(DavContext *ctx, UcxAllocator *a, UcxBuffer *bcode, DavQLExpression *expr, DavQLArgList *ap) {
+static int add_cmd(DavContext *ctx, const CxAllocator *a, CxBuffer *bcode, DavQLExpression *expr, DavQLArgList *ap) {
     if(!expr) {
         return 0;
     }
@@ -771,7 +782,7 @@
     memset(&cmd, 0, sizeof(DavQLCmd));
     davqlerror_t error;
     
-    sstr_t src = expr->srctext;
+    cxstring src = expr->srctext;
     switch(expr->type) {
         default: break;
         case DAVQL_NUMBER: {   
@@ -779,7 +790,7 @@
             if(src.ptr[0] == '%') {
                 cmd.data.integer = dav_ql_getarg_int(ap);
             } else if(util_strtoint(src.ptr, &cmd.data.integer)) {
-                ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
             } else {
                 // error
                 return -1;
@@ -790,14 +801,14 @@
         case DAVQL_STRING: {
             cmd.type = DAVQL_CMD_STRING;
             cmd.data.string = dav_format_string(a, src, ap, &error);
-            ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+            cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
             break;
         }
         case DAVQL_TIMESTAMP: {
             if(src.ptr[0] == '%') {
                 cmd.type = DAVQL_CMD_TIMESTAMP;
                 cmd.data.timestamp = dav_ql_getarg_time(ap);
-                ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
             } else {
                 // error
                 return -1;
@@ -805,7 +816,7 @@
             break;
         }
         case DAVQL_IDENTIFIER: {
-            sstr_t propertyname = sstrchr(src, ':');
+            cxstring propertyname = cx_strchr(src, ':');
             cmd.type = DAVQL_CMD_RES_IDENTIFIER;
             if(propertyname.length > 0) {
                 cmd.type = DAVQL_CMD_PROP_IDENTIFIER;
@@ -813,7 +824,7 @@
                 char *name;
                 dav_get_property_namespace_str(
                         ctx,
-                        sstrdup_a(a, src).ptr,
+                        cx_strdup_a(a, src).ptr,
                         &ns,
                         &name);
                 if(ns && name) {
@@ -824,10 +835,10 @@
                     return -1;
                 }
             } else if(!dav_identifier2resprop(src, &cmd.data.resprop)) {
-                if(!sstrcmp(src, S("true"))) {
+                if(!cx_strcmp(src, CX_STR("true"))) {
                     cmd.type = DAVQL_CMD_INT;
                     cmd.data.integer = 1;
-                } else if(!sstrcmp(src, S("false"))) {
+                } else if(!cx_strcmp(src, CX_STR("false"))) {
                     cmd.type = DAVQL_CMD_INT;
                     cmd.data.integer = 0;
                 } else {
@@ -835,7 +846,7 @@
                     return -1;
                 }
             }
-            ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+            cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
             break;
         }
         case DAVQL_UNARY: {
@@ -848,12 +859,12 @@
                 }
                 case DAVQL_SUB: {
                     cmd.type = DAVQL_CMD_OP_UNARY_SUB;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_NEG: {
                     cmd.type = DAVQL_CMD_OP_UNARY_NEG;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 default: break;
@@ -894,7 +905,7 @@
                 }
                 default: break;
             }
-            ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+            cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
             break;
         }
         case DAVQL_LOGICAL: {
@@ -907,12 +918,12 @@
                 case DAVQL_NOT: {
                     numcmd += add_cmd(ctx, a, bcode, expr->left, ap);
                     cmd.type = DAVQL_CMD_OP_LOGICAL_NOT;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_LAND: {
                     cmd.type = DAVQL_CMD_OP_LOGICAL_AND;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_LOR: {
@@ -920,61 +931,61 @@
                     
                     cmd.type = DAVQL_CMD_OP_LOGICAL_OR_L;
                     DavQLCmd *or_l = (DavQLCmd*)(bcode->space + bcode->pos);
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     
                     int nright = add_cmd(ctx, a, bcode, expr->right, ap);
                     or_l->data.integer = nright + 1;
                     
                     cmd.type = DAVQL_CMD_OP_LOGICAL_OR;
                     cmd.data.integer = 0;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     
                     numcmd += nleft + nright;
                     break;
                 }
                 case DAVQL_LXOR: {
                     cmd.type = DAVQL_CMD_OP_LOGICAL_XOR;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_EQ: {
                     cmd.type = DAVQL_CMD_OP_EQ;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_NEQ: {
                     cmd.type = DAVQL_CMD_OP_NEQ;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_LT: {
                     cmd.type = DAVQL_CMD_OP_LT;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_GT: {
                     cmd.type = DAVQL_CMD_OP_GT;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_LE: {
                     cmd.type = DAVQL_CMD_OP_LE;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_GE: {
                     cmd.type = DAVQL_CMD_OP_GE;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_LIKE: {
                     cmd.type = DAVQL_CMD_OP_LIKE;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 case DAVQL_UNLIKE: {
                     cmd.type = DAVQL_CMD_OP_UNLIKE;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     break;
                 }
                 default: break;
@@ -995,12 +1006,12 @@
                     // numargs
                     cmd.type = DAVQL_CMD_INT;
                     cmd.data.integer = count_func_args(expr);
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     
                     // TODO: resolve function name
                     cmd.type = DAVQL_CMD_CALL;
                     cmd.data.func = NULL;
-                    ucx_buffer_write(&cmd, sizeof(cmd), 1, bcode);
+                    cxBufferWrite(&cmd, sizeof(cmd), 1, bcode);
                     
                     numcmd = 2;
                     numcmd += nright;
@@ -1020,14 +1031,14 @@
     return numcmd;
 }
 
-UcxBuffer* dav_compile_expr(DavContext *ctx, UcxAllocator *a, DavQLExpression *lexpr, DavQLArgList  *ap) {
-    UcxBuffer *bcode = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND);
+CxBuffer* dav_compile_expr(DavContext *ctx, const CxAllocator *a, DavQLExpression *lexpr, DavQLArgList  *ap) {
+    CxBuffer *bcode = cxBufferCreate(NULL, 512, a, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     if(!bcode) {
         return NULL;
     }
     
     if(add_cmd(ctx, a, bcode, lexpr, ap) <= 0) {
-        ucx_buffer_free(bcode);
+        cxBufferFree(bcode);
         return NULL;
     }
     
@@ -1035,53 +1046,56 @@
 }
 
 static int cmd_str_cmp(DavQLStackObj obj1, DavQLStackObj obj2, davqlcmdtype_t cmd) {
-    sstr_t s1 = obj1.type == 1 ?
-        sstrn(obj1.data.string, obj1.length) :
-        ucx_sprintf("%" PRId64, obj1.data.integer);
-    sstr_t s2 = obj1.type == 1 ?
-        sstrn(obj2.data.string, obj2.length) :
-        ucx_sprintf("%" PRId64, obj2.data.integer);
+    cxmutstr s1m = obj1.type == 1 ?
+        cx_mutstrn(obj1.data.string, obj1.length) :
+        cx_asprintf("%" PRId64, obj1.data.integer);
+    cxmutstr s2m = obj1.type == 1 ?
+        cx_mutstrn(obj2.data.string, obj2.length) :
+        cx_asprintf("%" PRId64, obj2.data.integer);
+    
+    cxstring s1 = cx_strcast(s1m);
+    cxstring s2 = cx_strcast(s2m);
     
     int res = 0;
     switch(cmd) {
         case DAVQL_CMD_OP_EQ: {
-            res = sstrcmp(s1, s2) == 0;
+            res = cx_strcmp(s1, s2) == 0;
             break;
         }
         case DAVQL_CMD_OP_NEQ: {
-            res = sstrcmp(s1, s2) != 0;
+            res = cx_strcmp(s1, s2) != 0;
             break;
         }
         case DAVQL_CMD_OP_LT: {
-            res = sstrcmp(s1, s2) < 0;
+            res = cx_strcmp(s1, s2) < 0;
             break;
         }
         case DAVQL_CMD_OP_GT: {
-            res = sstrcmp(s1, s2) > 0;
+            res = cx_strcmp(s1, s2) > 0;
             break;
         }
         case DAVQL_CMD_OP_LE: {
-            res  = sstrcmp(s1, s2) <= 0;
+            res  = cx_strcmp(s1, s2) <= 0;
             break;
         }
         case DAVQL_CMD_OP_GE: {
-            res = sstrcmp(s1, s2) >= 0;
+            res = cx_strcmp(s1, s2) >= 0;
             break;
         }
         default: break;
     }
     
     if(obj1.type == 0) {
-        free(s1.ptr);
+        free(s1m.ptr);
     }
     if(obj2.type == 0) {
-        free(s2.ptr);
+        free(s2m.ptr);
     }
     
     return res;
 }
 
-int dav_exec_expr(UcxBuffer *bcode, DavResource *res, DavQLStackObj *result) {
+int dav_exec_expr(CxBuffer *bcode, DavResource *res, DavQLStackObj *result) {
     if(!bcode) {
         result->type = 0;
         result->length = 0;

mercurial