IconvFBSDTransService.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:56k
源码类别:
词法分析
开发平台:
Visual C++
- /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001 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) 2001, International
- * Business Machines, Inc., http://www.ibm.com . For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- /*
- * $Log: IconvFBSDTransService.cpp,v $
- * Revision 1.14 2003/05/17 16:32:17 knoaman
- * Memory manager implementation : transcoder update.
- *
- * Revision 1.13 2003/05/16 21:37:00 knoaman
- * Memory manager implementation: Modify constructors to pass in the memory manager.
- *
- * Revision 1.12 2003/05/15 18:47:04 knoaman
- * Partial implementation of the configurable memory manager.
- *
- * Revision 1.11 2003/03/09 17:02:57 peiyongz
- * PanicHandler
- *
- * Revision 1.10 2003/03/07 15:08:57 tng
- * [Bug 17571] fix building IconvFBSD (namespaces) . Patch from Bjoern A. Zeeb.
- *
- * Revision 1.9 2003/03/07 14:42:45 tng
- * [Bug 17570] IconvFBSD build on alpha,sparc. Patch from Bjoern A. Zeeb.
- *
- * Revision 1.8 2003/02/25 08:15:42 gareth
- * Patch to fix compile problem in bug #17358. Patch by Michael Cahill.
- *
- * Revision 1.7 2002/12/31 18:42:43 tng
- * [Bug 15608] IconvLCPTranscoder::transcode() is wrong at wcstombs() usage.
- *
- * Revision 1.6 2002/11/04 15:14:34 tng
- * C++ Namespace Support.
- *
- * Revision 1.5 2002/07/04 18:20:18 tng
- * [Bug 10253] Bugfix for the IconvFBSD transcoder. Patch from Max Gotlib.
- *
- * Revision 1.4 2002/04/11 15:38:05 knoaman
- * String lower case support for FreeBSD by Max Gotlib
- *
- * Revision 1.3 2002/04/09 15:44:00 knoaman
- * Add lower case string support.
- *
- * Revision 1.2 2002/03/18 13:39:11 tng
- * [Bug 7162 ] IconvFreeBSDTransService.cpp needs an #include statement fixed to use xercesc.
- *
- * Revision 1.1.1.1 2002/02/01 22:22:36 peiyongz
- * sane_include
- *
- * Revision 1.4 2002/01/14 19:45:15 tng
- * Support IconvFBSD in multi-threading environment with all the possible combinations of threading and transcoding options. By Max Gotlib.
- *
- * Revision 1.3 2001/12/12 14:48:16 tng
- * More bug fixes in IconvFBSD Transcoder. By Max Gotlib.
- *
- * Revision 1.2 2001/12/11 15:10:14 tng
- * More changes to IconvFBSDTransService. Allow using "old" TransServece implementation (via '-t native' option to runConfigure) or
- * to employ libiconv (it is a part of FreeBSD ports-collection) services. By Max Gotlib.
- *
- * Revision 1.1 2001/12/03 14:45:11 tng
- * FreeBSD native transcoder (IconvFBSD) added by Max Gotlib.
- *
- */
- // ---------------------------------------------------------------------------
- // Includes
- // ---------------------------------------------------------------------------
- #include <ctype.h>
- #ifdef XML_USE_LIBICONV
- # include <locale.h>
- # include <iconv.h>
- # include <errno.h>
- # include <machine/endian.h>
- // ---------------------------------------------------------------------------
- // 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 <wchar.h>
- # else
- # define wint_t XMLCh
- # endif
- #endif /* XML_USE_LIBICONV */
- #include <xercesc/util/XMLString.hpp>
- #include <xercesc/util/XMLUniDefs.hpp>
- #include <xercesc/util/XMLUni.hpp>
- #include <xercesc/util/PlatformUtils.hpp>
- #include <xercesc/util/TranscodingException.hpp>
- #include "IconvFBSDTransService.hpp"
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #if !defined(APP_NO_THREADS)
- #include <xercesc/util/Mutexes.hpp>
- #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)
- {
- 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) {
- ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
- /* 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)
- {
- 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*) XMLPlatformUtils::fgMemoryManager->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)
- XMLPlatformUtils::fgMemoryManager->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*) XMLPlatformUtils::fgMemoryManager->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)
- XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
- ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
- /* return 0; */
- }
- rc = pTmpArr - tmpBuff;
- totalLen += rc;
- if (rc == 0 || len == 0)
- break;
- }
- if (wBufPtr)
- XMLPlatformUtils::fgMemoryManager->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);
- 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)
- {
- // 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;
- size_t mblen;
- #ifndef XML_USE_LIBICONV
- wchar_t tmpWideCharArr[gTempBuffArraySize];
- wchar_t* allocatedArray = 0;
- wchar_t* wideCharBuf = 0;
- if (maxBytes >= gTempBuffArraySize)
- wideCharBuf = allocatedArray = (wchar_t*) XMLPlatformUtils::fgMemoryManager->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 ...
- mblen = fbsd_wcstombs(toFill, wideCharBuf, maxBytes);
- if (mblen == -1) {
- if (allocatedArray)
- XMLPlatformUtils::fgMemoryManager->deallocate(allocatedArray);//delete [] allocatedArray;
- return false;
- }
- if (allocatedArray)
- XMLPlatformUtils::fgMemoryManager->deallocate(allocatedArray);//delete [] allocatedArray;
- #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*) XMLPlatformUtils::fgMemoryManager->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;
- mblen = iconvTo(wideCharBuf, &len, &ptr, maxBytes);
- if (mblen == (size_t)-1) {
- if (wBufPtr)
- XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
- return false;
- }
- if (wBufPtr)
- XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
- #endif /* !XML_USE_LIBICONV */
- // Cap it off just in case
- toFill[mblen] = 0;
- 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);
- 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)
- {
- // 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*) XMLPlatformUtils::fgMemoryManager->allocate
- (
- (wLent + 1) * sizeof(wchar_t)
- );//new wchar_t[wLent + 1];
- else
- wideCharBuf = tmpWideCharArr;
- if (fbsd_mbstowcs(wideCharBuf, toTranscode, wLent) == -1) {
- if (allocatedArray)
- XMLPlatformUtils::fgMemoryManager->deallocate(allocatedArray);//delete [] allocatedArray;
- return false;
- }
- for (unsigned int i = 0; i < wLent; i++)
- toFill[i] = (XMLCh) wideCharBuf[i];
- if (allocatedArray)
- XMLPlatformUtils::fgMemoryManager->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*) XMLPlatformUtils::fgMemoryManager->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)
- XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
- return false;
- }
- if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER)
- mbsToXML (wideCharBuf, wLent, toFill, wLent);
- if (wBufPtr)
- XMLPlatformUtils::fgMemoryManager->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;
- ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
- }
- }
- 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;
- ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
- }
- 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