libidav/resource.c

changeset 747
efbd59642577
parent 736
40be8db6fe45
child 789
378b5ab86f77
--- a/libidav/resource.c	Sun Apr 16 14:12:24 2023 +0200
+++ b/libidav/resource.c	Fri Apr 21 21:25:32 2023 +0200
@@ -36,8 +36,12 @@
 #include "session.h"
 #include "methods.h"
 #include "crypto.h"
-#include "ucx/buffer.h"
-#include "ucx/utils.h"
+#include <cx/buffer.h>
+#include <cx/utils.h>
+#include <cx/hash_map.h>
+#include <cx/printf.h>
+#include <cx/basic_mempool.h>
+#include <cx/array_list.h>
 
 #include "resource.h"
 #include "xml.h"
@@ -45,11 +49,11 @@
 
 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
 
-DavResource* dav_resource_new(DavSession *sn, char *path) {
+DavResource* dav_resource_new(DavSession *sn, const char *path) {
     //char *href = util_url_path(url);
     //DavResource *res = dav_resource_new_href(sn, href);
     char *parent = util_parent_path(path);
-    char *name = util_resource_name(path); 
+    const char *name = util_resource_name(path); 
     char *href = dav_session_create_plain_href(sn, path);
     
     DavResource *res = dav_resource_new_full(sn, parent, name, href);
@@ -57,7 +61,7 @@
     return res;
 }
 
-DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, char *name) {
+DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name) {
     char *path = util_concat_path(parent->path, name);
     char *href = dav_session_create_plain_href(sn, path);
     DavResource *res = dav_resource_new_full(sn, parent->path, name, href);
@@ -66,8 +70,8 @@
 }
 
 
-DavResource* dav_resource_new_href(DavSession *sn, char *href) {  
-    DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource));
+DavResource* dav_resource_new_href(DavSession *sn, const char *href) {  
+    DavResource *res = cxCalloc(sn->mp->allocator, 1, sizeof(DavResource));
     res->session = sn;
     
     // set name, path and href
@@ -79,14 +83,14 @@
     return res;
 }
 
-DavResource* dav_resource_new_full(DavSession *sn, char *parent_path, char *name, char *href) {
-    sstr_t n = sstr(name);
+DavResource* dav_resource_new_full(DavSession *sn, const char *parent_path, const char *name, char *href) {
+    cxstring n = cx_str(name);
     // the name must not contain path separators
     if(n.length > 0 && href) {
         for(int i=0;i<n.length-1;i++) {
             char c = n.ptr[i];
             if(c == '/' || c == '\\') {
-                n = sstr(util_resource_name(href));
+                n = cx_str(util_resource_name(href));
                 break;
             }
         }
@@ -96,11 +100,11 @@
         n.length--;
     }
     
-    DavResource *res = ucx_mempool_calloc(sn->mp, 1, sizeof(DavResource));
+    DavResource *res = cxCalloc(sn->mp->allocator, 1, sizeof(DavResource));
     res->session = sn;
     
     // set name, path and href
-    res->name = sstrdup_a(sn->mp->allocator, n).ptr;
+    res->name = cx_strdup_a(sn->mp->allocator, n).ptr;
     
     char *path = util_concat_path(parent_path, name); 
     res->path = dav_session_strdup(sn, path);
@@ -112,23 +116,23 @@
     
     // cache href/path
     if(href) {
-        dav_session_cache_path(sn, sstr(path), sstr(href));
+        dav_session_cache_path(sn, cx_str(path), cx_str(href));
     }
     free(path);
     
     return res;
 }
 
-void resource_free_properties(DavSession *sn, UcxMap *properties) {
+void resource_free_properties(DavSession *sn, CxMap *properties) {
     if(!properties) return;
     
-    UcxMapIterator i = ucx_map_iterator(properties);
+    CxIterator i = cxMapIteratorValues(properties);
     DavProperty *property;
-    UCX_MAP_FOREACH(key, property, i) {
+    cx_foreach(DavProperty*, property, i) {
         // TODO: free everything
         dav_session_free(sn, property);
     }
-    ucx_map_free(properties);
+    cxMapDestroy(properties);
 }
 
 void dav_resource_free(DavResource *res) {
@@ -144,29 +148,62 @@
     resource_free_properties(sn, data->properties);
     resource_free_properties(sn, data->crypto_properties);
     
-    UCX_FOREACH(elm, data->set) {
-        DavProperty *p = elm->data;
-        dav_session_free(sn, p->ns->name);
-        if(p->ns->prefix) {
-            dav_session_free(sn, p->ns->prefix);
+    if(data->set) {
+        CxIterator i = cxListIterator(data->set);
+        cx_foreach(DavProperty *, p, i) {
+            dav_session_free(sn, p->ns->name);
+            if(p->ns->prefix) {
+                dav_session_free(sn, p->ns->prefix);
+            }
+            dav_session_free(sn, p->ns);
+
+            dav_session_free(sn, p->name);
+            dav_free_xml_node_sn(sn, p->value);
+            dav_session_free(sn, p);
         }
-        dav_session_free(sn, p->ns);
-        
-        dav_session_free(sn, p->name);
-        dav_free_xml_node_sn(sn, p->value);
-        dav_session_free(sn, p);
     }
     
-    UCX_FOREACH(elm, data->remove) {
-        DavProperty *p = elm->data;
-        dav_session_free(sn, p->ns->name);
-        if(p->ns->prefix) {
-            dav_session_free(sn, p->ns->prefix);
+    if(data->remove) {
+        CxIterator i = cxListIterator(data->remove);
+        cx_foreach(DavProperty *, p, i) {
+            dav_session_free(sn, p->ns->name);
+            if(p->ns->prefix) {
+                dav_session_free(sn, p->ns->prefix);
+            }
+            dav_session_free(sn, p->ns);
+
+            dav_session_free(sn, p->name);
+            dav_session_free(sn, p);
         }
-        dav_session_free(sn, p->ns);
-        
-        dav_session_free(sn, p->name);
-        dav_session_free(sn, p);
+    }
+    
+    if(data->crypto_set) {
+        CxIterator i = cxListIterator(data->crypto_set);
+        cx_foreach(DavProperty *, p, i) {
+            dav_session_free(sn, p->ns->name);
+            if(p->ns->prefix) {
+                dav_session_free(sn, p->ns->prefix);
+            }
+            dav_session_free(sn, p->ns);
+
+            dav_session_free(sn, p->name);
+            dav_free_xml_node_sn(sn, p->value);
+            dav_session_free(sn, p);
+        }
+    }
+    
+    if(data->crypto_remove) {
+        CxIterator i = cxListIterator(data->crypto_remove);
+        cx_foreach(DavProperty *, p, i) {
+            dav_session_free(sn, p->ns->name);
+            if(p->ns->prefix) {
+                dav_session_free(sn, p->ns->prefix);
+            }
+            dav_session_free(sn, p->ns);
+
+            dav_session_free(sn, p->name);
+            dav_session_free(sn, p);
+        }
     }
     
     if(!data->read && data->content) {
@@ -187,20 +224,20 @@
     }
 }
 
-void resource_set_href(DavResource *res, sstr_t href) {
-    res->href = sstrdup_a(res->session->mp->allocator, href).ptr;
+void resource_set_href(DavResource *res, cxstring href) {
+    res->href = cx_strdup_a(res->session->mp->allocator, href).ptr;
 }
 
-void resource_set_info(DavResource *res, char *href_str) {
+void resource_set_info(DavResource *res, const char *href_str) {
     char *url_str = NULL;
     curl_easy_getinfo(res->session->handle, CURLINFO_EFFECTIVE_URL, &url_str);
-    sstr_t name = sstr(util_resource_name(href_str));
-    sstr_t href = sstr(href_str);
+    cxstring name = cx_str(util_resource_name(href_str));
+    cxstring href = cx_str(href_str);
     
-    sstr_t base_href = sstr(util_url_path(res->session->base_url));
-    sstr_t path = sstrsubs(href, base_href.length - 1);
+    cxstring base_href = cx_str(util_url_path(res->session->base_url));
+    cxstring path = cx_strsubs(href, base_href.length - 1);
     
-    UcxAllocator *a = res->session->mp->allocator;
+    const CxAllocator *a = res->session->mp->allocator;
     CURL *handle = res->session->handle;
     
     int nlen = 0;
@@ -208,22 +245,22 @@
     int plen = 0;
     char *upath = curl_easy_unescape(handle, path.ptr, path.length, &plen); 
     
-    res->name = sstrdup_a(a, sstrn(uname, nlen)).ptr;
-    res->href = sstrdup_a(a, href).ptr;
-    res->path = sstrdup_a(a, sstrn(upath, plen)).ptr;
+    res->name = cx_strdup_a(a, cx_strn(uname, nlen)).ptr;
+    res->href = cx_strdup_a(a, href).ptr;
+    res->path = cx_strdup_a(a, cx_strn(upath, plen)).ptr;
     
     curl_free(uname);
     curl_free(upath);
 }
 
 DavResourceData* resource_data_new(DavSession *sn) {
-    DavResourceData *data = ucx_mempool_malloc(
-            sn->mp,
+    DavResourceData *data = cxMalloc(
+            sn->mp->allocator,
             sizeof(DavResourceData));
     if(!data) {
         return NULL;
     }
-    data->properties = ucx_map_new_a(sn->mp->allocator, 32);
+    data->properties = cxHashMapCreate(sn->mp->allocator, CX_STORE_POINTERS, 32);
     data->crypto_properties = NULL;
     data->set = NULL;
     data->remove = NULL;
@@ -257,9 +294,10 @@
     prop->ns = namespace;
     prop->value = val;
     
-    sstr_t key = dav_property_key(ns, name);
-    ucx_map_sstr_put(((DavResourceData*)res->data)->properties, key, prop);
-    free(key.ptr);
+    cxmutstr keystr = dav_property_key(ns, name);
+    CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
+    cxMapPut(((DavResourceData*)res->data)->properties, key, prop);
+    free(keystr.ptr);
 }
 
 void resource_add_property(DavResource *res, const char *ns, const char *name, xmlNode *val) {
@@ -278,15 +316,15 @@
     resource_add_prop(res, ns, name, dav_text_node(res->session, val));
 }
 
-void resource_set_crypto_properties(DavResource *res, UcxMap *cprops) {
+void resource_set_crypto_properties(DavResource *res, CxMap *cprops) {
     DavResourceData *data = res->data;
     resource_free_properties(res->session, data->crypto_properties);
     data->crypto_properties = cprops;
 }
 
 DavXmlNode* resource_get_property(DavResource *res, const char *ns, const char *name) {
-    sstr_t keystr = dav_property_key(ns, name);
-    UcxKey key = ucx_key(keystr.ptr, keystr.length);
+    cxmutstr keystr = dav_property_key(ns, name);
+    CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
     DavXmlNode *ret = resource_get_property_k(res, key);
     free(keystr.ptr);
     
@@ -294,37 +332,37 @@
 }
 
 DavXmlNode* resource_get_encrypted_property(DavResource *res, const char *ns, const char *name) {
-    sstr_t keystr = dav_property_key(ns, name);
-    UcxKey key = ucx_key(keystr.ptr, keystr.length);
+    cxmutstr keystr = dav_property_key(ns, name);
+    CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
     DavXmlNode *ret = resource_get_encrypted_property_k(res, key);
     free(keystr.ptr);
     
     return ret;
 }
 
-DavXmlNode* resource_get_property_k(DavResource *res, UcxKey key) {
+DavXmlNode* resource_get_property_k(DavResource *res, CxHashKey key) {
     DavResourceData *data = (DavResourceData*)res->data;
-    DavProperty *property = ucx_map_get(data->properties, key);
+    DavProperty *property = cxMapGet(data->properties, key);
     
     return property ? property->value : NULL;
 }
 
-DavXmlNode* resource_get_encrypted_property_k(DavResource *res, UcxKey key) {
+DavXmlNode* resource_get_encrypted_property_k(DavResource *res, CxHashKey key) {
     DavResourceData *data = (DavResourceData*)res->data;
-    DavProperty *property = ucx_map_get(data->crypto_properties, key);
+    DavProperty *property = cxMapGet(data->crypto_properties, key);
     
     return property ? property->value : NULL;
 }
 
-sstr_t dav_property_key(const char *ns, const char *name) {
-    return dav_property_key_a(ucx_default_allocator(), ns, name);
+cxmutstr dav_property_key(const char *ns, const char *name) {
+    return dav_property_key_a(cxDefaultAllocator, ns, name);
 }
 
-sstr_t dav_property_key_a(UcxAllocator *a, const char *ns, const char *name) {
-    scstr_t ns_str = scstr(ns);
-    scstr_t name_str = scstr(name);
+cxmutstr dav_property_key_a(const CxAllocator *a, const char *ns, const char *name) {
+    cxstring ns_str = cx_str(ns);
+    cxstring name_str = cx_str(name);
     
-    return sstrcat_a(a, 4, ns_str, S("\0"), name_str, S("\0"));
+    return cx_strcat_a(a, 4, ns_str, CX_STR("\0"), name_str, CX_STR("\0"));
 }
 
 
@@ -411,7 +449,7 @@
     return cr->descending ? -ret : ret;
 }
 
-void resource_add_ordered_child(DavResource *parent, DavResource *child, UcxList *ordercr) {
+void resource_add_ordered_child(DavResource *parent, DavResource *child, CxList *ordercr) {
     if(!ordercr) {
         resource_add_child(parent, child);
         return;
@@ -427,8 +465,8 @@
         DavResource *resource = parent->children;
         while(resource) {
             int r = 0;
-            UCX_FOREACH(elm, ordercr) {
-                DavOrderCriterion *cr = elm->data;
+            CxIterator i = cxListIterator(ordercr);
+            cx_foreach(DavOrderCriterion*, cr, i) {
                 r = resource_cmp(child, resource, cr);
                 if(r != 0) {
                     break;
@@ -495,8 +533,8 @@
     DavResourceData *data = res->data;
     
     DavXmlNode *property = NULL;
-    UcxList *remove_list = NULL;
-    UcxList *set_list = NULL;
+    CxList *remove_list = NULL;
+    CxList *set_list = NULL;
     
     if(encrypted) {
         // check if crypto_properties because it will only be created
@@ -515,23 +553,27 @@
     
     // resource_get_property only returns persistent properties
     // check the remove and set list
-    if(property) {
+    if(property && remove_list) {
         // if the property is in the remove list, we return NULL
-        UCX_FOREACH(elm, remove_list) {
-            DavProperty *p = elm->data;
+        CxIterator i = cxListIterator(remove_list);
+        cx_foreach(DavProperty*, p, i) {
             if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) {
                 return NULL;
             }
         }
     }
+    
     // the set list contains property updates
     // we return an updated property if possible
-    UCX_FOREACH(elm, set_list) {
-        DavProperty *p = elm->data;
-        if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) {
-            return p->value; // TODO: fix
+    if(set_list) {
+        CxIterator i = cxListIterator(set_list);
+        cx_foreach(DavProperty*, p, i) {
+            if(!strcmp(p->name, name) && !strcmp(p->ns->name, ns)) {
+                return p->value; // TODO: fix
+            }
         }
     }
+    
     // no property update
     
     return property;
@@ -572,18 +614,30 @@
     dav_set_string_property_ns(res, pns, pname, value);
 }
 
+static int add2propertylist(const CxAllocator *a, CxList **list, DavProperty *property) {
+    if(!*list) {
+        CxList *newlist = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS);
+        if(!newlist) {
+            return 1;
+        }
+        *list = newlist;
+    }
+    cxListAdd(*list, property);
+    return 0;
+}
+
 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value) {
     DavSession *sn = res->session;
-    UcxAllocator *a = res->session->mp->allocator;
+    const CxAllocator *a = res->session->mp->allocator;
     DavResourceData *data = res->data;
     
     DavProperty *property = createprop(res->session, ns, name);
     property->value = dav_text_node(res->session, value);
     
     if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) {
-        data->crypto_set = ucx_list_append_a(a, data->crypto_set, property);
+        add2propertylist(a, &data->crypto_set, property);
     } else {
-        data->set = ucx_list_append_a(a, data->set, property);
+        add2propertylist(a, &data->set, property);
     }
 }
 
@@ -596,7 +650,7 @@
 
 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) {
     DavSession *sn = res->session;
-    UcxAllocator *a = sn->mp->allocator; 
+    const CxAllocator *a = sn->mp->allocator; 
     DavResourceData *data = res->data;
     
     DavProperty *property = createprop(sn, ns, name);
@@ -605,9 +659,9 @@
     property->value = value;
     
     if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) {
-        data->crypto_set = ucx_list_append_a(a, data->crypto_set, property);
+        add2propertylist(a, &data->crypto_set, property);
     } else {
-        data->set = ucx_list_append_a(a, data->set, property);
+        add2propertylist(a, &data->set, property);
     }
 }
 
@@ -621,44 +675,44 @@
 void dav_remove_property_ns(DavResource *res, char *ns, char *name) {
     DavSession *sn = res->session;
     DavResourceData *data = res->data;
-    UcxAllocator *a = res->session->mp->allocator;
+    const CxAllocator *a = res->session->mp->allocator;
     
     DavProperty *property = createprop(res->session, ns, name);
     
     if(DAV_ENCRYPT_PROPERTIES(sn) && dav_namespace_is_encrypted(sn->context, ns)) {
-        data->crypto_remove = ucx_list_append_a(a, data->crypto_remove, property);
+        add2propertylist(a, &data->crypto_remove, property);
     } else {
-        data->remove = ucx_list_append_a(a, data->remove, property);
+        add2propertylist(a, &data->remove, property);
     }
 }
 
 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value) {
-    UcxAllocator *a = res->session->mp->allocator;
+    const CxAllocator *a = res->session->mp->allocator;
     DavResourceData *data = res->data;
     
     DavProperty *property = createprop(res->session, ns, name);
     property->value = value; // TODO: copy node?
     
-    data->crypto_set = ucx_list_append_a(a, data->crypto_set, property);
+    add2propertylist(a, &data->crypto_set, property);
 }
 
 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value) {
-    UcxAllocator *a = res->session->mp->allocator;
+    const CxAllocator *a = res->session->mp->allocator;
     DavResourceData *data = res->data;
     
     DavProperty *property = createprop(res->session, ns, name);
     property->value = dav_text_node(res->session, value);
     
-    data->crypto_set = ucx_list_append_a(a, data->crypto_set, property);
+    add2propertylist(a, &data->crypto_set, property);
 }
 
 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name) {
     DavResourceData *data = res->data;
-    UcxAllocator *a = res->session->mp->allocator;
+    const CxAllocator *a = res->session->mp->allocator;
     
     DavProperty *property = createprop(res->session, ns, name);
     
-    data->crypto_remove = ucx_list_append_a(a, data->crypto_remove, property);
+    add2propertylist(a, &data->crypto_remove, property);
 }
 
 static int compare_propname(const void *a, const void *b) {
@@ -676,17 +730,17 @@
 DavPropName* dav_get_property_names(DavResource *res, size_t *count) {
     DavResourceData *data = res->data;
     
-    *count = data->properties->count;
+    *count = data->properties->size;
     DavPropName *names = dav_session_calloc(
             res->session,
             *count,
             sizeof(DavPropName));
     
     
-    UcxMapIterator i = ucx_map_iterator(data->properties);
+    CxIterator i = cxMapIteratorValues(data->properties);
     DavProperty *value;
     int j = 0;
-    UCX_MAP_FOREACH(key, value, i) {
+    cx_foreach(DavProperty*, value, i) {
         DavPropName *name = &names[j];
         
         name->ns = value->ns->name;
@@ -726,34 +780,35 @@
 
 
 int dav_load(DavResource *res) {
-    UcxBuffer *rqbuf = create_allprop_propfind_request();
+    CxBuffer *rqbuf = create_allprop_propfind_request();
     int ret = dav_propfind(res->session, res, rqbuf);
-    ucx_buffer_free(rqbuf);
+    cxBufferFree(rqbuf);
     return ret;
 }
 
 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop) {
-    UcxMempool *mp = ucx_mempool_new(64);
+    CxMempool *mp = cxBasicMempoolCreate(64);
+    const CxAllocator *a = mp->allocator;
     
-    UcxList *proplist = NULL;
+    CxList *proplist = cxArrayListCreate(a, NULL, sizeof(DavProperty), numprop);
     for(size_t i=0;i<numprop;i++) {
-        DavProperty *p = ucx_mempool_malloc(mp, sizeof(DavProperty));
-        p->name = properties[i].name;
-        p->ns = ucx_mempool_malloc(mp, sizeof(DavNamespace));
-        p->ns->name = properties[i].ns;
+        DavProperty p;
+        p.name = properties[i].name;
+        p.ns = cxMalloc(a, sizeof(DavNamespace));
+        p.ns->name = properties[i].ns;
         if(!strcmp(properties[i].ns, "DAV:")) {
-            p->ns->prefix = "D";
+            p.ns->prefix = "D";
         } else {
-            p->ns->prefix = ucx_asprintf(mp->allocator, "x%d", i).ptr;
+            p.ns->prefix = cx_asprintf_a(a, "x%d", (int)i).ptr;
         }
-        p->value = NULL;
-        proplist = ucx_list_append_a(mp->allocator, proplist, p);
+        p.value = NULL;
+        cxListAdd(proplist, &p);
     }
     
-    UcxBuffer *rqbuf = create_propfind_request(res->session, proplist, "propfind", 0);
+    CxBuffer *rqbuf = create_propfind_request(res->session, proplist, "propfind", 0);
     int ret = dav_propfind(res->session, res, rqbuf);
-    ucx_buffer_free(rqbuf);
-    ucx_mempool_destroy(mp);
+    cxBufferFree(rqbuf);
+    cxMempoolDestroy(mp);
     return ret;
 }
 
@@ -805,7 +860,7 @@
         CURLcode ret;
         if(encryption) {
             AESEncrypter *enc = NULL;
-            UcxBuffer *buf = NULL;
+            CxBuffer *buf = NULL;
             if(data->read) {
                 enc = aes_encrypter_new(
                         sn->key,
@@ -813,13 +868,13 @@
                         data->read,
                         data->seek);
             } else {
-                buf = ucx_buffer_new(data->content, data->length, 0);
+                buf = cxBufferCreate(data->content, data->length, cxDefaultAllocator, 0);
                 buf->size = data->length;
                 enc = aes_encrypter_new(
                         sn->key,
                         buf,
-                        (dav_read_func)ucx_buffer_read,
-                        (dav_seek_func)dav_buffer_seek);
+                        (dav_read_func)cxBufferRead,
+                        (dav_seek_func)cxBufferSeek);
             }
               
             // put resource
@@ -838,7 +893,7 @@
             
             aes_encrypter_close(enc);
             if(buf) {
-                ucx_buffer_free(buf);
+                cxBufferFree(buf);
             }
             
             // add crypto properties
@@ -851,15 +906,15 @@
             free(enc_hash);
         } else if((sn->flags & DAV_SESSION_STORE_HASH) == DAV_SESSION_STORE_HASH) {
             HashStream hstr;
-            UcxBuffer *iobuf = NULL;
+            CxBuffer *iobuf = NULL;
             if(!data->read) {
-                iobuf = ucx_buffer_new(data->content, data->length, 0);
+                iobuf = cxBufferCreate(data->content, data->length, cxDefaultAllocator, 0);
                 iobuf->size = data->length;
                 init_hash_stream(
                         &hstr,
                         iobuf,
-                        (dav_read_func)ucx_buffer_read,
-                        (dav_seek_func)ucx_buffer_seek);
+                        (dav_read_func)cxBufferRead,
+                        (dav_seek_func)cxBufferSeek);
             } else {
                 init_hash_stream(
                         &hstr,
@@ -900,7 +955,7 @@
             res->session->error = 0;
             // cleanup node data
             if(!data->read) {
-                ucx_mempool_free(sn->mp, data->content);
+                cxFree(sn->mp->allocator, data->content);
             }
             data->content = NULL;
             data->read = NULL;
@@ -917,51 +972,56 @@
         int ret = 1;
         
         if(crypto_res) {
-            UcxBuffer *rqbuf = create_cryptoprop_propfind_request();
+            CxBuffer *rqbuf = create_cryptoprop_propfind_request();
             ret = dav_propfind(res->session, res, rqbuf);
-            ucx_buffer_free(rqbuf);
+            cxBufferFree(rqbuf);
         }
         
         if(!ret) {
             DavXmlNode *crypto_prop_node = dav_get_property_ns(crypto_res, DAV_NS, "crypto-prop");
-            UcxMap *crypto_props = parse_crypto_prop(sn, sn->key, crypto_prop_node);
+            CxMap *crypto_props = parse_crypto_prop(sn, sn->key, crypto_prop_node);
             if(!crypto_props) {
                 // resource hasn't encrypted properties yet
-                crypto_props = ucx_map_new(32); // create new map
+                crypto_props = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32); // create new map
             }
             
             // remove all properties
-            UCX_FOREACH(elm, data->crypto_remove) {
-                if(crypto_props->count == 0) {
-                    break; // map already empty, can't remove any more
+            if(data->crypto_remove) {
+                CxIterator i = cxListIterator(data->crypto_remove);
+                cx_foreach(DavProperty *, property, i) {
+                    if(crypto_props->size == 0) {
+                        break; // map already empty, can't remove any more
+                    }
+
+                    cxmutstr key = dav_property_key(property->ns->name, property->name);
+                    DavProperty *existing_prop = cxMapGet(crypto_props, cx_hash_key(key.ptr, key.length));
+                    if(existing_prop) {
+                        // TODO: free existing_prop
+                    }                
+                    free(key.ptr);
                 }
-                
-                DavProperty *property = elm->data;
-                sstr_t key = dav_property_key(property->ns->name, property->name);
-                DavProperty *existing_prop = ucx_map_sstr_remove(crypto_props, key);
-                if(existing_prop) {
-                    // TODO: free existing_prop
-                }                
-                free(key.ptr);
             }
             
             // set properties
-            UCX_FOREACH(elm, data->crypto_set) {
-                DavProperty *property = elm->data;
-                sstr_t key = dav_property_key(property->ns->name, property->name);
-                DavProperty *existing_prop = ucx_map_sstr_remove(crypto_props, key);
-                ucx_map_sstr_put(crypto_props, key, property);
-                if(existing_prop) {
-                    // TODO: free existing_prop
-                }  
-                free(key.ptr);
+            if(data->crypto_set) {
+                CxIterator i = cxListIterator(data->crypto_set);
+                cx_foreach(DavProperty *, property, i) {
+                    cxmutstr keystr = dav_property_key(property->ns->name, property->name);
+                    CxHashKey key = cx_hash_key(keystr.ptr, keystr.length);
+                    DavProperty *existing_prop = cxMapRemoveAndGet(crypto_props, key);
+                    cxMapPut(crypto_props, key, property);
+                    if(existing_prop) {
+                        // TODO: free existing_prop
+                    }  
+                    free(keystr.ptr);
+                }
             }
             
             DavXmlNode *crypto_prop_value = create_crypto_prop(sn, crypto_props);
             if(crypto_prop_value) {
                 DavProperty *new_crypto_prop = createprop(sn, DAV_NS, "crypto-prop");
                 new_crypto_prop->value = crypto_prop_value;
-                data->set = ucx_list_prepend_a(sn->mp->allocator, data->set, new_crypto_prop);
+                add2propertylist(sn->mp->allocator, &data->set, new_crypto_prop);
             }
             
             dav_resource_free(crypto_res);
@@ -976,8 +1036,8 @@
     int r = 0;
     sn->error = DAV_OK;
     if(data->set || data->remove) {
-        UcxBuffer *request = create_proppatch_request(data);
-        UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
+        CxBuffer *request = create_proppatch_request(data);
+        CxBuffer *response = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
         //printf("request:\n%.*s\n\n", request->pos, request->space);
 
         CURLcode ret = do_proppatch_request(sn, locktoken, request, response);
@@ -994,8 +1054,8 @@
             r = -1;
         }
         
-        ucx_buffer_free(request);
-        ucx_buffer_free(response);
+        cxBufferFree(request);
+        cxBufferFree(response);
     }
      
     return r;
@@ -1129,7 +1189,7 @@
     DavLock *lock = dav_get_lock(res->session, res->path);
     char *locktoken = lock ? lock->token : NULL;
     
-    UcxBuffer *response = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND);
+    CxBuffer *response = cxBufferCreate(NULL, 4096, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     CURLcode ret = do_delete_request(res->session, locktoken, response);
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
@@ -1145,7 +1205,7 @@
         r = 1;
     }
     
-    ucx_buffer_free(response);
+    cxBufferFree(response);
     return r;
 }
 
@@ -1172,7 +1232,7 @@
         curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &status);
         if(status == 201) {
             // resource successfully created
-            char *name = util_resource_name(p);
+            char *name = (char*)util_resource_name(p);
             int len = strlen(name);
             if(name[len - 1] == '/') {
                 name[len - 1] = '\0';
@@ -1225,9 +1285,9 @@
         // if the session has encrypted file names, add crypto infos
         if(!resource_add_crypto_info(sn, res->href, res->name, NULL)) {
             // do a minimal propfind request
-            UcxBuffer *rqbuf = create_propfind_request(sn, NULL, "propfind", 0);
+            CxBuffer *rqbuf = create_propfind_request(sn, NULL, "propfind", 0);
             int ret = dav_propfind(sn, res, rqbuf);
-            ucx_buffer_free(rqbuf);
+            cxBufferFree(rqbuf);
             return ret;
         } else {
             return 1;
@@ -1331,26 +1391,26 @@
     CURL *handle = sn->handle;
     util_set_url(sn, dav_resource_get_href(res));
     
-    UcxBuffer *request = create_lock_request();
-    UcxBuffer *response = ucx_buffer_new(NULL, 512, UCX_BUFFER_AUTOEXTEND);
+    CxBuffer *request = create_lock_request();
+    CxBuffer *response = cxBufferCreate(NULL, 512, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     CURLcode ret = do_lock_request(sn, request, response, timeout);
     
     //printf("\nlock\n");
     //printf("%.*s\n\n", request->size, request->space);
     //printf("%.*s\n\n", response->size, response->space);
     
-    ucx_buffer_free(request);
+    cxBufferFree(request);
     
     long status = 0;
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && (status >= 200 && status < 300)) {
         LockDiscovery lock;
-        if(parse_lock_response(sn, response, &lock)) {
+        int parse_error = parse_lock_response(sn, response, &lock);
+        cxBufferFree(response);
+        if(parse_error) {
             sn->error = DAV_ERROR;
-            ucx_buffer_free(response);
             return -1;
         }
-        ucx_buffer_free(response);
         
         DavLock *l = dav_create_lock(sn, lock.locktoken, lock.timeout);
         free(lock.locktoken);
@@ -1373,7 +1433,7 @@
         }
     } else {
         dav_session_set_error(sn, ret, status);
-        ucx_buffer_free(response);
+        cxBufferFree(response);
         return -1;
     }
 }
@@ -1408,46 +1468,47 @@
         return 0;
     }
     
-    UcxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash);
-    UcxBuffer *response = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
+    CxBuffer *request = create_crypto_proppatch_request(sn, sn->key, name, hash);
+    CxBuffer *response = cxBufferCreate(NULL, 1024, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     
     util_set_url(sn, href);
     // TODO: lock
     CURLcode ret = do_proppatch_request(sn, NULL, request, response);
-    ucx_buffer_free(request);
+    cxBufferFree(request);
     long status = 0;
     curl_easy_getinfo (sn->handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && status == 207) {
         // TODO: parse response
         sn->error = DAV_OK;   
-        ucx_buffer_free(response);
+        cxBufferFree(response);
         return 0;
     } else {
         dav_session_set_error(sn, ret, status);
-        ucx_buffer_free(response);
+        cxBufferFree(response);
         return 1;
     }
 }
 
 /* ----------------------------- crypto-prop  ----------------------------- */
 
-DavXmlNode* create_crypto_prop(DavSession *sn, UcxMap *properties) {
+DavXmlNode* create_crypto_prop(DavSession *sn, CxMap *properties) {
     if(!sn->key) {
         return NULL;
     }
     
-    UcxBuffer *content = ucx_buffer_new(NULL, 2048, UCX_BUFFER_AUTOEXTEND);
+    CxBuffer *content = cxBufferCreate(NULL, 2048, cxDefaultAllocator, CX_BUFFER_FREE_CONTENTS|CX_BUFFER_AUTO_EXTEND);
     
     // create an xml document containing all properties
-    UcxMap *nsmap = ucx_map_new(8);
-    ucx_map_cstr_put(nsmap, "DAV:", strdup("D"));
+    CxMap *nsmap = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 8);
+    nsmap->simple_destructor = free;
+    cxMapPut(nsmap, cx_hash_key_str("DAV:"), strdup("D"));
     
-    ucx_buffer_puts(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-    ucx_buffer_puts(content, "<D:prop xmlns:D=\"DAV:\">\n");
+    cxBufferPutString(content, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+    cxBufferPutString(content, "<D:prop xmlns:D=\"DAV:\">\n");
     
-    UcxMapIterator i = ucx_map_iterator(properties);
+    CxIterator i = cxMapIteratorValues(properties);
     DavProperty *prop;
-    UCX_MAP_FOREACH(key, prop, i) {
+    cx_foreach(DavProperty*, prop, i) {
         DavXmlNode pnode;
         pnode.type = DAV_XML_ELEMENT;
         pnode.namespace = prop->ns->name;
@@ -1460,18 +1521,17 @@
         pnode.content = NULL;
         pnode.contentlength = 0;
         
-        dav_print_node(content, (write_func)ucx_buffer_write, nsmap, &pnode);
-        ucx_buffer_putc(content, '\n');
+        dav_print_node(content, (cx_write_func)cxBufferWrite, nsmap, &pnode);
+        cxBufferPut(content, '\n');
     }
     
-    ucx_buffer_puts(content, "</D:prop>");
+    cxBufferPutString(content, "</D:prop>");
     
-    ucx_map_free_content(nsmap, (ucx_destructor)free);
-    ucx_map_free(nsmap);
+    cxMapDestroy(nsmap);
     
     // encrypt xml document
     char *crypto_prop_content = aes_encrypt(content->space, content->size, sn->key);
-    ucx_buffer_free(content);
+    cxBufferDestroy(content);
     
     DavXmlNode *ret = NULL;
     if(crypto_prop_content) {
@@ -1481,7 +1541,7 @@
     return ret;
 }
 
-UcxMap* parse_crypto_prop(DavSession *sn, DavKey *key, DavXmlNode *node) {
+CxMap* parse_crypto_prop(DavSession *sn, DavKey *key, DavXmlNode *node) {
     if(!node || node->type != DAV_XML_TEXT || node->contentlength == 0) {
         return NULL;
     }
@@ -1489,7 +1549,7 @@
     return parse_crypto_prop_str(sn, key, node->content);
 }
 
-UcxMap* parse_crypto_prop_str(DavSession *sn, DavKey *key, const char *content) {
+CxMap* parse_crypto_prop_str(DavSession *sn, DavKey *key, const char *content) {
     size_t len = 0;
     char *dec_str = aes_decrypt(content, &len, key);
     
@@ -1519,7 +1579,7 @@
     }
     
     // ready to get the properties
-    UcxMap *map = ucx_map_new(32);
+    CxMap *map = cxHashMapCreate(cxDefaultAllocator, CX_STORE_POINTERS, 32);
     xmlNode *n = xml_root->children;
     while(n) {
         if(n->type == XML_ELEMENT_NODE && n->ns && n->ns->href) {
@@ -1531,16 +1591,16 @@
                     dav_session_strdup(sn, (const char*)n->ns->prefix) : NULL;
             property->value = n->children ? dav_convert_xml(sn, n->children) : NULL;
             
-            sstr_t key = dav_property_key(property->ns->name, property->name);
-            ucx_map_sstr_put(map, key, property);
+            cxmutstr key = dav_property_key(property->ns->name, property->name);
+            cxMapPut(map, cx_hash_key(key.ptr, key.length), property);
             free(key.ptr);
         }
         n = n->next;
     }
     
     xmlFreeDoc(doc);
-    if(map->count == 0) {
-        ucx_map_free(map);
+    if(map->size == 0) {
+        cxMapDestroy(map);
         return NULL;
     }
     return map;

mercurial