示例#1
0
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
}
示例#3
0
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;
}