iconv400transservice.cpp

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

CPP
1,042
字号
        , false        , &err    );    if (err)   /*@01A*/    {        XMLCh tmpBuf[17];        XMLString::binToText((unsigned int)*startSrc, tmpBuf, 16, 16, getMemoryManager());        ThrowXMLwithMemMgr2        (            TranscodingException            , XMLExcepts::Trans_Unrepresentable            , tmpBuf            , getEncodingName()            , getMemoryManager()        );    }    // Fill in the chars we ate from the input    charsEaten = startSrc - srcPtr;    // Return the chars we stored    return startTarget - toFill;}bool Iconv400Transcoder::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. While    //  we are ate it, convert them to UChar format if required.    //    UChar           srcBuf[2];    unsigned int    srcCount = 1;    if (toCheck & 0xFFFF0000)    {        srcBuf[0] = UChar((toCheck >> 10) + 0xD800);        srcBuf[1] = UChar(toCheck & 0x3FF) + 0xDC00;        srcCount++;    }     else    {        srcBuf[0] = UChar(toCheck);    }    // Set upa temp buffer to format into. Make it more than big enough    char            tmpBuf[64];    char*           startTarget = tmpBuf;    const UChar*    startSrc = srcBuf;    UErrorCode  err = U_ZERO_ERROR;    ucnv_fromUnicode    (        fConverter        , &startTarget        , startTarget + 64        , &startSrc        , srcBuf + srcCount        , 0        , false        , &err    );    return (err==U_ZERO_ERROR);  /*@01A*/}// ---------------------------------------------------------------------------//  IconvLCPTranscoder: Constructors and Destructor// ---------------------------------------------------------------------------Iconv400LCPTranscoder::Iconv400LCPTranscoder(UConverter* const toAdopt) :    fConverter(toAdopt){}Iconv400LCPTranscoder::~Iconv400LCPTranscoder(){    // If there is a converter, ask Iconv to clean it up    if (fConverter)    {        // <TBD> Does this actually delete the structure???        ucnv_close(fConverter);        fConverter = 0;    }}// ---------------------------------------------------------------------------//  Iconv400LCPTranscoder: Constructors and Destructor// ---------------------------------------------------------------------------unsigned int Iconv400LCPTranscoder::calcRequiredSize(const XMLCh* const srcText                                                     , MemoryManager* const manager){    if (!srcText)        return 0;    // Lock and attempt the calculation    UErrorCode err = U_ZERO_ERROR;    int32_t targetCap;    {        XMLMutexLock lockConverter(&fMutex);        targetCap = ucnv_fromUChars        (            fConverter            , 0            , 0            , srcText            , &err        );    }    if (err != U_BUFFER_OVERFLOW_ERROR)        return 0;    return (unsigned int)targetCap;}unsigned int Iconv400LCPTranscoder::calcRequiredSize(const char* const srcText                                                     , MemoryManager* const manager){    if (!srcText)        return 0;    int32_t targetCap;    UErrorCode err = U_ZERO_ERROR;    {        XMLMutexLock lockConverter(&fMutex);        targetCap = ucnv_toUChars        (            fConverter            , 0            , 0            , srcText            , strlen(srcText)            , &err        );    }    if (err != U_BUFFER_OVERFLOW_ERROR)        return 0;    // Subtract one since it includes the terminator space    return (unsigned int)(targetCap - 1);}char* Iconv400LCPTranscoder::transcode(const XMLCh* const toTranscode){    char* retBuf = 0;    // Check for a couple of special cases    if (!toTranscode)        return 0;    if (!*toTranscode)    {        retBuf = new char[1];        retBuf[0] = 0;        return retBuf;    }    // Caculate a return buffer size not too big, but less likely to overflow    int32_t targetLen = (int32_t)(u_strlen(toTranscode) * 1.25);    // Allocate the return buffer    retBuf = new char[targetLen + 1];    // Lock now while we call the converter.    UErrorCode err = U_ZERO_ERROR;    int32_t targetCap;    {        XMLMutexLock lockConverter(&fMutex);        //Convert the Unicode string to char*        targetCap = ucnv_fromUChars        (            fConverter            , retBuf            , targetLen + 1            , toTranscode            , &err        );    }    // If targetLen is not enough then buffer overflow might occur    if (err == U_BUFFER_OVERFLOW_ERROR)    {        // Reset the error, delete the old buffer, allocate a new one, and try again        err = U_ZERO_ERROR;        delete [] retBuf;        retBuf = new char[targetCap];        // Lock again before we retry        XMLMutexLock lockConverter(&fMutex);        targetCap = ucnv_fromUChars        (            fConverter            , retBuf            , targetCap            , toTranscode            , &err        );    }    if (U_FAILURE(err))    {        delete [] retBuf;        return 0;    }    // Cap it off and return    retBuf[targetCap] = 0;    return retBuf;}char* Iconv400LCPTranscoder::transcode(const XMLCh* const toTranscode,                                       MemoryManager* const manager){    char* retBuf = 0;    // Check for a couple of special cases    if (!toTranscode)        return 0;    if (!*toTranscode)    {        retBuf = (char*) manager->allocate(sizeof(char));//new char[1];        retBuf[0] = 0;        return retBuf;    }    // Caculate a return buffer size not too big, but less likely to overflow    int32_t targetLen = (int32_t)(u_strlen(toTranscode) * 1.25);    // Allocate the return buffer    retBuf = (char*) manager->allocate((targetLen + 1) * sizeof(char));//new char[targetLen + 1];    // Lock now while we call the converter.    UErrorCode err = U_ZERO_ERROR;    int32_t targetCap;    {        XMLMutexLock lockConverter(&fMutex);        //Convert the Unicode string to char*        targetCap = ucnv_fromUChars        (            fConverter            , retBuf            , targetLen + 1            , toTranscode            , &err        );    }    // If targetLen is not enough then buffer overflow might occur    if (err == U_BUFFER_OVERFLOW_ERROR)    {        // Reset the error, delete the old buffer, allocate a new one, and try again        err = U_ZERO_ERROR;        manager->deallocate(retBuf);//delete [] retBuf;        retBuf = (char*) manager->allocate(targetCap * sizeof(char));//new char[targetCap];        // Lock again before we retry        XMLMutexLock lockConverter(&fMutex);        targetCap = ucnv_fromUChars        (            fConverter            , retBuf            , targetCap            , toTranscode            , &err        );    }    if (U_FAILURE(err))    {        manager->deallocate(retBuf);//delete [] retBuf;        return 0;    }    // Cap it off and return    retBuf[targetCap] = 0;    return retBuf;}XMLCh* Iconv400LCPTranscoder::transcode(const char* const toTranscode){    // Watch for a few pyscho corner cases    if (!toTranscode)        return 0;    XMLCh* retVal = 0;    if (!*toTranscode)    {        retVal = new XMLCh[1];        retVal[0] = 0;        return retVal;    }    //    //  Get the length of the string to transcode. The Unicode string will    //  almost always be no more chars than were in the source, so this is    //  the best guess as to the storage needed.    //    const int32_t srcLen = (int32_t)strlen(toTranscode);    // Allocate unicode string of equivalent length in unicode bytes    retVal = new XMLCh[srcLen+1];    // Now lock while we do these calculations    UErrorCode err = U_ZERO_ERROR;    {        XMLMutexLock lockConverter(&fMutex);        //        //  Here we don't know what the target length will be so use 0 and        //  expect an U_BUFFER_OVERFLOW_ERROR in which case it'd get resolved        //  by the correct capacity value.        //        int32_t targetCap;        targetCap = ucnv_toUChars        (            fConverter            , retVal            , srcLen+1            , toTranscode            , srcLen            , &err        );        if (err != U_BUFFER_OVERFLOW_ERROR)	{        err = U_ZERO_ERROR;        retVal = new XMLCh[targetCap];        ucnv_toUChars        (            fConverter            , retVal            , targetCap            , toTranscode            , srcLen            , &err           );	 }   }    if (U_FAILURE(err))    {        // Clean up if we got anything allocated        delete [] retVal;        return 0;    }    return retVal;}XMLCh* Iconv400LCPTranscoder::transcode(const char* const toTranscode,                                        MemoryManager* const manager){    // Watch for a few pyscho corner cases    if (!toTranscode)        return 0;    XMLCh* retVal = 0;    if (!*toTranscode)    {        retVal = (XMLCh*) manager->allocate(sizeof(XMLCh));//new XMLCh[1];        retVal[0] = 0;        return retVal;    }    //    //  Get the length of the string to transcode. The Unicode string will    //  almost always be no more chars than were in the source, so this is    //  the best guess as to the storage needed.    //    const int32_t srcLen = (int32_t)strlen(toTranscode);    // Allocate unicode string of equivalent length in unicode bytes    retVal = (XMLCh*) manager->allocate((srcLen + 1) * sizeof(XMLCh));//new XMLCh[srcLen+1];    // Now lock while we do these calculations    UErrorCode err = U_ZERO_ERROR;    {        XMLMutexLock lockConverter(&fMutex);        //        //  Here we don't know what the target length will be so use 0 and        //  expect an U_BUFFER_OVERFLOW_ERROR in which case it'd get resolved        //  by the correct capacity value.        //        int32_t targetCap;        targetCap = ucnv_toUChars        (            fConverter            , retVal            , srcLen+1            , toTranscode            , srcLen            , &err        );        if (err != U_BUFFER_OVERFLOW_ERROR)	{        err = U_ZERO_ERROR;        retVal = (XMLCh*) manager->allocate(targetCap * sizeof(XMLCh));//new XMLCh[targetCap];        ucnv_toUChars        (            fConverter            , retVal            , targetCap            , toTranscode            , srcLen            , &err           );	 }   }    if (U_FAILURE(err))    {        // Clean up if we got anything allocated        manager->deallocate(retVal);//delete [] retVal;        return 0;    }    return retVal;}bool Iconv400LCPTranscoder::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;    }    // Lock and do the transcode operation    UErrorCode err = U_ZERO_ERROR;    const int32_t srcLen = (int32_t)strlen(toTranscode);    {        XMLMutexLock lockConverter(&fMutex);        ucnv_toUChars        (            fConverter            , toFill            , maxChars + 1            , toTranscode            , srcLen            , &err        );    }    if (U_FAILURE(err))        return false;    return true;}bool Iconv400LCPTranscoder::transcode(   const   XMLCh* const    toTranscode                                    ,       char* const     toFill                                    , const unsigned int    maxChars                                    , MemoryManager* const  manager){    // Watch for a few psycho corner cases    if (!toTranscode || !maxChars)    {        toFill[0] = 0;        return true;    }    if (!*toTranscode)    {        toFill[0] = 0;        return true;    }    UErrorCode err = U_ZERO_ERROR;    int32_t targetCap;    {        XMLMutexLock lockConverter(&fMutex);        targetCap = ucnv_fromUChars        (            fConverter            , toFill            , maxChars + 1            , toTranscode            , &err        );    }    if (U_FAILURE(err))        return false;    toFill[targetCap] = 0;    return true;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?