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)
173 if (data && ((
char *)data)[maxLength-1] == 0)
176 text = (
char *)calloc(1, maxLength);
177 memcpy(text, data, maxLength);
181 text = (
char *)calloc(1, maxLength+1);
182 for (
unsigned int i = 0; i < maxLength; ++i)
184 text[i] = ((
char *)data)[i];
185 if (((
char *)data)[i] == 0)
203 CFStringRef cfString = (CFStringRef)cfs;
206 const char *utf8StringPtr = CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
211 CFIndex maxBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfString), kCFStringEncodingUTF8) + 1;
212 char *t = calloc(1, maxBytes);
213 CFStringGetCString(cfString, t, maxBytes, kCFStringEncodingUTF8);
239 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,
240 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,
241 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,
242 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,
243 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,
244 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,
245 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,
246 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3,
247 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
248 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1,
249 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,
250 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,
251 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,
252 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,
262 for (uint32_t pos = 0, state = 0; *data && pos++ < size; ++data)
264 uint32_t
byte = *data;
265 uint32_t type =
utf8d[byte];
268 (
byte & 0x3fu) | (codepoint << 6) :
269 (0xff >> type) & (byte);
271 state =
utf8d[256 + state*16 + type];
308 CFStringRef cf_str = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8*) data, size *
sizeof(uint32_t), kCFStringEncodingUTF32LE,
false);
312 CFIndex str_len = CFStringGetLength(cf_str);
313 CFRange range = CFRangeMake(0, str_len);
315 CFIndex length = CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, NULL, str_len, &usedBufLen );
319 char* buffer = (
char*) malloc(
sizeof(
char) * usedBufLen + 1);
321 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, (uint8_t*) buffer, usedBufLen + 1, &used);
342 size_t len = strlen(
string);
343 CFStringRef cf = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8 *)
string, len, kCFStringEncodingMacRoman,
false);
362 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
366 size_t length = CFStringGetLength(s);
387 return !text || text[0] == 0;
409 if (! text1 || ! text2)
410 return (! text1 && ! text2);
412 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
416 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
423 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive);
427 return (result == kCFCompareEqualTo);
437 if (! text1 || ! text2)
438 return text1 && !text2;
440 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
444 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
451 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive | flags);
455 return (result == kCFCompareLessThan);
475 return isLessThan(text1, text2, kCFCompareCaseInsensitive);
496 if (! comparison.isCaseSensitive)
503 if (comparison.type == VuoTextComparison_Equals)
507 else if (comparison.type == VuoTextComparison_Contains)
511 else if (comparison.type == VuoTextComparison_BeginsWith || comparison.type == VuoTextComparison_EndsWith)
522 int startIndex = (comparison.type == VuoTextComparison_BeginsWith ? 1 : aLength - bLength + 1);
531 else if (comparison.type == VuoTextComparison_MatchesWildcard)
536 return t1empty == t2empty;
538 locale_t locale = newlocale(LC_ALL_MASK,
"en_US.UTF-8", NULL);
539 locale_t oldLocale = uselocale(locale);
540 if (oldLocale != LC_GLOBAL_LOCALE)
541 freelocale(oldLocale);
543 match = fnmatch(text2, text1, 0) != FNM_NOMATCH;
546 else if (comparison.type == VuoTextComparison_MatchesRegEx)
551 return t1empty == t2empty;
554 int ret = regcomp(&re, text2, REG_EXTENDED);
558 regerror(ret, &re, errstr,
sizeof(errstr));
559 VUserLog(
"Error compiling regular expression: %s", errstr);
563 ret = regexec(&re, text1, 0, NULL, 0);
566 else if (ret == REG_NOMATCH)
571 regerror(ret, &re, errstr,
sizeof(errstr));
572 VUserLog(
"Error executing regular expression: %s", errstr);
577 if (! comparison.isCaseSensitive)
606 if (stringLength < substringLength)
609 for (
size_t i = startIndex; i <= stringLength - substringLength + 1; ++i)
643 size_t foundIndex = 0;
647 if (stringLength < substringLength)
650 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
675 if (stringLength < substringLength)
679 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
710 if (startIndex > originalLength)
715 length -= 1 - startIndex;
722 if (startIndex + length - 1 > originalLength)
723 length = originalLength - startIndex + 1;
725 size_t startIndexFromZero = startIndex - 1;
727 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault,
string, kCFStringEncodingUTF8);
731 CFStringRef ss = CFStringCreateWithSubstring(kCFAllocatorDefault, s, CFRangeMake(startIndexFromZero, length));
751 CFMutableArrayRef a = CFArrayCreateMutable(kCFAllocatorDefault, textsCount, &kCFTypeArrayCallBacks);
752 for (
size_t i = 0; i < textsCount; ++i)
756 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, texts[i], kCFStringEncodingUTF8);
759 CFArrayAppendValue(a, s);
764 CFStringRef s = CFStringCreateByCombiningStrings(kCFAllocatorDefault, a, CFSTR(
""));
769 return compositeString;
783 unsigned long outputIndex = 0;
784 bool previousText =
false;
785 for (
unsigned long inputIndex = 1; inputIndex <= textsCount; ++inputIndex)
788 if (includeEmptyParts)
790 textsArray[outputIndex++] = t;
791 if (inputIndex < textsCount)
792 textsArray[outputIndex++] = separator;
796 if (previousText && inputIndex <= textsCount)
797 textsArray[outputIndex++] = separator;
798 textsArray[outputIndex++] = t;
807 return compositeText;
816 if (!text || !separator)
819 CFMutableArrayRef splitTexts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
821 CFStringRef textCF = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
826 size_t textLength = CFStringGetLength(textCF);
828 CFStringRef separatorCF = CFStringCreateWithCString(kCFAllocatorDefault, separator, kCFStringEncodingUTF8);
831 VuoDefer(^{ CFRelease(separatorCF); });
833 size_t separatorLength = CFStringGetLength(separatorCF);
835 if (separatorLength > 0)
837 size_t startIndex = 1;
838 size_t separatorIndex = 0;
840 while (startIndex <= textLength)
842 CFRange rangeToSearch = CFRangeMake(startIndex - 1, textLength - (startIndex - 1));
844 Boolean found = CFStringFindWithOptions(textCF, separatorCF, rangeToSearch, 0, &foundRange);
845 separatorIndex = foundRange.location + 1;
847 separatorIndex = textLength + 1;
849 if (separatorIndex > startIndex || includeEmptyParts)
851 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(startIndex - 1, separatorIndex - startIndex));
854 CFArrayAppendValue(splitTexts, partStr);
859 startIndex = separatorIndex + separatorLength;
862 if (includeEmptyParts && textLength > 0 && separatorIndex + separatorLength - 1 == textLength)
864 CFStringRef emptyPartStr = CFStringCreateWithCString(kCFAllocatorDefault,
"", kCFStringEncodingUTF8);
867 CFArrayAppendValue(splitTexts, emptyPartStr);
868 CFRelease(emptyPartStr);
874 for (
size_t i = 1; i <= textLength; ++i)
876 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(i - 1, 1));
879 CFArrayAppendValue(splitTexts, partStr);
885 *partsCount = CFArrayGetCount(splitTexts);
887 for (
size_t i = 0; i < *partsCount; ++i)
889 CFStringRef part = CFArrayGetValueAtIndex(splitTexts, i);
892 CFRelease(splitTexts);
894 return splitTextsArr;
909 CFMutableStringRef subjectCF = CFStringCreateMutable(NULL, 0);
910 CFStringAppendCString(subjectCF, subject, kCFStringEncodingUTF8);
912 CFStringRef stringToFindCF = CFStringCreateWithCString(NULL, stringToFind, kCFStringEncodingUTF8);
915 CFRelease(subjectCF);
919 CFStringRef replacementCF = nil;
922 replacementCF = CFStringCreateWithCString(NULL, replacement, kCFStringEncodingUTF8);
925 CFRelease(stringToFindCF);
926 CFRelease(subjectCF);
931 CFStringFindAndReplace(subjectCF, stringToFindCF, replacementCF, CFRangeMake(0,CFStringGetLength(subjectCF)), kCFCompareNonliteral);
935 CFRelease(replacementCF);
936 CFRelease(stringToFindCF);
937 CFRelease(subjectCF);
939 return replacedSubject;
957 if(startIndex > len) {
958 const char *append[2] = { string, newText };
960 }
else if(startIndex <= 1) {
961 const char *append[2] = { newText,
string };
971 const char *append[3] = { left, newText, right };
986 length -= (1 - startIndex);
991 if(startIndex > len || length < 1)
1015 va_start(args, format);
1016 int size = vsnprintf(NULL, 0, format, args);
1019 char *formattedString = (
char *)malloc(size+1);
1020 va_start(args, format);
1021 vsnprintf(formattedString, size+1, format, args);
1024 return formattedString;
1039 size_t len = strlen(text);
1040 size_t firstNonSpace;
1041 for (firstNonSpace = 0; firstNonSpace < len && isspace(text[firstNonSpace]); ++firstNonSpace);
1043 if (firstNonSpace == len)
1046 size_t lastNonSpace;
1047 for (lastNonSpace = len-1; lastNonSpace > firstNonSpace && isspace(text[lastNonSpace]); --lastNonSpace);
1057 size_t len = strlen(text);
1058 for (
size_t i = 0; i < len; ++i)
1059 if (((
unsigned char *)text)[i] > 127)
1078 size_t len = strlen(text);
1079 char *processedString = malloc(len + 1);
1080 for (
size_t i = 0; i < len; ++i)
1081 processedString[i] = tolower(text[i]);
1082 processedString[len] = 0;
1084 return processedString;
1088 CFMutableStringRef mutable_str = CFStringCreateMutable(NULL, 0);
1089 CFStringAppendCString(mutable_str, text, kCFStringEncodingUTF8);
1090 CFLocaleRef locale = CFLocaleCopyCurrent();
1095 CFStringLowercase(mutable_str, locale);
1099 CFStringUppercase(mutable_str, locale);
1103 CFStringCapitalize(mutable_str, locale);
1109 CFStringLowercase(mutable_str, locale);
1112 CFStringRef tmp = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, CFRangeMake(0, CFStringGetLength(mutable_str)));
1113 CFMutableStringRef all_upper = CFStringCreateMutableCopy(NULL, 0, tmp);
1115 CFStringUppercase(all_upper, locale);
1117 CFStringTokenizerRef tokenizer = CFStringTokenizerCreate( kCFAllocatorDefault,
1119 CFRangeMake(0, CFStringGetLength(all_upper)),
1120 kCFStringTokenizerUnitSentence,
1123 CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
1126 while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)))
1128 CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
1130 if (tokenRange.location != kCFNotFound && tokenRange.length > 0)
1132 CFRange firstCharRange = CFRangeMake(tokenRange.location, 1);
1133 CFStringRef firstLetter = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, firstCharRange);
1134 CFMutableStringRef upperFirst = CFStringCreateMutableCopy(NULL, 0, firstLetter);
1135 CFRelease(firstLetter);
1136 CFStringCapitalize(upperFirst, locale);
1137 CFStringReplace(mutable_str, firstCharRange, upperFirst);
1138 CFRelease(upperFirst);
1142 CFRelease(all_upper);
1143 CFRelease(tokenizer);
1151 CFRelease(mutable_str);
1153 return processedString;
1167 CFMutableStringRef cf_str = CFStringCreateMutable(NULL, 0);
1168 CFStringAppendCString(cf_str, text, kCFStringEncodingUTF8);
1170 size_t str_len = CFStringGetLength(cf_str);
1172 CFRange range = CFRangeMake(0, str_len);
1174 *length = (size_t) CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, NULL, str_len, &usedBufLen );
1176 uint32_t* decimal = (uint32_t*) NULL;
1180 decimal = (uint32_t*) malloc(
sizeof(uint32_t) * usedBufLen );
1181 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, (uint8_t*) decimal, usedBufLen, NULL);