11 #include <Carbon/Carbon.h>
23 "description" :
"A Unicode (UTF-8) text string.",
24 "keywords" : [
"char *",
"character" ],
44 const char *textString = NULL;
45 if (json_object_get_type(js) == json_type_string)
59 return json_object_new_string(value);
73 if (length <= maxLength)
77 VuoText abbreviation =
VuoText_substring(subject, (where == VuoTextTruncation_End ? 1 : 1 + length - maxLength), maxLength);
79 VuoText summaryParts[2] = { abbreviation, ellipsis };
80 if (where == VuoTextTruncation_Beginning)
82 summaryParts[0] = ellipsis;
83 summaryParts[1] = abbreviation;
105 return strdup(
"<code>�</code>");
111 if (truncatedText != value)
115 if (truncatedText != value)
133 text = strdup(unquotedString);
157 if (data && ((
char *)data)[maxLength-1] == 0)
160 text = (
char *)calloc(1, maxLength);
161 memcpy(text, data, maxLength);
165 text = (
char *)calloc(1, maxLength+1);
166 for (
unsigned int i = 0; i < maxLength; ++i)
168 text[i] = ((
char *)data)[i];
169 if (((
char *)data)[i] == 0)
187 CFStringRef cfString = (CFStringRef)cfs;
190 const char *utf8StringPtr = CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
195 CFIndex maxBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfString), kCFStringEncodingUTF8) + 1;
196 char *t = calloc(1, maxBytes);
197 CFStringGetCString(cfString, t, maxBytes, kCFStringEncodingUTF8);
216 #define UTF8_ACCEPT 0
217 #define UTF8_REJECT 1
223 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
224 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
225 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
226 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
227 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
228 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
229 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
230 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3,
231 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
232 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1,
233 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1,
234 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,
235 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1,
236 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
246 for (uint32_t pos = 0, state = 0; *data && pos++ < size; ++data)
248 uint32_t
byte = *data;
249 uint32_t type =
utf8d[byte];
252 (
byte & 0x3fu) | (codepoint << 6) :
253 (0xff >> type) & (byte);
255 state =
utf8d[256 + state*16 + type];
291 CFStringRef cf_str = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8*) data, size *
sizeof(uint32_t), kCFStringEncodingUTF32LE,
false);
295 CFIndex str_len = CFStringGetLength(cf_str);
296 CFRange range = CFRangeMake(0, str_len);
298 CFIndex length = CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, NULL, str_len, &usedBufLen );
302 char* buffer = (
char*) malloc(
sizeof(
char) * usedBufLen + 1);
304 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, (uint8_t*) buffer, usedBufLen + 1, &used);
326 size_t len = strlen(
string);
327 CFStringRef cf = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8 *)
string, len, kCFStringEncodingMacRoman,
false);
346 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
350 size_t length = CFStringGetLength(s);
371 return !text || text[0] == 0;
393 if (! text1 || ! text2)
394 return (! text1 && ! text2);
396 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
400 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
407 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive);
411 return (result == kCFCompareEqualTo);
421 if (! text1 || ! text2)
422 return text1 && !text2;
424 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
428 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
435 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive | flags);
439 return (result == kCFCompareLessThan);
459 return isLessThan(text1, text2, kCFCompareCaseInsensitive);
470 return real1 < real2;
482 if (! comparison.isCaseSensitive)
489 if (comparison.type == VuoTextComparison_Equals)
493 else if (comparison.type == VuoTextComparison_Contains)
497 else if (comparison.type == VuoTextComparison_BeginsWith || comparison.type == VuoTextComparison_EndsWith)
508 int startIndex = (comparison.type == VuoTextComparison_BeginsWith ? 1 : aLength - bLength + 1);
517 else if (comparison.type == VuoTextComparison_MatchesWildcard)
522 return t1empty == t2empty;
524 locale_t locale = newlocale(LC_ALL_MASK,
"en_US.UTF-8", NULL);
525 locale_t oldLocale = uselocale(locale);
526 if (oldLocale != LC_GLOBAL_LOCALE)
527 freelocale(oldLocale);
529 match = fnmatch(text2, text1, 0) != FNM_NOMATCH;
532 else if (comparison.type == VuoTextComparison_MatchesRegEx)
537 return t1empty == t2empty;
540 int ret = regcomp(&re, text2, REG_EXTENDED);
544 regerror(ret, &re, errstr,
sizeof(errstr));
545 VUserLog(
"Error compiling regular expression: %s", errstr);
549 ret = regexec(&re, text1, 0, NULL, 0);
552 else if (ret == REG_NOMATCH)
557 regerror(ret, &re, errstr,
sizeof(errstr));
558 VUserLog(
"Error executing regular expression: %s", errstr);
563 if (! comparison.isCaseSensitive)
592 if (stringLength < substringLength)
595 for (
size_t i = startIndex; i <= stringLength - substringLength + 1; ++i)
629 size_t foundIndex = 0;
633 if (stringLength < substringLength)
636 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
661 if (stringLength < substringLength)
665 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
696 if (startIndex > originalLength)
701 length -= 1 - startIndex;
708 if (startIndex + length - 1 > originalLength)
709 length = originalLength - startIndex + 1;
711 size_t startIndexFromZero = startIndex - 1;
713 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault,
string, kCFStringEncodingUTF8);
717 CFStringRef ss = CFStringCreateWithSubstring(kCFAllocatorDefault, s, CFRangeMake(startIndexFromZero, length));
737 CFMutableArrayRef a = CFArrayCreateMutable(kCFAllocatorDefault, textsCount, &kCFTypeArrayCallBacks);
738 for (
size_t i = 0; i < textsCount; ++i)
742 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, texts[i], kCFStringEncodingUTF8);
745 CFArrayAppendValue(a, s);
750 CFStringRef s = CFStringCreateByCombiningStrings(kCFAllocatorDefault, a, CFSTR(
""));
755 return compositeString;
769 unsigned long outputIndex = 0;
770 bool previousText =
false;
771 for (
unsigned long inputIndex = 1; inputIndex <= textsCount; ++inputIndex)
774 if (includeEmptyParts)
776 textsArray[outputIndex++] = t;
777 if (inputIndex < textsCount)
778 textsArray[outputIndex++] = separator;
782 if (previousText && inputIndex <= textsCount)
783 textsArray[outputIndex++] = separator;
784 textsArray[outputIndex++] = t;
793 return compositeText;
802 if (!text || !separator)
805 CFMutableArrayRef splitTexts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
807 CFStringRef textCF = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
812 size_t textLength = CFStringGetLength(textCF);
814 CFStringRef separatorCF = CFStringCreateWithCString(kCFAllocatorDefault, separator, kCFStringEncodingUTF8);
817 VuoDefer(^{ CFRelease(separatorCF); });
819 size_t separatorLength = CFStringGetLength(separatorCF);
821 if (separatorLength > 0)
823 size_t startIndex = 1;
824 size_t separatorIndex = 0;
826 while (startIndex <= textLength)
828 CFRange rangeToSearch = CFRangeMake(startIndex - 1, textLength - (startIndex - 1));
830 Boolean found = CFStringFindWithOptions(textCF, separatorCF, rangeToSearch, 0, &foundRange);
831 separatorIndex = foundRange.location + 1;
833 separatorIndex = textLength + 1;
835 if (separatorIndex > startIndex || includeEmptyParts)
837 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(startIndex - 1, separatorIndex - startIndex));
840 CFArrayAppendValue(splitTexts, partStr);
845 startIndex = separatorIndex + separatorLength;
848 if (includeEmptyParts && textLength > 0 && separatorIndex + separatorLength - 1 == textLength)
850 CFStringRef emptyPartStr = CFStringCreateWithCString(kCFAllocatorDefault,
"", kCFStringEncodingUTF8);
853 CFArrayAppendValue(splitTexts, emptyPartStr);
854 CFRelease(emptyPartStr);
860 for (
size_t i = 1; i <= textLength; ++i)
862 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(i - 1, 1));
865 CFArrayAppendValue(splitTexts, partStr);
871 *partsCount = CFArrayGetCount(splitTexts);
873 for (
size_t i = 0; i < *partsCount; ++i)
875 CFStringRef part = CFArrayGetValueAtIndex(splitTexts, i);
878 CFRelease(splitTexts);
880 return splitTextsArr;
895 CFMutableStringRef subjectCF = CFStringCreateMutable(NULL, 0);
896 CFStringAppendCString(subjectCF, subject, kCFStringEncodingUTF8);
898 CFStringRef stringToFindCF = CFStringCreateWithCString(NULL, stringToFind, kCFStringEncodingUTF8);
901 CFRelease(subjectCF);
905 CFStringRef replacementCF = nil;
908 replacementCF = CFStringCreateWithCString(NULL, replacement, kCFStringEncodingUTF8);
911 CFRelease(stringToFindCF);
912 CFRelease(subjectCF);
917 CFStringFindAndReplace(subjectCF, stringToFindCF, replacementCF, CFRangeMake(0,CFStringGetLength(subjectCF)), kCFCompareNonliteral);
921 CFRelease(replacementCF);
922 CFRelease(stringToFindCF);
923 CFRelease(subjectCF);
925 return replacedSubject;
943 if(startIndex > len) {
944 const char *append[2] = { string, newText };
946 }
else if(startIndex <= 1) {
947 const char *append[2] = { newText,
string };
957 const char *append[3] = { left, newText, right };
972 length -= (1 - startIndex);
977 if(startIndex > len || length < 1)
998 va_start(args, format);
999 int size = vsnprintf(NULL, 0, format, args);
1002 char *formattedString = (
char *)malloc(size+1);
1003 va_start(args, format);
1004 vsnprintf(formattedString, size+1, format, args);
1007 return formattedString;
1022 size_t len = strlen(text);
1023 size_t firstNonSpace;
1024 for (firstNonSpace = 0; firstNonSpace < len && isspace(text[firstNonSpace]); ++firstNonSpace);
1026 if (firstNonSpace == len)
1029 size_t lastNonSpace;
1030 for (lastNonSpace = len-1; lastNonSpace > firstNonSpace && isspace(text[lastNonSpace]); --lastNonSpace);
1040 size_t len = strlen(text);
1041 for (
size_t i = 0; i < len; ++i)
1042 if (((
unsigned char *)text)[i] > 127)
1061 size_t len = strlen(text);
1062 char *processedString = malloc(len + 1);
1063 for (
size_t i = 0; i < len; ++i)
1064 processedString[i] = tolower(text[i]);
1065 processedString[len] = 0;
1067 return processedString;
1071 CFMutableStringRef mutable_str = CFStringCreateMutable(NULL, 0);
1072 CFStringAppendCString(mutable_str, text, kCFStringEncodingUTF8);
1073 CFLocaleRef locale = CFLocaleCopyCurrent();
1078 CFStringLowercase(mutable_str, locale);
1082 CFStringUppercase(mutable_str, locale);
1086 CFStringCapitalize(mutable_str, locale);
1092 CFStringLowercase(mutable_str, locale);
1095 CFStringRef tmp = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, CFRangeMake(0, CFStringGetLength(mutable_str)));
1096 CFMutableStringRef all_upper = CFStringCreateMutableCopy(NULL, 0, tmp);
1098 CFStringUppercase(all_upper, locale);
1100 CFStringTokenizerRef tokenizer = CFStringTokenizerCreate( kCFAllocatorDefault,
1102 CFRangeMake(0, CFStringGetLength(all_upper)),
1103 kCFStringTokenizerUnitSentence,
1106 CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
1109 while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)))
1111 CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
1113 if (tokenRange.location != kCFNotFound && tokenRange.length > 0)
1115 CFRange firstCharRange = CFRangeMake(tokenRange.location, 1);
1116 CFStringRef firstLetter = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, firstCharRange);
1117 CFMutableStringRef upperFirst = CFStringCreateMutableCopy(NULL, 0, firstLetter);
1118 CFRelease(firstLetter);
1119 CFStringCapitalize(upperFirst, locale);
1120 CFStringReplace(mutable_str, firstCharRange, upperFirst);
1121 CFRelease(upperFirst);
1125 CFRelease(all_upper);
1126 CFRelease(tokenizer);
1134 CFRelease(mutable_str);
1136 return processedString;
1150 CFMutableStringRef cf_str = CFStringCreateMutable(NULL, 0);
1151 CFStringAppendCString(cf_str, text, kCFStringEncodingUTF8);
1153 size_t str_len = CFStringGetLength(cf_str);
1155 CFRange range = CFRangeMake(0, str_len);
1157 *length = (size_t) CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, NULL, str_len, &usedBufLen );
1159 uint32_t* decimal = (uint32_t*) NULL;
1163 decimal = (uint32_t*) malloc(
sizeof(uint32_t) * usedBufLen );
1164 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, (uint8_t*) decimal, usedBufLen, NULL);