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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-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) 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.  * $Log: iconv_cnv.cpp,v $
  58.  * Revision 1.2  2002/11/04 15:14:33  tng
  59.  * C++ Namespace Support.
  60.  *
  61.  * Revision 1.1.1.1  2002/02/01 22:22:36  peiyongz
  62.  * sane_include
  63.  *
  64.  * Revision 1.1  2001/06/25 16:19:14  tng
  65.  * Rename iconv_cnv.c to iconv_cnv.cpp.  AS400 changes by Linda Swan.
  66.  *
  67.  * Revision 1.3  2001/06/19 19:31:04  tng
  68.  * Latest AS/400 update.
  69.  *
  70.  * Revision 1.2  2000/09/12 17:06:49  aruna1
  71.  * Replaced INDEX_OUTOFBOUNDS error to BUFFER_OVERFLOW error for toUnicode and from_Unicode functions for compatibility with icu 1.6
  72.  *
  73.  * Revision 1.1  2000/02/10 18:08:28  abagchi
  74.  * Initial checkin
  75.  *
  76.  */
  77. #include <stdio.h>
  78. #include <stdlib.h>
  79. #include <unistd.h>
  80. #include <errno.h>
  81. #include <iconv_util.hpp>
  82. #include <iconv_cnv.hpp>
  83. #include <qmhrtvm.h>
  84. #include <qusec.h>
  85. #include <xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp>
  86. #include <iconv.h>
  87. #include <errno.h>
  88. #define CHUNK_SIZE 5*1024
  89. XERCES_CPP_NAMESPACE_BEGIN
  90. void Convert_toUnicode(UConverter *,
  91.      UChar **,
  92.      const UChar *,
  93.      const char **,
  94.      const char *,
  95.      int32_t* offsets,
  96.      int,
  97.      UErrorCode *);
  98. void Convert_fromUnicode(UConverter *,
  99.        char **,
  100.        const char *,
  101.        const UChar **,
  102.        const UChar *,
  103.        int32_t* offsets,
  104.        int,
  105.        UErrorCode *);
  106. UChar getNextUChar(UConverter* converter,
  107.        const char** source,
  108.        const char* sourceLimit,
  109.        UErrorCode* err);
  110. void T_UConverter_fromCodepageToCodepage (UConverter * outConverter,
  111.  UConverter * inConverter,
  112.  char **target,
  113.  const char *targetLimit,
  114.  const char **source,
  115.  const char *sourceLimit,
  116.  int32_t* offsets,
  117.  int flush,
  118.  UErrorCode * err);
  119. void Converter_fromUnicode(UConverter * _this,
  120.  char **target,
  121.  const char *targetLimit,
  122.  const UChar ** source,
  123.  const UChar * sourceLimit,
  124.  int32_t *offsets,
  125.  int flush,
  126.  UErrorCode * err);
  127. /*Calls through createConverter */
  128. UConverter* ucnv_open (const char *name,
  129.        UErrorCode * err)
  130. {
  131.   if (U_FAILURE (*err))
  132.     return NULL;
  133.   /*In case "name" is NULL we want to open the default converter */
  134.   if (name != NULL)
  135.     return createConverter (name, err);
  136.   else
  137.     return createConverter (iconv_getDefaultCodepage(), err);
  138. }
  139. /*Extracts the UChar* to a char* and calls through createConverter */
  140. UConverter*  ucnv_openU (const UChar * name,
  141.  UErrorCode * err)
  142. {
  143.   char asciiName[MAX_CONVERTER_NAME_LENGTH];
  144.   if (U_FAILURE (*err))
  145.     return NULL;
  146.   if (name == NULL)
  147.     return ucnv_open (NULL, err);
  148.   if (u_strlen (name) > MAX_CONVERTER_NAME_LENGTH)
  149.     {
  150.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  151.       return NULL;
  152.     }
  153.   return ucnv_open (u_austrcpy (asciiName, name), err);
  154. }
  155. /*Decreases the reference counter in the shared immutable section of the object
  156.  *and frees the mutable part*/
  157. void ucnv_close (UConverter * converter)
  158. {
  159. /* for iconv we will close the handles and free the converter storage*/
  160.   iconv_close(converter->sharedData->toiconv_handle);
  161.   iconv_close(converter->sharedData->fromiconv_handle);
  162.   if (converter == NULL)
  163.     return;
  164.   free (converter);
  165.   return;
  166. }
  167. /* currently required for iconv suuport */
  168. /* XMLReader calls this and uses fact that it is different than min
  169. to go thru a calculation otherwise if max and min same then there is
  170. a calculation speed up - we will keep the two routines but have them
  171. return different sizes - later will ifdef XMLreader for ICONV to remove the calls*/
  172.  int8_t  ucnv_getMaxCharSize (const UConverter * converter)
  173. {
  174.   return (4); /* dummy returns just need to be different in XMLParser - need something else for ICU replacement */
  175. }
  176. /* currently required for iconv support */
  177. /* see note for ucnv_getMaxCharSize */
  178. int8_t  ucnv_getMinCharSize (const UConverter * converter)
  179. {
  180.   return (1);
  181. }
  182. void   ucnv_fromUnicode (UConverter * _this,
  183.  char **target,
  184.  const char *targetLimit,
  185.  const UChar ** source,
  186.  const UChar * sourceLimit,
  187.  int32_t* offsets,
  188.  int flush,
  189.  UErrorCode * err)
  190. {
  191.   /*
  192.    * Check parameters in for all conversions
  193.    */
  194.   if (U_FAILURE (*err))   return;
  195.   if ((_this == NULL) || ((char *) targetLimit < *target) || (sourceLimit < *source))
  196.     {
  197.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  198.       return;
  199.     }
  200.   /*calls the specific conversion routines */
  201.   Converter_fromUnicode(_this,target,targetLimit,source,sourceLimit,
  202.    offsets,flush,err);
  203.   return;
  204. }
  205. void   ucnv_toUnicode (UConverter * _this,
  206.        UChar ** target,
  207.        const UChar * targetLimit,
  208.        const char **source,
  209.        const char *sourceLimit,
  210.        int32_t* offsets,
  211.        int flush,
  212.        UErrorCode * err)
  213. {
  214.   /*
  215.    * Check parameters in for all conversions
  216.    */
  217.   if (U_FAILURE (*err))   return;
  218.   if ((_this == NULL) || ((UChar *) targetLimit < *target) || (sourceLimit < *source))
  219.     {
  220.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  221.       return;
  222.     }
  223.   /*calls the specific conversion routines */
  224.   Convert_toUnicode(_this,target,targetLimit,source,sourceLimit,
  225.   offsets,flush,err);
  226.   return;
  227. }
  228. int32_t   ucnv_fromUChars (const UConverter * converter,
  229.    char *target,
  230.    int32_t targetSize,
  231.    const UChar * source,
  232.    UErrorCode * err)
  233. {
  234.   const UChar *mySource = source;
  235.   const UChar *mySource_limit;
  236.   int32_t mySourceLength = 0;
  237.   UConverter myConverter;
  238.   char *myTarget = target;
  239.   int32_t targetCapacity = 0;
  240.   if (U_FAILURE (*err))
  241.     return 0;
  242.   if ((converter == NULL) || (targetSize < 0))
  243.     {
  244.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  245.       return 0;
  246.     }
  247.   /*makes a local copy of the UConverter */
  248.   myConverter = *converter;
  249.   /*if the source is empty we return immediately */
  250.   mySourceLength = u_strlen (source);
  251.   if (mySourceLength == 0)
  252.     {
  253.       /*for consistency we still need to
  254.        *store 0 in the targetCapacity
  255.        *if the user requires it
  256.        */
  257.       return 0;
  258.     }
  259.   mySource_limit = mySource + mySourceLength;
  260.   if (targetSize > 0)
  261.     {
  262.       ucnv_fromUnicode (&myConverter,
  263. &myTarget,
  264. target + targetSize,
  265. &mySource,
  266. mySource_limit,
  267. NULL,
  268. TRUE,
  269. err);
  270.       targetCapacity = myTarget - target;
  271.     }
  272.   /*Updates targetCapacity to contain the number of bytes written to target */
  273.   if (targetSize == 0)
  274.     {
  275.       *err = U_BUFFER_OVERFLOW_ERROR;
  276.     }
  277.   /* If the output buffer is exhausted, we need to stop writing
  278.    * to it but continue the conversion in order to store in targetSize
  279.    * the number of bytes that was required*/
  280.   if (*err == U_BUFFER_OVERFLOW_ERROR)
  281.     {
  282.       char target2[CHUNK_SIZE];
  283.       char *target2_alias = target2;
  284.       const char *target2_limit = target2 + CHUNK_SIZE;
  285.       /*We use a stack allocated buffer around which we loop
  286.        *(in case the output is greater than CHUNK_SIZE)
  287.        */
  288.       while (*err == U_BUFFER_OVERFLOW_ERROR)
  289. {
  290.   *err = U_ZERO_ERROR;
  291.   target2_alias = target2;
  292.   ucnv_fromUnicode (&myConverter,
  293.     &target2_alias,
  294.     target2_limit,
  295.     &mySource,
  296.     mySource_limit,
  297.     NULL,
  298.     TRUE,
  299.     err);
  300.   /*updates the output parameter to contain the number of char required */
  301.   targetCapacity += (target2_alias - target2) + 1;
  302. }
  303.       /*We will set the erro code to BUFFER_OVERFLOW_ERROR only if
  304.        *nothing graver happened in the previous loop*/
  305.       (targetCapacity)--;
  306.       if (U_SUCCESS (*err))
  307. *err = U_BUFFER_OVERFLOW_ERROR;
  308.     }
  309.   return targetCapacity;
  310. }
  311. int32_t ucnv_toUChars (const UConverter * converter,
  312.        UChar * target,
  313.        int32_t targetSize,
  314.        const char *source,
  315.        int32_t sourceSize,
  316.        UErrorCode * err)
  317. {
  318.   const char *mySource = source;
  319.   const char *mySource_limit = source + sourceSize;
  320.   UConverter myConverter;
  321.   UChar *myTarget = target;
  322.   int32_t targetCapacity;
  323.   if (U_FAILURE (*err))
  324.     return 0;
  325.   if ((converter == NULL) || (targetSize < 0) || (sourceSize < 0))
  326.     {
  327.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  328.       return 0;
  329.     }
  330.   /*Means there is no work to be done */
  331.   if (sourceSize == 0)
  332.     {
  333.       /*for consistency we still need to
  334.        *store 0 in the targetCapacity
  335.        *if the user requires it
  336.        */
  337.       if (targetSize >= 1)
  338. {
  339.   target[0] = 0x0000;
  340.   return 1;
  341. }
  342.       else
  343. return 0;
  344.     }
  345.   /*makes a local copy of the UConverter */
  346.   myConverter = *converter;
  347.   /*Not in pure pre-flight mode */
  348.   if (targetSize > 0)
  349.     {
  350.      /*  Changed from (targetSize * 2) to (targetSize) */
  351.       ucnv_toUnicode (&myConverter,
  352.       &myTarget,
  353.       target + (targetSize-1),   /*Save a spot for the Null terminator */
  354.       &mySource,
  355.       mySource_limit,
  356.       NULL,
  357.       TRUE,
  358.       err);
  359.       /*Null terminates the string */
  360.       *(myTarget) = 0x0000;
  361.     }
  362.   /*Rigs targetCapacity to have at least one cell for zero termination */
  363.   /*Updates targetCapacity to contain the number of bytes written to target */
  364.   targetCapacity = 1;
  365.   targetCapacity += myTarget - target;
  366.   if (targetSize == 0)
  367.     {
  368.       *err = U_BUFFER_OVERFLOW_ERROR;
  369.     }
  370.   /* If the output buffer is exhausted, we need to stop writing
  371.    * to it but if the input buffer is not exhausted,
  372.    * we need to continue the conversion in order to store in targetSize
  373.    * the number of bytes that was required
  374.    */
  375.   if (*err == U_BUFFER_OVERFLOW_ERROR)
  376.     {
  377.       UChar target2[CHUNK_SIZE];
  378.       UChar *target2_alias = target2;
  379.       const UChar *target2_limit = target2 + CHUNK_SIZE;
  380.       /*We use a stack allocated buffer around which we loop
  381.          (in case the output is greater than CHUNK_SIZE) */
  382.       while (*err == U_BUFFER_OVERFLOW_ERROR)
  383. {
  384.   *err = U_ZERO_ERROR;
  385.   target2_alias = target2;
  386.   ucnv_toUnicode (&myConverter,
  387.   &target2_alias,
  388.   target2_limit,
  389.   &mySource,
  390.   mySource_limit,
  391.   NULL,
  392.   TRUE,
  393.   err);
  394.   /*updates the output parameter to contain the number of char required */
  395.   targetCapacity += target2_alias - target2 + 1;
  396. }
  397.       (targetCapacity)--; /*adjust for last one */
  398.       if (U_SUCCESS (*err))
  399. *err = U_BUFFER_OVERFLOW_ERROR;
  400.     }
  401.   return targetCapacity;
  402. }
  403. UChar ucnv_getNextUChar (UConverter * converter,
  404.  const char **source,
  405.  const char *sourceLimit,
  406.  UErrorCode * err)
  407. {
  408.   /*calls the specific conversion routines */
  409.   /*as dictated in a code review, avoids a switch statement */
  410.   return getNextUChar(converter,source,sourceLimit,err);
  411. }
  412. /**************************
  413. * Will convert a sequence of bytes from one codepage to another.
  414. * @param toConverterName: The name of the converter that will be used to encode the output buffer
  415. * @param fromConverterName: The name of the converter that will be used to decode the input buffer
  416. * @param target: Pointer to the output buffer* written
  417. * @param targetLength: on input contains the capacity of target, on output the number of bytes copied to target
  418. * @param source: Pointer to the input buffer
  419. * @param sourceLength: on input contains the capacity of source, on output the number of bytes processed in "source"
  420. * @param internal: used internally to store store state data across calls
  421. * @param err: fills in an error status
  422. */
  423. void
  424. T_UConverter_fromCodepageToCodepage (UConverter * outConverter,
  425.      UConverter * inConverter,
  426.      char **target,
  427.      const char *targetLimit,
  428.      const char **source,
  429.      const char *sourceLimit,
  430.      int32_t* offsets,
  431.      int flush,
  432.      UErrorCode * err)
  433. {
  434.   UChar out_chunk[CHUNK_SIZE];
  435.   const UChar *out_chunk_limit = out_chunk + CHUNK_SIZE;
  436.   UChar *out_chunk_alias;
  437.   UChar const *out_chunk_alias2;
  438.   if (U_FAILURE (*err))    return;
  439.   /*loops until the input buffer is completely consumed
  440.    *or if an error has be encountered
  441.    *first we convert from inConverter codepage to Unicode
  442.    *then from Unicode to outConverter codepage
  443.    */
  444.   while ((*source != sourceLimit) && U_SUCCESS (*err))
  445.     {
  446.       out_chunk_alias = out_chunk;
  447.       ucnv_toUnicode (inConverter,
  448.       &out_chunk_alias,
  449.       out_chunk_limit,
  450.       source,
  451.       sourceLimit,
  452.       NULL,
  453.       flush,
  454.       err);
  455.       /*BUFFER_OVERFLOW_ERROR means that the output "CHUNK" is full
  456.        *we will require at least another loop (it's a recoverable error)
  457.        */
  458.       if (U_SUCCESS (*err) || (*err == U_BUFFER_OVERFLOW_ERROR))
  459. {
  460.   *err = U_ZERO_ERROR;
  461.   out_chunk_alias2 = out_chunk;
  462.   while ((out_chunk_alias2 != out_chunk_alias) && U_SUCCESS (*err))
  463.     {
  464.       ucnv_fromUnicode (outConverter,
  465. target,
  466. targetLimit,
  467. &out_chunk_alias2,
  468. out_chunk_alias,
  469. NULL,
  470. TRUE,
  471. err);
  472.     }
  473. }
  474.       else
  475. break;
  476.     }
  477.   return;
  478. }
  479. int32_t  ucnv_convert(const char *toConverterName,
  480.       const char *fromConverterName,
  481.       char *target,
  482.       int32_t targetSize,
  483.       const char *source,
  484.       int32_t sourceSize,
  485.       UErrorCode * err)
  486. {
  487.   const char *mySource = source;
  488.   const char *mySource_limit = source + sourceSize;
  489.   int32_t mySourceLength = 0;
  490.   UConverter *inConverter;
  491.   UConverter *outConverter;
  492.   char *myTarget = target;
  493.   int32_t targetCapacity = 0;
  494.   if (U_FAILURE (*err))
  495.     return 0;
  496.   if ((targetSize < 0) || (sourceSize < 0))
  497.     {
  498.       *err = U_ILLEGAL_ARGUMENT_ERROR;
  499.       return 0;
  500.     }
  501.   /*if there is no input data, we're done */
  502.   if (sourceSize == 0)
  503.     {
  504.       /*in case the caller passed an output ptr
  505.        *we update it
  506.        */
  507.       return 0;
  508.     }
  509.   /*create the converters */
  510.   inConverter = ucnv_open (fromConverterName, err);
  511.   if (U_FAILURE (*err)) return 0;
  512.   outConverter = ucnv_open (toConverterName, err);
  513.   if (U_FAILURE (*err))
  514.     {
  515.       ucnv_close (inConverter);
  516.       return 0;
  517.     }
  518.   if (targetSize > 0)
  519.     {
  520.       T_UConverter_fromCodepageToCodepage (outConverter,
  521.    inConverter,
  522.    &myTarget,
  523.    target + targetSize,
  524.    &mySource,
  525.    mySource_limit,
  526.    NULL,
  527.    TRUE,
  528.    err);
  529.     }
  530.   /*Updates targetCapacity to contain the number of bytes written to target */
  531.   targetCapacity = myTarget - target;
  532.   if (targetSize == 0)
  533.     {
  534.       *err = U_BUFFER_OVERFLOW_ERROR;
  535.     }
  536.   /* If the output buffer is exhausted, we need to stop writing
  537.    * to it but continue the conversion in order to store in targetSize
  538.    * the number of bytes that was required*/
  539.   if (*err == U_BUFFER_OVERFLOW_ERROR)
  540.     {
  541.       char target2[CHUNK_SIZE];
  542.       char *target2_alias = target2;
  543.       const char *target2_limit = target2 + CHUNK_SIZE;
  544.       /*We use a stack allocated buffer around which we loop
  545.        *(in case the output is greater than CHUNK_SIZE)
  546.        */
  547.       while (*err == U_BUFFER_OVERFLOW_ERROR)
  548. {
  549.   *err = U_ZERO_ERROR;
  550.   target2_alias = target2;
  551.   T_UConverter_fromCodepageToCodepage (outConverter,
  552.        inConverter,
  553.        &target2_alias,
  554.        target2_limit,
  555.        &mySource,
  556.        mySource_limit,
  557.        NULL,
  558.        TRUE,
  559.        err);
  560.   /*updates the output parameter to contain the number of char required */
  561.   targetCapacity += (target2_alias - target2) + 1;
  562. }
  563.       /*We will set the erro code to BUFFER_OVERFLOW_ERROR only if
  564.        *nothing graver happened in the previous loop*/
  565.       (targetCapacity)--;
  566.       if (U_SUCCESS (*err))
  567. *err = U_BUFFER_OVERFLOW_ERROR;
  568.     }
  569.   ucnv_close (inConverter);
  570.   ucnv_close (outConverter);
  571.   return targetCapacity;
  572. }
  573. void Converter_fromUnicode(UConverter * _this,
  574.  char **target,
  575.  const char *targetLimit,
  576.  const UChar ** source,
  577.  const UChar * sourceLimit,
  578.  int32_t *offsets,
  579.  int flush,
  580.  UErrorCode * err)
  581. {
  582.   int chardone;
  583.   const UChar *mySource = *source;
  584.   unsigned char *myTarget = (unsigned char *) *target;
  585.   int32_t targetLength = targetLimit - (char *) myTarget;
  586.   int32_t sourceLength = (sourceLimit - mySource) * 2;
  587.   unsigned char targetChar = 0x00;
  588.   /* pick up the iconv handle and perform the conversion */
  589.   errno = 0;
  590.   chardone =iconv(_this->sharedData->fromiconv_handle,(char**)source,  (size_t*) &sourceLength,target,(size_t *)&targetLength);
  591.   if (errno!=0)
  592.     if (errno == E2BIG)
  593.       {
  594.   *err = U_BUFFER_OVERFLOW_ERROR;
  595.           return;
  596.       }
  597.     else
  598.       if ((errno ==EBADDATA)|| (errno ==ECONVERT))
  599.        {
  600.         char errno_id[7];
  601.         send_message(NULL,ICONV_CONVERT_PROBLEM,'d');
  602.         convert_errno(errno_id,errno);
  603.         send_message(NULL,errno_id,'d');
  604.         *err = U_INVALID_CHAR_FOUND;
  605. return;
  606. }
  607.   return;
  608.        }
  609. void Convert_toUnicode(UConverter * _this,
  610.   UChar ** target,
  611.   const UChar * targetLimit,
  612.   const char **source,
  613.   const char *sourceLimit,
  614.   int32_t *offsets,
  615.   int flush,
  616.   UErrorCode * err)
  617. {
  618.   char *mySource = (char *) *source;
  619.   UChar *myTarget = *target;
  620.   int32_t targetLength = (targetLimit - myTarget)*2;  /* multiply by 2 */
  621.   int32_t sourceLength = (sourceLimit - (char *) mySource);
  622.   int chardone;
  623.   /* pick up the iconv handle */
  624.   errno = 0;
  625.   chardone =iconv(_this->sharedData->toiconv_handle,(char**)source,  (size_t*) &sourceLength,(char **)target,(size_t *)&targetLength);
  626.   if (errno!=0)
  627.   {
  628.     if (errno == E2BIG)
  629.       {
  630.   *err = U_BUFFER_OVERFLOW_ERROR;
  631.           return;
  632.       }
  633.     else
  634.       if ((errno ==EBADDATA)|| (errno ==ECONVERT))
  635.        {
  636.         char errno_id[7];
  637.         send_message(NULL,ICONV_CONVERT_PROBLEM,'d');
  638.         convert_errno(errno_id,errno);
  639.         send_message(NULL,errno_id,'d');
  640.         *err = U_INVALID_CHAR_FOUND;
  641.         return;
  642. }
  643. }
  644.   return;
  645. }
  646. UChar getNextUChar(UConverter* converter,
  647.        const char** source,
  648.        const char* sourceLimit,
  649.        UErrorCode* err)
  650. {
  651.   UChar myUChar;
  652.   UChar* myUCharptr;
  653.   size_t numberibytes=sizeof(UChar);
  654.   size_t numberobytes=sizeof(UChar);
  655.   int chardone;
  656.   if ((*source)+1 > sourceLimit)
  657.     {
  658.       *err = U_INDEX_OUTOFBOUNDS_ERROR;
  659.       return 0xFFFD;
  660.     }
  661.   /*pick up the iconv handle */
  662.   /* convert the requested character - need to cache characters 6 will do - XMLReader is using this function to get header to process*/
  663.   myUCharptr  = &myUChar;
  664.  chardone =iconv(converter->sharedData->toiconv_handle,(char**)source,  (size_t*) &numberibytes,(char **)&myUCharptr,(size_t *)&numberobytes);
  665.   if (myUChar != 0xFFFD) return myUChar;
  666.   else
  667.     {
  668.       UChar* myUCharPtr = &myUChar;
  669.       const char* sourceFinal = *source;
  670.       *err = U_INVALID_CHAR_FOUND;
  671.       /*makes the internal caching transparent to the user*/
  672.       if (*err == U_INDEX_OUTOFBOUNDS_ERROR) *err = U_ZERO_ERROR;
  673.       return myUChar;
  674.     }
  675. }
  676. XERCES_CPP_NAMESPACE_END