iconv_cnv.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 753 行 · 第 1/2 页

CPP
753
字号
/* * Copyright 1999-2001,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//** * $Log: iconv_cnv.cpp,v $ * Revision 1.5  2004/09/24 11:25:31  cargilld * Fixes to build on OS400.  Thanks to Patrick Townsend and Jay Hansen. * * Revision 1.4  2004/09/23 21:44:13  cargilld * Fixes to build on OS400.  Thanks to Patrick Townsend and Jay Hansen. * * Revision 1.3  2004/09/08 13:56:45  peiyongz * Apache License Version 2.0 * * Revision 1.2  2002/11/04 15:14:33  tng * C++ Namespace Support. * * Revision 1.1.1.1  2002/02/01 22:22:36  peiyongz * sane_include * * Revision 1.1  2001/06/25 16:19:14  tng * Rename iconv_cnv.c to iconv_cnv.cpp.  AS400 changes by Linda Swan. * * Revision 1.3  2001/06/19 19:31:04  tng * Latest AS/400 update. * * Revision 1.2  2000/09/12 17:06:49  aruna1 * Replaced INDEX_OUTOFBOUNDS error to BUFFER_OVERFLOW error for toUnicode and from_Unicode functions for compatibility with icu 1.6 * * Revision 1.1  2000/02/10 18:08:28  abagchi * Initial checkin * */#include <xercesc/util/XercesDefs.hpp>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <iconv_util.hpp>#include <iconv_cnv.hpp>#include <qmhrtvm.h>#include <qusec.h>#include <xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp>#include <iconv.h>#include <errno.h>#define CHUNK_SIZE 5*1024XERCES_CPP_NAMESPACE_BEGINvoid Convert_toUnicode(UConverter *,				     UChar **,				     const UChar *,				     const char **,				     const char *,				     int32_t* offsets,				     int,				     UErrorCode *);void Convert_fromUnicode(UConverter *,				       char **,				       const char *,				       const UChar **,				       const UChar *,				       int32_t* offsets,				       int,				       UErrorCode *);UChar getNextUChar(UConverter* converter,					       const char** source,					       const char* sourceLimit,					       UErrorCode* err);void T_UConverter_fromCodepageToCodepage (UConverter * outConverter,						 UConverter * inConverter,						 char **target,						 const char *targetLimit,						 const char **source,						 const char *sourceLimit,						 int32_t* offsets,						 int flush,						 UErrorCode * err);void Converter_fromUnicode(UConverter * _this,				 char **target,				 const char *targetLimit,				 const UChar ** source,				 const UChar * sourceLimit,				 int32_t *offsets,				 int flush,				 UErrorCode * err);/*Calls through createConverter */UConverter* ucnv_open (const char *name,		       UErrorCode * err){  if (U_FAILURE (*err))    return NULL;  /*In case "name" is NULL we want to open the default converter */  if (name != NULL)    return createConverter (name, err);  else    return createConverter (iconv_getDefaultCodepage(), err);}/*Extracts the UChar* to a char* and calls through createConverter */UConverter*  ucnv_openU (const UChar * name,			 UErrorCode * err){  char asciiName[MAX_CONVERTER_NAME_LENGTH];  if (U_FAILURE (*err))    return NULL;  if (name == NULL)    return ucnv_open (NULL, err);  if (u_strlen (name) > MAX_CONVERTER_NAME_LENGTH)    {      *err = U_ILLEGAL_ARGUMENT_ERROR;      return NULL;    }  return ucnv_open (u_austrcpy (asciiName, name), err);}/*Decreases the reference counter in the shared immutable section of the object *and frees the mutable part*/void ucnv_close (UConverter * converter){/* for iconv we will close the handles and free the converter storage*/  iconv_close(converter->sharedData->toiconv_handle);  iconv_close(converter->sharedData->fromiconv_handle);  if (converter == NULL)    return;  free (converter);  return;}/* currently required for iconv suuport *//* XMLReader calls this and uses fact that it is different than minto go thru a calculation otherwise if max and min same then there isa calculation speed up - we will keep the two routines but have themreturn different sizes - later will ifdef XMLreader for ICONV to remove the calls*/ int8_t  ucnv_getMaxCharSize (const UConverter * converter){  return (4); /* dummy returns just need to be different in XMLParser - need something else for ICU replacement */}/* currently required for iconv support *//* see note for ucnv_getMaxCharSize */int8_t  ucnv_getMinCharSize (const UConverter * converter){  return (1);}void   ucnv_fromUnicode (UConverter * _this,			 char **target,			 const char *targetLimit,			 const UChar ** source,			 const UChar * sourceLimit,			 int32_t* offsets,			 int flush,			 UErrorCode * err){  /*   * Check parameters in for all conversions   */  if (U_FAILURE (*err))   return;  if ((_this == NULL) || ((char *) targetLimit < *target) || (sourceLimit < *source))    {      *err = U_ILLEGAL_ARGUMENT_ERROR;      return;    }  /*calls the specific conversion routines */  Converter_fromUnicode(_this,target,targetLimit,source,sourceLimit,					   offsets,flush,err);  return;}void   ucnv_toUnicode (UConverter * _this,		       UChar ** target,		       const UChar * targetLimit,		       const char **source,		       const char *sourceLimit,		       int32_t* offsets,		       int flush,		       UErrorCode * err){  /*   * Check parameters in for all conversions   */  if (U_FAILURE (*err))   return;  if ((_this == NULL) || ((UChar *) targetLimit < *target) || (sourceLimit < *source))    {      *err = U_ILLEGAL_ARGUMENT_ERROR;      return;    }  /*calls the specific conversion routines */  Convert_toUnicode(_this,target,targetLimit,source,sourceLimit,					  offsets,flush,err);  return;}int32_t   ucnv_fromUChars (const UConverter * converter,			   char *target,			   int32_t targetSize,			   const UChar * source,			   UErrorCode * err){  const UChar *mySource = source;  const UChar *mySource_limit;  int32_t mySourceLength = 0;  UConverter myConverter;  char *myTarget = target;  int32_t targetCapacity = 0;  if (U_FAILURE (*err))    return 0;  if ((converter == NULL) || (targetSize < 0))    {      *err = U_ILLEGAL_ARGUMENT_ERROR;      return 0;    }  /*makes a local copy of the UConverter */  myConverter = *converter;  /*if the source is empty we return immediately */  mySourceLength = u_strlen (source);  if (mySourceLength == 0)    {      /*for consistency we still need to       *store 0 in the targetCapacity       *if the user requires it       */      return 0;    }  mySource_limit = mySource + mySourceLength;  if (targetSize > 0)    {      ucnv_fromUnicode (&myConverter,			&myTarget,			target + targetSize,			&mySource,			mySource_limit,			NULL,			TRUE,			err);      targetCapacity = myTarget - target;    }  /*Updates targetCapacity to contain the number of bytes written to target */  if (targetSize == 0)    {      *err = U_BUFFER_OVERFLOW_ERROR;    }  /* If the output buffer is exhausted, we need to stop writing   * to it but continue the conversion in order to store in targetSize   * the number of bytes that was required*/  if (*err == U_BUFFER_OVERFLOW_ERROR)    {      char target2[CHUNK_SIZE];      char *target2_alias = target2;      const char *target2_limit = target2 + CHUNK_SIZE;      /*We use a stack allocated buffer around which we loop       *(in case the output is greater than CHUNK_SIZE)       */      while (*err == U_BUFFER_OVERFLOW_ERROR)	{	  *err = U_ZERO_ERROR;	  target2_alias = target2;	  ucnv_fromUnicode (&myConverter,			    &target2_alias,			    target2_limit,			    &mySource,			    mySource_limit,			    NULL,			    TRUE,			    err);	  /*updates the output parameter to contain the number of char required */	  targetCapacity += (target2_alias - target2) + 1;	}      /*We will set the erro code to BUFFER_OVERFLOW_ERROR only if       *nothing graver happened in the previous loop*/      (targetCapacity)--;      if (U_SUCCESS (*err))	*err = U_BUFFER_OVERFLOW_ERROR;    }  return targetCapacity;}int32_t ucnv_toUChars (const UConverter * converter,		       UChar * target,		       int32_t targetSize,		       const char *source,		       int32_t sourceSize,		       UErrorCode * err){  const char *mySource = source;  const char *mySource_limit = source + sourceSize;  UConverter myConverter;  UChar *myTarget = target;  int32_t targetCapacity;  if (U_FAILURE (*err))    return 0;  if ((converter == NULL) || (targetSize < 0) || (sourceSize < 0))    {      *err = U_ILLEGAL_ARGUMENT_ERROR;      return 0;    }  /*Means there is no work to be done */  if (sourceSize == 0)    {      /*for consistency we still need to       *store 0 in the targetCapacity       *if the user requires it       */      if (targetSize >= 1)	{	  target[0] = 0x0000;	  return 1;	}      else	return 0;    }  /*makes a local copy of the UConverter */  myConverter = *converter;  /*Not in pure pre-flight mode */  if (targetSize > 0)    {     /*  Changed from (targetSize * 2) to (targetSize) */      ucnv_toUnicode (&myConverter,		      &myTarget,		      target + (targetSize-1),	  /*Save a spot for the Null terminator */		      &mySource,		      mySource_limit,		      NULL,		      TRUE,		      err);      /*Null terminates the string */      *(myTarget) = 0x0000;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?