wchar16_t * ambstowc16s(const char * input) { CFIndex inputlen = strlen(input); wchar16_t * output; uint32_t ret; CFIndex produced = 0; // output units produced output = malloc(sizeof(wchar16_t) *(inputlen + 1)); if (output == NULL) { return NULL; } ret = CFStringEncodingBytesToUnicode( kCFStringEncodingUTF8, CONVERSION_FLAGS, (const uint8_t *)input, inputlen, &inputlen, output, inputlen * sizeof(wchar16_t), &produced); if (ret != kCFStringEncodingConversionSuccess) { free(output); return NULL; } output[produced] = '\0'; return output; }
static CFIndex loadCharacters(UniChar *base, CFIndex maxLength, _CFXMLInputStream *stream) { const uint8_t *dataEnd = CFDataGetBytePtr(stream->data) + CFDataGetLength(stream->data); if (stream->flags & (ENCODING_IS_UNICODE_NATURAL|ENCODING_IS_UNICODE_SWAPPED) ) { CFIndex charsToTranslate = (dataEnd - stream->currentByte) / sizeof(UniChar); if (charsToTranslate > maxLength) { charsToTranslate = maxLength; } if (stream->flags & ENCODING_IS_UNICODE_NATURAL) { memmove(base, stream->currentByte, charsToTranslate * sizeof(UniChar)); stream->currentByte += (charsToTranslate * sizeof(UniChar)); } else { CFIndex i; uint8_t *baseBytePtr = (uint8_t *)base; for (i = 0; i < charsToTranslate; i ++) { *(baseBytePtr + 1) = *stream->currentByte; *baseBytePtr = *(stream->currentByte + 1); baseBytePtr += 2; stream->currentByte += 2; } } return charsToTranslate; } else { CFIndex lengthConsumed = 0; CFIndex usedByteLength, usedCharLength; UInt32 conversionResult; if (stream->flags & ENCODING_MATCHES_ASCII) { while (stream->currentByte < dataEnd && lengthConsumed < maxLength) { if (*stream->currentByte > 0x7f) break; *base = *stream->currentByte; base ++; stream->currentByte ++; lengthConsumed ++; } if (stream->currentByte == dataEnd || lengthConsumed == maxLength) { return lengthConsumed; } } conversionResult = CFStringEncodingBytesToUnicode(stream->encoding, 0, stream->currentByte, dataEnd - stream->currentByte, &usedByteLength, base, maxLength-lengthConsumed, &usedCharLength); if(kCFStringEncodingConversionSuccess != conversionResult) { switch(conversionResult) { case kCFStringEncodingConverterUnavailable: case kCFStringEncodingInvalidInputStream: stream->flags |= ENCODING_COMPOSITION_ERROR; break; case kCFStringEncodingInsufficientOutputBufferLength: default: break; } } if (usedByteLength > 0) { stream->currentByte += usedByteLength; lengthConsumed += usedCharLength; } return lengthConsumed; } }
static UniChar getSlashedChar(_CFStringsFileParseInfo *pInfo) { UniChar ch = *(pInfo->curr); pInfo->curr ++; switch (ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { uint8_t num = ch - '0'; UniChar result; CFIndex usedCharLen; /* three digits maximum to avoid reading \000 followed by 5 as \5 ! */ if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { // we use in this test the fact that the buffer is zero-terminated pInfo->curr ++; num = (num << 3) + ch - '0'; if ((pInfo->curr < pInfo->end) && (ch = *(pInfo->curr)) >= '0' && ch <= '7') { pInfo->curr ++; num = (num << 3) + ch - '0'; } } CFStringEncodingBytesToUnicode(kCFStringEncodingNextStepLatin, 0, &num, sizeof(uint8_t), NULL, &result, 1, &usedCharLen); return (usedCharLen == 1) ? result : 0; } case 'U': { unsigned num = 0, numDigits = 4; /* Parse four digits */ while (pInfo->curr < pInfo->end && numDigits--) { if (((ch = *(pInfo->curr)) < 128) && isxdigit(ch)) { pInfo->curr ++; num = (num << 4) + ((ch <= '9') ? (ch - '0') : ((ch <= 'F') ? (ch - 'A' + 10) : (ch - 'a' + 10))); } } return num; } case 'a': return '\a'; // Note: the meaning of '\a' varies with -traditional to gcc case 'b': return '\b'; case 'f': return '\f'; case 'n': return '\n'; case 'r': return '\r'; case 't': return '\t'; case 'v': return '\v'; case '"': return '\"'; case '\n': return '\n'; } return ch; }