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 ); }
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 ); }
// --------------------------------------------------------------------------- // 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); }
// --------------------------------------------------------------------------- // 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); }