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 + -
显示快捷键?