IconvGNUTransService.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:42k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2002 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: IconvGNUTransService.cpp,v $
  58.  * Revision 1.9  2003/05/17 16:32:18  knoaman
  59.  * Memory manager implementation : transcoder update.
  60.  *
  61.  * Revision 1.8  2003/05/16 21:37:00  knoaman
  62.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  63.  *
  64.  * Revision 1.7  2003/05/15 18:47:05  knoaman
  65.  * Partial implementation of the configurable memory manager.
  66.  *
  67.  * Revision 1.6  2003/04/07 16:52:13  peiyongz
  68.  * Bug# 18672: IconvGNUTranscoder can't be build when namespaces is on.
  69.  *                       Patch from Bacek@yandex-team.ru (Vasily Tchekalkin)
  70.  *
  71.  * Revision 1.5  2003/03/09 17:03:25  peiyongz
  72.  * PanicHandler
  73.  *
  74.  * Revision 1.4  2002/12/31 18:42:54  tng
  75.  * [Bug 15608] IconvLCPTranscoder::transcode() is wrong at wcstombs() usage.
  76.  *
  77.  * Revision 1.3  2002/11/04 15:14:34  tng
  78.  * C++ Namespace Support.
  79.  *
  80.  * Revision 1.2  2002/09/27 13:33:43  tng
  81.  * [Bug 12547] Xerces C++ 2.1 fails to build on Linux 64 bits arch with -tlinux.  Patch from Guillaume Morin.
  82.  *
  83.  * Revision 1.1  2002/08/19 19:38:18  tng
  84.  * [Bug 11771] Linux specific IconvGNU transcoder.  Patch from Vasily Tchekalkin.
  85.  *
  86.  */
  87. // ---------------------------------------------------------------------------
  88. //  Includes
  89. // ---------------------------------------------------------------------------
  90. #include <ctype.h>
  91. #include <locale.h>
  92. #include <iconv.h>
  93. #include <errno.h>
  94. #include <endian.h>
  95. #include <xercesc/util/XMLString.hpp>
  96. #include <xercesc/util/XMLUniDefs.hpp>
  97. #include <xercesc/util/XMLUni.hpp>
  98. #include <xercesc/util/PlatformUtils.hpp>
  99. #include <xercesc/util/TranscodingException.hpp>
  100. #include "IconvGNUTransService.hpp"
  101. #if !defined(APP_NO_THREADS)
  102. #include <xercesc/util/Mutexes.hpp>
  103. #endif /* !APP_NO_THREADS */
  104. XERCES_CPP_NAMESPACE_BEGIN
  105. #if !defined(APP_NO_THREADS)
  106. // Iconv() access syncronization point
  107. static XMLMutex    *gIconvMutex = NULL;
  108. #  define ICONV_LOCK    XMLMutexLock lockConverter(gIconvMutex);
  109. #else /* APP_NO_THREADS */
  110. # define ICONV_LOCK
  111. #endif /* !APP_NO_THREADS */
  112. // ---------------------------------------------------------------------------
  113. // Description of encoding schemas, supported by iconv()
  114. // ---------------------------------------------------------------------------
  115. typedef struct __IconvGNUEncoding {
  116.     const char*    fSchema;    // schema name
  117.     size_t    fUChSize;    // size of the character
  118.     unsigned int fUBO;        // byte order, relative to the host
  119. } IconvGNUEncoding;
  120. static const IconvGNUEncoding    gIconvGNUEncodings[] = {
  121.     { "UCS-2LE",        2,    LITTLE_ENDIAN },
  122.     { "ucs-2-internal",        2,    LITTLE_ENDIAN },
  123.     { NULL, 0,    0 }
  124. };
  125. //--------------------------------------------------
  126. // Macro-definitions to translate "native unicode"
  127. // characters <-> XMLCh with different host byte order
  128. // and encoding schemas.
  129. # if BYTE_ORDER == LITTLE_ENDIAN
  130. #  define IXMLCh2WC16(x,w)            
  131.     *(w) = ((*(x)) >> 8) & 0xFF;        
  132.     *((w)+1) = (*(x)) & 0xFF
  133. #  define IWC162XMLCh(w,x)    *(x) = ((*(w)) << 8) | (*((w)+1))
  134. #  define XMLCh2WC16(x,w)            
  135.     *(w) = (*(x)) & 0xFF;            
  136.     *((w)+1) = ((*(x)) >> 8) & 0xFF
  137. #  define WC162XMLCh(w,x)    *(x) = ((*((w)+1)) << 8) | (*(w))
  138. #  define IXMLCh2WC32(x,w)            
  139.     *(w) = ((*(x)) >> 24) & 0xFF;        
  140.     *((w)+1) = ((*(x)) >> 16) & 0xFF;    
  141.     *((w)+2) = ((*(x)) >> 8) & 0xFF;    
  142.     *((w)+3) = (*(x)) & 0xFF
  143. #  define IWC322XMLCh(w,x)                
  144.       *(x) = ((*(w)) << 24) | ((*((w)+1)) << 16) |    
  145.           ((*((w)+2)) << 8) | (*((w)+3))
  146. #  define XMLCh2WC32(x,w)            
  147.     *((w)+3) = ((*(x)) >> 24) & 0xFF;    
  148.     *((w)+2) = ((*(x)) >> 16) & 0xFF;    
  149.     *((w)+1) = ((*(x)) >> 8) & 0xFF;    
  150.     *(w) = (*(x)) & 0xFF
  151. #  define WC322XMLCh(w,x)                    
  152.       *(x) = ((*((w)+3)) << 24) | ((*((w)+2)) << 16) |    
  153.         ((*((w)+1)) << 8) | (*(w))
  154. # else /* BYTE_ORDER != LITTLE_ENDIAN */
  155. #  define XMLCh2WC16(x,w)            
  156.     *(w) = ((*(x)) >> 8) & 0xFF;        
  157.     *((w)+1) = (*(x)) & 0xFF
  158. #  define WC162XMLCh(w,x)    *(x) = ((*(w)) << 8) | (*((w)+1))
  159. #  define IXMLCh2WC16(x,w)            
  160.     *(w) = (*(x)) & 0xFF;            
  161.     *((w)+1) = ((*(x)) >> 8) & 0xFF
  162. #  define IWC162XMLCh(w,x)    *(x) = ((*((w)+1)) << 8) | (*(w))
  163. #  define XMLCh2WC32(x,w)            
  164.     *(w) = ((*(x)) >> 24) & 0xFF;        
  165.     *((w)+1) = ((*(x)) >> 16) & 0xFF;    
  166.     *((w)+2) = ((*(x)) >> 8) & 0xFF;    
  167.     *((w)+3) = (*(x)) & 0xFF
  168. #  define WC322XMLCh(w,x)                
  169.       *(x) = ((*(w)) << 24) | ((*((w)+1)) << 16) |    
  170.           ((*((w)+2)) << 8) | (*((w)+3))
  171. #  define IXMLCh2WC32(x,w)            
  172.     *((w)+3) = ((*(x)) >> 24) & 0xFF;    
  173.     *((w)+2) = ((*(x)) >> 16) & 0xFF;    
  174.     *((w)+1) = ((*(x)) >> 8) & 0xFF;    
  175.     *(w) = (*(x)) & 0xFF
  176. #  define IWC322XMLCh(w,x)                    
  177.       *(x) = ((*((w)+3)) << 24) | ((*((w)+2)) << 16) |    
  178.         ((*((w)+1)) << 8) | (*(w))
  179. # endif /* BYTE_ORDER == LITTLE_ENDIAN */
  180. #include <wchar.h>
  181. #include <string.h>
  182. #include <stdlib.h>
  183. #include <stdio.h>
  184. // ---------------------------------------------------------------------------
  185. //  Local, const data
  186. // ---------------------------------------------------------------------------
  187. static const unsigned int    gTempBuffArraySize = 4096;
  188. static const XMLCh        gMyServiceId[] =
  189. {
  190.     chLatin_I, chLatin_C, chLatin_o, chLatin_n, chLatin_v, chNull
  191. };
  192. // ---------------------------------------------------------------------------
  193. //  Local methods
  194. // ---------------------------------------------------------------------------
  195. static unsigned int getWideCharLength(const XMLCh* const src)
  196. {
  197.     if (!src)
  198.         return 0;
  199.     unsigned int len = 0;
  200.     const XMLCh* pTmp = src;
  201.     while (*pTmp++)
  202.         len++;
  203.     return len;
  204. }
  205. //----------------------------------------------------------------------------
  206. // There is implementation of the libiconv for FreeBSD (available through the
  207. // ports collection). The following is a wrapper around the iconv().
  208. //----------------------------------------------------------------------------
  209. IconvGNUWrapper::IconvGNUWrapper ()
  210.     : fUChSize(0), fUBO(LITTLE_ENDIAN),
  211.       fCDTo((iconv_t)-1), fCDFrom((iconv_t)-1)
  212. {
  213. }
  214. IconvGNUWrapper::IconvGNUWrapper ( iconv_t    cd_from,
  215.                iconv_t    cd_to,
  216.                size_t    uchsize,
  217.                unsigned int    ubo )
  218.     : fUChSize(uchsize), fUBO(ubo),
  219.       fCDTo(cd_to), fCDFrom(cd_from)
  220. {
  221.     if (fCDFrom == (iconv_t) -1 || fCDTo == (iconv_t) -1) {
  222.     XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService);
  223.     }
  224. }
  225. IconvGNUWrapper::~IconvGNUWrapper()
  226. {
  227. }
  228. // Convert "native unicode" character into XMLCh
  229. void    IconvGNUWrapper::mbcToXMLCh (const char *mbc, XMLCh *toRet) const
  230. {
  231.     if (fUBO == LITTLE_ENDIAN) {
  232.         if (fUChSize == sizeof(XMLCh))
  233.             *toRet = *((XMLCh*) mbc);
  234.         else if (fUChSize == 2) {
  235.             WC162XMLCh( mbc, toRet );
  236.         } else {
  237.             WC322XMLCh( mbc, toRet );
  238.         }
  239.     } else {
  240.         if (fUChSize == 2) {
  241.             IWC162XMLCh( mbc, toRet );
  242.         } else {
  243.             IWC322XMLCh( mbc, toRet );
  244.         }
  245.     }
  246. }
  247. // Convert XMLCh into "native unicode" character
  248. void    IconvGNUWrapper::xmlChToMbc (XMLCh xch, char *mbc) const
  249. {
  250.     if (fUBO == LITTLE_ENDIAN) {
  251.         if (fUChSize == sizeof(XMLCh)) {
  252.             memcpy (mbc, &xch, fUChSize);
  253.             return;
  254.         }
  255.         if (fUChSize == 2) {
  256.             XMLCh2WC16( &xch, mbc );
  257.         } else {
  258.             XMLCh2WC32( &xch, mbc );
  259.         }
  260.     } else {
  261.         if (fUChSize == 2) {
  262.             IXMLCh2WC16( &xch, mbc );
  263.         } else {
  264.             IXMLCh2WC32( &xch, mbc );
  265.         }
  266.     }
  267. }
  268. // Return uppercase equivalent for XMLCh
  269. XMLCh    IconvGNUWrapper::toUpper (const XMLCh ch) const
  270. {
  271.     if (ch <= 0x7F)
  272.         return toupper(ch);
  273.     char    wcbuf[fUChSize * 2];
  274.     xmlChToMbc (ch, wcbuf);
  275.     char    tmpArr[4];
  276.     char*    ptr = wcbuf;
  277.     size_t    len = fUChSize;
  278.     char    *pTmpArr = tmpArr;
  279.     size_t    bLen = 2;
  280.     ICONV_LOCK;
  281.     if (::iconv (fCDTo, &ptr, &len,
  282.          &pTmpArr, &bLen) == (size_t) -1)
  283.     return 0;
  284.     tmpArr[1] = toupper (*((unsigned char *)tmpArr));
  285.     *tmpArr = tmpArr[1];
  286.     len = 1;
  287.     pTmpArr = wcbuf;
  288.     bLen = fUChSize;
  289.     ptr = tmpArr;
  290.     if (::iconv (fCDFrom, &ptr, &len,
  291.          &pTmpArr, &bLen) == (size_t) -1)
  292.     return 0;
  293.     mbcToXMLCh (wcbuf, (XMLCh*) &ch);
  294.     return ch;
  295. }
  296. // Return lowercase equivalent for XMLCh
  297. XMLCh    IconvGNUWrapper::toLower (const XMLCh ch) const
  298. {
  299.     if (ch <= 0x7F)
  300.         return tolower(ch);
  301.     char    wcbuf[fUChSize * 2];
  302.     xmlChToMbc (ch, wcbuf);
  303.     char    tmpArr[4];
  304.     char*    ptr = wcbuf;
  305.     size_t    len = fUChSize;
  306.     char    *pTmpArr = tmpArr;
  307.     size_t    bLen = 2;
  308.     ICONV_LOCK;
  309.     if (::iconv (fCDTo, &ptr, &len,
  310.          &pTmpArr, &bLen) == (size_t) -1)
  311.     return 0;
  312.     tmpArr[1] = tolower (*((unsigned char*)tmpArr));
  313.     *tmpArr = tmpArr[1];
  314.     len = 1;
  315.     pTmpArr = wcbuf;
  316.     bLen = fUChSize;
  317.     ptr = tmpArr;
  318.     if (::iconv (fCDFrom, &ptr, &len,
  319.          &pTmpArr, &bLen) == (size_t) -1)
  320.     return 0;
  321.     mbcToXMLCh (wcbuf, (XMLCh*) &ch);
  322.     return ch;
  323. }
  324. // Check if passed characters belongs to the :space: class
  325. bool    IconvGNUWrapper::isSpace(const XMLCh toCheck) const
  326. {
  327.     if (toCheck <= 0x7F)
  328.         return isspace(toCheck);
  329.     char    wcbuf[fUChSize * 2];
  330.     char    tmpArr[4];
  331.     xmlChToMbc (toCheck, wcbuf);
  332.     char*    ptr = wcbuf;
  333.     size_t    len = fUChSize;
  334.     char    *pTmpArr = tmpArr;
  335.     size_t    bLen = 2;
  336.     {
  337.         ICONV_LOCK;
  338.         if (::iconv (fCDTo, &ptr, &len,
  339.                  &pTmpArr, &bLen) == (size_t) -1)
  340.             return 0;
  341.     }
  342.     return isspace(*tmpArr);
  343. }
  344. // Fill array of XMLCh characters with data, supplyed in the array
  345. // of "native unicode" characters.
  346. XMLCh*    IconvGNUWrapper::mbsToXML
  347. (
  348.     const char*        mbs_str
  349.     ,      size_t    mbs_cnt
  350.     ,      XMLCh*    xml_str
  351.     ,      size_t    xml_cnt
  352. ) const
  353. {
  354.     if (mbs_str == NULL || mbs_cnt == 0 || xml_str == NULL || xml_cnt == 0)
  355.         return NULL;
  356.     size_t    cnt = (mbs_cnt < xml_cnt) ? mbs_cnt : xml_cnt;
  357.     if (fUBO == LITTLE_ENDIAN) {
  358.         if (fUChSize == sizeof(XMLCh)) {
  359.             // null-transformation
  360.             memcpy (xml_str, mbs_str, fUChSize * cnt);
  361.             return xml_str;
  362.         }
  363.         if (fUChSize == 2)
  364.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) {
  365.                 WC162XMLCh( mbs_str, xml_str + i);
  366.             }
  367.         else
  368.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) {
  369.                 WC322XMLCh( mbs_str, xml_str + i );
  370.             }
  371.     } else {
  372.         if (fUChSize == 2)
  373.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) {
  374.                 IWC162XMLCh( mbs_str, xml_str + i );
  375.             }
  376.         else
  377.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize) {
  378.                 IWC322XMLCh( mbs_str, xml_str + i );
  379.             }
  380.     }
  381.     return xml_str;
  382. }
  383. // Fill array of "native unicode" characters with data, supplyed
  384. // in the array of XMLCh characters.
  385. char*    IconvGNUWrapper::xmlToMbs
  386. (
  387.     const XMLCh*    xml_str
  388.     ,      size_t    xml_cnt
  389.     ,      char*        mbs_str
  390.     ,      size_t    mbs_cnt
  391. ) const
  392. {
  393.     if (mbs_str == NULL || mbs_cnt == 0 || xml_str == NULL || xml_cnt == 0)
  394.         return NULL;
  395.     size_t    cnt = (mbs_cnt < xml_cnt) ? mbs_cnt : xml_cnt;
  396.     char    *toReturn = mbs_str;
  397.     if (fUBO == LITTLE_ENDIAN) {
  398.         if (fUChSize == sizeof(XMLCh)) {
  399.             // null-transformation
  400.             memcpy (mbs_str, xml_str, fUChSize * cnt);
  401.             return toReturn;
  402.         }
  403.         if (fUChSize == 2)
  404.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) {
  405.                 XMLCh2WC16( xml_str, mbs_str );
  406.             }
  407.         else
  408.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) {
  409.                 XMLCh2WC32( xml_str, mbs_str );
  410.             }
  411.     } else {
  412.         if (fUChSize == 2)
  413.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) {
  414.                 IXMLCh2WC16( xml_str, mbs_str );
  415.             }
  416.         else
  417.             for (size_t i = 0; i < cnt; i++, mbs_str += fUChSize, xml_str++) {
  418.                 IXMLCh2WC32( xml_str, mbs_str );
  419.             }
  420.     }
  421.     return toReturn;
  422. }
  423. size_t    IconvGNUWrapper::iconvFrom ( const char    *fromPtr,
  424.                  size_t        *fromLen,
  425.                  char        **toPtr,
  426.                  size_t        toLen ) const
  427. {
  428.     ICONV_LOCK;
  429.     char ** tmpPtr = (char**)&fromPtr;
  430.     return ::iconv (fCDFrom, tmpPtr, fromLen, toPtr, &toLen);
  431. }
  432. size_t    IconvGNUWrapper::iconvTo ( const char    *fromPtr,
  433.                    size_t        *fromLen,
  434.                    char        **toPtr,
  435.                    size_t        toLen ) const
  436. {
  437.     ICONV_LOCK;
  438.     char ** tmpPtr = (char**)&fromPtr;
  439.     return ::iconv (fCDTo, tmpPtr, fromLen, toPtr, &toLen);
  440. }
  441. // ---------------------------------------------------------------------------
  442. //  IconvGNUTransService: Constructors and Destructor
  443. // ---------------------------------------------------------------------------
  444. IconvGNUTransService::IconvGNUTransService()
  445.     : IconvGNUWrapper(), fUnicodeCP(0)
  446. {
  447. #if !defined(APP_NO_THREADS)
  448.     // Create global lock object
  449.     if (gIconvMutex == NULL) {
  450.         gIconvMutex = new XMLMutex;
  451.         if (gIconvMutex == NULL)
  452.             XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService);
  453.     }
  454. #endif
  455.     // Try to obtain local (host) characterset through the environment
  456.     char*    fLocalCP = setlocale (LC_CTYPE, "");
  457.     if (fLocalCP == NULL)
  458.         fLocalCP = "iso-8859-1";    // fallback locale
  459.     else {
  460.         char    *ptr = strchr (fLocalCP, '.');
  461.         if (ptr == NULL)
  462.             fLocalCP = "iso-8859-1";    // fallback locale
  463.         else
  464.             fLocalCP = ptr + 1;
  465.     }
  466.     // Select the native unicode characters encoding schema
  467.     const IconvGNUEncoding    *eptr;
  468.     // first - try to use the schema with character size, equil to XMLCh
  469.     for (eptr = gIconvGNUEncodings; eptr->fSchema; eptr++) {
  470.         if (eptr->fUChSize != sizeof(XMLCh))
  471.             continue;
  472.         ICONV_LOCK;
  473.         // try to create conversion descriptor
  474.         iconv_t    cd_to = iconv_open(fLocalCP, eptr->fSchema);
  475.         if (cd_to == (iconv_t)-1)
  476.             continue;
  477.         iconv_t    cd_from = iconv_open(eptr->fSchema, fLocalCP);
  478.         if (cd_to == (iconv_t)-1) {
  479.             iconv_close (cd_to);
  480.             continue;
  481.         }
  482.         // got it
  483.         setUChSize(eptr->fUChSize);
  484.         setUBO(eptr->fUBO);
  485.         setCDTo(cd_to);
  486.         setCDFrom(cd_from);
  487.         fUnicodeCP = eptr->fSchema;
  488.         break;
  489.     }
  490.     if (fUnicodeCP == NULL)
  491.         // try to use any known schema
  492.         for (eptr = gIconvGNUEncodings; eptr->fSchema; eptr++) {
  493.             // try to create conversion descriptor
  494.             ICONV_LOCK;
  495.             iconv_t    cd_to = iconv_open(fLocalCP, eptr->fSchema);
  496.             if (cd_to == (iconv_t)-1)
  497.                 continue;
  498.             iconv_t    cd_from = iconv_open(eptr->fSchema, fLocalCP);
  499.             if (cd_to == (iconv_t)-1) {
  500.                 iconv_close (cd_to);
  501.                 continue;
  502.             }
  503.             // got it
  504.             setUChSize(eptr->fUChSize);
  505.             setUBO(eptr->fUBO);
  506.             setCDTo(cd_to);
  507.             setCDFrom(cd_from);
  508.             fUnicodeCP = eptr->fSchema;
  509.             break;
  510.         }
  511.     if (fUnicodeCP == NULL || cdTo() == (iconv_t)-1 || cdFrom() == (iconv_t)-1)
  512.         XMLPlatformUtils::panic (PanicHandler::Panic_NoTransService);
  513. }
  514. IconvGNUTransService::~IconvGNUTransService()
  515. {
  516.     if (cdTo() != (iconv_t) -1) {
  517.         iconv_close (cdTo());
  518.         setCDTo ((iconv_t)-1);
  519.     }
  520.     if (cdFrom() != (iconv_t) -1) {
  521.         iconv_close (cdFrom());
  522.         setCDFrom ((iconv_t)-1);
  523.     }
  524. }
  525. // ---------------------------------------------------------------------------
  526. //  IconvGNUTransService: The virtual transcoding service API
  527. // ---------------------------------------------------------------------------
  528. int IconvGNUTransService::compareIString(const XMLCh* const    comp1
  529.                                         , const XMLCh* const    comp2)
  530. {
  531.     const XMLCh* cptr1 = comp1;
  532.     const XMLCh* cptr2 = comp2;
  533.     XMLCh    c1 = toUpper(*cptr1);
  534.     XMLCh    c2 = toUpper(*cptr2);
  535.     while ( (*cptr1 != 0) && (*cptr2 != 0) ) {
  536.         if (c1 != c2)
  537.             break;
  538.         c1 = toUpper(*(++cptr1));
  539.         c2 = toUpper(*(++cptr2));
  540.     }
  541.     return (int) ( c1 - c2 );
  542. }
  543. int IconvGNUTransService::compareNIString(const XMLCh* const    comp1
  544.                                          , const XMLCh* const    comp2
  545.                                          , const unsigned int    maxChars)
  546. {
  547.     unsigned int  n = 0;
  548.     const XMLCh* cptr1 = comp1;
  549.     const XMLCh* cptr2 = comp2;
  550.     while (true && maxChars)
  551.     {
  552.         XMLCh    c1 = toUpper(*cptr1);
  553.         XMLCh    c2 = toUpper(*cptr2);
  554.         if (c1 != c2)
  555.             return (int) (c1 - c2);
  556.         // If either ended, then both ended, so equal
  557.         if (!*cptr1 || !*cptr2)
  558.             break;
  559.         cptr1++;
  560.         cptr2++;
  561.         //  Bump the count of chars done. If it equals the count then we
  562.         //  are equal for the requested count, so break out and return
  563.         //  equal.
  564.         n++;
  565.         if (n == maxChars)
  566.             break;
  567.     }
  568.     return 0;
  569. }
  570. const XMLCh* IconvGNUTransService::getId() const
  571. {
  572.     return gMyServiceId;
  573. }
  574. bool IconvGNUTransService::isSpace(const XMLCh toCheck) const
  575. {
  576.     return IconvGNUWrapper::isSpace(toCheck);
  577. }
  578. XMLLCPTranscoder* IconvGNUTransService::makeNewLCPTranscoder()
  579. {
  580.     return new IconvGNULCPTranscoder (cdFrom(), cdTo(), uChSize(), UBO());
  581. }
  582. bool IconvGNUTransService::supportsSrcOfs() const
  583. {
  584.     return true;
  585. }
  586. // ---------------------------------------------------------------------------
  587. //  IconvGNUTransService: The protected virtual transcoding service API
  588. // ---------------------------------------------------------------------------
  589. XMLTranscoder*
  590. IconvGNUTransService::makeNewXMLTranscoder
  591. (
  592.     const    XMLCh* const    encodingName
  593.     ,    XMLTransService::Codes&    resValue
  594.     , const    unsigned int    blockSize
  595.     ,        MemoryManager* const    manager
  596. )
  597. {
  598.     resValue = XMLTransService::UnsupportedEncoding;
  599.     IconvGNUTranscoder    *newTranscoder = NULL;
  600.     char    *encLocal = XMLString::transcode(encodingName, manager);
  601.     iconv_t    cd_from, cd_to;
  602.     {
  603.         ICONV_LOCK;
  604.         cd_from = iconv_open (fUnicodeCP, encLocal);
  605.         if (cd_from == (iconv_t)-1) {
  606.             resValue = XMLTransService::SupportFilesNotFound;
  607.             if (encLocal)
  608.                 manager->deallocate(encLocal);//delete [] encLocal;
  609.             return NULL;
  610.         }
  611.         cd_to = iconv_open (encLocal, fUnicodeCP);
  612.         if (cd_to == (iconv_t)-1) {
  613.             resValue = XMLTransService::SupportFilesNotFound;
  614.             iconv_close (cd_from);
  615.             if (encLocal)
  616.                 manager->deallocate(encLocal);//delete [] encLocal;
  617.             return NULL;
  618.         }
  619.         newTranscoder = new (manager) IconvGNUTranscoder (encodingName,
  620.                              blockSize,
  621.                              cd_from, cd_to,
  622.                              uChSize(), UBO(), manager);
  623.     }
  624.     if (newTranscoder)
  625.         resValue = XMLTransService::Ok;
  626.     if (encLocal)
  627.         manager->deallocate(encLocal);//delete [] encLocal;
  628.     return newTranscoder;
  629. }
  630. void IconvGNUTransService::upperCase(XMLCh* const toUpperCase) const
  631. {
  632.     XMLCh* outPtr = toUpperCase;
  633.     while (*outPtr)
  634.     {
  635.         *outPtr = toUpper(*outPtr);
  636.         outPtr++;
  637.     }
  638. }
  639. void IconvGNUTransService::lowerCase(XMLCh* const toLowerCase) const
  640. {
  641.     XMLCh* outPtr = toLowerCase;
  642.     while (*outPtr)
  643.     {
  644.         *outPtr = toLower(*outPtr);
  645.         outPtr++;
  646.     }
  647. }
  648. // ---------------------------------------------------------------------------
  649. //  IconvGNULCPTranscoder: The virtual transcoder API
  650. // ---------------------------------------------------------------------------
  651. unsigned int
  652. IconvGNULCPTranscoder::calcRequiredSize (const char* const srcText)
  653. {
  654.     if (!srcText)
  655.         return 0;
  656.     size_t      len, srcLen;
  657.     len = srcLen = strlen(srcText);
  658.     if (len == 0)
  659.         return 0;
  660.     char    tmpWideArr[gTempBuffArraySize];
  661.     size_t    totalLen = 0;
  662.     for (;;) {
  663.         char        *pTmpArr = tmpWideArr;
  664.         const char    *ptr = srcText + srcLen - len;
  665.         size_t    rc = iconvFrom(ptr, &len, &pTmpArr, gTempBuffArraySize);
  666.         if (rc == (size_t) -1 && errno != E2BIG) {
  667.             ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
  668.             /* return 0; */
  669.         }
  670.         rc = pTmpArr - (char *) tmpWideArr;
  671.         totalLen += rc;
  672.         if (rc == 0 || len == 0)
  673.             break;
  674.     }
  675.     return totalLen / uChSize();
  676. }
  677. unsigned int
  678. IconvGNULCPTranscoder::calcRequiredSize(const XMLCh* const srcText)
  679. {
  680.     if (!srcText)
  681.         return 0;
  682.     unsigned int  wLent = getWideCharLength(srcText);
  683.     if (wLent == 0)
  684.         return 0;
  685.     char    tmpWBuff[gTempBuffArraySize];
  686.     char    *wBuf = 0;
  687.     char    *wBufPtr = 0;
  688.     size_t      len = wLent * uChSize();
  689.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  690.         if (len > gTempBuffArraySize) {
  691.             wBufPtr = (char*) XMLPlatformUtils::fgMemoryManager->allocate
  692.             (
  693.                 len * sizeof(char)
  694.             );//new char[len];
  695.             if (wBufPtr == NULL)
  696.             return 0;
  697.             wBuf = wBufPtr;
  698.         } else
  699.             wBuf = tmpWBuff;
  700.         xmlToMbs (srcText, wLent, wBuf, wLent);
  701.     } else
  702.         wBuf = (char *) srcText;
  703.     char    tmpBuff[gTempBuffArraySize];
  704.     size_t    totalLen = 0;
  705.     char    *srcEnd = wBuf + wLent * uChSize();
  706.     for (;;) {
  707.         char        *pTmpArr = tmpBuff;
  708.         const char    *ptr = srcEnd - len;
  709.         size_t    rc = iconvTo(ptr, &len, &pTmpArr, gTempBuffArraySize);
  710.         if (rc == (size_t) -1 && errno != E2BIG) {
  711.             if (wBufPtr)
  712.                 XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
  713.             ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
  714.             /* return 0; */
  715.         }
  716.         rc = pTmpArr - tmpBuff;
  717.         totalLen += rc;
  718.         if (rc == 0 || len == 0)
  719.             break;
  720.     }
  721.     if (wBufPtr)
  722.         XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
  723.     return totalLen;
  724. }
  725. char* IconvGNULCPTranscoder::transcode(const XMLCh* const toTranscode)
  726. {
  727.     if (!toTranscode)
  728.         return 0;
  729.     char* retVal = 0;
  730.     if (*toTranscode) {
  731.         unsigned int  wLent = getWideCharLength(toTranscode);
  732.         // Calc needed size.
  733.         const size_t neededLen = calcRequiredSize (toTranscode);
  734.         if (neededLen == 0)
  735.             return 0;
  736.         // allocate output buffer
  737.         retVal = new char[neededLen + 1];
  738.         if (retVal == NULL)
  739.             return 0;
  740.         // prepare the original
  741.         char    tmpWBuff[gTempBuffArraySize];
  742.         char    *wideCharBuf = 0;
  743.         char    *wBufPtr = 0;
  744.         size_t  len = wLent * uChSize();
  745.         if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  746.             if (len > gTempBuffArraySize) {
  747.                 wBufPtr = new char[len];
  748.                 if (wBufPtr == NULL)
  749.                     return 0;
  750.                 wideCharBuf = wBufPtr;
  751.             } else
  752.                 wideCharBuf = tmpWBuff;
  753.             xmlToMbs (toTranscode, wLent, wideCharBuf, wLent);
  754.         } else
  755.             wideCharBuf = (char *) toTranscode;
  756.         // perform conversion
  757.         wLent *= uChSize();
  758.         char    *ptr = retVal;
  759.         size_t    rc = iconvTo(wideCharBuf, (size_t *) &wLent, &ptr, neededLen);
  760.         if (rc == (size_t)-1) {
  761.             if (wBufPtr)
  762.             delete [] wBufPtr;
  763.             return 0;
  764.         }
  765.         if (wBufPtr)
  766.             delete [] wBufPtr;
  767.         retVal[neededLen] = 0;
  768.     } else {
  769.         retVal = new char[1];
  770.         if (retVal == NULL)
  771.             return 0;
  772.         retVal[0] = 0;
  773.     }
  774.     return retVal;
  775. }
  776. char* IconvGNULCPTranscoder::transcode(const XMLCh* const toTranscode,
  777.                                        MemoryManager* const manager)
  778. {
  779.     if (!toTranscode)
  780.         return 0;
  781.     char* retVal = 0;
  782.     if (*toTranscode) {
  783.         unsigned int  wLent = getWideCharLength(toTranscode);
  784.         // Calc needed size.
  785.         const size_t neededLen = calcRequiredSize (toTranscode);
  786.         if (neededLen == 0)
  787.             return 0;
  788.         // allocate output buffer
  789.         retVal = (char*) manager->allocate((neededLen + 1) * sizeof(char));//new char[neededLen + 1];
  790.         if (retVal == NULL)
  791.             return 0;
  792.         // prepare the original
  793.         char    tmpWBuff[gTempBuffArraySize];
  794.         char    *wideCharBuf = 0;
  795.         char    *wBufPtr = 0;
  796.         size_t  len = wLent * uChSize();
  797.         if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  798.             if (len > gTempBuffArraySize) {
  799.                 wBufPtr = (char*) manager->allocate(len * sizeof(char));//new char[len];
  800.                 if (wBufPtr == NULL)
  801.                     return 0;
  802.                 wideCharBuf = wBufPtr;
  803.             } else
  804.                 wideCharBuf = tmpWBuff;
  805.             xmlToMbs (toTranscode, wLent, wideCharBuf, wLent);
  806.         } else
  807.             wideCharBuf = (char *) toTranscode;
  808.         // perform conversion
  809.         wLent *= uChSize();
  810.         char    *ptr = retVal;
  811.         size_t    rc = iconvTo(wideCharBuf, (size_t *) &wLent, &ptr, neededLen);
  812.         if (rc == (size_t)-1) {
  813.             if (wBufPtr)
  814.             manager->deallocate(wBufPtr);//delete [] wBufPtr;
  815.             return 0;
  816.         }
  817.         if (wBufPtr)
  818.             manager->deallocate(wBufPtr);//delete [] wBufPtr;
  819.         retVal[neededLen] = 0;
  820.     } else {
  821.         retVal = (char*) manager->allocate(sizeof(char));//new char[1];
  822.         if (retVal == NULL)
  823.             return 0;
  824.         retVal[0] = 0;
  825.     }
  826.     return retVal;
  827. }
  828. bool IconvGNULCPTranscoder::transcode( const   XMLCh* const    toTranscode
  829.                     , char* const        toFill
  830.                     , const unsigned int    maxBytes)
  831. {
  832.     // Watch for a couple of pyscho corner cases
  833.     if (!toTranscode || !maxBytes) {
  834.         toFill[0] = 0;
  835.         return true;
  836.     }
  837.     if (!*toTranscode) {
  838.         toFill[0] = 0;
  839.         return true;
  840.     }
  841.     unsigned int  wLent = getWideCharLength(toTranscode);
  842.     if (wLent > maxBytes)
  843.         wLent = maxBytes;
  844.     // Fill the "unicode" string
  845.     char    tmpWBuff[gTempBuffArraySize];
  846.     char    *wideCharBuf = 0;
  847.     char    *wBufPtr = 0;
  848.     size_t  len = wLent * uChSize();
  849.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  850.         if (len > gTempBuffArraySize) {
  851.             wBufPtr = (char*) XMLPlatformUtils::fgMemoryManager->allocate
  852.             (
  853.                 len * sizeof(char)
  854.             );//new char[len];
  855.             if (wBufPtr == NULL)
  856.                 return 0;
  857.         wideCharBuf = wBufPtr;
  858.         } else
  859.             wideCharBuf = tmpWBuff;
  860.         xmlToMbs (toTranscode, wLent, wideCharBuf, wLent);
  861.     } else
  862.         wideCharBuf = (char *) toTranscode;
  863.     // Ok, go ahead and try the transcoding. If it fails, then ...
  864.     char    *ptr = toFill;
  865.     size_t    rc = iconvTo(wideCharBuf, &len, &ptr, maxBytes);
  866.     if (rc == (size_t)-1) {
  867.         if (wBufPtr)
  868.             XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
  869.         return false;
  870.     }
  871.     if (wBufPtr)
  872.         XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
  873.     // Cap it off just in case
  874.     toFill[rc] = 0;
  875.     return true;
  876. }
  877. XMLCh* IconvGNULCPTranscoder::transcode(const char* const toTranscode)
  878. {
  879.     if (!toTranscode)
  880.         return 0;
  881.     XMLCh* retVal = 0;
  882.     if (*toTranscode) {
  883.         const unsigned int wLent = calcRequiredSize(toTranscode);
  884.         if (wLent == 0) {
  885.             retVal = new XMLCh[1];
  886.             retVal[0] = 0;
  887.             return retVal;
  888.         }
  889.         char    tmpWBuff[gTempBuffArraySize];
  890.         char    *wideCharBuf = 0;
  891.         char    *wBufPtr = 0;
  892.         size_t  len = wLent * uChSize();
  893.         retVal = new XMLCh[wLent + 1];
  894.         if (retVal == NULL)
  895.             return NULL;
  896.         if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  897.             if (len > gTempBuffArraySize) {
  898.                 wBufPtr = new char[len];
  899.                 if (wBufPtr == NULL)
  900.                     return 0;
  901.                 wideCharBuf = wBufPtr;
  902.             } else
  903.                 wideCharBuf = tmpWBuff;
  904.         } else
  905.             wideCharBuf = (char *) retVal;
  906.         size_t    flen = strlen(toTranscode);
  907.         char    *ptr = wideCharBuf;
  908.         size_t    rc = iconvFrom(toTranscode, &flen, &ptr, len);
  909.         if (rc == (size_t) -1) {
  910.             if (wBufPtr)
  911.             delete [] wBufPtr;
  912.             return NULL;
  913.         }
  914.         if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER)
  915.             mbsToXML (wideCharBuf, wLent, retVal, wLent);
  916.         if (wBufPtr)
  917.             delete [] wBufPtr;
  918.         retVal[wLent] = 0x00;
  919.     }
  920.     else {
  921.         retVal = new XMLCh[1];
  922.         if (retVal == NULL )
  923.             return 0;
  924.         retVal[0] = 0;
  925.     }
  926.     return retVal;
  927. }
  928. XMLCh* IconvGNULCPTranscoder::transcode(const char* const toTranscode,
  929.                                         MemoryManager* const manager)
  930. {
  931.     if (!toTranscode)
  932.         return 0;
  933.     XMLCh* retVal = 0;
  934.     if (*toTranscode) {
  935.         const unsigned int wLent = calcRequiredSize(toTranscode);
  936.         if (wLent == 0) {
  937.             retVal = (XMLCh*) manager->allocate(sizeof(XMLCh));/new XMLCh[1];
  938.             retVal[0] = 0;
  939.             return retVal;
  940.         }
  941.         char    tmpWBuff[gTempBuffArraySize];
  942.         char    *wideCharBuf = 0;
  943.         char    *wBufPtr = 0;
  944.         size_t  len = wLent * uChSize();
  945.         retVal = (XMLCh*) manager->allocate((wLent + 1) * sizeof(XMLCh));//new XMLCh[wLent + 1];
  946.         if (retVal == NULL)
  947.             return NULL;
  948.         if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  949.             if (len > gTempBuffArraySize) {
  950.                 wBufPtr = (char*) manager->allocate(len * sizeof(char));//new char[len];
  951.                 if (wBufPtr == NULL)
  952.                     return 0;
  953.                 wideCharBuf = wBufPtr;
  954.             } else
  955.                 wideCharBuf = tmpWBuff;
  956.         } else
  957.             wideCharBuf = (char *) retVal;
  958.         size_t    flen = strlen(toTranscode);
  959.         char    *ptr = wideCharBuf;
  960.         size_t    rc = iconvFrom(toTranscode, &flen, &ptr, len);
  961.         if (rc == (size_t) -1) {
  962.             if (wBufPtr)
  963.             manager->deallocate(wBufPtr);//delete [] wBufPtr;
  964.             return NULL;
  965.         }
  966.         if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER)
  967.             mbsToXML (wideCharBuf, wLent, retVal, wLent);
  968.         if (wBufPtr)
  969.             manager->deallocate(wBufPtr);//delete [] wBufPtr;
  970.         retVal[wLent] = 0x00;
  971.     }
  972.     else {
  973.         retVal = (XMLCh*) manager->allocate(sizeof(XMLCh));//new XMLCh[1];
  974.         if (retVal == NULL )
  975.             return 0;
  976.         retVal[0] = 0;
  977.     }
  978.     return retVal;
  979. }
  980. bool IconvGNULCPTranscoder::transcode(const   char* const    toTranscode
  981.                        ,       XMLCh* const    toFill
  982.                        , const unsigned int    maxChars)
  983. {
  984.     // Check for a couple of psycho corner cases
  985.     if (!toTranscode || !maxChars)
  986.     {
  987.         toFill[0] = 0;
  988.         return true;
  989.     }
  990.     if (!*toTranscode)
  991.     {
  992.         toFill[0] = 0;
  993.         return true;
  994.     }
  995.     size_t wLent = calcRequiredSize(toTranscode);
  996.     if (wLent > maxChars)
  997.         wLent = maxChars;
  998.     char    tmpWBuff[gTempBuffArraySize];
  999.     char    *wideCharBuf = 0;
  1000.     char    *wBufPtr = 0;
  1001.     size_t    len = wLent * uChSize();
  1002.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  1003.         if (len > gTempBuffArraySize) {
  1004.             wBufPtr = (char*) XMLPlatformUtils::fgMemoryManager->allocate
  1005.             (
  1006.                 len * sizeof(char)
  1007.             );//new char[len];
  1008.             if (wBufPtr == NULL)
  1009.                 return 0;
  1010.             wideCharBuf = wBufPtr;
  1011.         } else
  1012.             wideCharBuf = tmpWBuff;
  1013.     } else
  1014.         wideCharBuf = (char *) toFill;
  1015.     size_t    flen = strlen(toTranscode); // wLent;
  1016.     char    *ptr = wideCharBuf;
  1017.     size_t    rc = iconvFrom(toTranscode, &flen, &ptr, len);
  1018.     if (rc == (size_t)-1) {
  1019.         if (wBufPtr)
  1020.             XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
  1021.         return false;
  1022.     }
  1023.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER)
  1024.         mbsToXML (wideCharBuf, wLent, toFill, wLent);
  1025.     if (wBufPtr)
  1026.         XMLPlatformUtils::fgMemoryManager->deallocate(wBufPtr);//delete [] wBufPtr;
  1027.     toFill[wLent] = 0x00;
  1028.     return true;
  1029. }
  1030. // ---------------------------------------------------------------------------
  1031. //  IconvGNULCPTranscoder: Constructors and Destructor
  1032. // ---------------------------------------------------------------------------
  1033. IconvGNULCPTranscoder::IconvGNULCPTranscoder (iconv_t        cd_from,
  1034.                         iconv_t        cd_to,
  1035.                         size_t        uchsize,
  1036.                         unsigned int    ubo)
  1037.     : IconvGNUWrapper (cd_from, cd_to, uchsize, ubo)
  1038. {
  1039. }
  1040. IconvGNULCPTranscoder::~IconvGNULCPTranscoder()
  1041. {
  1042. }
  1043. // ---------------------------------------------------------------------------
  1044. //  IconvGNUTranscoder: Constructors and Destructor
  1045. // ---------------------------------------------------------------------------
  1046. IconvGNUTranscoder::IconvGNUTranscoder (const    XMLCh* const    encodingName
  1047.                       , const unsigned int    blockSize
  1048.                       ,    iconv_t        cd_from
  1049.                       ,    iconv_t        cd_to
  1050.                       ,    size_t        uchsize
  1051.                       ,    unsigned int    ubo
  1052.                       , MemoryManger* const manager
  1053.     )
  1054.     : XMLTranscoder(encodingName, blockSize, manager)
  1055.     , IconvGNUWrapper (cd_from, cd_to, uchsize, ubo)
  1056. {
  1057. }
  1058. IconvGNUTranscoder::~IconvGNUTranscoder()
  1059. {
  1060.     ICONV_LOCK;
  1061.     if (cdTo() != (iconv_t)-1) {
  1062.         iconv_close (cdTo());
  1063.         setCDTo ((iconv_t)-1);
  1064.     }
  1065.     if (cdFrom() != (iconv_t)-1) {
  1066.         iconv_close (cdFrom());
  1067.         setCDFrom ((iconv_t)-1);
  1068.     }
  1069. }
  1070. // ---------------------------------------------------------------------------
  1071. //  IconvGNUTranscoder: Implementation of the virtual transcoder API
  1072. // ---------------------------------------------------------------------------
  1073. unsigned int    IconvGNUTranscoder::transcodeFrom
  1074. (
  1075.     const   XMLByte* const          srcData
  1076.     , const unsigned int            srcCount
  1077.     ,       XMLCh* const            toFill
  1078.     , const unsigned int            maxChars
  1079.     ,       unsigned int&           bytesEaten
  1080.     ,       unsigned char* const    charSizes )
  1081. {
  1082.     // Transcode TO XMLCh
  1083.     const char*  startSrc = (const char*) srcData;
  1084.     const char*  endSrc = (const char*) srcData + srcCount;
  1085.     char    tmpWBuff[gTempBuffArraySize];
  1086.     char    *startTarget = 0;
  1087.     char    *wBufPtr = 0;
  1088.     size_t    len = maxChars * uChSize();
  1089.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  1090.         if (len > gTempBuffArraySize) {
  1091.             wBufPtr = (char*) getMemoryManager()->allocate
  1092.             (
  1093.                 len * sizeof(char)
  1094.             );//new char[len];
  1095.             if (wBufPtr == NULL)
  1096.                 return 0;
  1097.             startTarget = wBufPtr;
  1098.         } else
  1099.             startTarget = tmpWBuff;
  1100.     } else
  1101.     startTarget = (char *) toFill;
  1102.     // Do character-by-character transcoding
  1103.     char    *orgTarget = startTarget;
  1104.     size_t    srcLen = srcCount;
  1105.     size_t    prevSrcLen = srcLen;
  1106.     unsigned int toReturn = 0;
  1107.     bytesEaten = 0;
  1108.     for (size_t cnt = 0; cnt < maxChars && srcLen; cnt++) {
  1109.         size_t    rc = iconvFrom(startSrc, &srcLen, &orgTarget, uChSize());
  1110.         if (rc == (size_t)-1) {
  1111.             if (errno != E2BIG || prevSrcLen == srcLen) {
  1112.                 if (wBufPtr)
  1113.                     getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr;
  1114.                 ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
  1115.             }
  1116.         }
  1117.         charSizes[cnt] = prevSrcLen - srcLen;
  1118.         prevSrcLen = srcLen;
  1119.         bytesEaten += charSizes[cnt];
  1120.         startSrc = endSrc - srcLen;
  1121.         toReturn++;
  1122.     }
  1123.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER)
  1124.         mbsToXML (startTarget, toReturn, toFill, toReturn);
  1125.     if (wBufPtr)
  1126.         getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr;
  1127.     return toReturn;
  1128. }
  1129. unsigned int    IconvGNUTranscoder::transcodeTo
  1130. (
  1131.     const   XMLCh* const    srcData
  1132.     , const unsigned int    srcCount
  1133.     ,       XMLByte* const    toFill
  1134.     , const unsigned int    maxBytes
  1135.     ,       unsigned int&    charsEaten
  1136.     , const UnRepOpts        options )
  1137. {
  1138.     // Transcode FROM XMLCh
  1139.     char    tmpWBuff[gTempBuffArraySize];
  1140.     char    *startSrc = tmpWBuff;
  1141.     char    *wBufPtr = 0;
  1142.     size_t    len = srcCount * uChSize();
  1143.     if (uChSize() != sizeof(XMLCh) || UBO() != BYTE_ORDER) {
  1144.         if (len > gTempBuffArraySize) {
  1145.             wBufPtr = (char*) getMemoryManager()->allocate
  1146.             (
  1147.                 len * sizeof(char)
  1148.             );//new char[len];
  1149.             if (wBufPtr == NULL)
  1150.                 return 0;
  1151.             startSrc = wBufPtr;
  1152.         } else
  1153.             startSrc = tmpWBuff;
  1154.         xmlToMbs (srcData, srcCount, startSrc, srcCount);
  1155.     } else
  1156.         startSrc = (char *) srcData;
  1157.     char*    startTarget = (char *) toFill;
  1158.     size_t    srcLen = len;
  1159.     size_t    rc = iconvTo (startSrc, &srcLen, &startTarget, maxBytes);
  1160.     if (rc == (size_t)-1 && errno != E2BIG) {
  1161.         if (wBufPtr)
  1162.             getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr;
  1163.         ThrowXML(TranscodingException, XMLExcepts::Trans_BadSrcSeq);
  1164.     }
  1165.     charsEaten = srcCount - srcLen / uChSize();
  1166.     if (wBufPtr)
  1167.         getMemoryManager()->deallocate(wBufPtr);//delete [] wBufPtr;
  1168.     return startTarget - (char *)toFill;
  1169. }
  1170. bool        IconvGNUTranscoder::canTranscodeTo
  1171. (
  1172.     const unsigned int toCheck
  1173. )   const
  1174. {
  1175.     //
  1176.     //  If the passed value is really a surrogate embedded together, then
  1177.     //  we need to break it out into its two chars. Else just one.
  1178.     //
  1179.     char        srcBuf[2 * uChSize()];
  1180.     unsigned int    srcCount = 1;
  1181.     if (toCheck & 0xFFFF0000) {
  1182.         XMLCh    ch1 = (toCheck >> 10) + 0xD800;
  1183.         XMLCh    ch2 = toCheck & 0x3FF + 0xDC00;
  1184.         xmlToMbs(&ch1, 1, srcBuf, 1);
  1185.         xmlToMbs(&ch2, 1, srcBuf + uChSize(), 1);
  1186.         srcCount++;
  1187.     } else
  1188.         xmlToMbs((const XMLCh*) &toCheck, 1, srcBuf, 1);
  1189.     size_t    len = srcCount * uChSize();
  1190.     char    tmpBuf[64];
  1191.     char*    pTmpBuf = tmpBuf;
  1192.     size_t    rc = iconvTo( srcBuf, &len, &pTmpBuf, 64);
  1193.     return (rc != (size_t)-1) && (len == 0);
  1194. }
  1195. XERCES_CPP_NAMESPACE_END