?? uniconv390transservice.cpp
字號:
/* * Copyright 2002-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: Uniconv390TransService.cpp,v 1.8 2004/09/08 13:56:46 peiyongz Exp $ */// ---------------------------------------------------------------------------// Includes// ---------------------------------------------------------------------------#include <xercesc/util/Janitor.hpp>#include <xercesc/util/TranscodingException.hpp>#include <xercesc/util/RefHashTableOf.hpp>#include <xercesc/util/RefVectorOf.hpp>#include <xercesc/util/Transcoders/Uniconv390/XML88591Transcoder390.hpp>#include <xercesc/util/Transcoders/Uniconv390/XMLASCIITranscoder390.hpp>#include <xercesc/util/XMLChTranscoder.hpp>#include <xercesc/util/Transcoders/Uniconv390/XMLEBCDICTranscoder390.hpp>#include <xercesc/util/XMLUCS4Transcoder.hpp>#include <xercesc/util/Transcoders/Uniconv390/XMLIBM1047Transcoder390.hpp>#include <xercesc/util/Transcoders/Uniconv390/XMLIBM1140Transcoder390.hpp>#include <xercesc/util/Transcoders/Uniconv390/XMLUTF8Transcoder390.hpp>#include <xercesc/util/XMLUTF16Transcoder.hpp>#include <xercesc/util/Transcoders/Uniconv390/XMLWin1252Transcoder390.hpp>#include <xercesc/util/TransENameMap.hpp>#include <xercesc/util/XMLUni.hpp>#include <xercesc/util/XMLString.hpp>#include <xercesc/util/XMLUniDefs.hpp>#include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>#include "Uniconv390TransService.hpp"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <langinfo.h>#include <locale.h>#include <xercesc/util/regx/XMLUniCharacter.hpp>#include <xercesc/util/XML88591Transcoder.hpp>#include <xercesc/util/XMLASCIITranscoder.hpp>#include <xercesc/util/XMLChTranscoder.hpp>#include <xercesc/util/XMLEBCDICTranscoder.hpp>#include <xercesc/util/XMLIBM1047Transcoder.hpp>#include <xercesc/util/XMLIBM1140Transcoder.hpp>#include <xercesc/util/XMLUCS4Transcoder.hpp>#include <xercesc/util/XMLUTF8Transcoder.hpp>#include <xercesc/util/XMLUTF16Transcoder.hpp>#include <xercesc/util/XMLWin1252Transcoder.hpp>XERCES_CPP_NAMESPACE_BEGIN// debug printfs.... I'll take these out after function test./*#define DBGPRINTF1(a) {}#define DBGPRINTF2(a,b) {}#define DBGPRINTF3(a,b,c) {}#define DBGPRINTF4(a,b,c,d) {}#define DBGPRINTF5(a,b,c,d,e) {}#define DBGPRINTF6(a,b,c,d,e,f) {}#define DBGPRINTF7(a,b,c,d,e,f,g) {}*/#define DBGPRINTF1(a) {if (gViewDebug) printf(a);}#define DBGPRINTF2(a,b) {if (gViewDebug) printf(a,b);}#define DBGPRINTF3(a,b,c) {if (gViewDebug) printf(a,b,c);}#define DBGPRINTF4(a,b,c,d) {if (gViewDebug) printf(a,b,c,d);}#define DBGPRINTF5(a,b,c,d,e) {if (gViewDebug) printf(a,b,c,d,e);}#define DBGPRINTF6(a,b,c,d,e,f) {if (gViewDebug) printf(a,b,c,d,e,f);}#define DBGPRINTF7(a,b,c,d,e,f,g) {if (gViewDebug) printf(a,b,c,d,e,f,g);}// ---------------------------------------------------------------------------// Local, const data// ---------------------------------------------------------------------------static const XMLCh gMyServiceId[] ={ chLatin_U, chLatin_N, chLatin_I, chLatin_C, chLatin_O, chLatin_N, chLatin_V, chNull};// These will hold the environment variable settings.bool gViewTranscoder;static bool gViewDebug;static int gForceTranscode;#define NO_FORCE 0#define MUST_USE_ICU 1#define MUST_USE_UNICONV 2// ---------------------------------------------------------------------------// Local functions// ---------------------------------------------------------------------------// This is a local service routine to figure out the number of characters (not bytes)// in a unicode string.static unsigned int getWideCharLength(const XMLCh* const src){ if (!src) return 0; unsigned int len = 0; const XMLCh* pTmp = src; while (*pTmp++) len++; return len;}// This is a local service routine to open a transcoder to/from unicode.static uniconvconverter * addConverter(const char* const EncodingName ,XMLTransService::Codes& resValue){DBGPRINTF1("Add converter\n"); uniconvconverter *tconv = new uniconvconverter; tconv->fIconv390DescriptorFrom = uniconv_open("UCS-2",EncodingName); if (tconv->fIconv390DescriptorFrom <= (uniconv_t)(0)) {DBGPRINTF2("uniconv_open from failed rc=%d\n",(int)tconv->fIconv390DescriptorFrom); resValue = XMLTransService::UnsupportedEncoding; delete tconv; return 0; } tconv->fIconv390DescriptorTo = uniconv_open(EncodingName,"UCS-2"); if (tconv->fIconv390DescriptorTo <= (uniconv_t)(0)) {DBGPRINTF2("uniconv_open to failed rc=%d\n",(int)tconv->fIconv390DescriptorTo); resValue = XMLTransService::UnsupportedEncoding; uniconv_close(tconv->fIconv390DescriptorFrom); delete tconv; return 0; } return tconv;}// This is a local service routine to close the transcoders.static void removeConverter(uniconvconverter* const converter){DBGPRINTF1("remove converter\n"); if (converter) { uniconv_close(converter->fIconv390DescriptorFrom); uniconv_close(converter->fIconv390DescriptorTo); delete converter; }}// ***************************************************************************// ***************************************************************************// ***************************************************************************// ***************************************************************************// *************** Uniconv390TransService Class ******************************// ***************************************************************************// ***************************************************************************// ***************************************************************************// ***************************************************************************// ---------------------------------------------------------------------------// Uniconv390TransService: Constructor and Destructor// ---------------------------------------------------------------------------Uniconv390TransService::Uniconv390TransService(){ fCaseConverter = new uniconvcaseconverter; fCaseConverter->ftoupperhand=UNICONV_NOHANDLE; fCaseConverter->ftolowerhand=UNICONV_NOHANDLE; char * myenviron = getenv("_IXM_FORCE_CONVERSION"); gForceTranscode = NO_FORCE; if ( !strcmp(myenviron,"USE_ICU") ) gForceTranscode = MUST_USE_ICU; else if ( !strcmp(myenviron,"USE_NATIVE") ) gForceTranscode = MUST_USE_UNICONV; DBGPRINTF3("FORCE PARM=%s %d\n",myenviron,gForceTranscode); fICUService = new ICUTransService; gViewTranscoder = false; if ( !strcmp(getenv("_IXM_VIEW_CONVERSION"),"YES") ) gViewTranscoder = true; gViewDebug = false; if ( !strcmp(getenv("_IXM_DEBUG_CONVERSION"),"YES") ) gViewDebug = true;}Uniconv390TransService::~Uniconv390TransService(){ if ( (fCaseConverter->ftoupperhand!=UNICONV_NOHANDLE) && (fCaseConverter->ftoupperhand!=UNICONV_ERROR) ) { uniconv_toupper_close(fCaseConverter->ftoupperhand); fCaseConverter->ftoupperhand=UNICONV_NOHANDLE; } if ( (fCaseConverter->ftolowerhand!=UNICONV_NOHANDLE) && (fCaseConverter->ftolowerhand!=UNICONV_ERROR) ) { uniconv_tolower_close(fCaseConverter->ftolowerhand); fCaseConverter->ftolowerhand=UNICONV_NOHANDLE; } if (fCaseConverter) { delete [] fCaseConverter; fCaseConverter=0; } if (fICUService) { delete fICUService; }}// ---------------------------------------------------------------------------// Uniconv390TransService: The virtual transcoding service API// ---------------------------------------------------------------------------int Uniconv390TransService::compareIString(const XMLCh* const comp1 , const XMLCh* const comp2){//char localname1[500];//XMLString::transcode(comp1,localname1,400);//char localname2[500];//XMLString::transcode(comp2,localname2,400);//DBGPRINTF3("comparing %s %s \n",localname1,localname2);//printf("toupper handle=%x\n",fCaseConverter->ftoupperhand); if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) { const XMLCh* psz1 = comp1; const XMLCh* psz2 = comp2; XMLCh tmp1; XMLCh tmp2; XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex); if (fCaseConverter->ftoupperhand==UNICONV_NOHANDLE) { fCaseConverter->ftoupperhand=uniconv_toupper_open(); } unsigned int curCount = 0; while (fCaseConverter->ftoupperhand!=UNICONV_ERROR) { tmp1 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz1); if (errno==0) tmp2 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz2); if (errno) { uniconv_toupper_close(fCaseConverter->ftoupperhand); fCaseConverter->ftoupperhand=UNICONV_ERROR; break; } // // If an inequality, then return the difference. // if (tmp1 != tmp2) return int(*psz1) - int(*psz2); // If either has ended, then they both ended, so equal if (!*psz1 || !*psz2) break; // Move upwards for the next round psz1++; psz2++; } } // check if unicode services does not support upper casing again, then call ICU. if (fCaseConverter->ftoupperhand == UNICONV_ERROR) { return fICUService->compareIString(comp1,comp2); } return 0;}int Uniconv390TransService::compareNIString(const XMLCh* const comp1 , const XMLCh* const comp2 , const unsigned int maxChars){//char localname1[500];//XMLString::transcode(comp1,localname1,400);//char localname2[500];//XMLString::transcode(comp2,localname2,400);//DBGPRINTF3("comparing NI %s %s \n",localname1,localname2);//printf("toupper handle=%x\n",fCaseConverter->ftoupperhand);//printf("!!!***comparing NI %s %s\n",localname1,localname2); if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) { const XMLCh* psz1 = comp1; const XMLCh* psz2 = comp2; XMLCh tmp1; XMLCh tmp2; XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex); if (fCaseConverter->ftoupperhand==UNICONV_NOHANDLE) { fCaseConverter->ftoupperhand=uniconv_toupper_open(); } unsigned int curCount = 0; while (fCaseConverter->ftoupperhand!=UNICONV_ERROR) { tmp1 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz1); if (errno==0) tmp2 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz2); if (errno) { uniconv_toupper_close(fCaseConverter->ftoupperhand); fCaseConverter->ftoupperhand=UNICONV_ERROR; break; } // // If an inequality, then return the difference. // if (tmp1 != tmp2) return int(*psz1) - int(*psz2); // If either ended, then both ended, so equal if (!*psz1 || !*psz2) break; // Move upwards to next chars psz1++; psz2++; // // Bump the count of chars done. If it equals the count then we // are equal for the requested count, so break out and return // equal. // curCount++; if (maxChars == curCount) break; } } // check if unicode services does not support upper casing, then call ICU. if (fCaseConverter->ftoupperhand == UNICONV_ERROR) { return fICUService->compareNIString(comp1,comp2,maxChars); } return 0;}const XMLCh* Uniconv390TransService::getId() const{ return gMyServiceId;}bool Uniconv390TransService::isSpace(const XMLCh toCheck) const{DBGPRINTF2("isspace checking %x\n",toCheck); unsigned short chartype = XMLUniCharacter::getType(toCheck); if ( (chartype == XMLUniCharacter::SPACE_SEPARATOR) || (chartype == XMLUniCharacter::LINE_SEPARATOR) || (chartype == XMLUniCharacter::PARAGRAPH_SEPARATOR) ) return true; else return false;}bool Uniconv390TransService::supportsSrcOfs() const{ return false;}void Uniconv390TransService::upperCase(XMLCh* const toUpperCase) const{//char localname1[500];//XMLString::transcode(toUpperCase,localname1,400);//DBGPRINTF2("upper casing %s \n",localname1);//printf("toupper handle=%x\n",fCaseConverter->ftoupperhand); if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) { XMLCh* outPtr = toUpperCase;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -