10 #include <Carbon/Carbon.h>
22 "description" :
"A Unicode (UTF-8) text string.",
23 "keywords" : [
"char *",
"character" ],
42 const char *textString = NULL;
43 if (json_object_get_type(js) == json_type_string)
57 return json_object_new_string(value);
71 if (length <= maxLength)
75 VuoText abbreviation =
VuoText_substring(subject, (where == VuoTextTruncation_End ? 1 : 1 + length - maxLength), maxLength);
77 VuoText summaryParts[2] = { abbreviation, ellipsis };
78 if (where == VuoTextTruncation_Beginning)
80 summaryParts[0] = ellipsis;
81 summaryParts[1] = abbreviation;
103 return strdup(
"<code>�</code>");
109 if (truncatedText != value)
113 if (truncatedText != value)
131 text = strdup(unquotedString);
155 if (data && ((
char *)data)[maxLength-1] == 0)
158 text = (
char *)calloc(1, maxLength);
159 memcpy(text, data, maxLength);
163 text = (
char *)calloc(1, maxLength+1);
164 for (
unsigned int i = 0; i < maxLength; ++i)
166 text[i] = ((
char *)data)[i];
167 if (((
char *)data)[i] == 0)
185 CFStringRef cfString = (CFStringRef)cfs;
189 const char *useUTF8StringPtr = NULL;
190 char *freeUTF8StringPtr = NULL;
192 if ((useUTF8StringPtr = CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8)) == NULL)
194 CFIndex stringLength = CFStringGetLength(cfString);
195 CFIndex maxBytes = 4 * stringLength + 1;
196 freeUTF8StringPtr = malloc(maxBytes);
197 CFStringGetCString(cfString, freeUTF8StringPtr, maxBytes, kCFStringEncodingUTF8);
198 useUTF8StringPtr = freeUTF8StringPtr;
203 if (freeUTF8StringPtr != NULL)
204 free(freeUTF8StringPtr);
222 #define UTF8_ACCEPT 0
223 #define UTF8_REJECT 1
229 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,
230 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,
231 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,
232 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,
233 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,
234 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,
235 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,
236 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3,
237 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
238 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1,
239 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,
240 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,
241 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,
242 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,
252 for (uint32_t pos = 0, state = 0; *data && pos++ < size; ++data)
254 uint32_t
byte = *data;
255 uint32_t type =
utf8d[byte];
258 (
byte & 0x3fu) | (codepoint << 6) :
259 (0xff >> type) & (byte);
261 state =
utf8d[256 + state*16 + type];
297 CFStringRef cf_str = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8*) data, size *
sizeof(uint32_t), kCFStringEncodingUTF32LE,
false);
301 CFIndex str_len = CFStringGetLength(cf_str);
302 CFRange range = CFRangeMake(0, str_len);
304 CFIndex length = CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, NULL, str_len, &usedBufLen );
308 char* buffer = (
char*) malloc(
sizeof(
char) * usedBufLen + 1);
310 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF8,
'?',
false, (uint8_t*) buffer, usedBufLen + 1, &used);
332 size_t len = strlen(
string);
333 CFStringRef cf = CFStringCreateWithBytes(kCFAllocatorDefault, (
const UInt8 *)
string, len, kCFStringEncodingMacRoman,
false);
352 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
356 size_t length = CFStringGetLength(s);
377 return !text || text[0] == 0;
399 if (! text1 || ! text2)
400 return (! text1 && ! text2);
402 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
406 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
413 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive);
417 return (result == kCFCompareEqualTo);
427 if (! text1 || ! text2)
428 return text1 && !text2;
430 CFStringRef s1 = CFStringCreateWithCString(kCFAllocatorDefault, text1, kCFStringEncodingUTF8);
434 CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault, text2, kCFStringEncodingUTF8);
441 CFComparisonResult result = CFStringCompare(s1, s2, kCFCompareNonliteral | kCFCompareWidthInsensitive | flags);
445 return (result == kCFCompareLessThan);
465 return isLessThan(text1, text2, kCFCompareCaseInsensitive);
476 return real1 < real2;
488 if (! comparison.isCaseSensitive)
495 if (comparison.type == VuoTextComparison_Equals)
499 else if (comparison.type == VuoTextComparison_Contains)
503 else if (comparison.type == VuoTextComparison_BeginsWith || comparison.type == VuoTextComparison_EndsWith)
514 int startIndex = (comparison.type == VuoTextComparison_BeginsWith ? 1 : aLength - bLength + 1);
523 else if (comparison.type == VuoTextComparison_MatchesWildcard)
528 return t1empty == t2empty;
530 locale_t oldLocale = uselocale(NULL);
531 locale_t locale = newlocale(LC_ALL_MASK,
"en_US.UTF-8", NULL);
534 match = fnmatch(text2, text1, 0) != FNM_NOMATCH;
536 uselocale(oldLocale);
540 else if (comparison.type == VuoTextComparison_MatchesRegEx)
545 return t1empty == t2empty;
548 int ret = regcomp(&re, text2, REG_EXTENDED);
552 regerror(ret, &re, errstr,
sizeof(errstr));
553 VUserLog(
"Error compiling regular expression: %s", errstr);
557 ret = regexec(&re, text1, 0, NULL, 0);
560 else if (ret == REG_NOMATCH)
565 regerror(ret, &re, errstr,
sizeof(errstr));
566 VUserLog(
"Error executing regular expression: %s", errstr);
571 if (! comparison.isCaseSensitive)
600 if (stringLength < substringLength)
603 for (
size_t i = startIndex; i <= stringLength - substringLength + 1; ++i)
637 size_t foundIndex = 0;
641 if (stringLength < substringLength)
644 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
669 if (stringLength < substringLength)
673 for (
size_t i = 1; i <= stringLength - substringLength + 1; ++i)
704 if (startIndex > originalLength)
709 length -= 1 - startIndex;
716 if (startIndex + length - 1 > originalLength)
717 length = originalLength - startIndex + 1;
719 size_t startIndexFromZero = startIndex - 1;
721 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault,
string, kCFStringEncodingUTF8);
725 CFStringRef ss = CFStringCreateWithSubstring(kCFAllocatorDefault, s, CFRangeMake(startIndexFromZero, length));
742 CFMutableArrayRef a = CFArrayCreateMutable(kCFAllocatorDefault, textsCount, &kCFTypeArrayCallBacks);
743 for (
size_t i = 0; i < textsCount; ++i)
747 CFStringRef s = CFStringCreateWithCString(kCFAllocatorDefault, texts[i], kCFStringEncodingUTF8);
750 CFArrayAppendValue(a, s);
755 CFStringRef s = CFStringCreateByCombiningStrings(kCFAllocatorDefault, a, CFSTR(
""));
760 return compositeString;
769 if (!text || !separator)
772 CFMutableArrayRef splitTexts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
774 CFStringRef textCF = CFStringCreateWithCString(kCFAllocatorDefault, text, kCFStringEncodingUTF8);
779 size_t textLength = CFStringGetLength(textCF);
781 CFStringRef separatorCF = CFStringCreateWithCString(kCFAllocatorDefault, separator, kCFStringEncodingUTF8);
784 VuoDefer(^{ CFRelease(separatorCF); });
786 size_t separatorLength = CFStringGetLength(separatorCF);
788 if (separatorLength > 0)
790 size_t startIndex = 1;
791 size_t separatorIndex = 0;
793 while (startIndex <= textLength)
795 CFRange rangeToSearch = CFRangeMake(startIndex - 1, textLength - (startIndex - 1));
797 Boolean found = CFStringFindWithOptions(textCF, separatorCF, rangeToSearch, 0, &foundRange);
798 separatorIndex = foundRange.location + 1;
800 separatorIndex = textLength + 1;
802 if (separatorIndex > startIndex || includeEmptyParts)
804 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(startIndex - 1, separatorIndex - startIndex));
807 CFArrayAppendValue(splitTexts, partStr);
812 startIndex = separatorIndex + separatorLength;
815 if (includeEmptyParts && textLength > 0 && separatorIndex + separatorLength - 1 == textLength)
817 CFStringRef emptyPartStr = CFStringCreateWithCString(kCFAllocatorDefault,
"", kCFStringEncodingUTF8);
820 CFArrayAppendValue(splitTexts, emptyPartStr);
821 CFRelease(emptyPartStr);
827 for (
size_t i = 1; i <= textLength; ++i)
829 CFStringRef partStr = CFStringCreateWithSubstring(kCFAllocatorDefault, textCF, CFRangeMake(i - 1, 1));
832 CFArrayAppendValue(splitTexts, partStr);
838 *partsCount = CFArrayGetCount(splitTexts);
840 for (
size_t i = 0; i < *partsCount; ++i)
842 CFStringRef part = CFArrayGetValueAtIndex(splitTexts, i);
845 CFRelease(splitTexts);
847 return splitTextsArr;
862 CFMutableStringRef subjectCF = CFStringCreateMutable(NULL, 0);
863 CFStringAppendCString(subjectCF, subject, kCFStringEncodingUTF8);
865 CFStringRef stringToFindCF = CFStringCreateWithCString(NULL, stringToFind, kCFStringEncodingUTF8);
868 CFRelease(subjectCF);
872 CFStringRef replacementCF = nil;
875 replacementCF = CFStringCreateWithCString(NULL, replacement, kCFStringEncodingUTF8);
878 CFRelease(stringToFindCF);
879 CFRelease(subjectCF);
884 CFStringFindAndReplace(subjectCF, stringToFindCF, replacementCF, CFRangeMake(0,CFStringGetLength(subjectCF)), kCFCompareNonliteral);
888 CFRelease(replacementCF);
889 CFRelease(stringToFindCF);
890 CFRelease(subjectCF);
892 return replacedSubject;
910 if(startIndex > len) {
911 const char *append[2] = { string, newText };
913 }
else if(startIndex <= 1) {
914 const char *append[2] = { newText,
string };
924 const char *append[3] = { left, newText, right };
939 length -= (1 - startIndex);
944 if(startIndex > len || length < 1)
965 va_start(args, format);
966 int size = vsnprintf(NULL, 0, format, args);
969 char *formattedString = (
char *)malloc(size+1);
970 va_start(args, format);
971 vsnprintf(formattedString, size+1, format, args);
974 return formattedString;
989 size_t len = strlen(text);
990 size_t firstNonSpace;
991 for (firstNonSpace = 0; firstNonSpace < len && isspace(text[firstNonSpace]); ++firstNonSpace);
993 if (firstNonSpace == len)
997 for (lastNonSpace = len-1; lastNonSpace > firstNonSpace && isspace(text[lastNonSpace]); --lastNonSpace);
1007 size_t len = strlen(text);
1008 for (
size_t i = 0; i < len; ++i)
1009 if (((
unsigned char *)text)[i] > 127)
1028 size_t len = strlen(text);
1029 char *processedString = malloc(len + 1);
1030 for (
size_t i = 0; i < len; ++i)
1031 processedString[i] = tolower(text[i]);
1032 processedString[len] = 0;
1034 return processedString;
1038 CFMutableStringRef mutable_str = CFStringCreateMutable(NULL, 0);
1039 CFStringAppendCString(mutable_str, text, kCFStringEncodingUTF8);
1040 CFLocaleRef locale = CFLocaleCopyCurrent();
1045 CFStringLowercase(mutable_str, locale);
1049 CFStringUppercase(mutable_str, locale);
1053 CFStringCapitalize(mutable_str, locale);
1059 CFStringLowercase(mutable_str, locale);
1062 CFStringRef tmp = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, CFRangeMake(0, CFStringGetLength(mutable_str)));
1063 CFMutableStringRef all_upper = CFStringCreateMutableCopy(NULL, 0, tmp);
1065 CFStringUppercase(all_upper, locale);
1067 CFStringTokenizerRef tokenizer = CFStringTokenizerCreate( kCFAllocatorDefault,
1069 CFRangeMake(0, CFStringGetLength(all_upper)),
1070 kCFStringTokenizerUnitSentence,
1073 CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone;
1076 while(kCFStringTokenizerTokenNone != (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)))
1078 CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);
1080 if (tokenRange.location != kCFNotFound && tokenRange.length > 0)
1082 CFRange firstCharRange = CFRangeMake(tokenRange.location, 1);
1083 CFStringRef firstLetter = CFStringCreateWithSubstring(kCFAllocatorDefault, mutable_str, firstCharRange);
1084 CFMutableStringRef upperFirst = CFStringCreateMutableCopy(NULL, 0, firstLetter);
1085 CFRelease(firstLetter);
1086 CFStringCapitalize(upperFirst, locale);
1087 CFStringReplace(mutable_str, firstCharRange, upperFirst);
1088 CFRelease(upperFirst);
1092 CFRelease(all_upper);
1093 CFRelease(tokenizer);
1101 CFRelease(mutable_str);
1103 return processedString;
1117 CFMutableStringRef cf_str = CFStringCreateMutable(NULL, 0);
1118 CFStringAppendCString(cf_str, text, kCFStringEncodingUTF8);
1120 size_t str_len = CFStringGetLength(cf_str);
1122 CFRange range = CFRangeMake(0, str_len);
1124 *length = (size_t) CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, NULL, str_len, &usedBufLen );
1126 uint32_t* decimal = (uint32_t*) NULL;
1130 decimal = (uint32_t*) malloc(
sizeof(uint32_t) * usedBufLen );
1131 CFStringGetBytes(cf_str, range, kCFStringEncodingUTF32,
'?',
false, (uint8_t*) decimal, usedBufLen, NULL);