CF_PRIVATE CFIndex __CFStringEncodingPlatformUnicodeToBytes(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) { #if DEPLOYMENT_TARGET_WINDOWS WORD dwFlags = 0; CFIndex usedLen; if ((kCFStringEncodingUTF7 != encoding) && (kCFStringEncodingGB_18030_2000 != encoding) && (0x0800 != (encoding & 0x0F00))) { // not UTF-7/GB18030/ISO-2022-* dwFlags |= (flags & (kCFStringEncodingAllowLossyConversion|kCFStringEncodingSubstituteCombinings) ? WC_DEFAULTCHAR : 0); dwFlags |= (flags & kCFStringEncodingComposeCombinings ? WC_COMPOSITECHECK : 0); dwFlags |= (flags & kCFStringEncodingIgnoreCombinings ? WC_DISCARDNS : 0); } if ((usedLen = WideCharToMultiByte(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCWSTR)characters, numChars, (LPSTR)bytes, maxByteLen, NULL, NULL)) == 0) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { CPINFO cpInfo; if (!GetCPInfo(CFStringConvertEncodingToWindowsCodepage(encoding), &cpInfo)) { cpInfo.MaxCharSize = 1; // Is this right ??? } if (cpInfo.MaxCharSize == 1) { numChars = maxByteLen; } else { usedLen = WideCharToMultiByte(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCWSTR)characters, numChars, NULL, 0, NULL, NULL); usedLen -= maxByteLen; numChars = (numChars > usedLen ? numChars - usedLen : 1); } if (WideCharToMultiByte(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCWSTR)characters, numChars, (LPSTR)bytes, maxByteLen, NULL, NULL) == 0) { if (usedCharLen) *usedCharLen = 0; if (usedByteLen) *usedByteLen = 0; } else { CFIndex lastUsedLen = 0; while ((usedLen = WideCharToMultiByte(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCWSTR)characters, ++numChars, (LPSTR)bytes, maxByteLen, NULL, NULL))) lastUsedLen = usedLen; if (usedCharLen) *usedCharLen = (numChars - 1); if (usedByteLen) *usedByteLen = lastUsedLen; } return kCFStringEncodingInsufficientOutputBufferLength; } else { return kCFStringEncodingInvalidInputStream; } } else { if (usedCharLen) *usedCharLen = numChars; if (usedByteLen) *usedByteLen = usedLen; return kCFStringEncodingConversionSuccess; } #endif /* DEPLOYMENT_TARGET_WINDOWS */ return kCFStringEncodingConverterUnavailable; }
CF_INLINE bool __CFIsPlatformConverterAvailable(int encoding) { #if DEPLOYMENT_TARGET_WINDOWS return (IsValidCodePage(CFStringConvertEncodingToWindowsCodepage(encoding)) ? true : false); #else return false; #endif }
CF_PRIVATE CFIndex __CFStringEncodingPlatformBytesToUnicode(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen) { #if DEPLOYMENT_TARGET_WINDOWS WORD dwFlags = 0; CFIndex usedLen; if ((kCFStringEncodingUTF7 != encoding) && (kCFStringEncodingGB_18030_2000 != encoding) && (0x0800 != (encoding & 0x0F00))) { // not UTF-7/GB18030/ISO-2022-* dwFlags |= (flags & (kCFStringEncodingAllowLossyConversion|kCFStringEncodingSubstituteCombinings) ? 0 : MB_ERR_INVALID_CHARS); dwFlags |= (flags & (kCFStringEncodingUseCanonical|kCFStringEncodingUseHFSPlusCanonical) ? MB_COMPOSITE : MB_PRECOMPOSED); } if ((usedLen = MultiByteToWideChar(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCSTR)bytes, numBytes, (LPWSTR)characters, maxCharLen)) == 0) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { CPINFO cpInfo; if (!GetCPInfo(CFStringConvertEncodingToWindowsCodepage(encoding), &cpInfo)) { cpInfo.MaxCharSize = 1; // Is this right ??? } if (cpInfo.MaxCharSize == 1) { numBytes = maxCharLen; } else { usedLen = MultiByteToWideChar(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCSTR)bytes, numBytes, (LPWSTR)characters, maxCharLen); usedLen -= maxCharLen; numBytes = (numBytes > usedLen ? numBytes - usedLen : 1); } while ((usedLen = MultiByteToWideChar(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCSTR)bytes, numBytes, (LPWSTR)characters, maxCharLen)) == 0) { if ((--numBytes) == 0) break; } if (usedCharLen) *usedCharLen = usedLen; if (usedByteLen) *usedByteLen = numBytes; return kCFStringEncodingInsufficientOutputBufferLength; } else { return kCFStringEncodingInvalidInputStream; } } else { if (usedCharLen) *usedCharLen = usedLen; if (usedByteLen) *usedByteLen = numBytes; return kCFStringEncodingConversionSuccess; } #endif /* DEPLOYMENT_TARGET_WINDOWS */ return kCFStringEncodingConverterUnavailable; }