/* * 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 191823 2005-06-22 12:45:35Z cargilld $ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Uniconv390TransService.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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() { 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); // If we are forcing ICU to be used fro transcoding then we also should // force it to be used for case conversions. if (gForceTranscode == MUST_USE_ICU) { fCaseConverter = new uniconvcaseconverter; fCaseConverter->ftoupperhand=UNICONV_ERROR; fCaseConverter->ftolowerhand=UNICONV_ERROR; } else { fCaseConverter = new uniconvcaseconverter; fCaseConverter->ftoupperhand=UNICONV_NOHANDLE; fCaseConverter->ftolowerhand=UNICONV_NOHANDLE; } 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 { /* copied from ICU */ if ((toCheck == 0x09) || (toCheck == 0x0A) || (toCheck == 0x0D)) { return true; } return (u_isspace(UChar(toCheck)) != 0); } 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; 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=%x\n",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 - %s\n",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=%x\n",gForceTranscode,(int)tconv); if (tconv) { if (gViewTranscoder) printf("IXM1005I LCP - Using Unicode Services - %s\n",nl_langinfo(CODESET)); fLCPTranscoder = new Uniconv390LCPTranscoder(tconv); } else { if (gForceTranscode != MUST_USE_UNICONV) { if (gViewTranscoder) printf("IXM1006I LCP - Using ICU - %s\n",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 janText((char*)localname, manager); DBGPRINTF3("makeNewXMLTranscoder() encoding=%s blocksize=%d\n",localname,blockSize); if (gForceTranscode == MUST_USE_ICU) { if (gViewTranscoder) printf("IXM1001I XML - Using ICU - %s\n",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 - %s\n",localname); return fICUService->makeNewXMLTranscoder(encodingName,resValue,blockSize, manager); } } if (gViewTranscoder) printf("IXM1003I XML - Using Unicode Services - %s\n",localname); return new (manager) Uniconv390Transcoder(encodingName, tconv, blockSize, manager); } // --------------------------------------------------------------------------- // Uniconv390TransService: Hidden Init Method // // This is called by OS390 platform utils during startup. // --------------------------------------------------------------------------- void Uniconv390TransService::initTransService() { // Need to first check if the translate instruction is supported // by this processor ... if it is use the new intrinsics. if (((*(int*) 200) & 0x00001000) != 0) { // // A stupid way to increment the fCurCount inside the RefVectorOf // for (unsigned int i = 0; i < XMLRecognizer::Encodings_Count; i++) gMappingsRecognizer->addElement(0); // // Add in the magical mapping for the native XMLCh transcoder. This // is used for internal entities. // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgXMLChEncodingString), XMLRecognizer::XERCES_XMLCH); gMappings->put((void*)XMLUni::fgXMLChEncodingString, new ENameMapFor(XMLUni::fgXMLChEncodingString)); // // Add in our mappings for ASCII. // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgUSASCIIEncodingString), XMLRecognizer::US_ASCII); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString, new ENameMapFor(XMLUni::fgUSASCIIEncodingString)); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString2, new ENameMapFor(XMLUni::fgUSASCIIEncodingString2)); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString3, new ENameMapFor(XMLUni::fgUSASCIIEncodingString3)); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString4, new ENameMapFor(XMLUni::fgUSASCIIEncodingString4)); // // Add in our mappings for UTF-8 // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgUTF8EncodingString), XMLRecognizer::UTF_8); gMappings->put((void*)XMLUni::fgUTF8EncodingString, new ENameMapFor(XMLUni::fgUTF8EncodingString)); gMappings->put((void*)XMLUni::fgUTF8EncodingString2, new ENameMapFor(XMLUni::fgUTF8EncodingString2)); // // Add in our mappings for Latin1 // gMappings->put((void*)XMLUni::fgISO88591EncodingString, new ENameMapFor(XMLUni::fgISO88591EncodingString)); gMappings->put((void*)XMLUni::fgISO88591EncodingString2, new ENameMapFor(XMLUni::fgISO88591EncodingString2)); gMappings->put((void*)XMLUni::fgISO88591EncodingString3, new ENameMapFor(XMLUni::fgISO88591EncodingString3)); gMappings->put((void*)XMLUni::fgISO88591EncodingString4, new ENameMapFor(XMLUni::fgISO88591EncodingString4)); gMappings->put((void*)XMLUni::fgISO88591EncodingString5, new ENameMapFor(XMLUni::fgISO88591EncodingString5)); gMappings->put((void*)XMLUni::fgISO88591EncodingString6, new ENameMapFor(XMLUni::fgISO88591EncodingString6)); gMappings->put((void*)XMLUni::fgISO88591EncodingString7, new ENameMapFor(XMLUni::fgISO88591EncodingString7)); gMappings->put((void*)XMLUni::fgISO88591EncodingString8, new ENameMapFor(XMLUni::fgISO88591EncodingString8)); gMappings->put((void*)XMLUni::fgISO88591EncodingString9, new ENameMapFor(XMLUni::fgISO88591EncodingString9)); gMappings->put((void*)XMLUni::fgISO88591EncodingString10, new ENameMapFor(XMLUni::fgISO88591EncodingString10)); gMappings->put((void*)XMLUni::fgISO88591EncodingString11, new ENameMapFor(XMLUni::fgISO88591EncodingString11)); gMappings->put((void*)XMLUni::fgISO88591EncodingString12, new ENameMapFor(XMLUni::fgISO88591EncodingString12)); // // Add in our mappings for UTF-16 and UCS-4, little endian // bool swapped = false; #if defined(ENDIANMODE_BIG) swapped = true; #endif gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUTF16LEncodingString, swapped), XMLRecognizer::UTF_16L); gMappings->put ( (void*)XMLUni::fgUTF16LEncodingString, new EEndianNameMapFor ( XMLUni::fgUTF16LEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUTF16LEncodingString2, new EEndianNameMapFor ( XMLUni::fgUTF16LEncodingString2 , swapped ) ); gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUCS4LEncodingString, swapped), XMLRecognizer::UCS_4L); gMappings->put ( (void*)XMLUni::fgUCS4LEncodingString, new EEndianNameMapFor ( XMLUni::fgUCS4LEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUCS4LEncodingString2, new EEndianNameMapFor ( XMLUni::fgUCS4LEncodingString2 , swapped ) ); // // Add in our mappings for UTF-16 and UCS-4, big endian // swapped = false; #if defined(ENDIANMODE_LITTLE) swapped = true; #endif gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUTF16BEncodingString, swapped), XMLRecognizer::UTF_16B); gMappings->put ( (void*)XMLUni::fgUTF16BEncodingString, new EEndianNameMapFor ( XMLUni::fgUTF16BEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUTF16BEncodingString2, new EEndianNameMapFor ( XMLUni::fgUTF16BEncodingString2 , swapped ) ); gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUCS4BEncodingString, swapped), XMLRecognizer::UCS_4B); gMappings->put ( (void*)XMLUni::fgUCS4BEncodingString, new EEndianNameMapFor ( XMLUni::fgUCS4BEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUCS4BEncodingString2, new EEndianNameMapFor ( XMLUni::fgUCS4BEncodingString2 , swapped ) ); // // Add in our mappings for UTF-16 and UCS-4 which does not indicate endian // assumes the same endian encoding as the OS // gMappings->put ( (void*)XMLUni::fgUTF16EncodingString, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString2, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString2 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString3, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString3 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString4, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString4 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString5, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString5 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString6, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString6 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString7, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString7 , false ) ); gMappings->put ( (void*)XMLUni::fgUCS4EncodingString, new EEndianNameMapFor ( XMLUni::fgUCS4EncodingString , false ) ); gMappings->put ( (void*)XMLUni::fgUCS4EncodingString2, new EEndianNameMapFor ( XMLUni::fgUCS4EncodingString2 , false ) ); gMappings->put ( (void*)XMLUni::fgUCS4EncodingString3, new EEndianNameMapFor ( XMLUni::fgUCS4EncodingString3 , false ) ); // // Add in our mappings for IBM037, and the one alias we support for // it, which is EBCDIC-CP-US. // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgEBCDICEncodingString), XMLRecognizer::EBCDIC); gMappings->put((void*)XMLUni::fgIBM037EncodingString, new ENameMapFor(XMLUni::fgIBM037EncodingString)); gMappings->put((void*)XMLUni::fgIBM037EncodingString2, new ENameMapFor(XMLUni::fgIBM037EncodingString2)); //hhe gMappings->put((void*)XMLUni::fgIBM1047EncodingString, new ENameMapFor(XMLUni::fgIBM1047EncodingString)); gMappings->put((void*)XMLUni::fgIBM1047EncodingString2, new ENameMapFor(XMLUni::fgIBM1047EncodingString2)); // // Add in our mappings for IBM037 with Euro update, i.e. IBM1140. It // has alias IBM01140, the one suggested by IANA // gMappings->put((void*)XMLUni::fgIBM1140EncodingString, new ENameMapFor(XMLUni::fgIBM1140EncodingString)); gMappings->put((void*)XMLUni::fgIBM1140EncodingString2, new ENameMapFor(XMLUni::fgIBM1140EncodingString2)); gMappings->put((void*)XMLUni::fgIBM1140EncodingString3, new ENameMapFor(XMLUni::fgIBM1140EncodingString3)); gMappings->put((void*)XMLUni::fgIBM1140EncodingString4, new ENameMapFor(XMLUni::fgIBM1140EncodingString4)); // // Add in our mappings for Windows-1252. We don't have any aliases for // this one, so there is just one mapping. // gMappings->put((void*)XMLUni::fgWin1252EncodingString, new ENameMapFor(XMLUni::fgWin1252EncodingString)); } // use new intrinsics else // use old intrinsics { // // A stupid way to increment the fCurCount inside the RefVectorOf // for (unsigned int i = 0; i < XMLRecognizer::Encodings_Count; i++) gMappingsRecognizer->addElement(0); // // Add in the magical mapping for the native XMLCh transcoder. This // is used for internal entities. // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgXMLChEncodingString), XMLRecognizer::XERCES_XMLCH); gMappings->put((void*)XMLUni::fgXMLChEncodingString, new ENameMapFor(XMLUni::fgXMLChEncodingString)); // // Add in our mappings for ASCII. // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgUSASCIIEncodingString), XMLRecognizer::US_ASCII); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString, new ENameMapFor(XMLUni::fgUSASCIIEncodingString)); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString2, new ENameMapFor(XMLUni::fgUSASCIIEncodingString2)); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString3, new ENameMapFor(XMLUni::fgUSASCIIEncodingString3)); gMappings->put((void*)XMLUni::fgUSASCIIEncodingString4, new ENameMapFor(XMLUni::fgUSASCIIEncodingString4)); // // Add in our mappings for UTF-8 // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgUTF8EncodingString), XMLRecognizer::UTF_8); gMappings->put((void*)XMLUni::fgUTF8EncodingString, new ENameMapFor(XMLUni::fgUTF8EncodingString)); gMappings->put((void*)XMLUni::fgUTF8EncodingString2, new ENameMapFor(XMLUni::fgUTF8EncodingString2)); // // Add in our mappings for Latin1 // gMappings->put((void*)XMLUni::fgISO88591EncodingString, new ENameMapFor(XMLUni::fgISO88591EncodingString)); gMappings->put((void*)XMLUni::fgISO88591EncodingString2, new ENameMapFor(XMLUni::fgISO88591EncodingString2)); gMappings->put((void*)XMLUni::fgISO88591EncodingString3, new ENameMapFor(XMLUni::fgISO88591EncodingString3)); gMappings->put((void*)XMLUni::fgISO88591EncodingString4, new ENameMapFor(XMLUni::fgISO88591EncodingString4)); gMappings->put((void*)XMLUni::fgISO88591EncodingString5, new ENameMapFor(XMLUni::fgISO88591EncodingString5)); gMappings->put((void*)XMLUni::fgISO88591EncodingString6, new ENameMapFor(XMLUni::fgISO88591EncodingString6)); gMappings->put((void*)XMLUni::fgISO88591EncodingString7, new ENameMapFor(XMLUni::fgISO88591EncodingString7)); gMappings->put((void*)XMLUni::fgISO88591EncodingString8, new ENameMapFor(XMLUni::fgISO88591EncodingString8)); gMappings->put((void*)XMLUni::fgISO88591EncodingString9, new ENameMapFor(XMLUni::fgISO88591EncodingString9)); gMappings->put((void*)XMLUni::fgISO88591EncodingString10, new ENameMapFor(XMLUni::fgISO88591EncodingString10)); gMappings->put((void*)XMLUni::fgISO88591EncodingString11, new ENameMapFor(XMLUni::fgISO88591EncodingString11)); gMappings->put((void*)XMLUni::fgISO88591EncodingString12, new ENameMapFor(XMLUni::fgISO88591EncodingString12)); // // Add in our mappings for UTF-16 and UCS-4, little endian // bool swapped = false; #if defined(ENDIANMODE_BIG) swapped = true; #endif gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUTF16LEncodingString, swapped), XMLRecognizer::UTF_16L); gMappings->put ( (void*)XMLUni::fgUTF16LEncodingString, new EEndianNameMapFor ( XMLUni::fgUTF16LEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUTF16LEncodingString2, new EEndianNameMapFor ( XMLUni::fgUTF16LEncodingString2 , swapped ) ); gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUCS4LEncodingString, swapped), XMLRecognizer::UCS_4L); gMappings->put ( (void*)XMLUni::fgUCS4LEncodingString, new EEndianNameMapFor ( XMLUni::fgUCS4LEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUCS4LEncodingString2, new EEndianNameMapFor ( XMLUni::fgUCS4LEncodingString2 , swapped ) ); // // Add in our mappings for UTF-16 and UCS-4, big endian // swapped = false; #if defined(ENDIANMODE_LITTLE) swapped = true; #endif gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUTF16BEncodingString, swapped), XMLRecognizer::UTF_16B); gMappings->put ( (void*)XMLUni::fgUTF16BEncodingString, new EEndianNameMapFor ( XMLUni::fgUTF16BEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUTF16BEncodingString2, new EEndianNameMapFor ( XMLUni::fgUTF16BEncodingString2 , swapped ) ); gMappingsRecognizer->setElementAt(new EEndianNameMapFor(XMLUni::fgUCS4BEncodingString, swapped), XMLRecognizer::UCS_4B); gMappings->put ( (void*)XMLUni::fgUCS4BEncodingString, new EEndianNameMapFor ( XMLUni::fgUCS4BEncodingString , swapped ) ); gMappings->put ( (void*)XMLUni::fgUCS4BEncodingString2, new EEndianNameMapFor ( XMLUni::fgUCS4BEncodingString2 , swapped ) ); // // Add in our mappings for UTF-16 and UCS-4 which does not indicate endian // assumes the same endian encoding as the OS // gMappings->put ( (void*)XMLUni::fgUTF16EncodingString, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString2, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString2 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString3, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString3 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString4, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString4 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString5, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString5 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString6, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString6 , false ) ); gMappings->put ( (void*)XMLUni::fgUTF16EncodingString7, new EEndianNameMapFor ( XMLUni::fgUTF16EncodingString7 , false ) ); gMappings->put ( (void*)XMLUni::fgUCS4EncodingString, new EEndianNameMapFor ( XMLUni::fgUCS4EncodingString , false ) ); gMappings->put ( (void*)XMLUni::fgUCS4EncodingString2, new EEndianNameMapFor ( XMLUni::fgUCS4EncodingString2 , false ) ); gMappings->put ( (void*)XMLUni::fgUCS4EncodingString3, new EEndianNameMapFor ( XMLUni::fgUCS4EncodingString3 , false ) ); // // Add in our mappings for IBM037, and the one alias we support for // it, which is EBCDIC-CP-US. // gMappingsRecognizer->setElementAt(new ENameMapFor(XMLUni::fgEBCDICEncodingString), XMLRecognizer::EBCDIC); gMappings->put((void*)XMLUni::fgIBM037EncodingString, new ENameMapFor(XMLUni::fgIBM037EncodingString)); gMappings->put((void*)XMLUni::fgIBM037EncodingString2, new ENameMapFor(XMLUni::fgIBM037EncodingString2)); //hhe gMappings->put((void*)XMLUni::fgIBM1047EncodingString, new ENameMapFor(XMLUni::fgIBM1047EncodingString)); gMappings->put((void*)XMLUni::fgIBM1047EncodingString2, new ENameMapFor(XMLUni::fgIBM1047EncodingString2)); // // Add in our mappings for IBM037 with Euro update, i.e. IBM1140. It // has alias IBM01140, the one suggested by IANA // gMappings->put((void*)XMLUni::fgIBM1140EncodingString, new ENameMapFor(XMLUni::fgIBM1140EncodingString)); gMappings->put((void*)XMLUni::fgIBM1140EncodingString2, new ENameMapFor(XMLUni::fgIBM1140EncodingString2)); gMappings->put((void*)XMLUni::fgIBM1140EncodingString3, new ENameMapFor(XMLUni::fgIBM1140EncodingString3)); gMappings->put((void*)XMLUni::fgIBM1140EncodingString4, new ENameMapFor(XMLUni::fgIBM1140EncodingString4)); // // Add in our mappings for Windows-1252. We don't have any aliases for // this one, so there is just one mapping. // gMappings->put((void*)XMLUni::fgWin1252EncodingString, new ENameMapFor(XMLUni::fgWin1252EncodingString)); } // use old intrinsics }//end initTransService() // *************************************************************************** // *************************************************************************** // *************************************************************************** // *************************************************************************** // *************** 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=%d\n",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=%d\n",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::canTranscodeTo\n"); //printf("!!!***Uniconv390Transcoder::canTranscodeTo\n"); // // 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 , MemoryManager* const manager) { 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, manager); if (result) { thesize = strlen(result); manager->deallocate(result);//delete [] result; } return thesize; } unsigned int Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText , MemoryManager* const manager) { 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, manager); if (result) { thesize = getWideCharLength(result); manager->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=%x\n",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=%d\n",wLent); { // Locking scope XMLMutexLock lockConverter(&fConverter->fMutex); retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft); } //printf("!!!transcode uniconv finished rc=%d errno=%d\n",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):%s\n",retVal); return retVal; } char* Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode, MemoryManager* const manager) { //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode) "); //printf("transcode handle=%x\n",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=%d\n",wLent); { // Locking scope XMLMutexLock lockConverter(&fConverter->fMutex); retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft); } //printf("!!!transcode uniconv finished rc=%d errno=%d\n",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):%s\n",retVal); return retVal; } XMLCh* Uniconv390LCPTranscoder::transcode(const char* const toTranscode) { DBGPRINTF2("Uniconv390LCPTranscoder::transcode(const char* const toTranscode):%s \n",toTranscode); //printf("transcode handle=%x\n",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=%x\n",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 , MemoryManager* const manager) { DBGPRINTF1("Uniconv390LCPTranscoder::transcode(const char* const toTranscode, etc.... \n"); //printf("transcode handle=%x\n",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 , MemoryManager* const manager) { DBGPRINTF1("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode, etc.... \n"); //printf("transcode handle=%x\n",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