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 + -
显示快捷键?