--- 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 +