?? cygwintransservice.cpp
字號:
::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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -