libidav/session.c

changeset 208
1fb26aca5093
parent 207
de23f8881e9f
child 222
7b73058d782e
--- a/libidav/session.c	Mon Mar 14 11:54:55 2016 +0100
+++ b/libidav/session.c	Mon Mar 14 17:18:33 2016 +0100
@@ -65,6 +65,12 @@
     }
     sn->handle = curl_easy_init();
     curl_easy_setopt(sn->handle, CURLOPT_FOLLOWLOCATION, 1L);
+    
+    // create lock manager
+    DavLockManager *locks = ucx_mempool_malloc(sn->mp, sizeof(DavLockManager));
+    locks->resource_locks = ucx_map_new_a(sn->mp->allocator, 16);
+    locks->collection_locks = NULL;
+    sn->locks = locks;
 
     // set proxy
     DavProxy *proxy = sstrprefix(url, S("https")) ? context->https_proxy
@@ -359,3 +365,126 @@
         ucx_map_sstr_put(sn->pathcache, path, href.ptr);
     }
 }
+
+
+DavLock* dav_create_lock(DavSession *sn, char *token, char *timeout) {
+    DavLock *lock = dav_session_malloc(sn, sizeof(DavLock));
+    lock->path = NULL;
+    lock->token = dav_session_strdup(sn, token);
+    
+    // TODO: timeout
+    
+    return lock;
+}
+
+void dav_destroy_lock(DavSession *sn, DavLock *lock) {
+    dav_session_free(sn, lock->token);
+    if(lock->path) {
+        dav_session_free(sn, lock->path);
+    }
+    dav_session_free(sn, lock);
+}
+
+int dav_add_resource_lock(DavSession *sn, char *path, DavLock *lock) {
+    DavLockManager *locks = sn->locks;
+    if(ucx_map_cstr_get(locks->resource_locks, path)) {
+        return -1;
+    }
+    
+    ucx_map_cstr_put(locks->resource_locks, path, lock);
+    return 0;
+}
+
+static void insert_lock(DavSession *sn, UcxList *elm, UcxList *newelm) {
+    UcxList *next = elm->next;
+    if(next) {
+        next->prev = newelm;
+        newelm->next = next;
+    }
+    newelm->prev = elm;
+    elm->next = newelm;
+}
+
+int dav_add_collection_lock(DavSession *sn, char *path, DavLock *lock) {
+    DavLockManager *locks = sn->locks;
+    if(!locks->collection_locks) {
+        locks->collection_locks = ucx_list_append_a(
+                sn->mp->allocator,
+                NULL,
+                lock);
+        lock->path = dav_session_strdup(sn, path);
+        return 0;
+    }
+    
+    UcxList *elm = locks->collection_locks;
+    for(;;) {
+        DavLock *l = elm->data;
+        int cmp = strcmp(path, l->path);
+        if(cmp > 0) {
+            UcxList *newelm = ucx_list_append_a(sn->mp->allocator, NULL, lock);
+            lock->path = dav_session_strdup(sn, path);
+            insert_lock(sn, elm, newelm);
+        } else if(cmp == 0) {
+            return -1;
+        }
+        
+        if(elm->next) {
+            elm = elm->next;
+        } else {
+            UcxList *newelm = ucx_list_append_a(sn->mp->allocator, NULL, lock);
+            lock->path = dav_session_strdup(sn, path);
+            ucx_list_concat(elm, newelm);
+            break;
+        }
+    }
+    
+    return 0;
+}
+
+DavLock* dav_get_lock(DavSession *sn, char *path) {
+    DavLockManager *locks = sn->locks;
+    
+    DavLock *lock = ucx_map_cstr_get(locks->resource_locks, path);
+    if(lock) {
+        return lock;
+    }
+    
+    sstr_t p = sstr(path);
+    UCX_FOREACH(elm, locks->collection_locks) {
+        DavLock *cl = elm->data;
+        int cmd = strcmp(path, cl->path);
+        if(cmd == 0) {
+            return cl;
+        } else if(sstrprefix(p, sstr(cl->path)))  {
+            return cl;
+        } else if(cmd > 0) {
+            break;
+        }
+    }
+    
+    return NULL;
+}
+
+void dav_remove_lock(DavSession *sn, char *path, DavLock *lock) {
+    DavLockManager *locks = sn->locks;
+    
+    if(ucx_map_cstr_remove(locks->resource_locks, path)) {
+        return;
+    }
+    
+    UcxList *rm = NULL;
+    UCX_FOREACH(elm, locks->collection_locks) {
+        DavLock *cl = elm->data;
+        if(cl == lock) {
+            rm = elm;
+            break;
+        }
+    }
+    
+    if(rm) {
+        locks->collection_locks = ucx_list_remove_a(
+                sn->mp->allocator,
+                locks->collection_locks,
+                rm);
+    }
+}

mercurial