src/server/webdav/multistatus.c

changeset 415
d938228c382e
parent 403
0f678595d497
child 484
c036a8b242a8
--- a/src/server/webdav/multistatus.c	Wed Nov 02 19:19:01 2022 +0100
+++ b/src/server/webdav/multistatus.c	Sun Nov 06 15:53:32 2022 +0100
@@ -33,7 +33,8 @@
 #include "../daemon/protocol.h"
 #include "../util/platform.h"
 
-#include <ucx/string.h>
+#include <cx/string.h>
+#include <cx/hash_map.h>
 
 #include "multistatus.h"
 
@@ -51,48 +52,48 @@
     ms->response.addresource = multistatus_addresource;
     ms->sn = sn;
     ms->rq = rq;
-    ms->namespaces = ucx_map_new_a(session_get_allocator(ms->sn), 8);
+    ms->namespaces = cxHashMapCreate(pool_allocator(sn->pool), 8);
     ms->proppatch = FALSE;
     if(!ms->namespaces) {
         return NULL;
     }
-    if(ucx_map_cstr_put(ms->namespaces, "D", webdav_dav_namespace())) {
+    if(cxMapPut(ms->namespaces, cx_hash_key_str("D"), webdav_dav_namespace())) {
         return NULL;
     }
     return ms;
 }
 
 static int send_xml_root(Multistatus *ms, Writer *out) {
-    writer_puts(out, S("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
-                       "<D:multistatus"));
+    writer_put_lit(out, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+                        "<D:multistatus");
     
     // write the namespaces definitions
     // key is the namespace prefix
     // the map always contains the "DAV:" namespace with the prefix "D"
-    UcxMapIterator i = ucx_map_iterator(ms->namespaces);
-    WSNamespace *ns;
-    UCX_MAP_FOREACH(key, ns, i) {
-        writer_puts(out, S(" xmlns:"));
-        writer_put(out, key.data, key.len);
-        writer_puts(out, S("=\""));
-        writer_puts(out, sstr((char*)ns->href));
-        writer_puts(out, S("\""));
+    CxIterator i = cxMapIterator(ms->namespaces);
+    cx_foreach(CxMapEntry*, entry, i) {
+        WSNamespace *ns = entry->value;
+        writer_put_lit(out, " xmlns:");
+        writer_put    (out, entry->key->data.str, entry->key->len);
+        writer_put_lit(out, "=\"");
+        writer_put_str(out, (char*)ns->href);
+        writer_put_lit(out, "\"");
     }
     
-    writer_puts(out, S(">\n"));
+    writer_put_lit(out, ">\n");
     
     return out->error;
 }
 
 static void send_nsdef(WSNamespace *ns, Writer *out) {
-    writer_puts(out, S(" xmlns:"));
-    writer_puts(out, sstr((char*)ns->prefix));
-    writer_puts(out, S("=\""));
-    writer_puts(out, sstr((char*)ns->href));
-    writer_putc(out, '\"');
+    writer_put_lit(out, " xmlns:");
+    writer_put_str(out, (char*)ns->prefix);
+    writer_put_lit(out, "=\"");
+    writer_put_str(out, (char*)ns->href);
+    writer_putc   (out, '\"');
 }
 
-static void send_string_escaped(Writer *out, sstr_t str) {
+static void send_string_escaped(Writer *out, cxmutstr str) {
     char *begin = str.ptr;
     char *end = begin;
     char *escape = NULL;
@@ -150,10 +151,10 @@
         Writer *out)
 {
     // write: "<prefix:name"
-    writer_putc(out, '<');
-    writer_puts(out, sstr((char*)property->namespace->prefix));
-    writer_putc(out, ':');
-    writer_puts(out, sstr((char*)property->name));
+    writer_putc   (out, '<');
+    writer_put_str(out, (char*)property->namespace->prefix);
+    writer_putc   (out, ':');
+    writer_put_str(out, (char*)property->name);
     
     // send additional namespace definitions required for the value
     WebdavNSList *def = nsdef;
@@ -164,9 +165,9 @@
     
     // send xml lang attribute
     if(property->lang) {
-        writer_puts(out, S(" xml:lang=\""));
-        writer_puts(out, sstr((char*)property->lang));
-        writer_putc(out, '\"');
+        writer_put_lit(out, " xml:lang=\"");
+        writer_put_str(out, (char*)property->lang);
+        writer_putc   (out, '\"');
     }
     
     // end property tag and write content
@@ -202,55 +203,54 @@
         }
         
         // end tag
-        writer_puts(out, S("</"));
-        writer_puts(out, sstr((char*)property->namespace->prefix));
-        writer_putc(out, ':');
-        writer_puts(out, sstr((char*)property->name));
-        writer_putc(out, '>');
+        writer_put_lit(out, "</");
+        writer_put_str(out, (char*)property->namespace->prefix);
+        writer_putc   (out, ':');
+        writer_put_str(out, (char*)property->name);
+        writer_putc   (out, '>');
     } else {
-        writer_puts(out, S("/>"));
+        writer_put_lit(out, "/>");
     }
     
     return out->error;
 }
 
 static int send_response_tag(Multistatus *ms, MSResponse *rp, Writer *out) {
-    writer_puts(out, S(" <D:response>\n"
-                       "  <D:href>"));
-    //writer_puts(out, sstr(rp->resource.href));
-    send_string_escaped(out, sstr(rp->resource.href));
-    writer_puts(out, S("</D:href>\n"));
+    writer_put_lit(out, " <D:response>\n"
+                        "  <D:href>");
+    send_string_escaped(out, cx_mutstr(rp->resource.href));
+    writer_put_lit(out, "</D:href>\n");
     
     WSBool writeContent = ms->proppatch ? FALSE : TRUE;
     
     if(rp->plist_begin) {
-        writer_puts(out, S("  <D:propstat>\n"
-                           "   <D:prop>\n"));
+        writer_put_lit(out, "  <D:propstat>\n"
+                            "   <D:prop>\n");
         // send properties
         PropertyOkList *p = rp->plist_begin;
         while(p) {
-            writer_puts(out, S("    "));
+            writer_put_lit(out, "    ");
             if(send_property(ms, p->property, p->nsdef, writeContent, out)) {
                 return out->error;
             }
-            writer_puts(out, S("\n"));
+            writer_put_lit(out, "\n");
             p = p->next;
         }
         
-        writer_puts(out, S("   </D:prop>\n"
-                           "   <D:status>HTTP/1.1 200 OK</D:status>\n"
-                           "  </D:propstat>\n"));
+        writer_put_lit(out, "   </D:prop>\n"
+                            "   <D:status>HTTP/1.1 200 OK</D:status>\n"
+                            "  </D:propstat>\n");
     }
     
     // send error properties
     PropertyErrorList *error = rp->errors;
     while(error) {
-        writer_puts(out, S("  <D:propstat>\n"
-                           "   <D:prop>\n"));
+        writer_put_lit(out, "  <D:propstat>\n"
+                            "   <D:prop>\n");
         
         WebdavPList *errprop = error->begin;
         while(errprop) {
-            writer_puts(out, S("    "));
+            writer_put_lit(out, "    ");
             if(send_property(ms, errprop->property, NULL, FALSE, out)) {
                 return out->error;
             }
@@ -267,24 +267,24 @@
             statuscode[3] = ' ';
             sclen = 4;
         }
-        writer_puts(out, S("   </D:prop>\n"
-                           "   <D:status>HTTP/1.1 "));
+        writer_put_lit(out, "   </D:prop>\n"
+                            "   <D:status>HTTP/1.1 ");
         writer_put(out, statuscode, sclen);
         const char *status_msg = protocol_status_message(error->status);
         if(status_msg) {
             writer_put(out, status_msg, strlen(status_msg));
         } else {
-            writer_puts(out, S("Server Error"));
+            writer_put_lit(out, "Server Error");
         }
-        writer_puts(out, S("</D:status>\n"
-                           "  </D:propstat>\n"));
+        writer_put_lit(out, "</D:status>\n"
+                            "  </D:propstat>\n");
         
         
         error = error->next;
     }
     
     // end response tag
-    writer_puts(out, S(" </D:response>\n"));
+    writer_put_lit(out, " </D:response>\n");
     
     return out->error;
 }
