win32transservice.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,004 行 · 第 1/2 页
CPP
1,004 行
XMLTranscoder*Win32TransService::makeNewXMLTranscoder(const XMLCh* const encodingName , XMLTransService::Codes& resValue , const unsigned int blockSize , MemoryManager* const manager){ const unsigned int upLen = 1024; XMLCh upEncoding[upLen + 1]; // // Get an upper cased copy of the encoding name, since we use a hash // table and we store them all in upper case. // ::wcsncpy(upEncoding, encodingName, upLen); upEncoding[upLen] = 0; _wcsupr(upEncoding); // Now to try to find this guy in the CP map CPMapEntry* theEntry = fCPMap->get(upEncoding); // If not found, then return a null pointer if (!theEntry) { resValue = XMLTransService::UnsupportedEncoding; return 0; } // We found it, so return a Win32 transcoder for this encoding return new (manager) Win32Transcoder ( encodingName , theEntry->getWinCP() , theEntry->getIEEncoding() , blockSize , manager );}//---------------------------------------------------------------------------//// class Win32Transcoder Implementation ...////---------------------------------------------------------------------------// ---------------------------------------------------------------------------// Win32Transcoder: Constructors and Destructor// ---------------------------------------------------------------------------Win32Transcoder::Win32Transcoder(const XMLCh* const encodingName , const unsigned int winCP , const unsigned int ieCP , const unsigned int blockSize , MemoryManager* const manager) : XMLTranscoder(encodingName, blockSize, manager) , fIECP(ieCP) , fWinCP(winCP){}Win32Transcoder::~Win32Transcoder(){}// ---------------------------------------------------------------------------// Win32Transcoder: The virtual transcoder API// ---------------------------------------------------------------------------unsigned intWin32Transcoder::transcodeFrom( const XMLByte* const srcData , const unsigned int srcCount , XMLCh* const toFill , const unsigned int maxChars , unsigned int& bytesEaten , unsigned char* const charSizes){ // Get temp pointers to the in and out buffers, and the chars sizes one XMLCh* outPtr = toFill; const XMLByte* inPtr = srcData; unsigned char* sizesPtr = charSizes; // Calc end pointers for each of them XMLCh* outEnd = toFill + maxChars; const XMLByte* inEnd = srcData + srcCount; // // Now loop until we either get our max chars, or cannot get a whole // character from the input buffer. // bytesEaten = 0; while ((outPtr < outEnd) && (inPtr < inEnd)) { // // If we are looking at a leading byte of a multibyte sequence, // then we are going to eat 2 bytes, else 1. // const unsigned int toEat = ::IsDBCSLeadByteEx(fWinCP, *inPtr) ? 2 : 1; // Make sure a whol char is in the source if (inPtr + toEat > inEnd) break; // Try to translate this next char and check for an error const unsigned int converted = ::MultiByteToWideChar ( fWinCP , MB_PRECOMPOSED | MB_ERR_INVALID_CHARS , (const char*)inPtr , toEat , outPtr , 1 ); if (converted != 1) { if (toEat == 1) { XMLCh tmpBuf[17]; XMLString::binToText((unsigned int)(*inPtr), tmpBuf, 16, 16, getMemoryManager()); ThrowXMLwithMemMgr2 ( TranscodingException , XMLExcepts::Trans_BadSrcCP , tmpBuf , getEncodingName() , getMemoryManager() ); } else { ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, getMemoryManager()); } } // Update the char sizes array for this round *sizesPtr++ = toEat; // And update the bytes eaten count bytesEaten += toEat; // And update our in/out ptrs inPtr += toEat; outPtr++; } // Return the chars we output return (outPtr - toFill);}unsigned intWin32Transcoder::transcodeTo(const XMLCh* const srcData , const unsigned int srcCount , XMLByte* const toFill , const unsigned int maxBytes , unsigned int& charsEaten , const UnRepOpts options){ // Get pointers to the start and end of each buffer const XMLCh* srcPtr = srcData; const XMLCh* srcEnd = srcData + srcCount; XMLByte* outPtr = toFill; XMLByte* outEnd = toFill + maxBytes; // // Now loop until we either get our max chars, or cannot get a whole // character from the input buffer. // // NOTE: We have to use a loop for this unfortunately because the // conversion API is too dumb to tell us how many chars it converted if // it couldn't do the whole source. // BOOL usedDef; while ((outPtr < outEnd) && (srcPtr < srcEnd)) { // // Do one char and see if it made it. const unsigned int bytesStored = ::WideCharToMultiByte ( fWinCP , WC_COMPOSITECHECK | WC_SEPCHARS , srcPtr , 1 , (char*)outPtr , outEnd - outPtr , 0 , &usedDef ); // If we didn't transcode anything, then we are done if (!bytesStored) break; // // If the defaault char was used and the options indicate that // this isn't allowed, then throw. // if (usedDef && (options == UnRep_Throw)) { XMLCh tmpBuf[17]; XMLString::binToText((unsigned int)*srcPtr, tmpBuf, 16, 16, getMemoryManager()); ThrowXMLwithMemMgr2 ( TranscodingException , XMLExcepts::Trans_Unrepresentable , tmpBuf , getEncodingName() , getMemoryManager() ); } // Update our pointers outPtr += bytesStored; srcPtr++; } // Update the chars eaten charsEaten = srcPtr - srcData; // And return the bytes we stored return outPtr - toFill;}bool Win32Transcoder::canTranscodeTo(const unsigned int toCheck) const{ // // If the passed value is really a surrogate embedded together, then // we need to break it out into its two chars. Else just one. // XMLCh srcBuf[2]; unsigned int srcCount = 1; if (toCheck & 0xFFFF0000) { srcBuf[0] = XMLCh((toCheck >> 10) + 0xD800); srcBuf[1] = XMLCh(toCheck & 0x3FF) + 0xDC00; srcCount++; } else { srcBuf[0] = XMLCh(toCheck); } // // Use a local temp buffer that would hold any sane multi-byte char // sequence and try to transcode this guy into it. // char tmpBuf[64]; BOOL usedDef; const unsigned int bytesStored = ::WideCharToMultiByte ( fWinCP , WC_COMPOSITECHECK | WC_SEPCHARS , srcBuf , srcCount , tmpBuf , 64 , 0 , &usedDef ); if (!bytesStored || usedDef) return false; return true;}//---------------------------------------------------------------------------//// class Win32Transcoder Implementation ...////---------------------------------------------------------------------------// ---------------------------------------------------------------------------// Win32LCPTranscoder: Constructors and Destructor// ---------------------------------------------------------------------------Win32LCPTranscoder::Win32LCPTranscoder(){}Win32LCPTranscoder::~Win32LCPTranscoder(){}// ---------------------------------------------------------------------------// Win32LCPTranscoder: Implementation of the virtual transcoder interface// ---------------------------------------------------------------------------unsigned int Win32LCPTranscoder::calcRequiredSize(const char* const srcText , MemoryManager* const manager){ if (!srcText) return 0; return ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, srcText, -1, NULL, 0);}unsigned int Win32LCPTranscoder::calcRequiredSize(const XMLCh* const srcText , MemoryManager* const manager){ if (!srcText) return 0; return ::WideCharToMultiByte(CP_ACP, 0, srcText, -1, NULL, 0, NULL, NULL);}// Return value using global operator new// Revisit: deprecate ?char* Win32LCPTranscoder::transcode(const XMLCh* const toTranscode){ if (!toTranscode) return 0; char* retVal = 0; if (*toTranscode) { // Calc the needed size const unsigned int neededLen = calcRequiredSize(toTranscode); // Allocate a buffer of that size plus one for the null and transcode retVal = new char[neededLen + 1]; ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)toTranscode, -1, retVal, neededLen+1, NULL, NULL); // And cap it off anyway just to make sure retVal[neededLen] = 0; } else { retVal = new char[1]; retVal[0] = 0; } return retVal;}char* Win32LCPTranscoder::transcode(const XMLCh* const toTranscode, MemoryManager* const manager){ if (!toTranscode) return 0; char* retVal = 0; if (*toTranscode) { // Calc the needed size const unsigned int neededLen = calcRequiredSize(toTranscode, manager); // Allocate a buffer of that size plus one for the null and transcode retVal = (char*) manager->allocate((neededLen + 1) * sizeof(char)); //new char[neededLen + 1]; ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)toTranscode, -1, retVal, neededLen+1, NULL, NULL); // And cap it off anyway just to make sure retVal[neededLen] = 0; } else { retVal = (char*) manager->allocate(sizeof(char)); //new char[1]; retVal[0] = 0; } return retVal;}// Return value using global operator new// Revisit: deprecate ?XMLCh* Win32LCPTranscoder::transcode(const char* const toTranscode){ if (!toTranscode) return 0; XMLCh* retVal = 0; if (*toTranscode) { // Calculate the buffer size required const unsigned int neededLen = calcRequiredSize(toTranscode); if (neededLen == 0) { retVal = new XMLCh[1]; retVal[0] = 0; return retVal; } // Allocate a buffer of that size plus one for the null and transcode retVal = new XMLCh[neededLen + 1]; ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toTranscode, -1, (LPWSTR)retVal, neededLen + 1); // Cap it off just to make sure. We are so paranoid! retVal[neededLen] = 0; } else { retVal = new XMLCh[1]; retVal[0] = 0; } return retVal;}XMLCh* Win32LCPTranscoder::transcode(const char* const toTranscode, MemoryManager* const manager){ if (!toTranscode) return 0; XMLCh* retVal = 0; if (*toTranscode) { // Calculate the buffer size required const unsigned int neededLen = calcRequiredSize(toTranscode, manager); if (neededLen == 0) { retVal = (XMLCh*) manager->allocate(sizeof(XMLCh)); //new XMLCh[1]; retVal[0] = 0; return retVal; } // Allocate a buffer of that size plus one for the null and transcode retVal = (XMLCh*) manager->allocate((neededLen + 1) * sizeof(XMLCh)); //new XMLCh[neededLen + 1]; ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toTranscode, -1, (LPWSTR)retVal, neededLen + 1); // Cap it off just to make sure. We are so paranoid! retVal[neededLen] = 0; } else { retVal = (XMLCh*) manager->allocate(sizeof(XMLCh)); //new XMLCh[1]; retVal[0] = 0; } return retVal;}bool Win32LCPTranscoder::transcode( const char* const toTranscode , XMLCh* const toFill , const unsigned int maxChars , MemoryManager* const manager){ // Check for a couple of psycho corner cases if (!toTranscode || !maxChars) { toFill[0] = 0; return true; } if (!*toTranscode) { toFill[0] = 0; return true; } // This one has a fixed size output, so try it and if it fails it fails if ( 0 == ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toTranscode, -1, (LPWSTR)toFill, maxChars + 1) ) return false; return true;}bool Win32LCPTranscoder::transcode( const XMLCh* const toTranscode , char* const toFill , const unsigned int maxBytes , MemoryManager* const manager){ // Watch for a couple of pyscho corner cases if (!toTranscode || !maxBytes) { toFill[0] = 0; return true; } if (!*toTranscode) { toFill[0] = 0; return true; } // This one has a fixed size output, so try it and if it fails it fails if ( 0 == ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)toTranscode, -1, toFill, maxBytes + 1, NULL, NULL) ) return false; // Cap it off just in case toFill[maxBytes] = 0; return true;}XERCES_CPP_NAMESPACE_END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?