cygwintransservice.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,173 行 · 第 1/3 页

CPP
1,173
字号
        // 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            , (LPWSTR)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 intCygwinTranscoder::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            , (LPCWSTR)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 CygwinTranscoder::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        , (LPCWSTR)srcBuf        , srcCount        , tmpBuf        , 64        , 0        , &usedDef    );    if (!bytesStored || usedDef)        return false;    return true;}//---------------------------------------------------------------------------////  class CygwinTranscoder Implementation ...////---------------------------------------------------------------------------// ---------------------------------------------------------------------------//  CygwinLCPTranscoder: Constructors and Destructor// ---------------------------------------------------------------------------CygwinLCPTranscoder::CygwinLCPTranscoder(){}CygwinLCPTranscoder::~CygwinLCPTranscoder(){}// ---------------------------------------------------------------------------//  CygwinLCPTranscoder: Implementation of the virtual transcoder interface// ---------------------------------------------------------------------------unsigned int CygwinLCPTranscoder::calcRequiredSize(const char* const srcText                                                   , MemoryManager* const manager){    if (!srcText)        return 0;    return ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, srcText, -1, NULL, 0);}unsigned int CygwinLCPTranscoder::calcRequiredSize(const XMLCh* const srcText                                                   , MemoryManager* const manager){    if (!srcText)        return 0;    return ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)srcText, -1, NULL, 0, NULL, NULL);}char* CygwinLCPTranscoder::transcode(const XMLCh* const toTranscode){    if (!toTranscode)        return 0;    char* retVal = 0;    if (*toTranscode)    {        // Calc the needed size        const unsigned int neededLen = ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)toTranscode, -1, NULL, 0, NULL, NULL);        if (neededLen == 0)            return 0;        // Allocate a buffer of that size plus one for the null and transcode        // Returned length of WideCharToMultiByte includes terminating NUL.        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* CygwinLCPTranscoder::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 = ::WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)toTranscode, -1, NULL, 0, NULL, NULL);        if (neededLen == 0)            return 0;        // Allocate a buffer of that size plus one for the null and transcode        // Returned length of WideCharToMultiByte includes terminating NUL.        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;}XMLCh* CygwinLCPTranscoder::transcode(const char* const toTranscode){    if (!toTranscode)        return 0;    XMLCh* retVal = 0;    if (*toTranscode)    {        // Calculate the buffer size required        const unsigned int neededLen = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toTranscode, -1, NULL, 0);        if (neededLen == 0)            return 0;        // 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* CygwinLCPTranscoder::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 = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, toTranscode, -1, NULL, 0);        if (neededLen == 0)            return 0;        // 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 CygwinLCPTranscoder::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 CygwinLCPTranscoder::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 + -
显示快捷键?