cygwintransservice.cpp

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

CPP
1,173
字号
        ::RegCloseKey(encodingKey);        subIndex++;    }    //    //  Now loop one more time and this time we do just the aliases. For    //  each one we find, we look up that name in the map we've already    //  built and add a new entry with this new name and the same id    //  values we stored for the original.    //    subIndex = 0;    char aliasBuf[nameBufSz + 1];    while (true)    {        // Get the name of the next key        theSize = nameBufSz;        if (::RegEnumKeyExA        (            charsetKey            , subIndex            , nameBuf            , &theSize            , 0, 0, 0, 0) == ERROR_NO_MORE_ITEMS)        {            break;        }        // Open this subkey        HKEY encodingKey;        if (::RegOpenKeyExA        (            charsetKey            , nameBuf            , 0            , KEY_READ            , &encodingKey))        {            XMLPlatformUtils::panic(PanicHandler::Panic_NoTransService);        }        //        //  If its an alias, look up the name in the map. If we find it,        //  then construct a new one with the new name and the aliased        //  ids.        //        if (isAlias(encodingKey, aliasBuf, nameBufSz))        {            const unsigned int srcLen = strlen(aliasBuf);            const unsigned int targetLen = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aliasBuf, srcLen, NULL, 0);            XMLCh* uniAlias = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate            (                (targetLen + 1) * sizeof(XMLCh)            );//new XMLCh[targetLen + 1];            ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aliasBuf, srcLen, (LPWSTR)uniAlias, targetLen);            uniAlias[targetLen] = 0;            ::LCMapStringW( gLocaleId, LCMAP_UPPERCASE, (LPCWSTR)uniAlias, targetLen, (LPWSTR)uniAlias, targetLen);            // Look up the alias name            CPMapEntry* aliasedEntry = fCPMap->get(uniAlias);            if (aliasedEntry)            {                //                //  If the name is actually different, then take it.                //  Otherwise, don't take it. They map aliases that are                //  just different case.                //                if (auxCompareString(uniAlias, aliasedEntry->getEncodingName(), -1L, false))                {                    CPMapEntry* newEntry = new CPMapEntry(uniAlias, aliasedEntry->getWinCP(), aliasedEntry->getIEEncoding());                    fCPMap->put((void*)newEntry->getEncodingName(), newEntry);                }            }            XMLPlatformUtils::fgMemoryManager->deallocate(uniAlias);//delete [] uniAlias;        }        // And now close the subkey handle and bump the subkey index        ::RegCloseKey(encodingKey);        subIndex++;    }    // And close the main key handle    ::RegCloseKey(charsetKey);}CygwinTransService::~CygwinTransService(){    delete fCPMap;}// ---------------------------------------------------------------------------//  CygwinTransService: The virtual transcoding service API// ---------------------------------------------------------------------------int CygwinTransService::auxCompareString( const XMLCh* const comp1                                         , const XMLCh* const comp2                                         , signed long maxChars                                         , const bool ignoreCase){    const XMLCh* args[2] = { comp1, comp2 };    XMLCh*       firstBuf = NULL;    XMLCh*       secondBuf;    unsigned int len = XMLString::stringLen( comp1);    unsigned int otherLen = XMLString::stringLen( comp2);    unsigned int countChar = 0;    int          theResult = 0;    // Determine at what string index the comparison stops.    if ( maxChars != -1L )    {        len = ( len > maxChars ) ? maxChars : len;        otherLen = ( otherLen > maxChars ) ? maxChars : otherLen;        maxChars = ( len > otherLen ) ? otherLen : len;    }    else    {        // When no Max given must compare terminating NUL to return        // difference if one string is shorter than the other.        maxChars = ( len > otherLen ) ? otherLen : len;        ++maxChars;    }    // Handle situation when one argument or the other is NULL    // by returning +/- string length of non-NULL argument (inferred    // from XMLString::CompareNString).    // Obs. Definition of stringLen(XMLCh*) implies NULL ptr and ptr    // to Empty String are equivalent.  It handles NULL args, BTW.    if ( !comp1 )    {        // Negative because null ptr (c1) less than string (c2).        return ( 0 - otherLen );    }    if ( !comp2 )    {        // Positive because string (c1) still greater than null ptr (c2).        return len;    }    // Handle case-insensitive comparison by removing case from string.    if ( ignoreCase )    {        // Copy const parameter strings (plus terminating nul) into locals.        firstBuf = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate        (            (++len) * sizeof(XMLCh)        );//new XMLCh[ ++len];        secondBuf = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate        (            (++otherLen) * sizeof(XMLCh)        );//new XMLCh[ ++otherLen];        memcpy( firstBuf, comp1, len * sizeof(XMLCh));        memcpy( secondBuf, comp2, otherLen * sizeof(XMLCh));        // Then uppercase both strings, losing their case info.        ::LCMapStringW( gLocaleId, LCMAP_UPPERCASE, (LPWSTR)firstBuf, len, (LPWSTR)firstBuf, len);        ::LCMapStringW( gLocaleId, LCMAP_UPPERCASE, (LPWSTR)secondBuf, otherLen, (LPWSTR)secondBuf, otherLen);        // Replace original params in args array with UC ones.        args[0] = (const XMLCh*)firstBuf;        args[1] = (const XMLCh*)secondBuf;        // Not necessary only because they're not used beyond this pt.        // --len;        // --otherLen;    }    // Strings are equal until proven otherwise.    while ( ( countChar < maxChars ) && ( !theResult ) )    {        theResult = (int)(args[0][countChar]) - (int)(args[1][countChar]);        ++countChar;    }    // Clean-up buffers, equivalent to if ( ignoreCase )    if ( firstBuf )    {        XMLPlatformUtils::fgMemoryManager->deallocate(firstBuf);//delete [] firstBuf;        XMLPlatformUtils::fgMemoryManager->deallocate(secondBuf);//delete [] secondBuf;    }    return theResult;}int CygwinTransService::compareIString(  const   XMLCh* const    comp1                                        , const XMLCh* const    comp2){    return auxCompareString( comp1, comp2, -1L, true);}int CygwinTransService::compareNIString( const   XMLCh* const    comp1                                        , const XMLCh* const    comp2                                        , const unsigned int    maxChars){    // Promote maxChars to signed long. Avoid any conceivable    // portability issue from a simple C cast with extension    // of sign bit when maxChars >= 2^16.  Making that param    // signed long was necessary for reusability/an out-of-band    // indicator in CygwinTransService::auxCompareString().    // Obs. When maxChars == 0, return 0 (strings equal).    return auxCompareString( comp1, comp2, (maxChars & 0x0000FFFFL), true);}const XMLCh* CygwinTransService::getId() const{    return gMyServiceId;}bool CygwinTransService::isSpace(const XMLCh toCheck) const{    int theCount = 0;    while ( theCount < (sizeof(gWhitespace) / sizeof(XMLCh)) )    {        if ( toCheck == gWhitespace[theCount] )            return true;        ++theCount;    }    return false;}XMLLCPTranscoder* CygwinTransService::makeNewLCPTranscoder(){    // Just allocate a new LCP transcoder of our type    return new CygwinLCPTranscoder;}bool CygwinTransService::supportsSrcOfs() const{    //    //  Since the only mechanism we have to translate XML text in this    //  transcoder basically require us to do work that allows us to support    //  source offsets, we might as well do it.    //    return true;}void CygwinTransService::upperCase(XMLCh* const toUpperCase) const{    unsigned int itsLen = XMLString::stringLen( toUpperCase);    ::LCMapStringW( gLocaleId, LCMAP_UPPERCASE, (LPWSTR)toUpperCase, itsLen, (LPWSTR)toUpperCase, itsLen);}void CygwinTransService::lowerCase(XMLCh* const toLowerCase) const{    unsigned int itsLen = XMLString::stringLen( toLowerCase);    ::LCMapStringW( gLocaleId, LCMAP_LOWERCASE, (LPWSTR)toLowerCase, itsLen, (LPWSTR)toLowerCase, itsLen);}bool CygwinTransService::isAlias(const   HKEY            encodingKey                    ,       char* const     aliasBuf                    , const unsigned int    nameBufSz ){    unsigned long theType;    unsigned long theSize = nameBufSz;    return (::RegQueryValueExA    (        encodingKey        , "AliasForCharset"        , 0        , &theType        , (unsigned char*)aliasBuf        , &theSize    ) == ERROR_SUCCESS);}XMLTranscoder*CygwinTransService::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.    //    int itsLen = XMLString::stringLen( encodingName) + 1;    memcpy(        upEncoding        , encodingName        , sizeof(XMLCh) * ( ( itsLen > upLen) ? upLen : itsLen)    );    upEncoding[upLen] = 0;  // necessary? terminating NUL should've copied.    upperCase(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 Cygwin transcoder for this encoding    return new (manager) CygwinTranscoder    (        encodingName        , theEntry->getWinCP()        , theEntry->getIEEncoding()        , blockSize        , manager    );}//---------------------------------------------------------------------------////  class CygwinTranscoder Implementation ...////---------------------------------------------------------------------------// ---------------------------------------------------------------------------//  CygwinTranscoder: Constructors and Destructor// ---------------------------------------------------------------------------CygwinTranscoder::CygwinTranscoder(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){}CygwinTranscoder::~CygwinTranscoder(){}// ---------------------------------------------------------------------------//  CygwinTranscoder: The virtual transcoder API// ---------------------------------------------------------------------------unsigned intCygwinTranscoder::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;

⌨️ 快捷键说明

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