示例#1
0
XMLTranscoder*
Win32TransService::makeNewXMLTranscoder(const   XMLCh* const            encodingName
                                        ,       XMLTransService::Codes& resValue
                                        , const XMLSize_t               blockSize
                                        ,       MemoryManager* const    manager)
{
    const XMLSize_t 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.
    //
    XMLString::copyNString(upEncoding, encodingName, upLen);
    _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->getIEEncoding()
        , blockSize
        , manager
    );
}
示例#2
0
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.
    //
    unsigned 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
    );
}
示例#3
0
// ---------------------------------------------------------------------------
//  CygwinTransService: Constructors and Destructor
// ---------------------------------------------------------------------------
CygwinTransService::CygwinTransService()
{
    fCPMap = new RefHashTableOf<CPMapEntry>(109);

    //
    //  Open up the registry key that contains the info we want. Note that,
    //  if this key does not exist, then we just return. It will just mean
    //  that we don't have any support except for intrinsic encodings supported
    //  by the parser itself (and the LCP support of course.
    //
    HKEY charsetKey;
    if (::RegOpenKeyExA
    (
        HKEY_CLASSES_ROOT
        , "MIME\\Database\\Charset"
        , 0
        , KEY_READ
        , &charsetKey))
    {
        return;
    }

    //
    //  Read in the registry keys that hold the code page ids. Skip for now
    //  those entries which indicate that they are aliases for some other
    //  encodings. We'll come back and do a second round for those and look
    //  up the original name and get the code page id.
    //
    //  Note that we have to use A versions here so that this will run on
    //  98, and transcode the strings to Unicode.
    //
    const unsigned int nameBufSz = 1024;
    char nameBuf[nameBufSz + 1];
    unsigned int subIndex = 0;
    unsigned long theSize;
    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);
        }

        //
        //  Lts see if its an alias. If so, then ignore it in this first
        //  loop. Else, we'll add a new entry for this one.
        //
        if (!isAlias(encodingKey))
        {
            //
            //  Lets get the two values out of this key that we are
            //  interested in. There should be a code page entry and an
            //  IE entry.
            //
            unsigned long theType;
            unsigned int CPId;
            unsigned int IEId;

            theSize = sizeof(unsigned int);
            if (::RegQueryValueExA
            (
                encodingKey
                , "Codepage"
                , 0
                , &theType
                , (unsigned char*)&CPId
                , &theSize) != ERROR_SUCCESS)
            {
                XMLPlatformUtils::panic(PanicHandler::Panic_NoTransService);
            }

            //
            //  If this is not a valid Id, and it might not be because its
            //  not loaded on this system, then don't take it.
            //
            if (::IsValidCodePage(CPId))
            {
                theSize = sizeof(unsigned int);
                if (::RegQueryValueExA
                (
                    encodingKey
                    , "InternetEncoding"
                    , 0
                    , &theType
                    , (unsigned char*)&IEId
                    , &theSize) != ERROR_SUCCESS)
                {
                    XMLPlatformUtils::panic(PanicHandler::Panic_NoTransService);
                }

                CPMapEntry* newEntry = new CPMapEntry(nameBuf, CPId, IEId);
                fCPMap->put((void*)newEntry->getEncodingName(), newEntry);
            }
        }

        // And now close the subkey handle and bump the subkey index
        ::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);

}
示例#4
0
// ---------------------------------------------------------------------------
//  Win32TransService: Constructors and Destructor
// ---------------------------------------------------------------------------
Win32TransService::Win32TransService(MemoryManager* manager) :
    fCPMap(NULL)
    , fManager(manager)
{
    // Figure out if we are on XP or later and save that flag for later use.
    // We need this because of certain code page conversion calls.
    OSVERSIONINFO   OSVer;
    OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    ::GetVersionEx(&OSVer);

    if ((OSVer.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
        ((OSVer.dwMajorVersion == 5) && (OSVer.dwMinorVersion > 0)))
    {
        onXPOrLater = true;
    }

    fCPMap = new RefHashTableOf<CPMapEntry>(109);

    //
    //  Open up the registry key that contains the info we want. Note that,
    //  if this key does not exist, then we just return. It will just mean
    //  that we don't have any support except for intrinsic encodings supported
    //  by the parser itself (and the LCP support of course.
    //
    HKEY charsetKey;
    if (::RegOpenKeyExA
    (
        HKEY_CLASSES_ROOT
        , "MIME\\Database\\Charset"
        , 0
        , KEY_READ
        , &charsetKey))
    {
        return;
    }

    //
    //  Read in the registry keys that hold the code page ids. Skip for now
    //  those entries which indicate that they are aliases for some other
    //  encodings. We'll come back and do a second round for those and look
    //  up the original name and get the code page id.
    //
    //  Note that we have to use A versions here so that this will run on
    //  98, and transcode the strings to Unicode.
    //
    const unsigned int nameBufSz = 1024;
    char nameBuf[nameBufSz + 1];
    unsigned int subIndex;
    unsigned long theSize;
    for (subIndex = 0;;++subIndex)
    {
        // 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))
        {
            continue;
        }

        //
        //  Lts see if its an alias. If so, then ignore it in this first
        //  loop. Else, we'll add a new entry for this one.
        //
        if (!isAlias(encodingKey))
        {
            //
            //  Lets get the two values out of this key that we are
            //  interested in. There should be a code page entry and an
            //  IE entry.
            //
            //  The Codepage entry is the default code page for a computer using that charset
            //  while the InternetEncoding holds the code page that represents that charset
            //
            unsigned long theType;
            unsigned int CPId;
            unsigned int IEId;

            theSize = sizeof(unsigned int);
            if (::RegQueryValueExA
            (
                encodingKey
                , "Codepage"
                , 0
                , &theType
                , (unsigned char*)&CPId
                , &theSize) != ERROR_SUCCESS)
            {
                ::RegCloseKey(encodingKey);
                continue;
            }

            //
            //  If this is not a valid Id, and it might not be because its
            //  not loaded on this system, then don't take it.
            //
            if (::IsValidCodePage(CPId))
            {
                theSize = sizeof(unsigned int);
                if (::RegQueryValueExA
                (
                    encodingKey
                    , "InternetEncoding"
                    , 0
                    , &theType
                    , (unsigned char*)&IEId
                    , &theSize) != ERROR_SUCCESS)
                {
                    ::RegCloseKey(encodingKey);
                    continue;
                }

                CPMapEntry* newEntry = new (fManager) CPMapEntry(nameBuf, IEId, fManager);
                fCPMap->put((void*)newEntry->getEncodingName(), newEntry);
            }
        }

        // And close the subkey handle
        ::RegCloseKey(encodingKey);
    }

    //
    //  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.
    //
    char aliasBuf[nameBufSz + 1];
    for (subIndex = 0;;++subIndex)
    {
        // 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))
        {
            continue;
        }

        //
        //  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))
        {
            int targetLen = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aliasBuf, -1, NULL, 0);
            if(targetLen!=0)
            {
                XMLCh* uniAlias = (XMLCh*) fManager->allocate
                (
                    (targetLen + 1) * sizeof(XMLCh)
                );//new XMLCh[targetLen + 1];
                ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, aliasBuf, -1, (LPWSTR)uniAlias, targetLen);
                uniAlias[targetLen] = 0;
                _wcsupr(uniAlias);

                // Look up the alias name
                CPMapEntry* aliasedEntry = fCPMap->get(uniAlias);
                if (aliasedEntry)
                {
                    int targetLen = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, nameBuf, -1, NULL, 0);
                    if(targetLen!=0)
                    {
                        XMLCh* uniName = (XMLCh*) fManager->allocate
                        (
                            (targetLen + 1) * sizeof(XMLCh)
                        );//new XMLCh[targetLen + 1];
                        ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, nameBuf, -1, (LPWSTR)uniName, targetLen);
                        uniName[targetLen] = 0;
                        _wcsupr(uniName);

                        //
                        //  If the name is actually different, then take it.
                        //  Otherwise, don't take it. They map aliases that are
                        //  just different case.
                        //
						if (!XMLString::equals(uniName, aliasedEntry->getEncodingName()))
                        {
                            CPMapEntry* newEntry = new (fManager) CPMapEntry(uniName, aliasedEntry->getIEEncoding(), fManager);
                            fCPMap->put((void*)newEntry->getEncodingName(), newEntry);
                        }

                        fManager->deallocate(uniName);//delete [] uniName;
                    }
                }
                fManager->deallocate(uniAlias);//delete [] uniAlias;
            }
        }

        // And close the subkey handle
        ::RegCloseKey(encodingKey);
    }

    // And close the main key handle
    ::RegCloseKey(charsetKey);
}