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

xml/soap/webservice

开发平台:

C/C++

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