iconvgnutransservice.cpp

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

CPP
1,336
字号
    }    return toReturn;}size_t    IconvGNUWrapper::iconvFrom ( const char    *fromPtr,                 size_t        *fromLen,                 char        **toPtr,                 size_t        toLen ) const{    ICONV_LOCK;    char ** tmpPtr = (char**)&fromPtr;    return ::iconv (fCDFrom, tmpPtr, fromLen, toPtr, &toLen);}size_t    IconvGNUWrapper::iconvTo ( const char    *fromPtr,                   size_t        *fromLen,                   char        **toPtr,                   size_t        toLen ) const{    ICONV_LOCK;    char ** tmpPtr = (char**)&fromPtr;    return ::iconv (fCDTo, tmpPtr, fromLen, toPtr, &toLen);}// ---------------------------------------------------------------------------//  IconvGNUTransService: Constructors and Destructor// ---------------------------------------------------------------------------void reinitIconvGNUMutex(){    delete gIconvMutex;    gIconvMutex = 0;}IconvGNUTransService::IconvGNUTransService()    : IconvGNUWrapper(), fUnicodeCP(0){#if !defined(APP_NO_THREADS)    // Create global lock object    if (gIconvMutex == NULL) {        gIconvMutex = new XMLMutex;        if (gIconvMutex == NULL)            XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService);        IconvGNUMutexCleanup.registerCleanup(reinitIconvGNUMutex);    }#endif    // Try to obtain local (host) characterset through the environment    char*    fLocalCP = setlocale (LC_CTYPE, "");    if (fLocalCP == NULL)        fLocalCP = "iso-8859-1";    // fallback locale    else {        char    *ptr = strchr (fLocalCP, '.');        if (ptr == NULL)            fLocalCP = "iso-8859-1";    // fallback locale        else            fLocalCP = ptr + 1;    }    // Select the native unicode characters encoding schema    const IconvGNUEncoding    *eptr;    // first - try to use the schema with character size, equil to XMLCh    for (eptr = gIconvGNUEncodings; eptr->fSchema; eptr++) {        if (eptr->fUChSize != sizeof(XMLCh))            continue;        ICONV_LOCK;        // try to create conversion descriptor        iconv_t    cd_to = iconv_open(fLocalCP, eptr->fSchema);        if (cd_to == (iconv_t)-1)            continue;        iconv_t    cd_from = iconv_open(eptr->fSchema, fLocalCP);        if (cd_to == (iconv_t)-1) {            iconv_close (cd_to);            continue;        }        // got it        setUChSize(eptr->fUChSize);        setUBO(eptr->fUBO);        setCDTo(cd_to);        setCDFrom(cd_from);        fUnicodeCP = eptr->fSchema;        break;    }    if (fUnicodeCP == NULL)        // try to use any known schema        for (eptr = gIconvGNUEncodings; eptr->fSchema; eptr++) {            // try to create conversion descriptor            ICONV_LOCK;            iconv_t    cd_to = iconv_open(fLocalCP, eptr->fSchema);            if (cd_to == (iconv_t)-1)                continue;            iconv_t    cd_from = iconv_open(eptr->fSchema, fLocalCP);            if (cd_to == (iconv_t)-1) {                iconv_close (cd_to);                continue;            }            // got it            setUChSize(eptr->fUChSize);            setUBO(eptr->fUBO);            setCDTo(cd_to);            setCDFrom(cd_from);            fUnicodeCP = eptr->fSchema;            break;        }    if (fUnicodeCP == NULL || cdTo() == (iconv_t)-1 || cdFrom() == (iconv_t)-1)        XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService);}IconvGNUTransService::~IconvGNUTransService(){    if (cdTo() != (iconv_t) -1) {        iconv_close (cdTo());        setCDTo ((iconv_t)-1);    }    if (cdFrom() != (iconv_t) -1) {        iconv_close (cdFrom());        setCDFrom ((iconv_t)-1);    }}// ---------------------------------------------------------------------------//  IconvGNUTransService: The virtual transcoding service API// ---------------------------------------------------------------------------int IconvGNUTransService::compareIString(const XMLCh* const    comp1                                        , const XMLCh* const    comp2){    const XMLCh* cptr1 = comp1;    const XMLCh* cptr2 = comp2;    XMLCh    c1 = toUpper(*cptr1);    XMLCh    c2 = toUpper(*cptr2);    while ( (*cptr1 != 0) && (*cptr2 != 0) ) {        if (c1 != c2)            break;        c1 = toUpper(*(++cptr1));        c2 = toUpper(*(++cptr2));    }    return (int) ( c1 - c2 );}int IconvGNUTransService::compareNIString(const XMLCh* const    comp1                                         , const XMLCh* const    comp2                                         , const unsigned int    maxChars){    unsigned int  n = 0;    const XMLCh* cptr1 = comp1;    const XMLCh* cptr2 = comp2;    while (true && maxChars)    {        XMLCh    c1 = toUpper(*cptr1);        XMLCh    c2 = toUpper(*cptr2);        if (c1 != c2)            return (int) (c1 - c2);        // If either ended, then both ended, so equal        if (!*cptr1 || !*cptr2)            break;        cptr1++;        cptr2++;        //  Bump the count of chars done. If it equals the count then we        //  are equal for the requested count, so break out and return        //  equal.        n++;        if (n == maxChars)            break;    }    return 0;}const XMLCh* IconvGNUTransService::getId() const{    return gMyServiceId;}bool IconvGNUTransService::isSpace(const XMLCh toCheck) const{    return IconvGNUWrapper::isSpace(toCheck);}XMLLCPTranscoder* IconvGNUTransService::makeNewLCPTranscoder(){    return new IconvGNULCPTranscoder (cdFrom(), cdTo(), uChSize(), UBO());}bool IconvGNUTransService::supportsSrcOfs() const{    return true;}// ---------------------------------------------------------------------------//  IconvGNUTransService: The protected virtual transcoding service API// ---------------------------------------------------------------------------XMLTranscoder*IconvGNUTransService::makeNewXMLTranscoder(    const    XMLCh* const    encodingName    ,    XMLTransService::Codes&    resValue    , const    unsigned int    blockSize    ,        MemoryManager* const    manager){    resValue = XMLTransService::UnsupportedEncoding;    IconvGNUTranscoder    *newTranscoder = NULL;    char    *encLocal = XMLString::transcode(encodingName, manager);    iconv_t    cd_from, cd_to;    {        ICONV_LOCK;        cd_from = iconv_open (fUnicodeCP, encLocal);        if (cd_from == (iconv_t)-1) {            resValue = XMLTransService::SupportFilesNotFound;            if (encLocal)                manager->deallocate(encLocal);//delete [] encLocal;            return NULL;        }        cd_to = iconv_open (encLocal, fUnicodeCP);        if (cd_to == (iconv_t)-1) {            resValue = XMLTransService::SupportFilesNotFound;            iconv_close (cd_from);            if (encLocal)                manager->deallocate(encLocal);//delete [] encLocal;            return NULL;        }        newTranscoder = new (manager) IconvGNUTranscoder (encodingName,                             blockSize,                             cd_from, cd_to,                             uChSize(), UBO(), manager);    }    if (newTranscoder)        resValue = XMLTransService::Ok;    if (encLocal)        manager->deallocate(encLocal);//delete [] encLocal;    return newTranscoder;}void IconvGNUTransService::upperCase(XMLCh* const toUpperCase) const{    XMLCh* outPtr = toUpperCase;    while (*outPtr)    {        *outPtr = toUpper(*outPtr);        outPtr++;    }}void IconvGNUTransService::lowerCase(XMLCh* const toLowerCase) const{    XMLCh* outPtr = toLowerCase;    while (*outPtr)    {        *outPtr = toLower(*outPtr);        outPtr++;    }}// ---------------------------------------------------------------------------//  IconvGNULCPTranscoder: The virtual transcoder API// ---------------------------------------------------------------------------unsigned intIconvGNULCPTranscoder::calcRequiredSize (const char* const srcText                                         , MemoryManager* const manager){    if (!srcText)        return 0;    size_t      len, srcLen;    len = srcLen = strlen(srcText);    if (len == 0)        return 0;    char    tmpWideArr[gTempBuffArraySize];    size_t    totalLen = 0;    for (;;) {        char        *pTmpArr = tmpWideArr;        const char    *ptr = srcText + srcLen - len;        size_t    rc = iconvFrom(ptr, &len, &pTmpArr, gTempBuffArraySize);        if (rc == (size_t) -1 && errno != E2BIG) {            ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, manager);            /* return 0; */        }        rc = pTmpArr - (char *) tmpWideArr;        totalLen += rc;        if (rc == 0 || len == 0)            break;    }    return totalLen / uChSize();}unsigned intIconvGNULCPTranscoder::calcRequiredSize(const XMLCh* const srcText                                        , MemoryManager* const manager){    if (!srcText)        return 0;    unsigned int  wLent = getWideCharLength(srcText);    if (wLent == 0)        return 0;    char    tmpWBuff[gTempBuffArraySize];    char    *wBuf = 0;    char    *wBufPtr = 0;    size_t      len = wLent * uChSize();    if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {        if (len > gTempBuffArraySize) {            wBufPtr = (char*) manager->allocate            (                len * sizeof(char)            );//new char[len];            if (wBufPtr == NULL)            return 0;            wBuf = wBufPtr;        } else            wBuf = tmpWBuff;        xmlToMbs (srcText, wLent, wBuf, wLent);    } else        wBuf = (char *) srcText;    char    tmpBuff[gTempBuffArraySize];    size_t    totalLen = 0;    char    *srcEnd = wBuf + wLent * uChSize();    for (;;) {        char        *pTmpArr = tmpBuff;        const char    *ptr = srcEnd - len;        size_t    rc = iconvTo(ptr, &len, &pTmpArr, gTempBuffArraySize);        if (rc == (size_t) -1 && errno != E2BIG) {            if (wBufPtr)                manager->deallocate(wBufPtr);//delete [] wBufPtr;            ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, manager);            /* return 0; */        }        rc = pTmpArr - tmpBuff;        totalLen += rc;        if (rc == 0 || len == 0)            break;    }    if (wBufPtr)        manager->deallocate(wBufPtr);//delete [] wBufPtr;    return totalLen;}char* IconvGNULCPTranscoder::transcode(const XMLCh* const toTranscode){    if (!toTranscode)        return 0;    char* retVal = 0;    if (*toTranscode) {        unsigned int  wLent = getWideCharLength(toTranscode);        // Calc needed size.        const size_t neededLen = calcRequiredSize (toTranscode);        if (neededLen == 0)            return 0;        // allocate output buffer        retVal = new char[neededLen + 1];        if (retVal == NULL)            return 0;        // prepare the original        char    tmpWBuff[gTempBuffArraySize];        char    *wideCharBuf = 0;        char    *wBufPtr = 0;        size_t  len = wLent * uChSize();        if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {            if (len > gTempBuffArraySize) {                wBufPtr = new char[len];                if (wBufPtr == NULL)                    return 0;                wideCharBuf = wBufPtr;            } else                wideCharBuf = tmpWBuff;            xmlToMbs (toTranscode, wLent, wideCharBuf, wLent);        } else            wideCharBuf = (char *) toTranscode;        // perform conversion        wLent *= uChSize();        char    *ptr = retVal;        size_t    rc = iconvTo(wideCharBuf, (size_t *) &wLent, &ptr, neededLen);        if (rc == (size_t)-1) {            if (wBufPtr)            delete [] wBufPtr;            return 0;        }        if (wBufPtr)            delete [] wBufPtr;        retVal[neededLen] = 0;    } else {        retVal = new char[1];        if (retVal == NULL)            return 0;        retVal[0] = 0;    }    return retVal;}char* IconvGNULCPTranscoder::transcode(const XMLCh* const toTranscode,                                       MemoryManager* const manager){    if (!toTranscode)        return 0;    char* retVal = 0;    if (*toTranscode) {        unsigned int  wLent = getWideCharLength(toTranscode);        // Calc needed size.        const size_t neededLen = calcRequiredSize (toTranscode, manager);        if (neededLen == 0)            return 0;        // allocate output buffer        retVal = (char*) manager->allocate((neededLen + 1) * sizeof(char));//new char[neededLen + 1];        if (retVal == NULL)            return 0;        // prepare the original        char    tmpWBuff[gTempBuffArraySize];        char    *wideCharBuf = 0;        char    *wBufPtr = 0;        size_t  len = wLent * uChSize();        if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {            if (len > gTempBuffArraySize) {                wBufPtr = (char*) manager->allocate(len * sizeof(char));//new char[len];                if (wBufPtr == NULL)                    return 0;                wideCharBuf = wBufPtr;            } else                wideCharBuf = tmpWBuff;

⌨️ 快捷键说明

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