@@ -322,7 +322,7 @@
     }
     
     // end multistatus
-    writer_puts(out, S("</D:multistatus>\n"));
+    writer_put_lit(out, "</D:multistatus>\n");
     
     //printf("\n\n");
     //fflush(stdout);
@@ -355,7 +355,7 @@
     res->resource.addproperty = msresponse_addproperty;
     res->resource.close = msresponse_close;
     
-    res->properties = ucx_map_new_a(session_get_allocator(ms->sn), 32);
+    res->properties = cxHashMapCreate(pool_allocator(ms->sn->pool), 32);
     if(!res->properties) {
         return NULL;
     }
@@ -414,7 +414,6 @@
         int statuscode)
 {
     pool_handle_t *pool = response->multistatus->sn->pool;
-    UcxAllocator *a = session_get_allocator(response->multistatus->sn);
        
     response->resource.err++;
       
@@ -459,6 +458,15 @@
     return 0;
 }
 
+static CxHashKey ms_property_key(
+        CxAllocator *a,
+        const xmlChar *href,
+        const char *property_name)
+{
+    cxmutstr key_data = cx_strcat_a(a, 3, cx_str((const char*)href), (cxstring){ "\0", 1 }, cx_str(property_name));
+    return cx_hash_key_bytes((unsigned char*)key_data.ptr, key_data.length);
+}
+
 int msresponse_addproperty(
         WebdavResource *res,
         WebdavProperty *property,
@@ -486,21 +494,16 @@
     }
     
     // check if the property was already added to the resource
-    UcxAllocator *a = session_get_allocator(sn);
-    sstr_t key = sstrcat_a(
-            a,
-            3,
-            sstr((char*)property->namespace->href),
-            S("\0"),
-            sstr((char*)property->name));
-    if(ucx_map_sstr_get(response->properties, key)) {
-        a->free(a->pool, key.ptr);
+    CxAllocator *a = pool_allocator(sn->pool);
+    CxHashKey key = ms_property_key(a, property->namespace->href, property->name);
+    if(cxMapGet(response->properties, key)) {
+        cxFree(a, key.data.bytes);
         return 0;
     }
-    if(ucx_map_sstr_put(response->properties, key, property)) {
+    if(cxMapPut(response->properties, key, property)) {
         return 1; // OOM
     }
-    a->free(a->pool, key.ptr);
+    cxFree(a, key.data.bytes);
     
     // list of namespace definitions for this property
     WebdavNSList *nsdef_begin = NULL;
@@ -509,14 +512,14 @@
     // add namespace of this property to the namespace map
     // the namespace map will be used for global namespace definitions
     if(property->namespace->prefix) {
-        WSNamespace *ns = ucx_map_cstr_get(
+        WSNamespace *ns = cxMapGet(
                 response->multistatus->namespaces,
-                (const char*)property->namespace->prefix);
+                cx_hash_key_str((const char*)property->namespace->prefix));
         if(!ns) {
             // prefix is not in use -> we can add the namespace to the ns map
-            int err = ucx_map_cstr_put(
+            int err = cxMapPut(
                     response->multistatus->namespaces,
-                    (const char*)property->namespace->prefix,
+                    cx_hash_key_str((const char*)property->namespace->prefix),
                     property->namespace);
             if(err) {
                 return 1; // OOM
@@ -622,16 +625,11 @@
     }
     
     // add missing properties with status code 404
-    UcxAllocator *a = session_get_allocator(ms->sn);
+    CxAllocator *a = pool_allocator(ms->sn->pool);
     WebdavPList *pl = ms->response.op->reqprops;
     while(pl) {
-        sstr_t key = sstrcat_a(
-            a,
-            3,
-            sstr((char*)pl->property->namespace->href),
-            S("\0"),
-            sstr((char*)pl->property->name));
-        if(!ucx_map_sstr_get(response->properties, key)) {
+        CxHashKey key = ms_property_key(a, pl->property->namespace->href, pl->property->name);
+        if(!cxMapGet(response->properties, key)) {
             // property was not added to this response
             if(ms->proppatch) {
                 if(msresponse_addproperty(res, pl->property, 424)) {
@@ -668,7 +666,7 @@
     }
     
     // we don't need the properties anymore
-    ucx_map_free(response->properties);
+    cxMapDestroy(response->properties);
     
     response->resource.isclosed = TRUE;
     return ret;

mercurial