static const wxUint16* GetEncTable(wxFontEncoding enc) { #ifdef __WXMAC__ if( enc >= wxFONTENCODING_MACMIN && enc <= wxFONTENCODING_MACMAX ) { int i = enc-wxFONTENCODING_MACMIN ; if ( gMacEncodingsInited[i] == false ) { TECObjectRef converter ; TextEncodingBase code = wxMacGetSystemEncFromFontEnc( enc ) ; TextEncodingBase unicode = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ; OSStatus status = TECCreateConverter(&converter,code,unicode); char s[2] ; s[1] = 0 ; ByteCount byteInLen, byteOutLen ; for( unsigned char c = 255 ; c >= 128 ; --c ) { s[0] = c ; status = TECConvertText(converter, (ConstTextPtr) &s , 1, &byteInLen, (TextPtr) &gMacEncodings[i][c-128] , 2, &byteOutLen); } status = TECDisposeConverter(converter); gMacEncodingsInited[i]=true; } return gMacEncodings[i] ; } #endif for (int i = 0; encodings_list[i].table != NULL; i++) { if (encodings_list[i].encoding == enc) return encodings_list[i].table; } return NULL; }
wxString MacConvertString(TECObjectRef ec, wxString input) { OSStatus status = noErr; ByteCount byteOutLen; ByteCount byteInLen = input.Length(); ByteCount byteBufferLen = byteInLen * 8 + 1; char* buf = new char[byteBufferLen] ; status = TECConvertText(ec, (ConstTextPtr)input.c_str(), byteInLen, &byteInLen, (TextPtr)buf, byteBufferLen, &byteOutLen); if (status != noErr) { delete[] buf; return input; } buf[byteOutLen] = 0; wxString result = wxString(buf, wxConvLocal); delete[] buf; return result; }
XMLSize_t MacOSTranscoder::transcodeTo(const XMLCh* const srcData , const XMLSize_t srcCount , XMLByte* const toFill , const XMLSize_t maxBytes , XMLSize_t& charsEaten , const UnRepOpts options) { // Reset the tec state (since we don't know that we're part of a // larger run of text). TECClearConverterContextInfo(mUnicodeToText); // Do the conversion ByteCount bytesConsumed = 0; ByteCount bytesProduced = 0; OSStatus status = TECConvertText(mUnicodeToText, (ConstTextPtr) srcData, srcCount * sizeof(XMLCh), // inputBufferLength &bytesConsumed, // actualInputLength (TextPtr) toFill, // outputBuffer maxBytes, // outputBufferLength &bytesProduced); // actualOutputLength // Ignorable error codes if( status == kTECUsedFallbacksStatus || status == kTECOutputBufferFullStatus || status == kTECPartialCharErr ) status = noErr; std::size_t charsConsumed = bytesConsumed / sizeof(XMLCh); // Deal with errors if (status != noErr) { if (status == kTECUnmappableElementErr && options == UnRep_Throw) { XMLCh tmpBuf[17]; XMLString::binToText(srcData[charsConsumed], tmpBuf, 16, 16); ThrowXML2 ( TranscodingException , XMLExcepts::Trans_Unrepresentable , tmpBuf , getEncodingName() ); } } charsEaten = charsConsumed; return bytesProduced; }
XMLSize_t MacOSTranscoder::transcodeFrom( const XMLByte* const srcData , const XMLSize_t srcCount , XMLCh* const toFill , const XMLSize_t maxChars , XMLSize_t& bytesEaten , unsigned char* const charSizes) { // Reset the tec state (since we don't know that we're part of a // larger run of text). TECClearConverterContextInfo(mTextToUnicode); // Do the conversion ByteCount bytesConsumed = 0; ByteCount bytesProduced = 0; OSStatus status = TECConvertText(mTextToUnicode, (ConstTextPtr) srcData, srcCount, // inputBufferLength &bytesConsumed, // actualInputLength (TextPtr) toFill, // outputBuffer maxChars * sizeof(XMLCh), // outputBufferLength &bytesProduced); // actualOutputLength // Ignorable error codes if( status == kTECUsedFallbacksStatus || status == kTECOutputBufferFullStatus || status == kTECPartialCharErr ) status = noErr; if (status != noErr) ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq); std::size_t charsProduced = bytesProduced / sizeof(XMLCh); bytesEaten = bytesConsumed; return charsProduced; }
OSStatus TextCodecMac::decode(const unsigned char* inputBuffer, int inputBufferLength, int& inputLength, void *outputBuffer, int outputBufferLength, int& outputLength) { OSStatus status; unsigned long bytesRead = 0; unsigned long bytesWritten = 0; if (m_numBufferedBytes != 0) { // Finish converting a partial character that's in our buffer. // First, fill the partial character buffer with as many bytes as are available. ASSERT(m_numBufferedBytes < sizeof(m_bufferedBytes)); const int spaceInBuffer = sizeof(m_bufferedBytes) - m_numBufferedBytes; const int bytesToPutInBuffer = min(spaceInBuffer, inputBufferLength); ASSERT(bytesToPutInBuffer != 0); memcpy(m_bufferedBytes + m_numBufferedBytes, inputBuffer, bytesToPutInBuffer); // Now, do a conversion on the buffer. status = TECConvertText(m_converterTEC, m_bufferedBytes, m_numBufferedBytes + bytesToPutInBuffer, &bytesRead, reinterpret_cast<unsigned char*>(outputBuffer), outputBufferLength, &bytesWritten); ASSERT(bytesRead <= m_numBufferedBytes + bytesToPutInBuffer); if (status == kTECPartialCharErr && bytesRead == 0) { // Handle the case where the partial character was not converted. if (bytesToPutInBuffer >= spaceInBuffer) { LOG_ERROR("TECConvertText gave a kTECPartialCharErr but read none of the %zu bytes in the buffer", sizeof(m_bufferedBytes)); m_numBufferedBytes = 0; status = kTECUnmappableElementErr; // should never happen, but use this error code } else { // Tell the caller we read all the source bytes and keep them in the buffer. m_numBufferedBytes += bytesToPutInBuffer; bytesRead = bytesToPutInBuffer; status = noErr; } } else { // We are done with the partial character buffer. // Also, we have read some of the bytes from the main buffer. if (bytesRead > m_numBufferedBytes) { bytesRead -= m_numBufferedBytes; } else { LOG_ERROR("TECConvertText accepted some bytes it previously rejected with kTECPartialCharErr"); bytesRead = 0; } m_numBufferedBytes = 0; if (status == kTECPartialCharErr) { // While there may be a partial character problem in the small buffer, // we have to try again and not get confused and think there is a partial // character problem in the large buffer. status = noErr; } } } else { status = TECConvertText(m_converterTEC, inputBuffer, inputBufferLength, &bytesRead, static_cast<unsigned char*>(outputBuffer), outputBufferLength, &bytesWritten); ASSERT(static_cast<int>(bytesRead) <= inputBufferLength); } // Work around bug 3351093, where sometimes we get kTECBufferBelowMinimumSizeErr instead of kTECOutputBufferFullStatus. if (status == kTECBufferBelowMinimumSizeErr && bytesWritten != 0) status = kTECOutputBufferFullStatus; inputLength = bytesRead; outputLength = bytesWritten; return status; }