dav/tags.c

changeset 363
e9ed8e130ccf
parent 361
b6f2462ee055
child 373
dcc03142eb5f
--- a/dav/tags.c	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/tags.c	Sun Jan 07 12:59:21 2018 +0100
@@ -36,6 +36,10 @@
 
 #include "tags.h"
 
+#ifdef __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
 UcxList* parse_text_taglist(const char *buf, size_t length) {
     UcxList *tags = NULL;
     
@@ -175,3 +179,128 @@
     }
     return tag1;
 }
+
+
+#ifdef __APPLE__
+static DavTag* tagstr2davtag(const char *str) {
+    const char *name = str;
+    const char *color = NULL;
+    size_t len = strlen(str);
+    size_t namelen = len;
+    
+    if(len == 0) {
+        return NULL;
+    }
+    
+    // start with 1 because the first char should not be a linebreak
+    for(int i=1;i<len;i++) {
+        if(str[i] == '\n') {
+            if(!color) {
+                color = str + i + 1;
+                namelen = i;
+            }
+        }
+    }
+    int colorlen = len - namelen - 1;
+    
+    DavTag *tag = malloc(sizeof(DavTag));
+    tag = malloc(sizeof(DavTag));
+    tag->name = malloc(namelen + 1);
+    memcpy(tag->name, name, namelen);
+    tag->name[namelen] = 0;
+    if(colorlen > 0) {
+        tag->color = malloc(colorlen + 1);
+        memcpy(tag->color, color, colorlen);
+        tag->color[colorlen] = 0;
+    } else {
+        tag->color = NULL;
+    }
+    
+    return tag;
+}
+
+UcxList* parse_macos_taglist(const char *buf, size_t length) {
+    UcxList *taglist = NULL;
+    
+    CFDataRef data = CFDataCreateWithBytesNoCopy(
+            kCFAllocatorDefault,
+            (const UInt8*)buf,
+            length,
+            kCFAllocatorNull);
+    CFPropertyListRef propertylist = CFPropertyListCreateWithData(kCFAllocatorDefault, data, 0, NULL, NULL);
+    CFArrayRef array = propertylist;
+    int count = CFArrayGetCount(array);
+    for(int i=0;i<count;i++) {
+        CFStringRef str = CFArrayGetValueAtIndex(array, i);
+        int slen = CFStringGetLength(str);
+        size_t cstrbuflen = slen * 4 + 4;
+        char *cstr = malloc(cstrbuflen);
+        if(CFStringGetCString(str, cstr, cstrbuflen, kCFStringEncodingUTF8)) {
+            DavTag *tag = tagstr2davtag(cstr);
+            if(tag) {
+                taglist = ucx_list_append(taglist, tag);
+            }
+        }
+        free(cstr);
+    }
+    
+    CFRelease(propertylist);
+    CFRelease(data);
+    
+    return taglist;
+}
+
+UcxBuffer* create_macos_taglist(UcxList *tags) {
+    size_t count = ucx_list_size(tags);
+    if(count == 0) {
+        return NULL;
+    }
+    
+    CFStringRef *strings = calloc(sizeof(CFStringRef), count);
+    int i = 0;
+    UCX_FOREACH(elm, tags) {
+        DavTag *tag = elm->data;
+        CFStringRef str = NULL;
+        if(tag->color) {
+            sstr_t s = sstrcat(3, sstr(tag->name), S("\n"), sstr(tag->color));
+            str = CFStringCreateWithCString(kCFAllocatorDefault, s.ptr, kCFStringEncodingUTF8);
+            free(s.ptr);
+        } else {
+            str = CFStringCreateWithCString(kCFAllocatorDefault, tag->name, kCFStringEncodingUTF8);
+        }
+        strings[i] = str;
+        i++; 
+    }
+    
+    CFPropertyListRef array = CFArrayCreate(kCFAllocatorDefault, (const void**)strings, count, &kCFTypeArrayCallBacks);
+    CFDataRef data = CFPropertyListCreateData(kCFAllocatorDefault, array, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
+    
+    UcxBuffer *buf = NULL;
+    if(data) {
+        int datalen = CFDataGetLength(data);
+        CFRange range;
+        range.location = 0;
+        range.length = datalen;
+        buf = ucx_buffer_new(NULL, datalen, 0);
+        CFDataGetBytes(data, range, (UInt8*)buf->space);
+        buf->size = datalen;
+        CFRelease(data);
+    }
+    
+    for(int i=0;i<count;i++) {
+        CFRelease(strings[i]);
+    }
+    CFRelease(array);
+    
+    return buf;
+}
+
+#else
+UcxList* parse_macos_taglist(const char *buf, size_t length) {
+    return NULL;
+}
+UcxBuffer* create_macos_taglist(UcxList *tags) {
+    return NULL;
+}
+#endif
+

mercurial