diff options
author | Hoa V. Dinh <dinh.viet.hoa@gmail.com> | 2014-10-24 17:09:53 -0700 |
---|---|---|
committer | Hoa V. Dinh <dinh.viet.hoa@gmail.com> | 2014-10-24 17:09:53 -0700 |
commit | 128a11a36103c3a57372cf72a51e52744524d827 (patch) | |
tree | 92c59ef7861668bc3a0f3944cd64793615457781 /src | |
parent | aa94649aabb8bf5f83155dd09d2f3db367c6225f (diff) |
Implemented String primitive using CoreFoundation instead of ICU
Diffstat (limited to 'src')
-rw-r--r-- | src/core/basetypes/MCString.cc | 152 |
1 files changed, 150 insertions, 2 deletions
diff --git a/src/core/basetypes/MCString.cc b/src/core/basetypes/MCString.cc index bcc1ec9d..de975d44 100644 --- a/src/core/basetypes/MCString.cc +++ b/src/core/basetypes/MCString.cc @@ -1,10 +1,14 @@ #include "MCString.h" +#define DISABLE_ICU 1 + #include <string.h> #include <stdlib.h> +#if !DISABLE_ICU #include <unicode/ustring.h> #include <unicode/ucnv.h> #include <unicode/utypes.h> +#endif #include <uuid/uuid.h> #include <pthread.h> #include <libetpan/libetpan.h> @@ -30,9 +34,68 @@ using namespace mailcore; +#if DISABLE_ICU +static int32_t u_strlen(const UChar *s) { + if (s == NULL) { + return 0; + } + const UChar * p = s; + while (* p != 0) { + p ++; + } + return (int32_t) (p - s); +} + +static UChar * u_memcpy(UChar * dest, const UChar * src, int32_t count) { + memcpy(dest, src, count * sizeof(* src)); + return dest; +} + +static UChar * u_strstr(const UChar * s, const UChar * substring) +{ + if (s == NULL) { + return NULL; + } + CFStringRef cfS = CFStringCreateWithCharactersNoCopy(NULL, (const UniChar *) s, u_strlen(s), kCFAllocatorNull); + CFStringRef cfSubstring = CFStringCreateWithCharactersNoCopy(NULL, (const UniChar *) substring, u_strlen(substring), kCFAllocatorNull); + + CFRange range = CFStringFind(cfS, cfSubstring, 0); + CFRelease(cfSubstring); + CFRelease(cfS); + if (range.length == 0) { + return NULL; + } + return (UChar *) (s + range.location); +} + +static UChar * u_strrstr(const UChar * s, const UChar * substring) +{ + if (s == NULL) { + return NULL; + } + CFStringRef cfS = CFStringCreateWithCharactersNoCopy(NULL, (const UniChar *) s, u_strlen(s), kCFAllocatorNull); + CFStringRef cfSubstring = CFStringCreateWithCharactersNoCopy(NULL, (const UniChar *) substring, u_strlen(substring), kCFAllocatorNull); + + CFRange range = CFStringFind(cfS, cfSubstring, kCFCompareBackwards); + CFRelease(cfSubstring); + CFRelease(cfS); + if (range.length == 0) { + return NULL; + } + return (UChar *) (s + range.location); +} + +static int32_t u_memcmp(const UChar * buf1, const UChar * buf2, int32_t count) +{ + return memcmp(buf1, buf2, count * sizeof(* buf1)); +} +#endif + void mailcore::setICUDataDirectory(String * directory) { +#if !DISABLE_ICU u_setDataDirectory(directory->fileSystemRepresentation()); +#endif } #pragma mark quote headers string @@ -814,7 +877,11 @@ void String::appendCharactersLength(const UChar * unicodeCharacters, unsigned in return; } allocate(mLength + length); +#if DISABLE_ICU + memcpy(&mUnicodeChars[mLength], unicodeCharacters, length * sizeof(* mUnicodeChars)); +#else u_strncpy(&mUnicodeChars[mLength], unicodeCharacters, length); +#endif mLength += length; mUnicodeChars[mLength] = 0; } @@ -843,7 +910,16 @@ void String::appendUTF8CharactersLength(const char * UTF8Characters, unsigned in if (UTF8Characters == NULL) { return; } - + +#if DISABLE_ICU + CFStringRef cfStr = CFStringCreateWithBytes(NULL, (const UInt8 *) UTF8Characters, length, + kCFStringEncodingUTF8, false); + UniChar * characters = (UniChar *) malloc(sizeof(* characters) * CFStringGetLength(cfStr)); + CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), characters); + appendCharactersLength(characters, (unsigned int) CFStringGetLength(cfStr)); + free(characters); + CFRelease(cfStr); +#else UChar * dest; int32_t destLength; int32_t destCapacity; @@ -866,6 +942,7 @@ void String::appendUTF8CharactersLength(const char * UTF8Characters, unsigned in appendCharactersLength(dest, destLength); free(dest); +#endif } void String::appendUTF8Characters(const char * UTF8Characters) @@ -888,6 +965,17 @@ const UChar * String::unicodeCharacters() const char * String::UTF8Characters() { +#if DISABLE_ICU + CFStringRef cfStr = CFStringCreateWithCharactersNoCopy(NULL, mUnicodeChars, mLength, kCFAllocatorNull); + char * buffer = (char *) malloc(mLength * 6 + 1); + CFIndex usedBufLen; + CFStringGetBytes(cfStr, CFRangeMake(0, mLength), kCFStringEncodingUTF8, '?', false, (UInt8 *) buffer, mLength * 6, &usedBufLen); + buffer[usedBufLen] = 0; + Data * data = Data::dataWithBytes(buffer, (unsigned int) usedBufLen + 1); + free(buffer); + + return data->bytes(); +#else char * dest; int32_t destLength; int32_t destCapacity; @@ -905,6 +993,7 @@ const char * String::UTF8Characters() free(dest); return data->bytes(); +#endif } unsigned int String::length() @@ -1092,12 +1181,21 @@ int String::compareWithCaseSensitive(String * otherString, bool caseSensitive) return -1; } +#if DISABLE_ICU + CFStringRef cfThis = CFStringCreateWithCharactersNoCopy(NULL, mUnicodeChars, mLength, kCFAllocatorNull); + CFStringRef cfOther = CFStringCreateWithCharactersNoCopy(NULL, otherString->mUnicodeChars, otherString->mLength, kCFAllocatorNull); + CFComparisonResult result = CFStringCompare(cfThis, cfOther, caseSensitive ? 0 : kCFCompareCaseInsensitive); + CFRelease(cfThis); + CFRelease(cfOther); + return result; +#else if (caseSensitive) { return u_strcmp(unicodeCharacters(), otherString->unicodeCharacters()); } else { return u_strcasecmp(unicodeCharacters(), otherString->unicodeCharacters(), 0); } +#endif } int String::compare(String * otherString) @@ -1110,8 +1208,20 @@ int String::caseInsensitiveCompare(String * otherString) return compareWithCaseSensitive(otherString, false); } +//Any-Lower, Any-Upper String * String::lowercaseString() { +#if DISABLE_ICU + CFMutableStringRef cfStr = CFStringCreateMutable(NULL, 0); + CFStringAppendCharacters(cfStr, (const UniChar *) mUnicodeChars, mLength); + CFStringLowercase(cfStr, NULL); + UniChar * characters = (UniChar *) malloc(sizeof(* characters) * mLength); + CFStringGetCharacters(cfStr, CFRangeMake(0, mLength), characters); + String * result = String::stringWithCharacters(characters, mLength); + free(characters); + CFRelease(cfStr); + return result; +#else UErrorCode err; String * result = (String *) copy()->autorelease(); err = U_ZERO_ERROR; @@ -1119,10 +1229,22 @@ String * String::lowercaseString() result->mUnicodeChars, result->mLength, NULL, &err); return result; +#endif } String * String::uppercaseString() { +#if DISABLE_ICU + CFMutableStringRef cfStr = CFStringCreateMutable(NULL, 0); + CFStringAppendCharacters(cfStr, (const UniChar *) mUnicodeChars, mLength); + CFStringUppercase(cfStr, NULL); + UniChar * characters = (UniChar *) malloc(sizeof(* characters) * mLength); + CFStringGetCharacters(cfStr, CFRangeMake(0, mLength), characters); + String * result = String::stringWithCharacters(characters, mLength); + free(characters); + CFRelease(cfStr); + return result; +#else UErrorCode err; String * result = (String *) copy()->autorelease(); err = U_ZERO_ERROR; @@ -1130,6 +1252,7 @@ String * String::uppercaseString() result->mUnicodeChars, result->mLength, NULL, &err); return result; +#endif } void String::appendBytes(const char * bytes, unsigned int length, const char * charset) @@ -1272,7 +1395,14 @@ unsigned int String::replaceOccurrencesOfString(String * occurrence, String * re } // copy remaining if(p) { - u_strcpy(dest_p, p); +#if DISABLE_ICU + unsigned int remainingLength = mLength - (unsigned int) (p - mUnicodeChars); + memcpy(dest_p, p, remainingLength * sizeof(* p)); + dest_p += remainingLength; + * dest_p = 0; +#else + u_strcpy(dest_p, p); +#endif } free(mUnicodeChars); @@ -1300,7 +1430,11 @@ void String::deleteCharactersInRange(Range range) } int32_t count = mLength - (int32_t) (range.location + range.length); +#if DISABLE_ICU + memmove(&mUnicodeChars[range.location], &mUnicodeChars[range.location + range.length], count * sizeof(* mUnicodeChars)); +#else u_memmove(&mUnicodeChars[range.location], &mUnicodeChars[range.location + range.length], count); +#endif mLength -= range.length; mUnicodeChars[mLength] = 0; } @@ -1862,7 +1996,14 @@ String * String::lastPathComponent() // TODO: Improve Windows compatibility. if (mUnicodeChars == NULL) return MCSTR(""); +#if DISABLE_ICU + UChar slash[2]; + slash[0] = '/'; + slash[1] = 0; + UChar * component = u_strrstr(mUnicodeChars, slash); +#else UChar * component = u_strrchr(mUnicodeChars, '/'); +#endif if (component == NULL) return (String *) this->copy()->autorelease(); return String::stringWithCharacters(component + 1); @@ -1870,7 +2011,14 @@ String * String::lastPathComponent() String * String::pathExtension() { +#if DISABLE_ICU + UChar point[2]; + point[0] = '.'; + point[1] = 0; + UChar * component = u_strrstr(mUnicodeChars, point); +#else UChar * component = u_strrchr(mUnicodeChars, '.'); +#endif if (component == NULL) return MCSTR(""); return String::stringWithCharacters(component + 1); |