- return true;
-
- default:
- if (CFStringEncodingIsValidEncoding(encoding)) {
- const CFStringEncodingConverter *converter = CFStringEncodingGetConverter(encoding);
- Boolean isASCIISuperset = __CFStringEncodingIsSupersetOfASCII(encoding);
-
- if (!converter) return false;
-
- if (converter->encodingClass == kCFStringEncodingConverterCheapEightBit) {
- allASCII = !alwaysUnicode && isASCIISuperset;
- if (allASCII) {
- for (idx = 0; idx < len; idx++) {
- if (128 <= chars[idx]) {
- allASCII = false;
- break;
- }
+
+ case kCFStringEncodingUTF8:
+ if ((len >= 3) && (chars[0] == 0xef) && (chars[1] == 0xbb) && (chars[2] == 0xbf)) { // If UTF8 BOM, skip
+ chars += 3;
+ len -= 3;
+ if (0 == len) return true;
+ }
+ if (buffer->isASCII) {
+ for (idx = 0; idx < len; idx++) {
+ if (128 <= chars[idx]) {
+ buffer->isASCII = false;
+ break;
+ }
+ }
+ }
+ if (buffer->isASCII) {
+ buffer->numChars = len;
+ buffer->shouldFreeChars = !buffer->chars.ascii && (len <= MAX_LOCAL_CHARS) ? false : true;
+ buffer->chars.ascii = (buffer->chars.ascii ? buffer->chars.ascii : (len <= MAX_LOCAL_CHARS) ? (uint8_t *)buffer->localBuffer : CFAllocatorAllocate(buffer->allocator, len * sizeof(uint8_t), 0));
+ memmove(buffer->chars.ascii, chars, len * sizeof(uint8_t));
+ } else {
+ UInt32 numDone;
+ static CFStringEncodingToUnicodeProc __CFFromUTF8 = NULL;
+
+ if (!__CFFromUTF8) {
+ const CFStringEncodingConverter *converter = CFStringEncodingGetConverter(kCFStringEncodingUTF8);
+ __CFFromUTF8 = (CFStringEncodingToUnicodeProc)converter->toUnicode;
+ }
+
+ buffer->shouldFreeChars = !buffer->chars.unicode && (len <= MAX_LOCAL_UNICHARS) ? false : true;
+ buffer->chars.unicode = (buffer->chars.unicode ? buffer->chars.unicode : (len <= MAX_LOCAL_UNICHARS) ? (UniChar *)buffer->localBuffer : CFAllocatorAllocate(buffer->allocator, len * sizeof(UniChar), 0));
+ buffer->numChars = 0;
+ while (chars < end) {
+ numDone = 0;
+ chars += __CFFromUTF8(converterFlags, chars, end - chars, &(buffer->chars.unicode[buffer->numChars]), len - buffer->numChars, &numDone);
+
+ if (0 == numDone) {
+ if (buffer->shouldFreeChars) CFAllocatorDeallocate(buffer->allocator, buffer->chars.unicode);
+ buffer->isASCII = !alwaysUnicode;
+ buffer->shouldFreeChars = false;
+ buffer->chars.ascii = NULL;
+ buffer->numChars = 0;
+ return false;
+ }
+ buffer->numChars += numDone;
+ }
+ }
+ break;
+
+ default:
+ if (CFStringEncodingIsValidEncoding(encoding)) {
+ const CFStringEncodingConverter *converter = CFStringEncodingGetConverter(encoding);
+ Boolean isASCIISuperset = __CFStringEncodingIsSupersetOfASCII(encoding);
+
+ if (!converter) return false;
+
+ if (!isASCIISuperset) buffer->isASCII = false;
+
+ if (buffer->isASCII) {
+ for (idx = 0; idx < len; idx++) {
+ if (128 <= chars[idx]) {
+ buffer->isASCII = false;
+ break;