/* * Copyright 2001,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: IconvFBSDTransService.cpp 191054 2005-06-17 02:56:35Z jberry $ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #ifdef XML_USE_LIBICONV # include # include # include # include // --------------------------------------------------------------------------- // Description of encoding schemas, supported by iconv() // --------------------------------------------------------------------------- typedef struct __IconvFBSDEncoding { const char* fSchema; // schema name size_t fUChSize; // size of the character unsigned int fUBO; // byte order, relative to the host } IconvFBSDEncoding; static const IconvFBSDEncoding gIconvFBSDEncodings[] = { { "ucs-2-internal", 2, LITTLE_ENDIAN }, { "ucs2-internal", 2, LITTLE_ENDIAN }, { "ucs-4-internal", 4, LITTLE_ENDIAN }, { "ucs4-internal", 4, LITTLE_ENDIAN }, { "UNICODELITTLE", 2, LITTLE_ENDIAN }, { "UNICODEBIG", 2, BIG_ENDIAN }, { "iso-10646-ucs-2", 4, BIG_ENDIAN }, { "iso-10646-ucs-4", 4, BIG_ENDIAN }, /* { "iso-10646-utf-16", 2, BIG_ENDIAN }, */ { NULL, 0, 0 } }; //-------------------------------------------------- // Macro-definitions to translate "native unicode" // characters <-> XMLCh with different host byte order // and encoding schemas. # if BYTE_ORDER == LITTLE_ENDIAN # define IXMLCh2WC16(x,w) \ *(w) = ((*(x)) >> 8) & 0xFF; \ *((w)+1) = (*(x)) & 0xFF # define IWC162XMLCh(w,x) *(x) = ((*(w)) << 8) | (*((w)+1)) # define XMLCh2WC16(x,w) \ *(w) = (*(x)) & 0xFF; \ *((w)+1) = ((*(x)) >> 8) & 0xFF # define WC162XMLCh(w,x) *(x) = ((*((w)+1)) << 8) | (*(w)) # define IXMLCh2WC32(x,w) \ *(w) = ((*(x)) >> 24) & 0xFF; \ *((w)+1) = ((*(x)) >> 16) & 0xFF; \ *((w)+2) = ((*(x)) >> 8) & 0xFF; \ *((w)+3) = (*(x)) & 0xFF # define IWC322XMLCh(w,x) \ *(x) = ((*(w)) << 24) | ((*((w)+1)) << 16) | \ ((*((w)+2)) << 8) | (*((w)+3)) # define XMLCh2WC32(x,w) \ *((w)+3) = ((*(x)) >> 24) & 0xFF; \ *((w)+2) = ((*(x)) >> 16) & 0xFF; \ *((w)+1) = ((*(x)) >> 8) & 0xFF; \ *(w) = (*(x)) & 0xFF # define WC322XMLCh(w,x) \ *(x) = ((*((w)+3)) << 24) | ((*((w)+2)) << 16) | \ ((*((w)+1)) << 8) | (*(w)) # else /* BYTE_ORDER != LITTLE_ENDIAN */ # define XMLCh2WC16(x,w) \ *(w) = ((*(x)) >> 8) & 0xFF; \ *((w)+1) = (*(x)) & 0xFF # define WC162XMLCh(w,x) *(x) = ((*(w)) << 8) | (*((w)+1)) # define IXMLCh2WC16(x,w) \ *(w) = (*(x)) & 0xFF; \ *((w)+1) = ((*(x)) >> 8) & 0xFF # define IWC162XMLCh(w,x) *(x) = ((*((w)+1)) << 8) | (*(w)) # define XMLCh2WC32(x,w) \ *(w) = ((*(x)) >> 24) & 0xFF; \ *((w)+1) = ((*(x)) >> 16) & 0xFF; \ *((w)+2) = ((*(x)) >> 8) & 0xFF; \ *((w)+3) = (*(x)) & 0xFF # define WC322XMLCh(w,x) \ *(x) = ((*(w)) << 24) | ((*((w)+1)) << 16) | \ ((*((w)+2)) << 8) | (*((w)+3)) # define IXMLCh2WC32(x,w) \ *((w)+3) = ((*(x)) >> 24) & 0xFF; \ *((w)+2) = ((*(x)) >> 16) & 0xFF; \ *((w)+1) = ((*(x)) >> 8) & 0xFF; \ *(w) = (*(x)) & 0xFF # define IWC322XMLCh(w,x) \ *(x) = ((*((w)+3)) << 24) | ((*((w)+2)) << 16) | \ ((*((w)+1)) << 8) | (*(w)) # endif /* BYTE_ORDER == LITTLE_ENDIAN */ #else /* !XML_USE_LIBICONV */ # if __FreeBSD_cc_version > 430000 # include # else # define wint_t XMLCh # endif #endif /* XML_USE_LIBICONV */ #include #include #include #include #include #include "IconvFBSDTransService.hpp" #include #include #include #if !defined(APP_NO_THREADS) #include #endif XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // Local, const data // --------------------------------------------------------------------------- static const unsigned int gTempBuffArraySize = 4096; static const XMLCh gMyServiceId[] = { chLatin_I, chLatin_C, chLatin_o, chLatin_n, chLatin_v, chNull }; // --------------------------------------------------------------------------- // Local methods // --------------------------------------------------------------------------- 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; } #ifndef XML_USE_LIBICONV // --------------------------------------------------------------------------- // FreeBSD got the wide-characters support since 4.0 version. But (at least // up to the 4.4) this support differs from "others" in that the xxstoyys() // does not handle the NULL-dest argument properly. So the custom functions // are provided. // --------------------------------------------------------------------------- #define __TMP_ARRAY_SIZE__ 4 static size_t fbsd_wcstombs(char *dest, const wchar_t *src, size_t n) { char tarr[ __TMP_ARRAY_SIZE__ + 1 ]; size_t len = 0, lent = 0; char* ptr; size_t slen; wchar_t* wptr; if (dest) return ::wcstombs(dest, src, n); if (!src) return 0; for (wptr = (wchar_t *) src, slen = 0; *wptr; wptr++, slen++); if (slen == 0) return 0; wptr = (wchar_t *) src; ptr = dest; while ( (len = ::wcstombs(tarr, wptr, __TMP_ARRAY_SIZE__)) > 0 ) { wptr += len; lent += len; } if (len == (unsigned) -1) return 0; return lent; } static size_t fbsd_mbstowcs(wchar_t *dest, const char *src, size_t n) { wchar_t tarr[ __TMP_ARRAY_SIZE__ + 1 ]; size_t len = 0, lent = 0; char* ptr; if (dest) return ::mbstowcs(dest, src, n); ptr = (char*) src; if (!src || strlen(src) == 0) return 0; while ( (len = ::mbstowcs(tarr, ptr, __TMP_ARRAY_SIZE__)) > 0 ) { ptr += len; lent += len; } if (len == (unsigned) -1) return 0; return lent; } static wint_t fbsd_towupper(wint_t ch) { if (ch <= 0x7F) return toupper(ch); unsigned char buf[16]; wchar_t wc = wchar_t(ch); wcstombs((char*)buf, &wc, 16); return toupper(*buf); } static wint_t fbsd_towlower(wint_t ch) { if (ch <= 0x7F) return tolower(ch); unsigned char buf[16]; wchar_t wc = wchar_t(ch); wcstombs((char *)buf, &wc, 16); return tolower(*buf); } #else /* XML_USE_LIBICONV */ #if !defined(APP_NO_THREADS) // Iconv() access syncronization point static XMLMutex *gIconvMutex = NULL; # define ICONV_LOCK XMLMutexLock lockConverter(gIconvMutex); #else /* APP_NO_THREADS */ # define ICONV_LOCK #endif /* !APP_NO_THREADS */ //---------------------------------------------------------------------------- // There is implementation of the libiconv for FreeBSD (available through the // ports collection). The following is a wrapper around the iconv(). //---------------------------------------------------------------------------- IconvFBSDCD::IconvFBSDCD () : fUChSize(0), fUBO(LITTLE_ENDIAN), fCDTo((iconv_t)-1), fCDFrom((iconv_t)-1) { } IconvFBSDCD::IconvFBSDCD ( iconv_t cd_from, iconv_t cd_to, size_t uchsize, unsigned int ubo ) : fUChSize(uchsize), fUBO(ubo), fCDTo(cd_to), fCDFrom(cd_from) { if (fCDFrom == (iconv_t) -1 || fCDTo == (iconv_t) -1) { XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService); } } IconvFBSDCD::~IconvFBSDCD() { } // Convert "native unicode" character into XMLCh void IconvFBSDCD::mbcToXMLCh (const char *mbc, XMLCh *toRet) const { if (fUBO == LITTLE_ENDIAN) { if (fUChSize == sizeof(XMLCh)) *toRet = *((XMLCh*) mbc); else if (fUChSize == 2) { WC162XMLCh( mbc, toRet ); } else { WC322XMLCh( mbc, toRet ); } } else { if (fUChSize == 2) { IWC162XMLCh( mbc, toRet ); } else { IWC322XMLCh( mbc, toRet ); } } } // Convert XMLCh into "native unicode" character void IconvFBSDCD::xmlChToMbc (XMLCh xch, char *mbc) const { if (fUBO == LITTLE_ENDIAN) { if (fUChSize == sizeof(XMLCh)) { memcpy (mbc, &xch, fUChSize); return; } if (fUChSize == 2) { XMLCh2WC16( &xch, mbc ); } else { XMLCh2WC32( &xch, mbc ); } } else { if (fUChSize == 2) { IXMLCh2WC16( &xch, mbc ); } else { IXMLCh2WC32( &xch, mbc ); } } } // Return uppercase equivalent for XMLCh XMLCh IconvFBSDCD::toUpper (const XMLCh ch) const { if (ch <= 0x7F) return toupper(ch); char wcbuf[fUChSize * 2]; xmlChToMbc (ch, wcbuf); char tmpArr[4]; char* ptr = wcbuf; size_t len = fUChSize; char *pTmpArr = tmpArr; size_t bLen = 2; ICONV_LOCK; if (::iconv (fCDTo, (const char**) &ptr, &len, &pTmpArr, &bLen) == (size_t) -1) return 0; tmpArr[1] = toupper (*((unsigned char *)tmpArr)); *tmpArr = tmpArr[1]; len = 1; pTmpArr = wcbuf; bLen = fUChSize; ptr = tmpArr; if (::iconv (fCDFrom, (const char **)&ptr, &len, &pTmpArr, &bLen) == (size_t) -1) return 0; mbcToXMLCh (wcbuf, (XMLCh*) &ch); return ch; } // Return lowercase equivalent for XMLCh XMLCh IconvFBSDCD::toLower (const XMLCh ch) const { if (ch <= 0x7F) return tolower(ch); char wcbuf[fUChSize * 2]; xmlChToMbc (ch, wcbuf); char tmpArr[4]; char* ptr = wcbuf; size_t len = fUChSize; char *pTmpArr = tmpArr; size_t bLen = 2; ICONV_LOCK; if (::iconv (fCDTo, (const char**) &ptr, &len, &pTmpArr, &bLen) == (size_t) -1) return 0; tmpArr[1] = tolower (*((unsigned char*)tmpArr)); *tmpArr = tmpArr[1]; len = 1; pTmpArr = wcbuf; bLen = fUChSize; ptr = tmpArr; if (::iconv (fCDFrom, (const char **)&ptr, &len, &pTmpArr, &bLen) == (size_t) -1) return 0; mbcToXMLCh (wcbuf, (XMLCh*) &ch); return ch; } // Check if passed characters belongs to the :space: class bool IconvFBSDCD::isSpace(const XMLCh toCheck) const { if (toCheck <= 0x7F) return isspace(toCheck); char wcbuf[fUChSize * 2]; char tmpArr[4]; xmlChToMbc (toCheck, wcbuf); char* ptr = wcbuf; size_t len = fUChSize; char *pTmpArr = tmpArr; size_t bLen = 2; { ICONV_LOCK; if (::iconv (fCDTo, (const char**) &ptr, &len, &pTmpArr, &bLen) == (size_t) -1) return 0; } return isspace(*tmpArr); } // Fill array of XMLCh characters with data, supplyed in the array // of "native unicode" characters. XMLCh* IconvFBSDCD::mbsToXML ( const char* mbs_str , size_t mbs_cnt , XMLCh* xml_str , size_t xml_cnt ) const { if (mbs_str == NULL || mbs_cnt == 0 || xml_str == NULL || xml_cnt == 0) return NULL; size_t cnt = (mbs_cnt < xml_cnt) ? mbs_cnt : xml_cnt; if (fUBO == LITTLE_ENDIAN) { if (fUChSize == sizeof(XMLCh)) { // null-transformation memcpy (xml_str, mbs_str, fUChSize * cnt); return xml_str; } if (fUChSize == 2) for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) { WC162XMLCh( mbs_str, xml_str + i); } else for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) { WC322XMLCh( mbs_str, xml_str + i ); } } else { if (fUChSize == 2) for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) { IWC162XMLCh( mbs_str, xml_str + i ); } else for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) { IWC322XMLCh( mbs_str, xml_str + i ); } } return xml_str; } // Fill array of "native unicode" characters with data, supplyed // in the array of XMLCh characters. char* IconvFBSDCD::xmlToMbs ( const XMLCh* xml_str , size_t xml_cnt , char* mbs_str , size_t mbs_cnt ) const { if (mbs_str == NULL || mbs_cnt == 0 || xml_str == NULL || xml_cnt == 0) return NULL; size_t cnt = (mbs_cnt < xml_cnt) ? mbs_cnt : xml_cnt; char *toReturn = mbs_str; if (fUBO == LITTLE_ENDIAN) { if (fUChSize == sizeof(XMLCh)) { // null-transformation memcpy (mbs_str, xml_str, fUChSize * cnt); return toReturn; } if (fUChSize == 2) for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) { XMLCh2WC16( xml_str, mbs_str ); } else for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) { XMLCh2WC32( xml_str, mbs_str ); } } else { if (fUChSize == 2) for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) { IXMLCh2WC16( xml_str, mbs_str ); } else for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) { IXMLCh2WC32( xml_str, mbs_str ); } } return toReturn; } size_t IconvFBSDCD::iconvFrom ( const char *fromPtr, size_t *fromLen, char **toPtr, size_t toLen ) const { ICONV_LOCK; return ::iconv (fCDFrom, &fromPtr, fromLen, toPtr, &toLen); } size_t IconvFBSDCD::iconvTo ( const char *fromPtr, size_t *fromLen, char **toPtr, size_t toLen ) const { ICONV_LOCK; return ::iconv (fCDTo, &fromPtr, fromLen, toPtr, &toLen); } #endif /* !XML_USE_LIBICONV */ // --------------------------------------------------------------------------- // IconvFBSDTransService: Constructors and Destructor // --------------------------------------------------------------------------- IconvFBSDTransService::IconvFBSDTransService() #ifndef XML_USE_LIBICONV {} #else /* XML_USE_LIBICONV */ : IconvFBSDCD(), fUnicodeCP(0) { #if !defined(APP_NO_THREADS) // Create global lock object if (gIconvMutex == NULL) { gIconvMutex = new XMLMutex; if (gIconvMutex == NULL) XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService); } #endif // Try to obtain local (host) characterset through the environment char* fLocalCP = setlocale (LC_CTYPE, ""); if (fLocalCP == NULL) fLocalCP = "iso-8859-1"; // fallback locale else { char *ptr = strchr (fLocalCP, '.'); if (ptr == NULL) fLocalCP = "iso-8859-1"; // fallback locale else fLocalCP = ptr + 1; } // Select the native unicode characters encoding schema const IconvFBSDEncoding *eptr; // first - try to use the schema with character size, equil to XMLCh for (eptr = gIconvFBSDEncodings; eptr->fSchema; eptr++) { if (eptr->fUChSize != sizeof(XMLCh)) continue; ICONV_LOCK; // try to create conversion descriptor iconv_t cd_to = iconv_open(fLocalCP, eptr->fSchema); if (cd_to == (iconv_t)-1) continue; iconv_t cd_from = iconv_open(eptr->fSchema, fLocalCP); if (cd_to == (iconv_t)-1) { iconv_close (cd_to); continue; } // got it setUChSize(eptr->fUChSize); setUBO(eptr->fUBO); setCDTo(cd_to); setCDFrom(cd_from); fUnicodeCP = eptr->fSchema; break; } if (fUnicodeCP == NULL) // try to use any known schema for (eptr = gIconvFBSDEncodings; eptr->fSchema; eptr++) { // try to create conversion descriptor ICONV_LOCK; iconv_t cd_to = iconv_open(fLocalCP, eptr->fSchema); if (cd_to == (iconv_t)-1) continue; iconv_t cd_from = iconv_open(eptr->fSchema, fLocalCP); if (cd_to == (iconv_t)-1) { iconv_close (cd_to); continue; } // got it setUChSize(eptr->fUChSize); setUBO(eptr->fUBO); setCDTo(cd_to); setCDFrom(cd_from); fUnicodeCP = eptr->fSchema; break; } if (fUnicodeCP == NULL || cdTo() == (iconv_t)-1 || cdFrom() == (iconv_t)-1) XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService); } #endif /* XML_USE_LIBICONV */ IconvFBSDTransService::~IconvFBSDTransService() { #ifdef XML_USE_LIBICONV if (cdTo() != (iconv_t) -1) { iconv_close (cdTo()); setCDTo ((iconv_t)-1); } if (cdFrom() != (iconv_t) -1) { iconv_close (cdFrom()); setCDFrom ((iconv_t)-1); } #endif /* XML_USE_LIBICONV */ } // --------------------------------------------------------------------------- // IconvFBSDTransService: The virtual transcoding service API // --------------------------------------------------------------------------- int IconvFBSDTransService::compareIString(const XMLCh* const comp1 , const XMLCh* const comp2) { const XMLCh* cptr1 = comp1; const XMLCh* cptr2 = comp2; #ifndef XML_USE_LIBICONV while ( (*cptr1 != 0) && (*cptr2 != 0) ) { wint_t wch1 = fbsd_towupper(*cptr1); wint_t wch2 = fbsd_towupper(*cptr2); if (wch1 != wch2) break; cptr1++; cptr2++; } return (int) ( fbsd_towupper(*cptr1) - fbsd_towupper(*cptr2) ); #else /* XML_USE_LIBICONV */ XMLCh c1 = toUpper(*cptr1); XMLCh c2 = toUpper(*cptr2); while ( (*cptr1 != 0) && (*cptr2 != 0) ) { if (c1 != c2) break; c1 = toUpper(*(++cptr1)); c2 = toUpper(*(++cptr2)); } return (int) ( c1 - c2 ); #endif /* !XML_USE_LIBICONV */ } int IconvFBSDTransService::compareNIString(const XMLCh* const comp1 , const XMLCh* const comp2 , const unsigned int maxChars) { unsigned int n = 0; const XMLCh* cptr1 = comp1; const XMLCh* cptr2 = comp2; #ifndef XML_USE_LIBICONV while (true && maxChars) { wint_t wch1 = fbsd_towupper(*cptr1); wint_t wch2 = fbsd_towupper(*cptr2); if (wch1 != wch2) return (int) (wch1 - wch2); // If either ended, then both ended, so equal if (!*cptr1 || !*cptr2) break; cptr1++; cptr2++; // 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. n++; if (n == maxChars) break; } #else /* XML_USE_LIBICONV */ while (true && maxChars) { XMLCh c1 = toUpper(*cptr1); XMLCh c2 = toUpper(*cptr2); if (c1 != c2) return (int) (c1 - c2); // If either ended, then both ended, so equal if (!*cptr1 || !*cptr2) break; cptr1++; cptr2++; // 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. n++; if (n == maxChars) break; } #endif /* !XML_USE_LIBICONV */ return 0; } const XMLCh* IconvFBSDTransService::getId() const { return gMyServiceId; } bool IconvFBSDTransService::isSpace(const XMLCh toCheck) const { #ifndef XML_USE_LIBICONV if (toCheck <= 0x7F) return isspace(toCheck); char buf[16]; wchar_t wc = wchar_t(toCheck); wcstombs( buf, &wc, 16 ); return (isspace(*buf) != 0); #else /* XML_USE_LIBICONV */ return IconvFBSDCD::isSpace(toCheck); #endif /* !XML_USE_LIBICONV */ } XMLLCPTranscoder* IconvFBSDTransService::makeNewLCPTranscoder() { // Just allocate a new transcoder of our type #ifndef XML_USE_LIBICONV return new IconvFBSDLCPTranscoder; #else /* XML_USE_LIBICONV */ return new IconvFBSDLCPTranscoder (cdFrom(), cdTo(), uChSize(), UBO()); #endif /* !XML_USE_LIBICONV */ } bool IconvFBSDTransService::supportsSrcOfs() const { return true; } // --------------------------------------------------------------------------- // IconvFBSDTransService: The protected virtual transcoding service API // --------------------------------------------------------------------------- XMLTranscoder* IconvFBSDTransService::makeNewXMLTranscoder ( const XMLCh* const encodingName , XMLTransService::Codes& resValue , const unsigned int blockSize , MemoryManager* const manager ) { #ifndef XML_USE_LIBICONV // // NOTE: We don't use the block size here // // This is a minimalist transcoding service, that only supports a local // default transcoder. All named encodings return zero as a failure, // which means that only the intrinsic encodings supported by the parser // itself will work for XML data. // resValue = XMLTransService::UnsupportedEncoding; return 0; #else /* XML_USE_LIBICONV */ resValue = XMLTransService::UnsupportedEncoding; IconvFBSDTranscoder *newTranscoder = NULL; char *encLocal = XMLString::transcode(encodingName, manager); iconv_t cd_from, cd_to; { ICONV_LOCK; cd_from = iconv_open (fUnicodeCP, encLocal); if (cd_from == (iconv_t)-1) { resValue = XMLTransService::SupportFilesNotFound; if (encLocal) manager->deallocate(encLocal);//delete [] encLocal; return NULL; } cd_to = iconv_open (encLocal, fUnicodeCP); if (cd_to == (iconv_t)-1) { resValue = XMLTransService::SupportFilesNotFound; iconv_close (cd_from); if (encLocal) manager->deallocate(encLocal);//delete [] encLocal; return NULL; } newTranscoder = new (manager) IconvFBSDTranscoder (encodingName, blockSize, cd_from, cd_to, uChSize(), UBO(), manager); } if (newTranscoder) resValue = XMLTransService::Ok; if (encLocal) manager->deallocate(encLocal);//delete [] encLocal; return newTranscoder; #endif /* !XML_USE_LIBICONV */ } void IconvFBSDTransService::upperCase(XMLCh* const toUpperCase) const { XMLCh* outPtr = toUpperCase; while (*outPtr) { #ifndef XML_USE_LIBICONV *outPtr = fbsd_towupper(*outPtr); #else /* XML_USE_LIBICONV */ *outPtr = toUpper(*outPtr); #endif /* !XML_USE_LIBICONV */ outPtr++; } } void IconvFBSDTransService::lowerCase(XMLCh* const toLowerCase) const { XMLCh* outPtr = toLowerCase; while (*outPtr) { #ifndef XML_USE_LIBICONV *outPtr = fbsd_towlower(*outPtr); #else /* XML_USE_LIBICONV */ *outPtr = toLower(*outPtr); #endif /* !XML_USE_LIBICONV */ outPtr++; } } // --------------------------------------------------------------------------- // IconvFBSDLCPTranscoder: The virtual transcoder API // --------------------------------------------------------------------------- unsigned int IconvFBSDLCPTranscoder::calcRequiredSize (const char* const srcText , MemoryManager* const manager) { if (!srcText) return 0; #ifndef XML_USE_LIBICONV unsigned int retVal = fbsd_mbstowcs(NULL, srcText, 0); if (retVal == ~0) return 0; return retVal; #else /* XML_USE_LIBICONV */ size_t len, srcLen; len = srcLen = strlen(srcText); if (len == 0) return 0; char tmpWideArr[gTempBuffArraySize]; size_t totalLen = 0; for (;;) { char *pTmpArr = tmpWideArr; const char *ptr = srcText + srcLen - len; size_t rc = iconvFrom(ptr, &len, &pTmpArr, gTempBuffArraySize); if (rc == (size_t) -1 && errno != E2BIG) { ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, manager); /* return 0; */ } rc = pTmpArr - (char *) tmpWideArr; totalLen += rc; if (rc == 0 || len == 0) break; } return totalLen / uChSize(); #endif /* XML_USE_LIBICONV */ } unsigned int IconvFBSDLCPTranscoder::calcRequiredSize(const XMLCh* const srcText , MemoryManager* const manager) { if (!srcText) return 0; unsigned int wLent = getWideCharLength(srcText); if (wLent == 0) return 0; #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (wLent >= gTempBuffArraySize) wideCharBuf = allocatedArray = (wchar_t*) manager->allocate ( (wLent + 1) * sizeof(wchar_t) );//new wchar_t[wLent + 1]; else wideCharBuf = tmpWideCharArr; for (unsigned int i = 0; i < wLent; i++) wideCharBuf[i] = srcText[i]; wideCharBuf[wLent] = 0x00; const unsigned int retVal = fbsd_wcstombs(NULL, wideCharBuf, 0); if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; if (retVal == ~0) return 0; return retVal; #else /* XML_USE_LIBICONV */ char tmpWBuff[gTempBuffArraySize]; char *wBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) manager->allocate ( len * sizeof(char) );//new char[len]; if (wBufPtr == NULL) return 0; wBuf = wBufPtr; } else wBuf = tmpWBuff; xmlToMbs (srcText, wLent, wBuf, wLent); } else wBuf = (char *) srcText; char tmpBuff[gTempBuffArraySize]; size_t totalLen = 0; char *srcEnd = wBuf + wLent * uChSize(); for (;;) { char *pTmpArr = tmpBuff; const char *ptr = srcEnd - len; size_t rc = iconvTo(ptr, &len, &pTmpArr, gTempBuffArraySize); if (rc == (size_t) -1 && errno != E2BIG) { if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, manager); /* return 0; */ } rc = pTmpArr - tmpBuff; totalLen += rc; if (rc == 0 || len == 0) break; } if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; return totalLen; #endif /* !XML_USE_LIBICONV */ } char* IconvFBSDLCPTranscoder::transcode(const XMLCh* const toTranscode) { if (!toTranscode) return 0; char* retVal = 0; if (*toTranscode) { unsigned int wLent = getWideCharLength(toTranscode); #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (wLent >= gTempBuffArraySize) wideCharBuf = allocatedArray = new wchar_t[wLent + 1]; else wideCharBuf = tmpWideCharArr; for (unsigned int i = 0; i < wLent; i++) wideCharBuf[i] = toTranscode[i]; wideCharBuf[wLent] = 0x00; // Calc the needed size. const size_t neededLen = fbsd_wcstombs(NULL, wideCharBuf, 0); if (neededLen == -1) { if (allocatedArray) delete [] allocatedArray; return 0; } retVal = new char[neededLen + 1]; fbsd_wcstombs(retVal, wideCharBuf, neededLen); if (allocatedArray) delete [] allocatedArray; retVal[neededLen] = 0; #else /* XML_USE_LIBICONV */ // Calc needed size. const size_t neededLen = calcRequiredSize (toTranscode); if (neededLen == 0) return 0; // allocate output buffer retVal = new char[neededLen + 1]; if (retVal == NULL) return 0; // prepare the original char tmpWBuff[gTempBuffArraySize]; char *wideCharBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = new char[len]; if (wBufPtr == NULL) return 0; wideCharBuf = wBufPtr; } else wideCharBuf = tmpWBuff; xmlToMbs (toTranscode, wLent, wideCharBuf, wLent); } else wideCharBuf = (char *) toTranscode; // perform conversion wLent *= uChSize(); char *ptr = retVal; size_t tmpwLent = wLent; size_t rc = iconvTo(wideCharBuf, &tmpwLent, &ptr, neededLen); if (rc == (size_t)-1) { if (wBufPtr) delete [] wBufPtr; return 0; } if (wBufPtr) delete [] wBufPtr; retVal[neededLen] = 0; #endif /* !XML_USE_LIBICONV */ } else { retVal = new char[1]; if (retVal == NULL) return 0; retVal[0] = 0; } return retVal; } char* IconvFBSDLCPTranscoder::transcode(const XMLCh* const toTranscode, MemoryManager* const manager) { if (!toTranscode) return 0; char* retVal = 0; if (*toTranscode) { unsigned int wLent = getWideCharLength(toTranscode); #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (wLent >= gTempBuffArraySize) wideCharBuf = allocatedArray = (wchar_t*) manager->allocate ( (wLent + 1) * sizeof(wchar_t) );//new wchar_t[wLent + 1]; else wideCharBuf = tmpWideCharArr; for (unsigned int i = 0; i < wLent; i++) wideCharBuf[i] = toTranscode[i]; wideCharBuf[wLent] = 0x00; // Calc the needed size. const size_t neededLen = fbsd_wcstombs(NULL, wideCharBuf, 0); if (neededLen == -1) { if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; return 0; } retVal = (char*) manager->allocate((neededLen + 1) * sizeof(char));//new char[neededLen + 1]; fbsd_wcstombs(retVal, wideCharBuf, neededLen); if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; retVal[neededLen] = 0; #else /* XML_USE_LIBICONV */ // Calc needed size. const size_t neededLen = calcRequiredSize (toTranscode, manager); if (neededLen == 0) return 0; // allocate output buffer retVal = (char*) manager->allocate((neededLen + 1) * sizeof(char));//new char[neededLen + 1]; if (retVal == NULL) return 0; // prepare the original char tmpWBuff[gTempBuffArraySize]; char *wideCharBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) manager->allocate(len * sizeof(char));//new char[len]; if (wBufPtr == NULL) { manager->deallocate(retVal); return 0; } wideCharBuf = wBufPtr; } else wideCharBuf = tmpWBuff; xmlToMbs (toTranscode, wLent, wideCharBuf, wLent); } else wideCharBuf = (char *) toTranscode; // perform conversion wLent *= uChSize(); char *ptr = retVal; size_t tmpwLent = wLent; size_t rc = iconvTo(wideCharBuf, &tmpwLent, &ptr, neededLen); if (rc == (size_t)-1) { if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; return 0; } if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; retVal[neededLen] = 0; #endif /* !XML_USE_LIBICONV */ } else { retVal = (char*) manager->allocate(sizeof(char));//new char[1]; if (retVal == NULL) return 0; retVal[0] = 0; } return retVal; } bool IconvFBSDLCPTranscoder::transcode( const XMLCh* const toTranscode , char* const toFill , const unsigned int maxBytes , MemoryManager* const manager) { // Watch for a couple of pyscho corner cases if (!toTranscode || !maxBytes) { toFill[0] = 0; return true; } if (!*toTranscode) { toFill[0] = 0; return true; } unsigned int wLent = getWideCharLength(toTranscode); if (wLent > maxBytes) wLent = maxBytes; #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (maxBytes >= gTempBuffArraySize) wideCharBuf = allocatedArray = (wchar_t*) manager->allocate ( (maxBytes + 1) * sizeof(wchar_t) );//new wchar_t[maxBytes + 1]; else wideCharBuf = tmpWideCharArr; for (unsigned int i = 0; i < wLent; i++) wideCharBuf[i] = toTranscode[i]; wideCharBuf[wLent] = 0x00; // Ok, go ahead and try the transcoding. If it fails, then ... size_t mblen = fbsd_wcstombs(toFill, wideCharBuf, maxBytes); if (mblen == -1) { if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; return false; } if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; // Cap it off just in case toFill[mblen] = 0; #else /* XML_USE_LIBICONV */ // Fill the "unicode" string char tmpWBuff[gTempBuffArraySize]; char *wideCharBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) manager->allocate ( len * sizeof(char) );//new char[len]; if (wBufPtr == NULL) return 0; wideCharBuf = wBufPtr; } else wideCharBuf = tmpWBuff; xmlToMbs (toTranscode, wLent, wideCharBuf, wLent); } else wideCharBuf = (char *) toTranscode; // Ok, go ahead and try the transcoding. If it fails, then ... char *ptr = toFill; size_t rc = iconvTo(wideCharBuf, &len, &ptr, maxBytes); if (rc == (size_t)-1) { if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; return false; } if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; *ptr = 0; #endif /* !XML_USE_LIBICONV */ return true; } XMLCh* IconvFBSDLCPTranscoder::transcode(const char* const toTranscode) { if (!toTranscode) return 0; XMLCh* retVal = 0; if (*toTranscode) { const unsigned int wLent = calcRequiredSize(toTranscode); if (wLent == 0) { retVal = new XMLCh[1]; retVal[0] = 0; return retVal; } #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (wLent >= gTempBuffArraySize) wideCharBuf = allocatedArray = new wchar_t[wLent + 1]; else wideCharBuf = tmpWideCharArr; fbsd_mbstowcs(wideCharBuf, toTranscode, wLent); retVal = new XMLCh[wLent + 1]; if (retVal == NULL) { if (allocatedArray) delete [] allocatedArray; return NULL; } for (unsigned int i = 0; i < wLent; i++) retVal[i] = (XMLCh) wideCharBuf[i]; retVal[wLent] = 0x00; if (allocatedArray) delete [] allocatedArray; #else /* XML_USE_LIBICONV */ char tmpWBuff[gTempBuffArraySize]; char *wideCharBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); retVal = new XMLCh[wLent + 1]; if (retVal == NULL) return NULL; if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = new char[len]; if (wBufPtr == NULL) return 0; wideCharBuf = wBufPtr; } else wideCharBuf = tmpWBuff; } else wideCharBuf = (char *) retVal; size_t flen = strlen(toTranscode); char *ptr = wideCharBuf; size_t rc = iconvFrom(toTranscode, &flen, &ptr, len); if (rc == (size_t) -1) { if (wBufPtr) delete [] wBufPtr; return NULL; } if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) mbsToXML (wideCharBuf, wLent, retVal, wLent); if (wBufPtr) delete [] wBufPtr; retVal[wLent] = 0x00; #endif /* !XML_USE_LIBICONV */ } else { retVal = new XMLCh[1]; if (retVal == NULL ) return 0; retVal[0] = 0; } return retVal; } XMLCh* IconvFBSDLCPTranscoder::transcode(const char* const toTranscode, MemoryManager* const manager) { if (!toTranscode) return 0; XMLCh* retVal = 0; if (*toTranscode) { const unsigned int wLent = calcRequiredSize(toTranscode, manager); if (wLent == 0) { retVal = (XMLCh*) manager->allocate(sizeof(XMLCh));//new XMLCh[1]; retVal[0] = 0; return retVal; } #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (wLent >= gTempBuffArraySize) wideCharBuf = allocatedArray = (wchar_t*) manager->allocate ( (wLent + 1) * sizeof(wchar_t) );//new wchar_t[wLent + 1]; else wideCharBuf = tmpWideCharArr; fbsd_mbstowcs(wideCharBuf, toTranscode, wLent); retVal = (XMLCh*) manager->allocate((wLent + 1) * sizeof(XMLCh));//new XMLCh[wLent + 1]; if (retVal == NULL) { if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; return NULL; } for (unsigned int i = 0; i < wLent; i++) retVal[i] = (XMLCh) wideCharBuf[i]; retVal[wLent] = 0x00; if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; #else /* XML_USE_LIBICONV */ char tmpWBuff[gTempBuffArraySize]; char *wideCharBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); retVal = (XMLCh*) manager->allocate((wLent + 1) * sizeof(XMLCh));//new XMLCh[wLent + 1]; if (retVal == NULL) return NULL; if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) manager->allocate(len * sizeof(char));//new char[len]; if (wBufPtr == NULL) return 0; wideCharBuf = wBufPtr; } else wideCharBuf = tmpWBuff; } else wideCharBuf = (char *) retVal; size_t flen = strlen(toTranscode); char *ptr = wideCharBuf; size_t rc = iconvFrom(toTranscode, &flen, &ptr, len); if (rc == (size_t) -1) { if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; return NULL; } if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) mbsToXML (wideCharBuf, wLent, retVal, wLent); if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; retVal[wLent] = 0x00; #endif /* !XML_USE_LIBICONV */ } else { retVal = (XMLCh*) manager->allocate(sizeof(XMLCh));//new XMLCh[1]; if (retVal == NULL ) return 0; retVal[0] = 0; } return retVal; } bool IconvFBSDLCPTranscoder::transcode(const char* const toTranscode , XMLCh* const toFill , const unsigned int maxChars , MemoryManager* const manager) { // Check for a couple of psycho corner cases if (!toTranscode || !maxChars) { toFill[0] = 0; return true; } if (!*toTranscode) { toFill[0] = 0; return true; } size_t wLent = calcRequiredSize(toTranscode); if (wLent > maxChars) wLent = maxChars; #ifndef XML_USE_LIBICONV wchar_t tmpWideCharArr[gTempBuffArraySize]; wchar_t* allocatedArray = 0; wchar_t* wideCharBuf = 0; if (maxChars >= gTempBuffArraySize) wideCharBuf = allocatedArray = (wchar_t*) manager->allocate ( (wLent + 1) * sizeof(wchar_t) );//new wchar_t[wLent + 1]; else wideCharBuf = tmpWideCharArr; if (fbsd_mbstowcs(wideCharBuf, toTranscode, wLent) == -1) { if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; return false; } for (unsigned int i = 0; i < wLent; i++) toFill[i] = (XMLCh) wideCharBuf[i]; if (allocatedArray) manager->deallocate(allocatedArray);//delete [] allocatedArray; #else /* XML_USE_LIBICONV */ char tmpWBuff[gTempBuffArraySize]; char *wideCharBuf = 0; char *wBufPtr = 0; size_t len = wLent * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) manager->allocate ( len * sizeof(char) );//new char[len]; if (wBufPtr == NULL) return 0; wideCharBuf = wBufPtr; } else wideCharBuf = tmpWBuff; } else wideCharBuf = (char *) toFill; size_t flen = strlen(toTranscode); // wLent; char *ptr = wideCharBuf; size_t rc = iconvFrom(toTranscode, &flen, &ptr, len); if (rc == (size_t)-1) { if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; return false; } if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) mbsToXML (wideCharBuf, wLent, toFill, wLent); if (wBufPtr) manager->deallocate(wBufPtr);//delete [] wBufPtr; #endif /* !XML_USE_LIBICONV */ toFill[wLent] = 0x00; return true; } // --------------------------------------------------------------------------- // IconvFBSDLCPTranscoder: Constructors and Destructor // --------------------------------------------------------------------------- #ifdef XML_USE_LIBICONV IconvFBSDLCPTranscoder::IconvFBSDLCPTranscoder (iconv_t cd_from, iconv_t cd_to, size_t uchsize, unsigned int ubo) : IconvFBSDCD (cd_from, cd_to, uchsize, ubo) { } #endif /* XML_USE_LIBICONV */ #ifndef XML_USE_LIBICONV IconvFBSDLCPTranscoder::IconvFBSDLCPTranscoder() { } #endif /* !XML_USE_LIBICONV */ IconvFBSDLCPTranscoder::~IconvFBSDLCPTranscoder() { } #ifdef XML_USE_LIBICONV // --------------------------------------------------------------------------- // IconvFBSDTranscoder: Constructors and Destructor // --------------------------------------------------------------------------- IconvFBSDTranscoder::IconvFBSDTranscoder (const XMLCh* const encodingName , const unsigned int blockSize , iconv_t cd_from , iconv_t cd_to , size_t uchsize , unsigned int ubo , MemoryManager* const manager ) : XMLTranscoder(encodingName, blockSize, manager) , IconvFBSDCD (cd_from, cd_to, uchsize, ubo) { } IconvFBSDTranscoder::~IconvFBSDTranscoder() { ICONV_LOCK; if (cdTo() != (iconv_t)-1) { iconv_close (cdTo()); setCDTo ((iconv_t)-1); } if (cdFrom() != (iconv_t)-1) { iconv_close (cdFrom()); setCDFrom ((iconv_t)-1); } } // --------------------------------------------------------------------------- // IconvFBSDTranscoder: Implementation of the virtual transcoder API // --------------------------------------------------------------------------- unsigned int IconvFBSDTranscoder::transcodeFrom ( const XMLByte* const srcData , const unsigned int srcCount , XMLCh* const toFill , const unsigned int maxChars , unsigned int& bytesEaten , unsigned char* const charSizes ) { // Transcode TO XMLCh const char* startSrc = (const char*) srcData; const char* endSrc = (const char*) srcData + srcCount; char tmpWBuff[gTempBuffArraySize]; char *startTarget = 0; char *wBufPtr = 0; size_t len = maxChars * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) getMemoryManager()->allocate ( len * sizeof(char) );//new char[len]; if (wBufPtr == NULL) return 0; startTarget = wBufPtr; } else startTarget = tmpWBuff; } else startTarget = (char *) toFill; // Do character-by-character transcoding char *orgTarget = startTarget; size_t srcLen = srcCount; size_t prevSrcLen = srcLen; unsigned int toReturn = 0; bytesEaten = 0; for (size_t cnt = 0; cnt < maxChars && srcLen; cnt++) { size_t rc = iconvFrom(startSrc, &srcLen, &orgTarget, uChSize()); if (rc == (size_t)-1) { if (errno != E2BIG || prevSrcLen == srcLen) { if (wBufPtr) getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr; ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, getMemoryManager()); } } charSizes[cnt] = prevSrcLen - srcLen; prevSrcLen = srcLen; bytesEaten += charSizes[cnt]; startSrc = endSrc - srcLen; toReturn++; } if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) mbsToXML (startTarget, toReturn, toFill, toReturn); if (wBufPtr) getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr; return toReturn; } unsigned int IconvFBSDTranscoder::transcodeTo ( const XMLCh* const srcData , const unsigned int srcCount , XMLByte* const toFill , const unsigned int maxBytes , unsigned int& charsEaten , const UnRepOpts options ) { // Transcode FROM XMLCh char tmpWBuff[gTempBuffArraySize]; char *startSrc = tmpWBuff; char *wBufPtr = 0; size_t len = srcCount * uChSize(); if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) { if (len > gTempBuffArraySize) { wBufPtr = (char*) getMemoryManager()->allocate ( len * sizeof(char) );//new char[len]; if (wBufPtr == NULL) return 0; startSrc = wBufPtr; } else startSrc = tmpWBuff; xmlToMbs (srcData, srcCount, startSrc, srcCount); } else startSrc = (char *) srcData; char* startTarget = (char *) toFill; size_t srcLen = len; size_t rc = iconvTo (startSrc, &srcLen, &startTarget, maxBytes); if (rc == (size_t)-1 && errno != E2BIG) { if (wBufPtr) getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr; ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, getMemoryManager()); } charsEaten = srcCount - srcLen / uChSize(); if (wBufPtr) getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr; return startTarget - (char *)toFill; } bool IconvFBSDTranscoder::canTranscodeTo ( const unsigned int toCheck ) const { // // If the passed value is really a surrogate embedded together, then // we need to break it out into its two chars. Else just one. // char srcBuf[2 * uChSize()]; unsigned int srcCount = 1; if (toCheck & 0xFFFF0000) { XMLCh ch1 = (toCheck >> 10) + 0xD800; XMLCh ch2 = toCheck & 0x3FF + 0xDC00; xmlToMbs(&ch1, 1, srcBuf, 1); xmlToMbs(&ch2, 1, srcBuf + uChSize(), 1); srcCount++; } else xmlToMbs((const XMLCh*) &toCheck, 1, srcBuf, 1); size_t len = srcCount * uChSize(); char tmpBuf[64]; char* pTmpBuf = tmpBuf; size_t rc = iconvTo( srcBuf, &len, &pTmpBuf, 64); return (rc != (size_t)-1) && (len == 0); } #endif /* XML_USE_LIBICONV */ XERCES_CPP_NAMESPACE_END