10 #include <Carbon/Carbon.h>
22 "description" :
"A Unicode (UTF-8) text string.",
23 "keywords" : [
"char *",
"character" ],
43 const char *textString = NULL;
44 if (json_object_get_type(js) == json_type_string)
58 return json_object_new_string(value);
72 if (length <= maxLength)
76 VuoText abbreviation =
VuoText_substring(subject, (where == VuoTextTruncation_End ? 1 : 1 + length - maxLength), maxLength);
78 VuoText summaryParts[2] = { abbreviation, ellipsis };
79 if (where == VuoTextTruncation_Beginning)
81 summaryParts[0] = ellipsis;
82 summaryParts[1] = abbreviation;
104 return strdup(
"<code>�</code>");
110 if (truncatedText != value)
114 if (truncatedText != value)
132 text = strdup(unquotedString);
156 if (data && ((
char *)data)[maxLength-1] == 0)
159 text = (
char *)calloc(1, maxLength);
160 memcpy(text, data, maxLength);
164 text = (
char *)calloc(1, maxLength+1);
165 for (
unsigned int i = 0; i < maxLength; ++i)
167 text[i] = ((
char *)data)[i];
168 if (((
char *)data)[i] == 0)
186 CFStringRef cfString = (CFStringRef)cfs;
189 const char *utf8StringPtr = CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
194 CFIndex maxBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfString), kCFStringEncodingUTF8) + 1;
195 char *t = calloc(1, maxBytes);
196 CFStringGetCString(cfString, t, maxBytes, kCFStringEncodingUTF8);
215 #define UTF8_ACCEPT 0
216 #define UTF8_REJECT 1
222 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,
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 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,
227 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,
228 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,
229 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3,
230 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
231 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1,
232 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,
233 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,
234 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,
235 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,
245 for (uint32_t pos = 0, state = 0; *data && pos++ < size; ++data)
247 uint32_t
byte = *data;
248 uint32_t type =
utf8d[byte];
251 (
byte & 0x3fu) | (codepoint << 6) :
252 (0xff >> type) & (byte);
254 state =
utf8d[256 + state*16 + type];
290 CFStringRef cf_str = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8*) data, size *
sizeof(uint32_t), kCFStringEncodingUTF32LE,
false);
294 CFIndex str_len = CFStringGetLength(cf_str);
295 CFRange range = CFRangeMake(0, str_len);
297 CFIndex length = CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, NULL, str_len, &usedBufLen );
301 char* buffer = (
char*) malloc(
sizeof(
char) * usedBufLen + 1);
303 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, (uint8_t*) buffer, usedBufLen + 1, &used);
325 size_t len = strlen(
string);
326 CFStringRef cf = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8 *)
string, len, kCFStringEncodingMacRoman,
false);
345 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
349 size_t length = CFStringGetLength(s);
370 return !text || text[0] == 0;
392 if (! text1 || ! text2)
393 return (! text1 && ! text2);
395 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
399 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
406 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive);
410 return (result == kCFCompareEqualTo);
420 if (! text1 || ! text2)
421 return text1 && !text2;
423 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
427 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
434 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive | flags);
438 return (result == kCFCompareLessThan);
458 return isLessThan(text1, text2, kCFCompareCaseInsensitive);
469 return real1 < real2;
481 if (! comparison.isCaseSensitive)
488 if (comparison.type == VuoTextComparison_Equals)
492 else if (comparison.type == VuoTextComparison_Contains)
496 else if (comparison.type == VuoTextComparison_BeginsWith || comparison.type == VuoTextComparison_EndsWith)
507 int startIndex = (comparison.type == VuoTextComparison_BeginsWith ? 1 : aLength - bLength + 1);
516 else if (comparison.type == VuoTextComparison_MatchesWildcard)
521 return t1empty == t2empty;
523 locale_t locale = newlocale(LC_ALL_MASK,
"en_US.UTF-8", NULL);
524 locale_t oldLocale = uselocale(locale);
525 if (oldLocale != LC_GLOBAL_LOCALE)
526 freelocale(oldLocale);
528 match = fnmatch(text2, text1, 0) != FNM_NOMATCH;
531 else if (comparison.type == VuoTextComparison_MatchesRegEx)
536 return t1empty == t2empty;
539 int ret = regcomp(&re, text2, REG_EXTENDED);
543 regerror(ret, &re, errstr,
sizeof(errstr));
544 VUserLog(
"Error compiling regular expression: %s", errstr);
548 ret = regexec(&re, text1, 0, NULL, 0);
551 else if (ret == REG_NOMATCH)
556 regerror(ret, &re, errstr,
sizeof(errstr));
557 VUserLog(
"Error executing regular expression: %s", errstr);
562 if (! comparison.isCaseSensitive)
591 if (stringLength < substringLength)
594 for (
size_t i = startIndex; i <= stringLength - substringLength + 1; ++i)
628 size_t foundIndex = 0;
632 if (stringLength < substringLength)
635 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
660 if (stringLength < substringLength)
664 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
695 if (startIndex > originalLength)
700 length -= 1 - startIndex;
707 if (startIndex + length - 1 > originalLength)
708 length = originalLength - startIndex + 1;
710 size_t startIndexFromZero = startIndex - 1;
712 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault,
string, kCFStringEncodingUTF8);
716 CFStringRef ss = CFStringCreateWithSubstring(kCFAllocatorDefault, s, CFRangeMake(startIndexFromZero, length));
736 CFMutableArrayRef a = CFArrayCreateMutable(kCFAllocatorDefault, textsCount, &kCFTypeArrayCallBacks);
737 for (
size_t i = 0; i < textsCount; ++i)
741 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, texts[i], kCFStringEncodingUTF8);
744 CFArrayAppendValue(a, s);
749 CFStringRef s = CFStringCreateByCombiningStrings(kCFAllocatorDefault, a, CFSTR(
""));
754 return compositeString;
768 unsigned long outputIndex = 0;
769 bool previousText =
false;
770 for (
unsigned long inputIndex = 1; inputIndex <= textsCount; ++inputIndex)
773 if (includeEmptyParts)
775 textsArray[outputIndex++] = t;
776 if (inputIndex < textsCount)
777 textsArray[outputIndex++] = separator;
781 if (previousText && inputIndex <= textsCount)
782 textsArray[outputIndex++] = separator;
783 textsArray[outputIndex++] = t;
792 return compositeText;
801 if (!text || !separator)
804 CFMutableArrayRef splitTexts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
806 CFStringRef textCF = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
811 size_t textLength = CFStringGetLength(textCF);
813 CFStringRef separatorCF = CFStringCreateWithCString(kCFAllocatorDefault, separator, kCFStringEncodingUTF8);
816 VuoDefer(^{ CFRelease(separatorCF); });
818 size_t separatorLength = CFStringGetLength(separatorCF);
820 if (separatorLength > 0)
822 size_t startIndex = 1;
823 size_t separatorIndex = 0;
825 while (startIndex <= textLength)
827 CFRange rangeToSearch = CFRangeMake(startIndex - 1, textLength - (startIndex - 1));
829 Boolean found = CFStringFindWithOptions(textCF, separatorCF, rangeToSearch, 0, &foundRange);
830 separatorIndex = foundRange.location + 1;
832 separatorIndex = textLength + 1;
834 if (separatorIndex > startIndex || includeEmptyParts)
836 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(startIndex - 1, separatorIndex - startIndex));
839 CFArrayAppendValue(splitTexts, partStr);
844 startIndex = separatorIndex + separatorLength;
847 if (includeEmptyParts && textLength > 0 && separatorIndex + separatorLength - 1 == textLength)
849 CFStringRef emptyPartStr = CFStringCreateWithCString(kCFAllocatorDefault,
"", kCFStringEncodingUTF8);
852 CFArrayAppendValue(splitTexts, emptyPartStr);
853 CFRelease(emptyPartStr);
859 for (
size_t i = 1; i <= textLength; ++i)
861 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(i - 1, 1));
864 CFArrayAppendValue(splitTexts, partStr);
870 *partsCount = CFArrayGetCount(splitTexts);
872 for (
size_t i = 0; i < *partsCount; ++i)
874 CFStringRef part = CFArrayGetValueAtIndex(splitTexts, i);
877 CFRelease(splitTexts);
879 return splitTextsArr;
894 CFMutableStringRef subjectCF = CFStringCreateMutable(NULL, 0);
895 CFStringAppendCString(subjectCF, subject, kCFStringEncodingUTF8);
897 CFStringRef stringToFindCF = CFStringCreateWithCString(NULL, stringToFind, kCFStringEncodingUTF8);
900 CFRelease(subjectCF);
904 CFStringRef replacementCF = nil;
907 replacementCF = CFStringCreateWithCString(NULL, replacement, kCFStringEncodingUTF8);
910 CFRelease(stringToFindCF);
911 CFRelease(subjectCF);
916 CFStringFindAndReplace(subjectCF, stringToFindCF, replacementCF, CFRangeMake(0,CFStringGetLength(subjectCF)), kCFCompareNonliteral);
920 CFRelease(replacementCF);
921 CFRelease(stringToFindCF);
922 CFRelease(subjectCF);
924 return replacedSubject;
942 if(startIndex > len) {
943 const char *append[2] = { string, newText };
945 }
else if(startIndex <= 1) {
946 const char *append[2] = { newText,
string };
956 const char *append[3] = { left, newText, right };
971 length -= (1 - startIndex);
976 if(startIndex > len || length < 1)
997 va_start(args, format);
998 int size = vsnprintf(NULL, 0, format, args);
1001 char *formattedString = (
char *)malloc(size+1);
1002 va_start(args, format);
1003 vsnprintf(formattedString, size+1, format, args);
1006 return formattedString;
1021 size_t len = strlen(text);
1022 size_t firstNonSpace;
1023 for (firstNonSpace = 0; firstNonSpace < len && isspace(text[firstNonSpace]); ++firstNonSpace);
1025 if (firstNonSpace == len)
1028 size_t lastNonSpace;
1029 for (lastNonSpace = len-1; lastNonSpace > firstNonSpace && isspace(text[lastNonSpace]); --lastNonSpace);
1039 size_t len = strlen(text);
1040 for (
size_t i = 0; i < len; ++i)
1041 if (((
unsigned char *)text)[i] > 127)
1060 size_t len = strlen(text);
1061 char *processedString = malloc(len + 1);
1062 for (
size_t i = 0; i < len; ++i)
1063 processedString[i] = tolower(text[i]);
1064 processedString[len] = 0;
1066 return processedString;
1070 CFMutableStringRef mutable_str = CFStringCreateMutable(NULL, 0);
1071 CFStringAppendCString(mutable_str, text, kCFStringEncodingUTF8);
1072 CFLocaleRef locale = CFLocaleCopyCurrent();
1077 CFStringLowercase(mutable_str, locale);
1081 CFStringUppercase(mutable_str, locale);
1085 CFStringCapitalize(mutable_str, locale);
1091 CFStringLowercase(mutable_str, locale);
1094 CFStringRef tmp = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, CFRangeMake(0, CFStringGetLength(mutable_str)));
1095 CFMutableStringRef all_upper = CFStringCreateMutableCopy(NULL, 0, tmp);
1097 CFStringUppercase(all_upper, locale);
1099 CFStringTokenizerRef tokenizer = CFStringTokenizerCreate( kCFAllocatorDefault,
1101 CFRangeMake(0, CFStringGetLength(all_upper)),
1102 kCFStringTokenizerUnitSentence,
1105 CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
1108 while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)))
1110 CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
1112 if (tokenRange.location != kCFNotFound && tokenRange.length > 0)
1114 CFRange firstCharRange = CFRangeMake(tokenRange.location, 1);
1115 CFStringRef firstLetter = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, firstCharRange);
1116 CFMutableStringRef upperFirst = CFStringCreateMutableCopy(NULL, 0, firstLetter);
1117 CFRelease(firstLetter);
1118 CFStringCapitalize(upperFirst, locale);
1119 CFStringReplace(mutable_str, firstCharRange, upperFirst);
1120 CFRelease(upperFirst);
1124 CFRelease(all_upper);
1125 CFRelease(tokenizer);
1133 CFRelease(mutable_str);
1135 return processedString;
1149 CFMutableStringRef cf_str = CFStringCreateMutable(NULL, 0);
1150 CFStringAppendCString(cf_str, text, kCFStringEncodingUTF8);
1152 size_t str_len = CFStringGetLength(cf_str);
1154 CFRange range = CFRangeMake(0, str_len);
1156 *length = (size_t) CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, NULL, str_len, &usedBufLen );
1158 uint32_t* decimal = (uint32_t*) NULL;
1162 decimal = (uint32_t*) malloc(
sizeof(uint32_t) * usedBufLen );
1163 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, (uint8_t*) decimal, usedBufLen, NULL);