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

xml/soap/webservice

开发平台:

C/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_util.cpp,v $
  58.  * Revision 1.2  2001/10/24 14:06:59  peiyongz
  59.  * [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  60.  *
  61.  * Revision 1.1  2001/06/25 16:19:56  tng
  62.  * Rename iconv_util.h to iconv_util.hpp.  AS400 changes by Linda Swan.
  63.  *
  64.  * Revision 1.1  2000/02/10 18:08:28  abagchi
  65.  * Initial checkin
  66.  *
  67.  */
  68. #include <iconv.h>
  69. #include <util/Platforms/OS400/OS400PlatformUtils.hpp>
  70. #include <stdlib.h>
  71. #include <unistd.h>
  72. #include <iconv_util.hpp>
  73. #include <iconv_cnv.hpp>
  74. #include <ctype.h>
  75. #define COPYRIGHT_STRING_LENGTH  200
  76. #define MAX_STRLEN 0x00FFFFF
  77. #define CHARCCSIDSIZE 5
  78. static UConverter* _defaultConverter = NULL;
  79. static UErrorCode gErr = U_ZERO_ERROR;
  80. #include "utypes.h"
  81. void   shareConverterData (UConverterSharedData * data,char *InDescriptor) ;
  82. UConverterSharedData *getSharedConverterData(char *Descriptor);
  83. #define defaultConverter (_defaultConverter==NULL)?_defaultConverter=ucnv_open(NULL, &gErr):_defaultConverter
  84. /* Cleans up the default converter if it has been allocated.
  85.    This is a little messy, but I know the code well enough to
  86.    do anything neater.
  87.  */
  88. void cleanupDefaultConverter()
  89. {
  90. if (_defaultConverter != NULL) {
  91. ucnv_close(_defaultConverter);
  92. _defaultConverter = NULL;
  93. }
  94. }
  95. static char DEFAULT_CONVERTER_NAME[60] = "";
  96. const char* iconv_getDefaultCodepage()
  97. {
  98.   strcpy(DEFAULT_CONVERTER_NAME, "ibm037");
  99.   return DEFAULT_CONVERTER_NAME;
  100. }
  101. /* placeholder function to be deleted in 3_0 */
  102. /* used by String.c */
  103. int32_t
  104. u_strlen(const UChar *s)
  105. {
  106.   int32_t  i = 0;
  107.   while(*s++)
  108.     i++;
  109.   return  i;
  110. }
  111. /* note sure if needed -  think that this is needed in cnv.c */
  112. char* u_austrcpy(char *s1,
  113.          const UChar *ucs2 )
  114. {
  115.   char * anchor = s1;     /* save the start of result string */
  116.   UErrorCode err = U_ZERO_ERROR;
  117.   int32_t len;
  118.   len = ucnv_fromUChars(defaultConverter,
  119.                 s1,
  120.                 MAX_STRLEN,
  121.                 ucs2,
  122.                 &err);
  123.   s1[len] = '';
  124.   return s1;
  125. }
  126. /*Logic determines if the converter is Algorithmic AND/OR cached
  127.  *depending on that:
  128.  * -we either go to get data from disk and cache it (Data=TRUE, Cached=False)
  129.  * -Get it from a Hashphkramtable (Data=X, Cached=TRUE)
  130.  * -Call dataConverter initializer (Data=TRUE, Cached=TRUE)
  131.  * -Call AlgorithmicConverter initializer (Data=FALSE, Cached=TRUE)
  132.  */
  133. int QlgCvtTextDescToDesc(int,int,char *,int,char *,int,int);
  134. UConverter *
  135.   createConverter (const char *converterName, UErrorCode * err)
  136. {
  137.   char realName[MAX_CONVERTER_NAME_LENGTH];
  138.   char uppercased_converterName[MAX_CONVERTER_NAME_LENGTH];
  139.   UConverter *myUConverter = NULL;
  140.   UConverterSharedData *mySharedConverterData = NULL;
  141.   /* following parameters are passed to the convert text decscriptor
  142.      to descriptor          */
  143.   int  InType;
  144.   int  OutType=1;
  145.   char *InDescriptor;
  146.   int  InDescSize;
  147.   char OutDescriptor[CHARCCSIDSIZE]; /* 5 = size of a CCSID id on AS/400*/
  148.   int  OutDescSize;
  149.   int  JobCCSID=0;
  150.   char *inchar, *outchar; /* input and output conversion pointers*/
  151.   int tempchar;
  152.   if (U_FAILURE (*err))
  153.     return NULL;
  154. /******************************************************************/
  155. /* assume name is in EBCDIC. The convetername is assumed to be
  156. /* either upper/lower case ebcdic  and the text converter requires
  157. /* upper case - Since we do not know we will convert to upper case
  158. ** just in case
  159. /******************************************************************/
  160. inchar = (char*)converterName;
  161. outchar = &uppercased_converterName[0];
  162. while (*inchar) /*except for null terminator uppercase inputs*/
  163. {
  164.    tempchar = (int)(*inchar);
  165.    *outchar=(char)toupper(tempchar);
  166.    inchar ++;
  167.    outchar ++;
  168. }
  169.   if (outchar -&uppercased_converterName[0]<=MAX_CONVERTER_NAME_LENGTH)
  170.     *outchar = ''; /* replace the terminator                 */
  171.   if(!strcmp(uppercased_converterName, "IBM-37"))  /* We special-case this one */
  172.   {
  173.       memcpy(uppercased_converterName, "IBM-037", 7);
  174.       memset(uppercased_converterName + 7, '',1);
  175.   }
  176. /******************************************************************/
  177. /* convert name to AS/400 CCSID
  178. ** if CCSID is returned then we can complete building the converter
  179. ** otherwise we will return the same error as ICU converters
  180. */
  181. /******************************************************************/
  182.  InType = 11; /*set for IANA initially */
  183.  if (QlgCvtTextDescToDesc(InType, OutType,(char *)uppercased_converterName,                          strlen(uppercased_converterName),&OutDescriptor[0],sizeof(OutDescriptor),JobCCSID)<0)
  184.     {
  185.      InType = 3; /* change to AIX 4.1 if we fail above */
  186.      if (QlgCvtTextDescToDesc(InType, OutType,(char *)uppercased_converterName,                          strlen(uppercased_converterName),&OutDescriptor[0],sizeof(OutDescriptor),JobCCSID)<0)
  187.      {
  188.       *err = U_INVALID_TABLE_FILE;
  189.       send_message((char *)converterName,ICONV_CCSID_PROBLEM,'d');
  190.       return NULL;
  191.      }
  192.     }
  193. /*****************************************************************/
  194. /* create a new converter                                        */
  195. /*****************************************************************/
  196.  myUConverter = createNewConverter(&OutDescriptor[0], err);
  197.  if (U_FAILURE (*err) || (myUConverter == NULL))
  198.    {
  199.      return NULL;
  200.    }
  201.  return myUConverter;
  202. }
  203. UConverter* createNewConverter(const char *name, UErrorCode *err)
  204. {
  205.   char temp[33];
  206.   int32_t i = 0;
  207.   const int8_t *myByteArray = NULL;
  208.   const uint16_t *myIndexArray = NULL;
  209.   int32_t myValuesCount = 0;
  210.   int32_t myIndexCount = 0;
  211.   UConverter *myConverter = NULL;
  212.   int32_t myCheck;
  213.   int8_t errorLevel = 0;
  214.   char throwAway[COPYRIGHT_STRING_LENGTH];
  215.   char UNICODE_CCSID_ID_O[33]="IBMCCSID134880000000";
  216.   char UNICODE_CCSID_ID_I[33]="IBMCCSID13488";
  217.   char my_CCSID_ID[33]="";
  218.   char CONVERT_ID_START[9] ="IBMCCSID"; /* include null terminator for strcat */
  219.   char DEFAULTS[9] = "00000000";
  220.  if (U_FAILURE (*err))
  221.     return NULL;
  222. /* create the base shell for the converter */
  223.   myConverter = (UConverter *) malloc (sizeof (UConverter));
  224.   if (myConverter == NULL)
  225.     {
  226.       *err = U_MEMORY_ALLOCATION_ERROR;
  227.       return NULL;
  228.     }
  229. /* create the "shared area' and link into the shell */
  230.   myConverter->sharedData =
  231.     (UConverterSharedData *) malloc (sizeof (UConverterSharedData));
  232.   if (myConverter->sharedData == NULL)
  233.     {
  234.       free (myConverter);
  235.       *err = U_MEMORY_ALLOCATION_ERROR;
  236.       return NULL;
  237.     }
  238.   memset(my_CCSID_ID, '', 33);  /* sizeof(my_CCSID_ID)); */
  239.   memcpy(my_CCSID_ID,&CONVERT_ID_START[0],strlen(CONVERT_ID_START)+1);
  240.   memcpy(&my_CCSID_ID[8],&name[0],5);
  241.   memcpy(&my_CCSID_ID[13],&DEFAULTS[0],7);
  242.   memset(temp, '', 33);
  243.   memcpy(temp, my_CCSID_ID, 13);
  244.   myConverter->sharedData->toiconv_handle = iconv_open(UNICODE_CCSID_ID_I,my_CCSID_ID);
  245. /*  memset(&my_CCSID_ID[13],'0',19);  clear out the non necessary data to reverse */
  246.   my_CCSID_ID[13] = '';
  247.   myConverter->sharedData->fromiconv_handle = iconv_open(temp,UNICODE_CCSID_ID_O);
  248.   if ((myConverter->sharedData->toiconv_handle.return_value ==-1) ||(myConverter->sharedData->fromiconv_handle.return_value==-1))
  249.       {
  250. /*If it isn't any of the above, the file is invalid */
  251. *err = U_INVALID_TABLE_FILE;
  252. free (myConverter->sharedData);
  253. free (myConverter);
  254.       }
  255.   return myConverter;
  256. }