win32transservice.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,004 行 · 第 1/2 页
CPP
1,004 行
/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: Win32TransService.cpp,v 1.23 2004/09/14 20:33:39 amassari Exp $ */// ---------------------------------------------------------------------------// Includes// ---------------------------------------------------------------------------#include <xercesc/util/PlatformUtils.hpp>#include <xercesc/util/TranscodingException.hpp>#include <xercesc/util/XMLException.hpp>#include <xercesc/util/XMLString.hpp>#include <xercesc/util/XMLUniDefs.hpp>#include <xercesc/util/XMLUni.hpp>#include <xercesc/util/RefHashTableOf.hpp>#include "Win32TransService.hpp"#include <windows.h>XERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------// Local, const data// ---------------------------------------------------------------------------static const XMLCh gMyServiceId[] ={ chLatin_W, chLatin_i, chLatin_n, chDigit_3, chDigit_2, chNull};// ---------------------------------------------------------------------------// This is the simple CPMapEntry class. It just contains an encoding name// and a code page for that encoding.// ---------------------------------------------------------------------------class CPMapEntry : public XMemory{public : // ----------------------------------------------------------------------- // Constructors and Destructor // ----------------------------------------------------------------------- CPMapEntry ( const XMLCh* const encodingName , const unsigned int cpId , const unsigned int ieId ); CPMapEntry ( const char* const encodingName , const unsigned int cpId , const unsigned int ieId ); ~CPMapEntry(); // ----------------------------------------------------------------------- // Getter methods // ----------------------------------------------------------------------- const XMLCh* getEncodingName() const; const XMLCh* getKey() const; unsigned int getWinCP() const; unsigned int getIEEncoding() const;private : // ----------------------------------------------------------------------- // Unimplemented constructors and operators // ----------------------------------------------------------------------- CPMapEntry(); CPMapEntry(const CPMapEntry&); CPMapEntry& operator=(const CPMapEntry&); // ----------------------------------------------------------------------- // Private data members // // fEncodingName // This is the encoding name for the code page that this instance // represents. // // fCPId // This is the Windows specific code page for the encoding that this // instance represents. // // fIEId // This is the IE encoding id. Its not used at this time, but we // go ahead and get it and store it just in case for later. // ----------------------------------------------------------------------- XMLCh* fEncodingName; unsigned int fCPId; unsigned int fIEId;};// ---------------------------------------------------------------------------// CPMapEntry: Constructors and Destructor// ---------------------------------------------------------------------------CPMapEntry::CPMapEntry( const char* const encodingName , const unsigned int cpId , const unsigned int ieId) : fEncodingName(0) , fCPId(cpId) , fIEId(ieId){ // Transcode the name to Unicode and store that copy const unsigned int srcLen = strlen(encodingName); const unsigned charLen = ::mblen(encodingName, MB_CUR_MAX); if (charLen != -1) { const unsigned int targetLen = srcLen/charLen; fEncodingName = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate ( (targetLen + 1) * sizeof(XMLCh) );//new XMLCh[targetLen + 1]; ::mbstowcs(fEncodingName, encodingName, srcLen); fEncodingName[targetLen] = 0; // // Upper case it because we are using a hash table and need to be // sure that we find all case combinations. // _wcsupr(fEncodingName); }}CPMapEntry::CPMapEntry( const XMLCh* const encodingName , const unsigned int cpId , const unsigned int ieId) : fEncodingName(0) , fCPId(cpId) , fIEId(ieId){ fEncodingName = XMLString::replicate(encodingName, XMLPlatformUtils::fgMemoryManager); // // Upper case it because we are using a hash table and need to be // sure that we find all case combinations. // _wcsupr(fEncodingName);}CPMapEntry::~CPMapEntry(){ XMLPlatformUtils::fgMemoryManager->deallocate(fEncodingName);//delete [] fEncodingName;}// ---------------------------------------------------------------------------// CPMapEntry: Getter methods// ---------------------------------------------------------------------------const XMLCh* CPMapEntry::getEncodingName() const{ return fEncodingName;}unsigned int CPMapEntry::getWinCP() const{ return fCPId;}unsigned int CPMapEntry::getIEEncoding() const{ return fIEId;}//---------------------------------------------------------------------------//// class Win32TransService Implementation ...////---------------------------------------------------------------------------// ---------------------------------------------------------------------------// Win32TransService: Constructors and Destructor// ---------------------------------------------------------------------------Win32TransService::Win32TransService(){ 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. // 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 CPMapEntry(nameBuf, CPId, IEId); 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)) { const unsigned int srcLen = strlen(aliasBuf); const unsigned charLen = ::mblen(aliasBuf, MB_CUR_MAX); if (charLen != -1) { const unsigned int targetLen = srcLen/charLen; XMLCh* uniAlias = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate ( (targetLen + 1) * sizeof(XMLCh) );//new XMLCh[targetLen + 1]; ::mbstowcs(uniAlias, aliasBuf, srcLen); uniAlias[targetLen] = 0; _wcsupr(uniAlias); // Look up the alias name CPMapEntry* aliasedEntry = fCPMap->get(uniAlias); if (aliasedEntry) { const unsigned int srcLen = strlen(nameBuf); const unsigned charLen = ::mblen(nameBuf, MB_CUR_MAX); const unsigned int targetLen = srcLen/charLen; XMLCh* uniName = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate ( (targetLen + 1) * sizeof(XMLCh) );//new XMLCh[targetLen + 1]; ::mbstowcs(uniName, nameBuf, srcLen); 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 (::wcscmp(uniName, aliasedEntry->getEncodingName())) { CPMapEntry* newEntry = new CPMapEntry(uniName, aliasedEntry->getWinCP(), aliasedEntry->getIEEncoding()); fCPMap->put((void*)newEntry->getEncodingName(), newEntry); } XMLPlatformUtils::fgMemoryManager->deallocate(uniName);//delete [] uniName; } XMLPlatformUtils::fgMemoryManager->deallocate(uniAlias);//delete [] uniAlias; } } // And close the subkey handle ::RegCloseKey(encodingKey); } // And close the main key handle ::RegCloseKey(charsetKey);}Win32TransService::~Win32TransService(){ delete fCPMap;}// ---------------------------------------------------------------------------// Win32TransService: The virtual transcoding service API// ---------------------------------------------------------------------------int Win32TransService::compareIString( const XMLCh* const comp1 , const XMLCh* const comp2){ return _wcsicmp(comp1, comp2);}int Win32TransService::compareNIString( const XMLCh* const comp1 , const XMLCh* const comp2 , const unsigned int maxChars){ return _wcsnicmp(comp1, comp2, maxChars);}const XMLCh* Win32TransService::getId() const{ return gMyServiceId;}bool Win32TransService::isSpace(const XMLCh toCheck) const{ return (iswspace(toCheck) != 0);}XMLLCPTranscoder* Win32TransService::makeNewLCPTranscoder(){ // Just allocate a new LCP transcoder of our type return new Win32LCPTranscoder;}bool Win32TransService::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 Win32TransService::upperCase(XMLCh* const toUpperCase) const{ _wcsupr(toUpperCase);}void Win32TransService::lowerCase(XMLCh* const toLowerCase) const{ _wcslwr(toLowerCase);}bool Win32TransService::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);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?