IconvTransService.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:15k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2000 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) 1999, 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.  * $Id: IconvTransService.cpp,v 1.24 2001/07/27 14:52:49 tng Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <util/XMLUniDefs.hpp>
  63. #include <util/XMLUni.hpp>
  64. #include "IconvTransService.hpp"
  65. #include <wchar.h>
  66. #if defined (XML_GCC) || defined (XML_PTX) || defined (XML_IBMVAOS2)
  67. #include <wctype.h>
  68. #endif
  69. #include <string.h>
  70. #include <stdlib.h>
  71. #include <stdio.h>
  72. // ---------------------------------------------------------------------------
  73. //  Local, const data
  74. // ---------------------------------------------------------------------------
  75. static const int    gTempBuffArraySize = 1024;
  76. static const XMLCh  gMyServiceId[] =
  77. {
  78.     chLatin_I, chLatin_C, chLatin_o, chLatin_n, chLatin_v, chNull
  79. };
  80. // ---------------------------------------------------------------------------
  81. //  Local methods
  82. // ---------------------------------------------------------------------------
  83. static unsigned int getWideCharLength(const XMLCh* const src)
  84. {
  85.     if (!src)
  86.         return 0;
  87.     unsigned int len = 0;
  88.     const XMLCh* pTmp = src;
  89.     while (*pTmp++)
  90.         len++;
  91.     return len;
  92. }
  93. // ---------------------------------------------------------------------------
  94. //  IconvTransService: Constructors and Destructor
  95. // ---------------------------------------------------------------------------
  96. IconvTransService::IconvTransService()
  97. {
  98. }
  99. IconvTransService::~IconvTransService()
  100. {
  101. }
  102. // ---------------------------------------------------------------------------
  103. //  IconvTransService: The virtual transcoding service API
  104. // ---------------------------------------------------------------------------
  105. int IconvTransService::compareIString(  const   XMLCh* const    comp1
  106.                                         , const XMLCh* const    comp2)
  107. {
  108.     const XMLCh* cptr1 = comp1;
  109.     const XMLCh* cptr2 = comp2;
  110.     while ( (*cptr1 != 0) && (*cptr2 != 0) )
  111.     {
  112.         wint_t wch1 = towupper(*cptr1);
  113.         wint_t wch2 = towupper(*cptr2);
  114.         if (wch1 != wch2)
  115.             break;
  116.         cptr1++;
  117.         cptr2++;
  118.     }
  119.     return (int) ( towupper(*cptr1) - towupper(*cptr2) );
  120. }
  121. int IconvTransService::compareNIString( const   XMLCh* const    comp1
  122.                                         , const XMLCh* const    comp2
  123.                                         , const unsigned int    maxChars)
  124. {
  125.     unsigned int  n = 0;
  126.     const XMLCh* cptr1 = comp1;
  127.     const XMLCh* cptr2 = comp2;
  128.     while (true && maxChars)
  129.     {
  130.         wint_t wch1 = towupper(*cptr1);
  131.         wint_t wch2 = towupper(*cptr2);
  132.         if (wch1 != wch2)
  133.             return (int) (wch1 - wch2);
  134.         // If either ended, then both ended, so equal
  135.         if (!*cptr1 || !*cptr2)
  136.             break;
  137.         cptr1++;
  138.         cptr2++;
  139.         //  Bump the count of chars done. If it equals the count then we
  140.         //  are equal for the requested count, so break out and return
  141.         //  equal.
  142.         n++;
  143.         if (n == maxChars)
  144.             break;
  145.     }
  146.     return 0;
  147. }
  148. const XMLCh* IconvTransService::getId() const
  149. {
  150.     return gMyServiceId;
  151. }
  152. bool IconvTransService::isSpace(const XMLCh toCheck) const
  153. {
  154.     return (iswspace(toCheck) != 0);
  155. }
  156. XMLLCPTranscoder* IconvTransService::makeNewLCPTranscoder()
  157. {
  158.     // Just allocate a new transcoder of our type
  159.     return new IconvLCPTranscoder;
  160. }
  161. bool IconvTransService::supportsSrcOfs() const
  162. {
  163.     return true;
  164. }
  165. // ---------------------------------------------------------------------------
  166. //  IconvTransService: The protected virtual transcoding service API
  167. // ---------------------------------------------------------------------------
  168. XMLTranscoder*
  169. IconvTransService::makeNewXMLTranscoder(const   XMLCh* const            encodingName
  170.                                         ,       XMLTransService::Codes& resValue
  171.                                         , const unsigned int            )
  172. {
  173.     //
  174.     //  NOTE: We don't use the block size here
  175.     //
  176.     //  This is a minimalist transcoding service, that only supports a local
  177.     //  default transcoder. All named encodings return zero as a failure,
  178.     //  which means that only the intrinsic encodings supported by the parser
  179.     //  itself will work for XML data.
  180.     //
  181.     resValue = XMLTransService::UnsupportedEncoding;
  182.     return 0;
  183. }
  184. void IconvTransService::upperCase(XMLCh* const toUpperCase) const
  185. {
  186.     XMLCh* outPtr = toUpperCase;
  187.     while (*outPtr)
  188.     {
  189.         *outPtr = towupper(*outPtr);
  190.         outPtr++;
  191.     }
  192. }
  193. // ---------------------------------------------------------------------------
  194. //  IconvLCPTranscoder: The virtual transcoder API
  195. // ---------------------------------------------------------------------------
  196. unsigned int IconvLCPTranscoder::calcRequiredSize(const char* const srcText)
  197. {
  198.     if (!srcText)
  199.         return 0;
  200.     const unsigned int retVal = ::mbstowcs(NULL, srcText, 0);
  201.     if (retVal == ~0)
  202.         return 0;
  203.     return retVal;
  204. }
  205. unsigned int IconvLCPTranscoder::calcRequiredSize(const XMLCh* const srcText)
  206. {
  207.     if (!srcText)
  208.         return 0;
  209.     unsigned int  wLent = getWideCharLength(srcText);
  210.     wchar_t       tmpWideCharArr[gTempBuffArraySize];
  211.     wchar_t*      allocatedArray = 0;
  212.     wchar_t*      wideCharBuf = 0;
  213.     if (wLent >= gTempBuffArraySize)
  214.         wideCharBuf = allocatedArray = new wchar_t[wLent + 1];
  215.     else
  216.         wideCharBuf = tmpWideCharArr;
  217.     for (unsigned int i = 0; i < wLent; i++)
  218.     {
  219.         wideCharBuf[i] = srcText[i];
  220.     }
  221.     wideCharBuf[wLent] = 0x00;
  222.     const unsigned int retVal = ::wcstombs(NULL, wideCharBuf, 0);
  223.     delete [] allocatedArray;
  224.     if (retVal == ~0)
  225.         return 0;
  226.     return retVal;
  227. }
  228. char* IconvLCPTranscoder::transcode(const XMLCh* const toTranscode)
  229. {
  230.     if (!toTranscode)
  231.         return 0;
  232.     char* retVal = 0;
  233.     if (*toTranscode)
  234.     {
  235.         unsigned int  wLent = getWideCharLength(toTranscode);
  236.         wchar_t       tmpWideCharArr[gTempBuffArraySize];
  237.         wchar_t*      allocatedArray = 0;
  238.         wchar_t*      wideCharBuf = 0;
  239.         if (wLent >= gTempBuffArraySize)
  240.             wideCharBuf = allocatedArray = new wchar_t[wLent + 1];
  241.         else
  242.             wideCharBuf = tmpWideCharArr;
  243.         for (unsigned int i = 0; i < wLent; i++)
  244.         {
  245.             wideCharBuf[i] = toTranscode[i];
  246.         }
  247.         wideCharBuf[wLent] = 0x00;
  248.         // Calc the needed size.
  249.         const size_t neededLen = ::wcstombs(NULL, wideCharBuf, 0);
  250.         if (neededLen == -1)
  251.         {
  252.             delete [] allocatedArray;
  253.             return 0;
  254.         }
  255.         retVal = new char[neededLen + 1];
  256.         ::wcstombs(retVal, wideCharBuf, neededLen);
  257.         retVal[neededLen] = 0;
  258.         delete [] allocatedArray;
  259.     }
  260.     else
  261.     {
  262.         retVal = new char[1];
  263.         retVal[0] = 0;
  264.     }
  265.     return retVal;
  266. }
  267. bool IconvLCPTranscoder::transcode( const   XMLCh* const    toTranscode
  268.                                     ,       char* const     toFill
  269.                                     , const unsigned int    maxBytes)
  270. {
  271.     // Watch for a couple of pyscho corner cases
  272.     if (!toTranscode || !maxBytes)
  273.     {
  274.         toFill[0] = 0;
  275.         return true;
  276.     }
  277.     if (!*toTranscode)
  278.     {
  279.         toFill[0] = 0;
  280.         return true;
  281.     }
  282.     unsigned int  wLent = getWideCharLength(toTranscode);
  283.     wchar_t       tmpWideCharArr[gTempBuffArraySize];
  284.     wchar_t*      allocatedArray = 0;
  285.     wchar_t*      wideCharBuf = 0;
  286.     if (wLent > maxBytes) {
  287.         wLent = maxBytes;
  288.     }
  289.     if (maxBytes >= gTempBuffArraySize)
  290.         wideCharBuf = allocatedArray = new wchar_t[maxBytes + 1];
  291.     else
  292.         wideCharBuf = tmpWideCharArr;
  293.     for (unsigned int i = 0; i < wLent; i++)
  294.     {
  295.         wideCharBuf[i] = toTranscode[i];
  296.     }
  297.     wideCharBuf[wLent] = 0x00;
  298.     // Ok, go ahead and try the transcoding. If it fails, then ...
  299.     if (::wcstombs(toFill, wideCharBuf, maxBytes) == -1)
  300.     {
  301.         delete [] allocatedArray;
  302.         return false;
  303.     }
  304.     // Cap it off just in case
  305.     toFill[wLent] = 0;
  306.     delete [] allocatedArray;
  307.     return true;
  308. }
  309. XMLCh* IconvLCPTranscoder::transcode(const char* const toTranscode)
  310. {
  311.     if (!toTranscode)
  312.         return 0;
  313.     XMLCh* retVal = 0;
  314.     if (*toTranscode)
  315.     {
  316.         const unsigned int len = calcRequiredSize(toTranscode);
  317.         if (len == 0)
  318.         {
  319.             retVal = new XMLCh[1];
  320.             retVal[0] = 0;
  321.             return retVal;
  322.         }
  323.         wchar_t       tmpWideCharArr[gTempBuffArraySize];
  324.         wchar_t*      allocatedArray = 0;
  325.         wchar_t*      wideCharBuf = 0;
  326.         if (len >= gTempBuffArraySize)
  327.             wideCharBuf = allocatedArray = new wchar_t[len + 1];
  328.         else
  329.             wideCharBuf = tmpWideCharArr;
  330.         ::mbstowcs(wideCharBuf, toTranscode, len);
  331.         retVal = new XMLCh[len + 1];
  332.         for (unsigned int i = 0; i < len; i++)
  333.         {
  334.             retVal[i] = (XMLCh) wideCharBuf[i];
  335.         }
  336.         retVal[len] = 0x00;
  337.         delete [] allocatedArray;
  338.     }
  339.     else
  340.     {
  341.         retVal = new XMLCh[1];
  342.         retVal[0] = 0;
  343.     }
  344.     return retVal;
  345. }
  346. bool IconvLCPTranscoder::transcode( const   char* const     toTranscode
  347.                                     ,       XMLCh* const    toFill
  348.                                     , const unsigned int    maxChars)
  349. {
  350.     // Check for a couple of psycho corner cases
  351.     if (!toTranscode || !maxChars)
  352.     {
  353.         toFill[0] = 0;
  354.         return true;
  355.     }
  356.     if (!*toTranscode)
  357.     {
  358.         toFill[0] = 0;
  359.         return true;
  360.     }
  361.     unsigned int len = calcRequiredSize(toTranscode);
  362.     wchar_t       tmpWideCharArr[gTempBuffArraySize];
  363.     wchar_t*      allocatedArray = 0;
  364.     wchar_t*      wideCharBuf = 0;
  365.     if (len > maxChars) {
  366.         len = maxChars;
  367.     }
  368.     if (maxChars >= gTempBuffArraySize)
  369.         wideCharBuf = allocatedArray = new wchar_t[maxChars + 1];
  370.     else
  371.         wideCharBuf = tmpWideCharArr;
  372.     if (::mbstowcs(wideCharBuf, toTranscode, maxChars) == -1)
  373.     {
  374.         delete [] allocatedArray;
  375.         return false;
  376.     }
  377.     for (unsigned int i = 0; i < len; i++)
  378.     {
  379.         toFill[i] = (XMLCh) wideCharBuf[i];
  380.     }
  381.     toFill[len] = 0x00;
  382.     delete [] allocatedArray;
  383.     return true;
  384. }
  385. // ---------------------------------------------------------------------------
  386. //  IconvLCPTranscoder: Constructors and Destructor
  387. // ---------------------------------------------------------------------------
  388. IconvLCPTranscoder::IconvLCPTranscoder()
  389. {
  390. }
  391. IconvLCPTranscoder::~IconvLCPTranscoder()
  392. {
  393. }
  394. // ---------------------------------------------------------------------------
  395. //  IconvTranscoder: Constructors and Destructor
  396. // ---------------------------------------------------------------------------
  397. IconvTranscoder::IconvTranscoder(const  XMLCh* const    encodingName
  398.                                 , const unsigned int    blockSize) :
  399.     XMLTranscoder(encodingName, blockSize)
  400. {
  401. }
  402. IconvTranscoder::~IconvTranscoder()
  403. {
  404. }
  405. // ---------------------------------------------------------------------------
  406. //  IconvTranscoder: Implementation of the virtual transcoder API
  407. // ---------------------------------------------------------------------------
  408. XMLCh IconvTranscoder::transcodeOne(const   XMLByte* const  srcData
  409.                                     , const unsigned int    srcBytes
  410.                                     ,       unsigned int&   bytesEaten)
  411. {
  412.     wchar_t  toFill;
  413.     int eaten = ::mbtowc(&toFill, (const char*)srcData, srcBytes);
  414.     if (eaten == -1)
  415.     {
  416.         bytesEaten = 0;
  417.         return 0;
  418.     }
  419.     // Return the bytes we ate and the resulting char.
  420.     bytesEaten = eaten;
  421.     return toFill;
  422. }
  423. unsigned int
  424. IconvTranscoder::transcodeXML(  const   XMLByte* const          srcData
  425.                                 , const unsigned int            srcCount
  426.                                 ,       XMLCh* const            toFill
  427.                                 , const unsigned int            maxChars
  428.                                 ,       unsigned int&           bytesEaten
  429.                                 ,       unsigned char* const    charSizes)
  430. {
  431.     //
  432.     //  For this one, because we have to maintain the offset table, we have
  433.     //  to do them one char at a time until we run out of source data.
  434.     //
  435.     unsigned int countIn = 0;
  436.     unsigned int countOut = 0;
  437.     while (countOut < maxChars)
  438.     {
  439.         wchar_t   oneWideChar;
  440.         const int bytesEaten =
  441.             ::mbtowc(&oneWideChar, (const char*)&srcData[countIn], srcCount - countIn);
  442.         // We are done, so break out
  443.         if (bytesEaten == -1)
  444.             break;
  445.         toFill[countOut] = (XMLCh) oneWideChar;
  446.         countIn += (unsigned int) bytesEaten;
  447.         countOut++;
  448.     }
  449.     // Give back the counts of eaten and transcoded
  450.     bytesEaten = countIn;
  451.     return countOut;
  452. }