uniconv390transservice.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,475 行 · 第 1/4 页

CPP
1,475
字号
/* * 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 + =
减小字号Ctrl + -
显示快捷键?