adds support for macos file tags

Sun, 07 Jan 2018 12:59:21 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 Jan 2018 12:59:21 +0100
changeset 363
e9ed8e130ccf
parent 362
9a75b6df3307
child 364
3769ba002fd1

adds support for macos file tags

dav/Makefile file | annotate | diff | comparison | revisions
dav/main.c file | annotate | diff | comparison | revisions
dav/scfg.c file | annotate | diff | comparison | revisions
dav/scfg.h file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
dav/tags.c file | annotate | diff | comparison | revisions
dav/tags.h file | annotate | diff | comparison | revisions
osx.mk file | annotate | diff | comparison | revisions
--- a/dav/Makefile	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/Makefile	Sun Jan 07 12:59:21 2018 +0100
@@ -47,10 +47,10 @@
 SYNC_SRC += libxattr.c
 SYNC_SRC += tags.c
 
-
 DAV_OBJ = $(DAV_SRC:%.c=../build/tool/%$(OBJ_EXT))
 SYNC_OBJ = $(SYNC_SRC:%.c=../build/tool/%$(OBJ_EXT))
 
+
 all: ../build/dav ../build/dav-sync
 
 ../build/dav: $(DAV_OBJ) ../build/libidav$(LIB_EXT)
@@ -66,6 +66,7 @@
 ../build/tool/%$(OBJ_EXT): %.c 
 	$(CC) $(CFLAGS) $(DAV_CFLAGS) -I../ -I../ucx -o $@ $<
 
+
 cppcheck: $(DAV_SRC) $(SYNC_SRC)
 	$(CPPCHECK) $(CPPCHECK_CONFIG) $(CPPCHECK_FLAGS) -I../ucx -I../ $+ 2>> ../$(CPPCHECK_LOG)
 
--- a/dav/main.c	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/main.c	Sun Jan 07 12:59:21 2018 +0100
@@ -60,11 +60,12 @@
 }
 
 //define DO_THE_TEST
-#include <libidav/davqlparser.h>
-#include <libidav/davqlexec.h>
-#include "tags.h"
+//include <libidav/davqlparser.h>
+//include <libidav/davqlexec.h>
+//include "tags.h"
+
 void test() {
-
+    
 }
 
 int main(int argc, char **argv) {
--- a/dav/scfg.c	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/scfg.c	Sun Jan 07 12:59:21 2018 +0100
@@ -144,6 +144,8 @@
         return TAG_FORMAT_CSV;
     } else if(!strcmp(str, "xml")) {
         return TAG_FORMAT_XML;
+    } else if(!strcmp(str, "macos")) {
+        return TAG_FORMAT_MACOS;
     }
     return TAG_FORMAT_UNKNOWN;
 }
--- a/dav/scfg.h	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/scfg.h	Sun Jan 07 12:59:21 2018 +0100
@@ -67,6 +67,7 @@
     TAG_FORMAT_TEXT = 0,
     TAG_FORMAT_CSV,
     TAG_FORMAT_XML,
+    TAG_FORMAT_MACOS,
     TAG_FORMAT_UNKNOWN
 };
 typedef enum TagFormat TagFormat;
--- a/dav/sync.c	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/sync.c	Sun Jan 07 12:59:21 2018 +0100
@@ -1283,6 +1283,10 @@
                 data = create_csv_taglist(tags);
                 break;
             }
+            case TAG_FORMAT_MACOS: {
+                data = create_macos_taglist(tags);
+                break;
+            }
         }
         
         if(data) {
@@ -1321,6 +1325,10 @@
                     tags = parse_csv_taglist(tag_data, tag_length);
                     break;
                 }
+                case TAG_FORMAT_MACOS: {
+                    tags = parse_macos_taglist(tag_data, tag_length);
+                    break;
+                }
             }
         }
     }
--- 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
+
--- a/dav/tags.h	Mon Jan 01 19:54:37 2018 +0100
+++ b/dav/tags.h	Sun Jan 07 12:59:21 2018 +0100
@@ -43,7 +43,7 @@
     char *name;
     char *color;
 } DavTag;
-    
+
 UcxList* parse_text_taglist(const char *buf, size_t length);
 UcxBuffer* create_text_taglist(UcxList *tags);
 
@@ -53,6 +53,8 @@
 UcxList* parse_dav_xml_taglist(DavXmlNode *taglistnode);
 DavXmlNode* create_xml_taglist(UcxList *tags);
 
+UcxList* parse_macos_taglist(const char *buf, size_t length);
+UcxBuffer* create_macos_taglist(UcxList *tags);
 
 #ifdef __cplusplus
 }
--- a/osx.mk	Mon Jan 01 19:54:37 2018 +0100
+++ b/osx.mk	Sun Jan 07 12:59:21 2018 +0100
@@ -43,4 +43,4 @@
 APP_EXT =
 
 DAV_CFLAGS = `xml2-config --cflags`
-DAV_LDFLAGS = -lcurl -lxml2 -lpthread
+DAV_LDFLAGS = -framework CoreFoundation -lcurl -lxml2 -lpthread

mercurial