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 oldLocale = uselocale(NULL);
524 locale_t locale = newlocale(LC_ALL_MASK,
"en_US.UTF-8", NULL);
527 match = fnmatch(text2, text1, 0) != FNM_NOMATCH;
529 uselocale(oldLocale);
533 else if (comparison.type == VuoTextComparison_MatchesRegEx)
538 return t1empty == t2empty;
541 int ret = regcomp(&re, text2, REG_EXTENDED);
545 regerror(ret, &re, errstr,
sizeof(errstr));
546 VUserLog(
"Error compiling regular expression: %s", errstr);
550 ret = regexec(&re, text1, 0, NULL, 0);
553 else if (ret == REG_NOMATCH)
558 regerror(ret, &re, errstr,
sizeof(errstr));
559 VUserLog(
"Error executing regular expression: %s", errstr);
564 if (! comparison.isCaseSensitive)
593 if (stringLength < substringLength)
596 for (
size_t i = startIndex; i <= stringLength - substringLength + 1; ++i)
630 size_t foundIndex = 0;
634 if (stringLength < substringLength)
637 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
662 if (stringLength < substringLength)
666 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
697 if (startIndex > originalLength)
702 length -= 1 - startIndex;
709 if (startIndex + length - 1 > originalLength)
710 length = originalLength - startIndex + 1;
712 size_t startIndexFromZero = startIndex - 1;
714 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault,
string, kCFStringEncodingUTF8);
718 CFStringRef ss = CFStringCreateWithSubstring(kCFAllocatorDefault, s, CFRangeMake(startIndexFromZero, length));
738 CFMutableArrayRef a = CFArrayCreateMutable(kCFAllocatorDefault, textsCount, &kCFTypeArrayCallBacks);
739 for (
size_t i = 0; i < textsCount; ++i)
743 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, texts[i], kCFStringEncodingUTF8);
746 CFArrayAppendValue(a, s);
751 CFStringRef s = CFStringCreateByCombiningStrings(kCFAllocatorDefault, a, CFSTR(
""));
756 return compositeString;
770 unsigned long outputIndex = 0;
771 bool previousText =
false;
772 for (
unsigned long inputIndex = 1; inputIndex <= textsCount; ++inputIndex)
775 if (includeEmptyParts)
777 textsArray[outputIndex++] = t;
778 if (inputIndex < textsCount)
779 textsArray[outputIndex++] = separator;
783 if (previousText && inputIndex <= textsCount)
784 textsArray[outputIndex++] = separator;
785 textsArray[outputIndex++] = t;
794 return compositeText;
803 if (!text || !separator)
806 CFMutableArrayRef splitTexts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
808 CFStringRef textCF = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
813 size_t textLength = CFStringGetLength(textCF);
815 CFStringRef separatorCF = CFStringCreateWithCString(kCFAllocatorDefault, separator, kCFStringEncodingUTF8);
818 VuoDefer(^{ CFRelease(separatorCF); });
820 size_t separatorLength = CFStringGetLength(separatorCF);
822 if (separatorLength > 0)
824 size_t startIndex = 1;
825 size_t separatorIndex = 0;
827 while (startIndex <= textLength)
829 CFRange rangeToSearch = CFRangeMake(startIndex - 1, textLength - (startIndex - 1));
831 Boolean found = CFStringFindWithOptions(textCF, separatorCF, rangeToSearch, 0, &foundRange);
832 separatorIndex = foundRange.location + 1;
834 separatorIndex = textLength + 1;
836 if (separatorIndex > startIndex || includeEmptyParts)
838 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(startIndex - 1, separatorIndex - startIndex));
841 CFArrayAppendValue(splitTexts, partStr);
846 startIndex = separatorIndex + separatorLength;
849 if (includeEmptyParts && textLength > 0 && separatorIndex + separatorLength - 1 == textLength)
851 CFStringRef emptyPartStr = CFStringCreateWithCString(kCFAllocatorDefault,
"", kCFStringEncodingUTF8);
854 CFArrayAppendValue(splitTexts, emptyPartStr);
855 CFRelease(emptyPartStr);
861 for (
size_t i = 1; i <= textLength; ++i)
863 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(i - 1, 1));
866 CFArrayAppendValue(splitTexts, partStr);
872 *partsCount = CFArrayGetCount(splitTexts);
874 for (
size_t i = 0; i < *partsCount; ++i)
876 CFStringRef part = CFArrayGetValueAtIndex(splitTexts, i);
879 CFRelease(splitTexts);
881 return splitTextsArr;
896 CFMutableStringRef subjectCF = CFStringCreateMutable(NULL, 0);
897 CFStringAppendCString(subjectCF, subject, kCFStringEncodingUTF8);
899 CFStringRef stringToFindCF = CFStringCreateWithCString(NULL, stringToFind, kCFStringEncodingUTF8);
902 CFRelease(subjectCF);
906 CFStringRef replacementCF = nil;
909 replacementCF = CFStringCreateWithCString(NULL, replacement, kCFStringEncodingUTF8);
912 CFRelease(stringToFindCF);
913 CFRelease(subjectCF);
918 CFStringFindAndReplace(subjectCF, stringToFindCF, replacementCF, CFRangeMake(0,CFStringGetLength(subjectCF)), kCFCompareNonliteral);
922 CFRelease(replacementCF);
923 CFRelease(stringToFindCF);
924 CFRelease(subjectCF);
926 return replacedSubject;
944 if(startIndex > len) {
945 const char *append[2] = { string, newText };
947 }
else if(startIndex <= 1) {
948 const char *append[2] = { newText,
string };
958 const char *append[3] = { left, newText, right };
973 length -= (1 - startIndex);
978 if(startIndex > len || length < 1)
999 va_start(args, format);
1000 int size = vsnprintf(NULL, 0, format, args);
1003 char *formattedString = (
char *)malloc(size+1);
1004 va_start(args, format);
1005 vsnprintf(formattedString, size+1, format, args);
1008 return formattedString;
1023 size_t len = strlen(text);
1024 size_t firstNonSpace;
1025 for (firstNonSpace = 0; firstNonSpace < len && isspace(text[firstNonSpace]); ++firstNonSpace);
1027 if (firstNonSpace == len)
1030 size_t lastNonSpace;
1031 for (lastNonSpace = len-1; lastNonSpace > firstNonSpace && isspace(text[lastNonSpace]); --lastNonSpace);
1041 size_t len = strlen(text);
1042 for (
size_t i = 0; i < len; ++i)
1043 if (((
unsigned char *)text)[i] > 127)
1062 size_t len = strlen(text);
1063 char *processedString = malloc(len + 1);
1064 for (
size_t i = 0; i < len; ++i)
1065 processedString[i] = tolower(text[i]);
1066 processedString[len] = 0;
1068 return processedString;
1072 CFMutableStringRef mutable_str = CFStringCreateMutable(NULL, 0);
1073 CFStringAppendCString(mutable_str, text, kCFStringEncodingUTF8);
1074 CFLocaleRef locale = CFLocaleCopyCurrent();
1079 CFStringLowercase(mutable_str, locale);
1083 CFStringUppercase(mutable_str, locale);
1087 CFStringCapitalize(mutable_str, locale);
1093 CFStringLowercase(mutable_str, locale);
1096 CFStringRef tmp = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, CFRangeMake(0, CFStringGetLength(mutable_str)));
1097 CFMutableStringRef all_upper = CFStringCreateMutableCopy(NULL, 0, tmp);
1099 CFStringUppercase(all_upper, locale);
1101 CFStringTokenizerRef tokenizer = CFStringTokenizerCreate( kCFAllocatorDefault,
1103 CFRangeMake(0, CFStringGetLength(all_upper)),
1104 kCFStringTokenizerUnitSentence,
1107 CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
1110 while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)))
1112 CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
1114 if (tokenRange.location != kCFNotFound && tokenRange.length > 0)
1116 CFRange firstCharRange = CFRangeMake(tokenRange.location, 1);
1117 CFStringRef firstLetter = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, firstCharRange);
1118 CFMutableStringRef upperFirst = CFStringCreateMutableCopy(NULL, 0, firstLetter);
1119 CFRelease(firstLetter);
1120 CFStringCapitalize(upperFirst, locale);
1121 CFStringReplace(mutable_str, firstCharRange, upperFirst);
1122 CFRelease(upperFirst);
1126 CFRelease(all_upper);
1127 CFRelease(tokenizer);
1135 CFRelease(mutable_str);
1137 return processedString;
1151 CFMutableStringRef cf_str = CFStringCreateMutable(NULL, 0);
1152 CFStringAppendCString(cf_str, text, kCFStringEncodingUTF8);
1154 size_t str_len = CFStringGetLength(cf_str);
1156 CFRange range = CFRangeMake(0, str_len);
1158 *length = (size_t) CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, NULL, str_len, &usedBufLen );
1160 uint32_t* decimal = (uint32_t*) NULL;
1164 decimal = (uint32_t*) malloc(
sizeof(uint32_t) * usedBufLen );
1165 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, (uint8_t*) decimal, usedBufLen, NULL);