Uniconv390TransService.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:37k
源码类别:
词法分析
开发平台:
Visual C++
- /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com . For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- /*
- * $Id: Uniconv390TransService.cpp,v 1.3 2003/05/17 16:32:18 knoaman Exp $
- */
- // ---------------------------------------------------------------------------
- // Includes
- // ---------------------------------------------------------------------------
- #include <xercesc/util/Janitor.hpp>
- #include <xercesc/util/TranscodingException.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>
- 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 convertern");
- uniconvconverter *tconv = new uniconvconverter;
- tconv->fIconv390DescriptorFrom = uniconv_open("UCS-2",EncodingName);
- if (tconv->fIconv390DescriptorFrom <= (uniconv_t)(0)) {
- DBGPRINTF2("uniconv_open from failed rc=%dn",(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=%dn",(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 convertern");
- 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 %dn",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;
- }
- }
- // ---------------------------------------------------------------------------
- // 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=%xn",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=%xn",fCaseConverter->ftoupperhand);
- //printf("!!!***comparing NI %s %sn",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 %xn",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=%xn",fCaseConverter->ftoupperhand);
- if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) {
- XMLCh* outPtr = toUpperCase;
- XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex);
- if (fCaseConverter->ftoupperhand==UNICONV_NOHANDLE) {
- fCaseConverter->ftoupperhand=uniconv_toupper_open();
- }
- unsigned int curCount = 0;
- while ((fCaseConverter->ftoupperhand!=UNICONV_ERROR) && (*outPtr) ) {
- XMLCh tmp = uniconv_caseit(fCaseConverter->ftoupperhand,*outPtr);
- if (errno) {
- uniconv_toupper_close(fCaseConverter->ftoupperhand);
- fCaseConverter->ftoupperhand=UNICONV_ERROR;
- break;
- }
- *outPtr = tmp;
- outPtr++;
- }
- }
- if (fCaseConverter->ftoupperhand==UNICONV_ERROR) {
- return fICUService->upperCase(toUpperCase);
- }
- }
- void Uniconv390TransService::lowerCase(XMLCh* const toLowerCase) const
- {
- //char localname1[500];
- //XMLString::transcode(toLowerCase,localname1,400);
- //DBGPRINTF2("lower casing %s n",localname1);
- //printf("tolower handle=%xn",fCaseConverter->ftolowerhand);
- //printf("!!!***Lower casing function called: %s n",localname1);
- if (fCaseConverter->ftolowerhand!=UNICONV_ERROR) {
- XMLCh* outPtr = toLowerCase;
- XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex);
- if (fCaseConverter->ftolowerhand==UNICONV_NOHANDLE) {
- fCaseConverter->ftolowerhand=uniconv_tolower_open();
- }
- unsigned int curCount = 0;
- while ((fCaseConverter->ftolowerhand!=UNICONV_ERROR) && (*outPtr) ) {
- XMLCh tmp = uniconv_caseit(fCaseConverter->ftolowerhand,*outPtr);
- if (errno) {
- uniconv_tolower_close(fCaseConverter->ftolowerhand);
- fCaseConverter->ftolowerhand=UNICONV_ERROR;
- break;
- }
- *outPtr = tmp;
- outPtr++;
- }
- }
- if (fCaseConverter->ftolowerhand==UNICONV_ERROR) {
- return fICUService->lowerCase(toLowerCase);
- }
- }
- XMLLCPTranscoder* Uniconv390TransService::makeNewLCPTranscoder()
- {
- XMLTransService::Codes resValue;
- DBGPRINTF2("makeNewLCPTranscoder() localencoding=%s n",nl_langinfo(CODESET));
- // USS default code page is IBM-1047
- if (gForceTranscode == MUST_USE_ICU) {
- if (gViewTranscoder)
- printf("IXM1004I LCP - Using ICU - %sn",nl_langinfo(CODESET));
- fLCPTranscoder = fICUService->makeNewLCPTranscoder();
- } else {
- char codepage[32];
- sprintf(codepage,"%s-s390", nl_langinfo(CODESET));
- uniconvconverter *tconv=addConverter(codepage,resValue);
- DBGPRINTF3("gForce=%d,tconv=%xn",gForceTranscode,(int)tconv);
- if (tconv) {
- if (gViewTranscoder)
- printf("IXM1005I LCP - Using Unicode Services - %sn",nl_langinfo(CODESET));
- fLCPTranscoder = new Uniconv390LCPTranscoder(tconv);
- } else {
- if (gForceTranscode != MUST_USE_UNICONV) {
- if (gViewTranscoder)
- printf("IXM1006I LCP - Using ICU - %sn",nl_langinfo(CODESET));
- fLCPTranscoder = fICUService->makeNewLCPTranscoder();
- }
- }
- }
- return fLCPTranscoder;
- }
- // ---------------------------------------------------------------------------
- // Uniconv390TransService: The protected virtual transcoding service API
- // ---------------------------------------------------------------------------
- XMLTranscoder* Uniconv390TransService::
- makeNewXMLTranscoder(const XMLCh* const encodingName
- , XMLTransService::Codes& resValue
- , const unsigned int blockSize
- , MemoryManager* const manager)
- {
- char * localname = XMLString::transcode(encodingName, manager);
- ArrayJanitor<char> janText((char*)localname, manager);
- DBGPRINTF3("makeNewXMLTranscoder() encoding=%s blocksize=%dn",localname,blockSize);
- if (gForceTranscode == MUST_USE_ICU) {
- if (gViewTranscoder)
- printf("IXM1001I XML - Using ICU - %sn",localname);
- return fICUService->makeNewXMLTranscoder(encodingName,resValue,blockSize, manager);
- }
- uniconvconverter *tconv=addConverter(localname,resValue);
- if (tconv == 0) {
- DBGPRINTF1("uniconv failed!!!!!!!!n");
- if (gForceTranscode == MUST_USE_UNICONV)
- return 0;
- else {
- if (gViewTranscoder)
- printf("IXM1002I XML - Using ICU - %sn",localname);
- return fICUService->makeNewXMLTranscoder(encodingName,resValue,blockSize, manager);
- }
- }
- if (gViewTranscoder)
- printf("IXM1003I XML - Using Unicode Services - %sn",localname);
- return new (manager) Uniconv390Transcoder(encodingName, tconv, blockSize, manager);
- }
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // *************** Uniconv390Transcoder Class ********************************
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // ---------------------------------------------------------------------------
- // Uniconv390Transcoder: Constructors and Destructor
- // ---------------------------------------------------------------------------
- Uniconv390Transcoder::Uniconv390Transcoder(const XMLCh* const encodingName
- , uniconvconverter_t * const toAdopt
- , const unsigned int blockSize
- , MemoryManager* const manager) :
- XMLTranscoder(encodingName, blockSize, manager)
- , fConverter(toAdopt)
- {
- }
- Uniconv390Transcoder::~Uniconv390Transcoder()
- {
- // If there is a converter, clean it up
- if (fConverter) {
- removeConverter(fConverter);
- fConverter=0;
- }
- }
- // ---------------------------------------------------------------------------
- // Uniconv390Transcoder: The virtual transcoder API
- // ---------------------------------------------------------------------------
- // ignore charSizes since that is used to generate character offsets.
- unsigned int
- Uniconv390Transcoder::transcodeFrom(const XMLByte* const srcData
- , const unsigned int srcCount
- , XMLCh* const toFill
- , const unsigned int maxChars
- , unsigned int& bytesEaten
- , unsigned char* const charSizes)
- {
- unsigned int countIn = 0;
- unsigned int countOut = 0;
- DBGPRINTF2("Uniconv390Transcoder::transcodeFrom bytes=%dn",srcCount);
- int retCode;
- char *tmpInPtr = (char *) srcData;
- char *tmpOutPtr = (char *) toFill;
- unsigned int inByteLeft = srcCount;
- unsigned int outByteLeft = maxChars*sizeof(XMLCh);
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- DBGPRINTF5("Uniconv390Transcoder::transcodeFrom iconv finished, rc=%d inleft=%d outleft=%d errno=%d n",retCode,inByteLeft,outByteLeft,errno);
- if ( (retCode < 0 ) && (errno != E2BIG) ) {
- return 0;
- }
- // Give back the counts of eaten and transcoded
- bytesEaten = srcCount-inByteLeft;
- return maxChars-outByteLeft/sizeof(XMLCh);
- }
- // The returned int is really supposed to be the number of bytes, not chars!
- unsigned int
- Uniconv390Transcoder::transcodeTo( const XMLCh* const srcData
- , const unsigned int srcCount
- , XMLByte* const toFill
- , const unsigned int maxBytes
- , unsigned int& charsEaten
- , const UnRepOpts options)
- {
- unsigned int countIn = 0;
- unsigned int countOut = 0;
- DBGPRINTF2("Uniconv390Transcoder::transcodeTo bytes=%dn",srcCount);
- int retCode;
- char *tmpInPtr = (char *) srcData;
- char *tmpOutPtr = (char *) toFill;
- unsigned int inByteLeft = srcCount*sizeof(XMLCh);
- unsigned int outByteLeft = maxBytes;
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- if ( (retCode < 0) && (errno != E2BIG) ) {
- return 0;
- }
- // Give back the counts of eaten and transcoded
- charsEaten = srcCount-inByteLeft/sizeof(XMLCh);
- return maxBytes-outByteLeft;
- }
- bool Uniconv390Transcoder::canTranscodeTo(const unsigned int toCheck) const
- {
- int retCode;
- DBGPRINTF1("Uniconv390Transcoder::canTranscodeTon");
- //printf("!!!***Uniconv390Transcoder::canTranscodeTon");
- //
- // If the passed value is really a surrogate embedded together, then
- // we need to break it out into its two chars. Else just one. While
- // we are ate it, convert them to UChar format if required.
- //
- XMLCh srcBuf[2];
- unsigned int srcCount = 1;
- if (toCheck & 0xFFFF0000) {
- srcBuf[0] = XMLCh((toCheck >> 10) + 0xD800);
- srcBuf[1] = XMLCh(toCheck & 0x3FF) + 0xDC00;
- srcCount++;
- } else {
- srcBuf[0] = XMLCh(toCheck);
- }
- // Set up a temp buffer to format into. Make it more than big enough
- char tmpBuf[16];
- char *tmpInPtr = (char *) srcBuf;
- char *tmpOutPtr = (char *) tmpBuf;
- unsigned int inByteLeft = srcCount*sizeof(XMLCh);
- unsigned int outByteLeft = 16;
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- if ( (retCode < 0) && (errno != E2BIG) ) {
- return false;
- }
- return true;
- }
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // *************** Uniconv390LCPTranscoder Class *****************************
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // ***************************************************************************
- // ---------------------------------------------------------------------------
- // Uniconv390LCPTranscoder: Constructor and Destructor
- // ---------------------------------------------------------------------------
- Uniconv390LCPTranscoder::Uniconv390LCPTranscoder( uniconvconverter_t* const toAdopt) :
- fConverter(toAdopt)
- {
- }
- Uniconv390LCPTranscoder::~Uniconv390LCPTranscoder()
- {
- // If there is a converter, clean it up
- if (fConverter) {
- removeConverter(fConverter);
- fConverter=0;
- }
- }
- // ---------------------------------------------------------------------------
- // Uniconv390LCPTranscoder: calcRequiredSize
- //
- // The only way I can find to reliably determine the exact required size is to actually
- // transcode the string and see how long it is. Fortunately, this is only done as a last
- // ditch effort so it should only be used very rarely (if at all).
- // ---------------------------------------------------------------------------
- unsigned int Uniconv390LCPTranscoder::calcRequiredSize(const XMLCh* const srcText)
- {
- DBGPRINTF1("Uniconv390LCPTranscoder::calcRequiredSize(const XMLCh* const srcText) n");
- //printf("!!!***Uniconv390LCPTranscoder::calcRequiredSize(const XMLCh* const srcText) n");
- int thesize=0;
- if (!srcText)
- return 0;
- if (!*srcText)
- return 0;
- char * result = transcode(srcText, XMLPlatformUtils::fgMemoryManager);
- if (result) {
- thesize = strlen(result);
- XMLPlatformUtils::fgMemoryManager->deallocate(result);//delete [] result;
- }
- return thesize;
- }
- unsigned int Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText)
- {
- DBGPRINTF1("Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText) n");
- //printf("!!!***Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText) n");
- int thesize=0;
- if (!srcText)
- return 0;
- if (!*srcText)
- return 0;
- XMLCh * result = transcode(srcText, XMLPlatformUtils::fgMemoryManager);
- if (result) {
- thesize = getWideCharLength(result);
- XMLPlatformUtils::fgMemoryManager->deallocate(result);//delete [] result;
- }
- DBGPRINTF2("Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText) %d n",thesize);
- return thesize;
- }
- // ---------------------------------------------------------------------------
- // Uniconv390LCPTranscoder: transcode
- //
- // Now what follows are various methods to transcode to/from unicode.
- // ---------------------------------------------------------------------------
- char* Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode)
- {
- //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode) ");
- //printf("transcode handle=%xn",fConverter->fIconv390DescriptorTo);
- if (!toTranscode)
- return 0;
- char* retVal = 0;
- // find out the length of the source and use this as an estimate for the needed buffer length.
- unsigned int wLent = getWideCharLength(toTranscode);
- if (wLent == 0) {
- retVal = new char[1];
- retVal[0] = 0;
- return retVal;
- }
- retVal = new char[wLent * 2 + 1]; // get double just to be sure.
- while (true) {
- int retCode;
- char *tmpInPtr = (char*) toTranscode;
- char *tmpOutPtr = (char*) retVal;
- unsigned int inByteLeft = wLent*sizeof(XMLCh);
- unsigned int outByteLeft = wLent*sizeof(XMLCh);
- //printf("!!!transcode len=%dn",wLent);
- { // Locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- //printf("!!!transcode uniconv finished rc=%d errno=%dn",retCode,errno);
- // If the data does not fit into our estimation of the buffer size, then delete the buffer,
- // double the estimated length and try again.
- if ( ((retCode < 0) && (errno == E2BIG)) || (outByteLeft == 0) ) {
- //printf("!!!Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):Retrying with a bigger buffer.......n");
- delete [] retVal;
- wLent*=2;
- retVal = new char[wLent*sizeof(XMLCh) + 1];
- }
- // If uniconv doesn't complete for any other reason, then return failure.
- else if (retCode < 0) {
- return 0;
- }
- // it was successful so break out of the loop
- else {
- *tmpOutPtr = 0x00;
- break;
- }
- }
- //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):%sn",retVal);
- return retVal;
- }
- char* Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode,
- MemoryManager* const manager)
- {
- //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode) ");
- //printf("transcode handle=%xn",fConverter->fIconv390DescriptorTo);
- if (!toTranscode)
- return 0;
- char* retVal = 0;
- // find out the length of the source and use this as an estimate for the needed buffer length.
- unsigned int wLent = getWideCharLength(toTranscode);
- if (wLent == 0) {
- retVal = (char*) manager->allocate(sizeof(char));//new char[1];
- retVal[0] = 0;
- return retVal;
- }
- retVal = (char*) manager->allocate((wLent * 2 + 1) * sizeof(char));//new char[wLent * 2 + 1]; // get double just to be sure.
- while (true) {
- int retCode;
- char *tmpInPtr = (char*) toTranscode;
- char *tmpOutPtr = (char*) retVal;
- unsigned int inByteLeft = wLent*sizeof(XMLCh);
- unsigned int outByteLeft = wLent*sizeof(XMLCh);
- //printf("!!!transcode len=%dn",wLent);
- { // Locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- //printf("!!!transcode uniconv finished rc=%d errno=%dn",retCode,errno);
- // If the data does not fit into our estimation of the buffer size, then delete the buffer,
- // double the estimated length and try again.
- if ( ((retCode < 0) && (errno == E2BIG)) || (outByteLeft == 0) ) {
- //printf("!!!Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):Retrying with a bigger buffer.......n");
- manager->deallocate(retVal);//delete [] retVal;
- wLent*=2;
- retVal = (char*) manager->allocate
- (
- (wLent*sizeof(XMLCh) + 1) * sizeof(char)
- );//new char[wLent*sizeof(XMLCh) + 1];
- }
- // If uniconv doesn't complete for any other reason, then return failure.
- else if (retCode < 0) {
- return 0;
- }
- // it was successful so break out of the loop
- else {
- *tmpOutPtr = 0x00;
- break;
- }
- }
- //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):%sn",retVal);
- return retVal;
- }
- XMLCh* Uniconv390LCPTranscoder::transcode(const char* const toTranscode)
- {
- DBGPRINTF2("Uniconv390LCPTranscoder::transcode(const char* const toTranscode):%s n",toTranscode);
- //printf("transcode handle=%xn",fConverter->fIconv390DescriptorFrom);
- if (!toTranscode)
- return 0;
- XMLCh* retVal = 0;
- const unsigned int len = strlen(toTranscode);
- retVal = new XMLCh[len + 1]; // +1 is for the null terminator!
- if (len == 0) {
- retVal[0] = 0;
- return retVal;
- }
- int retCode;
- char *tmpInPtr = (char*) toTranscode;
- char *tmpOutPtr = (char*) retVal;
- unsigned int inByteLeft = len;
- unsigned int outByteLeft = len*sizeof(XMLCh);
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- // Because we check the length in the beginning, and we make sure the output buffer
- // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
- // return failure.
- if (retCode < 0) {
- delete [] retVal;
- return 0;
- }
- *tmpOutPtr = 0x00;
- *(tmpOutPtr+1) = 0x00;
- return retVal;
- }
- XMLCh* Uniconv390LCPTranscoder::transcode(const char* const toTranscode,
- MemoryManager* const manager)
- {
- DBGPRINTF2("Uniconv390LCPTranscoder::transcode(const char* const toTranscode):%s n",toTranscode);
- //printf("transcode handle=%xn",fConverter->fIconv390DescriptorFrom);
- if (!toTranscode)
- return 0;
- XMLCh* retVal = 0;
- const unsigned int len = strlen(toTranscode);
- retVal = (XMLCh*) manager->allocate((len + 1) * sizeof(XMLCh));//new XMLCh[len + 1]; // +1 is for the null terminator!
- if (len == 0) {
- retVal[0] = 0;
- return retVal;
- }
- int retCode;
- char *tmpInPtr = (char*) toTranscode;
- char *tmpOutPtr = (char*) retVal;
- unsigned int inByteLeft = len;
- unsigned int outByteLeft = len*sizeof(XMLCh);
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- // Because we check the length in the beginning, and we make sure the output buffer
- // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
- // return failure.
- if (retCode < 0) {
- manager->deallocate(retVal);//delete [] retVal;
- return 0;
- }
- *tmpOutPtr = 0x00;
- *(tmpOutPtr+1) = 0x00;
- return retVal;
- }
- bool Uniconv390LCPTranscoder::transcode(const char* const toTranscode
- , XMLCh* const toFill
- , const unsigned int maxChars)
- {
- DBGPRINTF1("Uniconv390LCPTranscoder::transcode(const char* const toTranscode, etc.... n");
- //printf("transcode handle=%xn",fConverter->fIconv390DescriptorFrom);
- // Check for a couple of psycho corner cases
- if (!toTranscode || !maxChars) {
- toFill[0] = 0;
- return true;
- }
- unsigned int Lent = strlen(toTranscode);
- if (Lent == 0) {
- toFill[0] = 0;
- return true;
- }
- int retCode;
- char *tmpInPtr = (char*) toTranscode;
- char *tmpOutPtr = (char*) toFill;
- unsigned int inByteLeft = Lent;
- unsigned int outByteLeft = maxChars*2;
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- // Because we check the length in the beginning, and the caller makes sure that the output buffer
- // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
- // return failure.
- if (retCode < 0) {
- return false;
- }
- *tmpOutPtr = 0x00;
- *(tmpOutPtr+1) = 0x00;
- return true;
- }
- bool Uniconv390LCPTranscoder::transcode( const XMLCh* const toTranscode
- , char* const toFill
- , const unsigned int maxBytes)
- {
- DBGPRINTF1("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode, etc.... n");
- //printf("transcode handle=%xn",fConverter->fIconv390DescriptorTo);
- // Watch for a couple of pyscho corner cases
- if (!toTranscode || !maxBytes) {
- toFill[0] = 0;
- return true;
- }
- //-------------------
- unsigned int wLent = getWideCharLength(toTranscode);
- if (wLent == 0) {
- toFill[0] = 0;
- return true;
- }
- int retCode;
- char *tmpInPtr = (char*) toTranscode;
- char *tmpOutPtr = (char*) toFill;
- unsigned int inByteLeft = wLent*sizeof(XMLCh);
- unsigned int outByteLeft = maxBytes;
- { // locking scope
- XMLMutexLock lockConverter(&fConverter->fMutex);
- retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
- }
- // Because we check the length in the beginning, and the caller makes sure that the output buffer
- // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
- // return failure.
- if (retCode < 0) {
- return false;
- }
- *tmpOutPtr = 0x00;
- return true;
- }
- XERCES_CPP_NAMESPACE_END