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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2002 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.  * $Id: Uniconv390TransService.cpp,v 1.3 2003/05/17 16:32:18 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/util/Janitor.hpp>
  63. #include <xercesc/util/TranscodingException.hpp>
  64. #include <xercesc/util/XMLString.hpp>
  65. #include <xercesc/util/XMLUniDefs.hpp>
  66. #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>
  67. #include "Uniconv390TransService.hpp"
  68. #include <stdio.h>
  69. #include <stdlib.h>
  70. #include <string.h>
  71. #include <errno.h>
  72. #include <langinfo.h>
  73. #include <locale.h>
  74. #include <xercesc/util/regx/XMLUniCharacter.hpp>
  75. XERCES_CPP_NAMESPACE_BEGIN
  76. // debug printfs.... I'll take these out after function test.
  77. /*
  78. #define DBGPRINTF1(a) {}
  79. #define DBGPRINTF2(a,b) {}
  80. #define DBGPRINTF3(a,b,c) {}
  81. #define DBGPRINTF4(a,b,c,d) {}
  82. #define DBGPRINTF5(a,b,c,d,e) {}
  83. #define DBGPRINTF6(a,b,c,d,e,f) {}
  84. #define DBGPRINTF7(a,b,c,d,e,f,g) {}
  85. */
  86. #define DBGPRINTF1(a) {if (gViewDebug) printf(a);}
  87. #define DBGPRINTF2(a,b) {if (gViewDebug) printf(a,b);}
  88. #define DBGPRINTF3(a,b,c) {if (gViewDebug) printf(a,b,c);}
  89. #define DBGPRINTF4(a,b,c,d) {if (gViewDebug) printf(a,b,c,d);}
  90. #define DBGPRINTF5(a,b,c,d,e) {if (gViewDebug) printf(a,b,c,d,e);}
  91. #define DBGPRINTF6(a,b,c,d,e,f) {if (gViewDebug) printf(a,b,c,d,e,f);}
  92. #define DBGPRINTF7(a,b,c,d,e,f,g) {if (gViewDebug) printf(a,b,c,d,e,f,g);}
  93. // ---------------------------------------------------------------------------
  94. //  Local, const data
  95. // ---------------------------------------------------------------------------
  96. static const XMLCh gMyServiceId[] =
  97. {
  98.     chLatin_U, chLatin_N, chLatin_I, chLatin_C, chLatin_O, chLatin_N, chLatin_V, chNull
  99. };
  100. // These will hold the environment variable settings.
  101. bool gViewTranscoder;
  102. static bool gViewDebug;
  103. static int gForceTranscode;
  104. #define NO_FORCE 0
  105. #define MUST_USE_ICU  1
  106. #define MUST_USE_UNICONV  2
  107. // ---------------------------------------------------------------------------
  108. //  Local functions
  109. // ---------------------------------------------------------------------------
  110. // This is a local service routine to figure out the number of characters (not bytes)
  111. // in a unicode string.
  112. static unsigned int  getWideCharLength(const XMLCh* const src)
  113. {
  114.    if (!src)
  115.       return 0;
  116.    unsigned int len = 0;
  117.    const XMLCh* pTmp = src;
  118.    while (*pTmp++)
  119.       len++;
  120.    return len;
  121. }
  122. // This is a local service routine to open a transcoder to/from unicode.
  123. static uniconvconverter * addConverter(const char* const EncodingName
  124.                              ,XMLTransService::Codes& resValue)
  125. {
  126. DBGPRINTF1("Add convertern");
  127.    uniconvconverter *tconv = new uniconvconverter;
  128.    tconv->fIconv390DescriptorFrom = uniconv_open("UCS-2",EncodingName);
  129.    if (tconv->fIconv390DescriptorFrom <= (uniconv_t)(0)) {
  130. DBGPRINTF2("uniconv_open from failed rc=%dn",(int)tconv->fIconv390DescriptorFrom);
  131.       resValue = XMLTransService::UnsupportedEncoding;
  132.       delete tconv;
  133.       return 0;
  134.    }
  135.    tconv->fIconv390DescriptorTo = uniconv_open(EncodingName,"UCS-2");
  136.    if (tconv->fIconv390DescriptorTo <= (uniconv_t)(0)) {
  137. DBGPRINTF2("uniconv_open to failed rc=%dn",(int)tconv->fIconv390DescriptorTo);
  138.       resValue = XMLTransService::UnsupportedEncoding;
  139.       uniconv_close(tconv->fIconv390DescriptorFrom);
  140.       delete tconv;
  141.       return 0;
  142.    }
  143.    return tconv;
  144. }
  145. // This is a local service routine to close the transcoders.
  146. static void removeConverter(uniconvconverter* const converter)
  147. {
  148. DBGPRINTF1("remove convertern");
  149.    if (converter) {
  150.       uniconv_close(converter->fIconv390DescriptorFrom);
  151.       uniconv_close(converter->fIconv390DescriptorTo);
  152.       delete converter;
  153.    }
  154. }
  155. // ***************************************************************************
  156. // ***************************************************************************
  157. // ***************************************************************************
  158. // ***************************************************************************
  159. // *************** Uniconv390TransService Class ******************************
  160. // ***************************************************************************
  161. // ***************************************************************************
  162. // ***************************************************************************
  163. // ***************************************************************************
  164. // ---------------------------------------------------------------------------
  165. //  Uniconv390TransService: Constructor and Destructor
  166. // ---------------------------------------------------------------------------
  167. Uniconv390TransService::Uniconv390TransService()
  168. {
  169.    fCaseConverter = new uniconvcaseconverter;
  170.    fCaseConverter->ftoupperhand=UNICONV_NOHANDLE;
  171.    fCaseConverter->ftolowerhand=UNICONV_NOHANDLE;
  172.    char * myenviron = getenv("_IXM_FORCE_CONVERSION");
  173.    gForceTranscode = NO_FORCE;
  174.    if ( !strcmp(myenviron,"USE_ICU") )
  175.       gForceTranscode = MUST_USE_ICU;
  176.    else if ( !strcmp(myenviron,"USE_NATIVE") )
  177.       gForceTranscode = MUST_USE_UNICONV;
  178.   DBGPRINTF3("FORCE PARM=%s %dn",myenviron,gForceTranscode);
  179.    fICUService = new ICUTransService;
  180.    gViewTranscoder = false;
  181.    if ( !strcmp(getenv("_IXM_VIEW_CONVERSION"),"YES") )
  182.       gViewTranscoder = true;
  183.    gViewDebug = false;
  184.    if ( !strcmp(getenv("_IXM_DEBUG_CONVERSION"),"YES") )
  185.       gViewDebug = true;
  186. }
  187. Uniconv390TransService::~Uniconv390TransService()
  188. {
  189.    if ( (fCaseConverter->ftoupperhand!=UNICONV_NOHANDLE) &&
  190.         (fCaseConverter->ftoupperhand!=UNICONV_ERROR) ) {
  191.       uniconv_toupper_close(fCaseConverter->ftoupperhand);
  192.       fCaseConverter->ftoupperhand=UNICONV_NOHANDLE;
  193.    }
  194.    if ( (fCaseConverter->ftolowerhand!=UNICONV_NOHANDLE) &&
  195.         (fCaseConverter->ftolowerhand!=UNICONV_ERROR) ) {
  196.       uniconv_tolower_close(fCaseConverter->ftolowerhand);
  197.       fCaseConverter->ftolowerhand=UNICONV_NOHANDLE;
  198.    }
  199.    if (fCaseConverter) {
  200.       delete [] fCaseConverter;
  201.       fCaseConverter=0;
  202.    }
  203. }
  204. // ---------------------------------------------------------------------------
  205. //  Uniconv390TransService: The virtual transcoding service API
  206. // ---------------------------------------------------------------------------
  207. int Uniconv390TransService::compareIString(const   XMLCh* const    comp1
  208.                                     , const XMLCh* const    comp2)
  209. {
  210. //char localname1[500];
  211. //XMLString::transcode(comp1,localname1,400);
  212. //char localname2[500];
  213. //XMLString::transcode(comp2,localname2,400);
  214. //DBGPRINTF3("comparing %s %s n",localname1,localname2);
  215. //printf("toupper handle=%xn",fCaseConverter->ftoupperhand);
  216.    if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) {
  217.       const XMLCh* psz1 = comp1;
  218.       const XMLCh* psz2 = comp2;
  219.       XMLCh tmp1;
  220.       XMLCh tmp2;
  221.       XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex);
  222.       if (fCaseConverter->ftoupperhand==UNICONV_NOHANDLE) {
  223.          fCaseConverter->ftoupperhand=uniconv_toupper_open();
  224.       }
  225.       unsigned int curCount = 0;
  226.       while (fCaseConverter->ftoupperhand!=UNICONV_ERROR)
  227.       {
  228.          tmp1 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz1);
  229.          if (errno==0)
  230.             tmp2 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz2);
  231.          if (errno) {
  232.             uniconv_toupper_close(fCaseConverter->ftoupperhand);
  233.             fCaseConverter->ftoupperhand=UNICONV_ERROR;
  234.             break;
  235.          }
  236.          //
  237.          //  If an inequality, then return the difference.
  238.          //
  239.          if (tmp1 != tmp2)
  240.             return int(*psz1) - int(*psz2);
  241.          // If either has ended, then they both ended, so equal
  242.          if (!*psz1 || !*psz2)
  243.             break;
  244.          // Move upwards for the next round
  245.          psz1++;
  246.          psz2++;
  247.       }
  248.    }
  249.    // check if unicode services does not support upper casing again, then call ICU.
  250.    if (fCaseConverter->ftoupperhand == UNICONV_ERROR) {
  251.       return fICUService->compareIString(comp1,comp2);
  252.    }
  253.    return 0;
  254. }
  255. int Uniconv390TransService::compareNIString(const  XMLCh* const    comp1
  256.                                     , const XMLCh* const    comp2
  257.                                     , const unsigned int    maxChars)
  258. {
  259. //char localname1[500];
  260. //XMLString::transcode(comp1,localname1,400);
  261. //char localname2[500];
  262. //XMLString::transcode(comp2,localname2,400);
  263. //DBGPRINTF3("comparing NI %s %s n",localname1,localname2);
  264. //printf("toupper handle=%xn",fCaseConverter->ftoupperhand);
  265. //printf("!!!***comparing NI %s %sn",localname1,localname2);
  266.    if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) {
  267.       const XMLCh* psz1 = comp1;
  268.       const XMLCh* psz2 = comp2;
  269.       XMLCh tmp1;
  270.       XMLCh tmp2;
  271.       XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex);
  272.       if (fCaseConverter->ftoupperhand==UNICONV_NOHANDLE) {
  273.          fCaseConverter->ftoupperhand=uniconv_toupper_open();
  274.       }
  275.       unsigned int curCount = 0;
  276.       while (fCaseConverter->ftoupperhand!=UNICONV_ERROR) {
  277.          tmp1 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz1);
  278.          if (errno==0)
  279.             tmp2 = uniconv_caseit(fCaseConverter->ftoupperhand,*psz2);
  280.          if (errno) {
  281.             uniconv_toupper_close(fCaseConverter->ftoupperhand);
  282.             fCaseConverter->ftoupperhand=UNICONV_ERROR;
  283.             break;
  284.          }
  285.          //
  286.          //  If an inequality, then return the difference.
  287.          //
  288.          if (tmp1 != tmp2)
  289.             return int(*psz1) - int(*psz2);
  290.          // If either ended, then both ended, so equal
  291.          if (!*psz1 || !*psz2)
  292.             break;
  293.          // Move upwards to next chars
  294.          psz1++;
  295.          psz2++;
  296.          //
  297.          //  Bump the count of chars done. If it equals the count then we
  298.          //  are equal for the requested count, so break out and return
  299.          //  equal.
  300.          //
  301.          curCount++;
  302.          if (maxChars == curCount)
  303.             break;
  304.       }
  305.    }
  306.    // check if unicode services does not support upper casing, then call ICU.
  307.    if (fCaseConverter->ftoupperhand == UNICONV_ERROR) {
  308.       return fICUService->compareNIString(comp1,comp2,maxChars);
  309.    }
  310.    return 0;
  311. }
  312. const XMLCh* Uniconv390TransService::getId() const
  313. {
  314.    return gMyServiceId;
  315. }
  316. bool Uniconv390TransService::isSpace(const XMLCh toCheck) const
  317. {
  318. DBGPRINTF2("isspace checking %xn",toCheck);
  319.    unsigned short chartype = XMLUniCharacter::getType(toCheck);
  320.    if ( (chartype == XMLUniCharacter::SPACE_SEPARATOR) ||
  321.         (chartype == XMLUniCharacter::LINE_SEPARATOR)   ||
  322.         (chartype == XMLUniCharacter::PARAGRAPH_SEPARATOR) )
  323.       return true;
  324.    else
  325.       return false;
  326. }
  327. bool Uniconv390TransService::supportsSrcOfs() const
  328. {
  329.    return false;
  330. }
  331. void Uniconv390TransService::upperCase(XMLCh* const toUpperCase) const
  332. {
  333. //char localname1[500];
  334. //XMLString::transcode(toUpperCase,localname1,400);
  335. //DBGPRINTF2("upper casing %s n",localname1);
  336. //printf("toupper handle=%xn",fCaseConverter->ftoupperhand);
  337.    if (fCaseConverter->ftoupperhand!=UNICONV_ERROR) {
  338.       XMLCh* outPtr = toUpperCase;
  339.       XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex);
  340.       if (fCaseConverter->ftoupperhand==UNICONV_NOHANDLE) {
  341.          fCaseConverter->ftoupperhand=uniconv_toupper_open();
  342.       }
  343.       unsigned int curCount = 0;
  344.       while ((fCaseConverter->ftoupperhand!=UNICONV_ERROR) && (*outPtr) ) {
  345.          XMLCh tmp = uniconv_caseit(fCaseConverter->ftoupperhand,*outPtr);
  346.          if (errno) {
  347.             uniconv_toupper_close(fCaseConverter->ftoupperhand);
  348.             fCaseConverter->ftoupperhand=UNICONV_ERROR;
  349.             break;
  350.          }
  351.          *outPtr = tmp;
  352.          outPtr++;
  353.       }
  354.    }
  355.    if (fCaseConverter->ftoupperhand==UNICONV_ERROR) {
  356.      return fICUService->upperCase(toUpperCase);
  357.    }
  358. }
  359. void Uniconv390TransService::lowerCase(XMLCh* const toLowerCase) const
  360. {
  361. //char localname1[500];
  362. //XMLString::transcode(toLowerCase,localname1,400);
  363. //DBGPRINTF2("lower casing %s n",localname1);
  364. //printf("tolower handle=%xn",fCaseConverter->ftolowerhand);
  365. //printf("!!!***Lower casing function called: %s n",localname1);
  366.    if (fCaseConverter->ftolowerhand!=UNICONV_ERROR) {
  367.       XMLCh* outPtr = toLowerCase;
  368.       XMLMutexLock lockcaser(&fCaseConverter->fcaseMutex);
  369.       if (fCaseConverter->ftolowerhand==UNICONV_NOHANDLE) {
  370.          fCaseConverter->ftolowerhand=uniconv_tolower_open();
  371.       }
  372.       unsigned int curCount = 0;
  373.       while ((fCaseConverter->ftolowerhand!=UNICONV_ERROR) && (*outPtr) ) {
  374.          XMLCh tmp = uniconv_caseit(fCaseConverter->ftolowerhand,*outPtr);
  375.          if (errno) {
  376.             uniconv_tolower_close(fCaseConverter->ftolowerhand);
  377.             fCaseConverter->ftolowerhand=UNICONV_ERROR;
  378.             break;
  379.          }
  380.          *outPtr = tmp;
  381.          outPtr++;
  382.       }
  383.    }
  384.    if (fCaseConverter->ftolowerhand==UNICONV_ERROR) {
  385.      return fICUService->lowerCase(toLowerCase);
  386.    }
  387. }
  388. XMLLCPTranscoder* Uniconv390TransService::makeNewLCPTranscoder()
  389. {
  390.    XMLTransService::Codes resValue;
  391. DBGPRINTF2("makeNewLCPTranscoder() localencoding=%s n",nl_langinfo(CODESET));
  392.    // USS default code page is IBM-1047
  393.    if (gForceTranscode == MUST_USE_ICU) {
  394.       if (gViewTranscoder)
  395.          printf("IXM1004I LCP - Using ICU - %sn",nl_langinfo(CODESET));
  396.       fLCPTranscoder = fICUService->makeNewLCPTranscoder();
  397.    } else {
  398.       char codepage[32];
  399.       sprintf(codepage,"%s-s390", nl_langinfo(CODESET));
  400.       uniconvconverter *tconv=addConverter(codepage,resValue);
  401.       DBGPRINTF3("gForce=%d,tconv=%xn",gForceTranscode,(int)tconv);
  402.       if (tconv) {
  403.          if (gViewTranscoder)
  404.             printf("IXM1005I LCP - Using Unicode Services - %sn",nl_langinfo(CODESET));
  405.          fLCPTranscoder = new Uniconv390LCPTranscoder(tconv);
  406.       } else {
  407.          if (gForceTranscode != MUST_USE_UNICONV) {
  408.             if (gViewTranscoder)
  409.                printf("IXM1006I LCP - Using ICU - %sn",nl_langinfo(CODESET));
  410.             fLCPTranscoder = fICUService->makeNewLCPTranscoder();
  411.          }
  412.       }
  413.    }
  414.    return fLCPTranscoder;
  415. }
  416. // ---------------------------------------------------------------------------
  417. //  Uniconv390TransService: The protected virtual transcoding service API
  418. // ---------------------------------------------------------------------------
  419. XMLTranscoder* Uniconv390TransService::
  420. makeNewXMLTranscoder(const  XMLCh* const            encodingName
  421.                     ,       XMLTransService::Codes& resValue
  422.                     , const unsigned int            blockSize
  423.                     ,       MemoryManager* const    manager)
  424. {
  425. char * localname = XMLString::transcode(encodingName, manager);
  426. ArrayJanitor<char> janText((char*)localname, manager);
  427. DBGPRINTF3("makeNewXMLTranscoder() encoding=%s blocksize=%dn",localname,blockSize);
  428.    if (gForceTranscode == MUST_USE_ICU) {
  429.       if (gViewTranscoder)
  430.          printf("IXM1001I XML - Using ICU - %sn",localname);
  431.       return fICUService->makeNewXMLTranscoder(encodingName,resValue,blockSize, manager);
  432.    }
  433.    uniconvconverter *tconv=addConverter(localname,resValue);
  434.    if (tconv == 0) {
  435.       DBGPRINTF1("uniconv failed!!!!!!!!n");
  436.       if (gForceTranscode == MUST_USE_UNICONV)
  437.          return 0;
  438.       else {
  439.          if (gViewTranscoder)
  440.             printf("IXM1002I XML - Using ICU - %sn",localname);
  441.          return fICUService->makeNewXMLTranscoder(encodingName,resValue,blockSize, manager);
  442.       }
  443.    }
  444.    if (gViewTranscoder)
  445.       printf("IXM1003I XML - Using Unicode Services - %sn",localname);
  446.    return new (manager) Uniconv390Transcoder(encodingName, tconv, blockSize, manager);
  447. }
  448. // ***************************************************************************
  449. // ***************************************************************************
  450. // ***************************************************************************
  451. // ***************************************************************************
  452. // *************** Uniconv390Transcoder Class ********************************
  453. // ***************************************************************************
  454. // ***************************************************************************
  455. // ***************************************************************************
  456. // ***************************************************************************
  457. // ---------------------------------------------------------------------------
  458. //  Uniconv390Transcoder: Constructors and Destructor
  459. // ---------------------------------------------------------------------------
  460. Uniconv390Transcoder::Uniconv390Transcoder(const  XMLCh* const        encodingName
  461.                             ,        uniconvconverter_t * const   toAdopt
  462.                             , const unsigned int        blockSize
  463.                             , MemoryManager* const manager) :
  464.     XMLTranscoder(encodingName, blockSize, manager)
  465.     , fConverter(toAdopt)
  466. {
  467. }
  468. Uniconv390Transcoder::~Uniconv390Transcoder()
  469. {
  470.    // If there is a converter, clean it up
  471.    if (fConverter) {
  472.       removeConverter(fConverter);
  473.       fConverter=0;
  474.    }
  475. }
  476. // ---------------------------------------------------------------------------
  477. //  Uniconv390Transcoder: The virtual transcoder API
  478. // ---------------------------------------------------------------------------
  479. // ignore  charSizes since that is used to generate character offsets.
  480. unsigned int
  481. Uniconv390Transcoder::transcodeFrom(const  XMLByte* const          srcData
  482.                             , const unsigned int            srcCount
  483.                             ,       XMLCh* const            toFill
  484.                             , const unsigned int            maxChars
  485.                             ,       unsigned int&           bytesEaten
  486.                             ,       unsigned char* const    charSizes)
  487. {
  488.    unsigned int countIn = 0;
  489.    unsigned int countOut = 0;
  490. DBGPRINTF2("Uniconv390Transcoder::transcodeFrom bytes=%dn",srcCount);
  491.    int retCode;
  492.    char *tmpInPtr = (char *) srcData;
  493.    char *tmpOutPtr = (char *) toFill;
  494.    unsigned int inByteLeft = srcCount;
  495.    unsigned int outByteLeft = maxChars*sizeof(XMLCh);
  496.    { // locking scope
  497.       XMLMutexLock lockConverter(&fConverter->fMutex);
  498.       retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  499.    }
  500. DBGPRINTF5("Uniconv390Transcoder::transcodeFrom iconv finished, rc=%d inleft=%d outleft=%d errno=%d n",retCode,inByteLeft,outByteLeft,errno);
  501.    if ( (retCode < 0 ) && (errno != E2BIG) ) {
  502.       return 0;
  503.    }
  504.    // Give back the counts of eaten and transcoded
  505.    bytesEaten = srcCount-inByteLeft;
  506.    return maxChars-outByteLeft/sizeof(XMLCh);
  507. }
  508. // The returned int is really supposed to be the number of bytes, not chars!
  509. unsigned int
  510. Uniconv390Transcoder::transcodeTo( const   XMLCh* const    srcData
  511.                             , const unsigned int    srcCount
  512.                             ,       XMLByte* const  toFill
  513.                             , const unsigned int    maxBytes
  514.                             ,       unsigned int&   charsEaten
  515.                             , const UnRepOpts       options)
  516. {
  517.    unsigned int countIn = 0;
  518.    unsigned int countOut = 0;
  519. DBGPRINTF2("Uniconv390Transcoder::transcodeTo bytes=%dn",srcCount);
  520.    int retCode;
  521.    char *tmpInPtr = (char *) srcData;
  522.    char *tmpOutPtr = (char *) toFill;
  523.    unsigned int inByteLeft = srcCount*sizeof(XMLCh);
  524.    unsigned int outByteLeft = maxBytes;
  525.    { // locking scope
  526.       XMLMutexLock lockConverter(&fConverter->fMutex);
  527.       retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  528.    }
  529.    if ( (retCode < 0) && (errno != E2BIG) ) {
  530.       return 0;
  531.    }
  532.    // Give back the counts of eaten and transcoded
  533.    charsEaten = srcCount-inByteLeft/sizeof(XMLCh);
  534.    return maxBytes-outByteLeft;
  535. }
  536. bool Uniconv390Transcoder::canTranscodeTo(const unsigned int toCheck) const
  537. {
  538.    int retCode;
  539. DBGPRINTF1("Uniconv390Transcoder::canTranscodeTon");
  540. //printf("!!!***Uniconv390Transcoder::canTranscodeTon");
  541.    //
  542.    //  If the passed value is really a surrogate embedded together, then
  543.    //  we need to break it out into its two chars. Else just one. While
  544.    //  we are ate it, convert them to UChar format if required.
  545.    //
  546.    XMLCh          srcBuf[2];
  547.    unsigned int    srcCount = 1;
  548.    if (toCheck & 0xFFFF0000) {
  549.       srcBuf[0] = XMLCh((toCheck >> 10) + 0xD800);
  550.       srcBuf[1] = XMLCh(toCheck & 0x3FF) + 0xDC00;
  551.       srcCount++;
  552.    } else {
  553.       srcBuf[0] = XMLCh(toCheck);
  554.    }
  555.    // Set up a temp buffer to format into. Make it more than big enough
  556.    char  tmpBuf[16];
  557.    char *tmpInPtr = (char *) srcBuf;
  558.    char *tmpOutPtr = (char *) tmpBuf;
  559.    unsigned int inByteLeft = srcCount*sizeof(XMLCh);
  560.    unsigned int outByteLeft = 16;
  561.    { // locking scope
  562.       XMLMutexLock lockConverter(&fConverter->fMutex);
  563.       retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  564.    }
  565.    if ( (retCode < 0) && (errno != E2BIG) ) {
  566.       return false;
  567.    }
  568.    return true;
  569. }
  570. // ***************************************************************************
  571. // ***************************************************************************
  572. // ***************************************************************************
  573. // ***************************************************************************
  574. // *************** Uniconv390LCPTranscoder Class *****************************
  575. // ***************************************************************************
  576. // ***************************************************************************
  577. // ***************************************************************************
  578. // ***************************************************************************
  579. // ---------------------------------------------------------------------------
  580. //  Uniconv390LCPTranscoder: Constructor and Destructor
  581. // ---------------------------------------------------------------------------
  582. Uniconv390LCPTranscoder::Uniconv390LCPTranscoder( uniconvconverter_t* const toAdopt) :
  583.     fConverter(toAdopt)
  584. {
  585. }
  586. Uniconv390LCPTranscoder::~Uniconv390LCPTranscoder()
  587. {
  588.     // If there is a converter, clean it up
  589.    if (fConverter) {
  590.       removeConverter(fConverter);
  591.       fConverter=0;
  592.    }
  593. }
  594. // ---------------------------------------------------------------------------
  595. //  Uniconv390LCPTranscoder: calcRequiredSize
  596. //
  597. // The only way I can find to reliably determine the exact required size is to actually
  598. // transcode the string and see how long it is. Fortunately, this is only done as a last
  599. // ditch effort so it should only be used very rarely (if at all).
  600. // ---------------------------------------------------------------------------
  601. unsigned int Uniconv390LCPTranscoder::calcRequiredSize(const XMLCh* const srcText)
  602. {
  603. DBGPRINTF1("Uniconv390LCPTranscoder::calcRequiredSize(const XMLCh* const srcText)  n");
  604. //printf("!!!***Uniconv390LCPTranscoder::calcRequiredSize(const XMLCh* const srcText)  n");
  605.    int thesize=0;
  606.    if (!srcText)
  607.       return 0;
  608.    if (!*srcText)
  609.       return 0;
  610.    char * result = transcode(srcText, XMLPlatformUtils::fgMemoryManager);
  611.    if (result) {
  612.       thesize = strlen(result);
  613.       XMLPlatformUtils::fgMemoryManager->deallocate(result);//delete [] result;
  614.    }
  615.    return thesize;
  616. }
  617. unsigned int Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText)
  618. {
  619. DBGPRINTF1("Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText)  n");
  620. //printf("!!!***Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText)  n");
  621.    int thesize=0;
  622.    if (!srcText)
  623.       return 0;
  624.    if (!*srcText)
  625.       return 0;
  626.    XMLCh * result = transcode(srcText, XMLPlatformUtils::fgMemoryManager);
  627.    if (result) {
  628.       thesize = getWideCharLength(result);
  629.       XMLPlatformUtils::fgMemoryManager->deallocate(result);//delete [] result;
  630.    }
  631. DBGPRINTF2("Uniconv390LCPTranscoder::calcRequiredSize(const char* const srcText) %d  n",thesize);
  632.    return thesize;
  633. }
  634. // ---------------------------------------------------------------------------
  635. //  Uniconv390LCPTranscoder: transcode
  636. //
  637. // Now what follows are various methods to transcode to/from unicode.
  638. // ---------------------------------------------------------------------------
  639. char* Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode)
  640. {
  641. //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode) ");
  642. //printf("transcode handle=%xn",fConverter->fIconv390DescriptorTo);
  643.    if (!toTranscode)
  644.       return 0;
  645.    char* retVal = 0;
  646.     // find out the length of the source and use this as an estimate for the needed buffer length.
  647.    unsigned int  wLent = getWideCharLength(toTranscode);
  648.    if (wLent == 0) {
  649.       retVal = new char[1];
  650.       retVal[0] = 0;
  651.       return retVal;
  652.    }
  653.    retVal = new char[wLent * 2 + 1]; // get double just to be sure.
  654.    while (true) {
  655.       int retCode;
  656.       char *tmpInPtr = (char*) toTranscode;
  657.       char *tmpOutPtr = (char*) retVal;
  658.       unsigned int inByteLeft = wLent*sizeof(XMLCh);
  659.       unsigned int outByteLeft = wLent*sizeof(XMLCh);
  660. //printf("!!!transcode len=%dn",wLent);
  661.       { // Locking scope
  662.          XMLMutexLock lockConverter(&fConverter->fMutex);
  663.          retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  664.       }
  665. //printf("!!!transcode uniconv finished rc=%d errno=%dn",retCode,errno);
  666.       // If the data does not fit into our estimation of the buffer size, then delete the buffer,
  667.       // double the estimated length and try again.
  668.       if ( ((retCode < 0) && (errno == E2BIG)) || (outByteLeft == 0) ) {
  669. //printf("!!!Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):Retrying with a bigger buffer.......n");
  670.          delete [] retVal;
  671.          wLent*=2;
  672.          retVal = new char[wLent*sizeof(XMLCh) + 1];
  673.       }
  674.       // If uniconv doesn't complete for any other reason, then return failure.
  675.       else if (retCode < 0) {
  676.          return 0;
  677.       }
  678.       // it was successful so break out of the loop
  679.       else {
  680.          *tmpOutPtr = 0x00;
  681.          break;
  682.       }
  683.    }
  684. //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):%sn",retVal);
  685.    return retVal;
  686. }
  687. char* Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode,
  688.                                          MemoryManager* const manager)
  689. {
  690. //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode) ");
  691. //printf("transcode handle=%xn",fConverter->fIconv390DescriptorTo);
  692.    if (!toTranscode)
  693.       return 0;
  694.    char* retVal = 0;
  695.     // find out the length of the source and use this as an estimate for the needed buffer length.
  696.    unsigned int  wLent = getWideCharLength(toTranscode);
  697.    if (wLent == 0) {
  698.       retVal = (char*) manager->allocate(sizeof(char));//new char[1];
  699.       retVal[0] = 0;
  700.       return retVal;
  701.    }
  702.    retVal = (char*) manager->allocate((wLent * 2 + 1) * sizeof(char));//new char[wLent * 2 + 1]; // get double just to be sure.
  703.    while (true) {
  704.       int retCode;
  705.       char *tmpInPtr = (char*) toTranscode;
  706.       char *tmpOutPtr = (char*) retVal;
  707.       unsigned int inByteLeft = wLent*sizeof(XMLCh);
  708.       unsigned int outByteLeft = wLent*sizeof(XMLCh);
  709. //printf("!!!transcode len=%dn",wLent);
  710.       { // Locking scope
  711.          XMLMutexLock lockConverter(&fConverter->fMutex);
  712.          retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  713.       }
  714. //printf("!!!transcode uniconv finished rc=%d errno=%dn",retCode,errno);
  715.       // If the data does not fit into our estimation of the buffer size, then delete the buffer,
  716.       // double the estimated length and try again.
  717.       if ( ((retCode < 0) && (errno == E2BIG)) || (outByteLeft == 0) ) {
  718. //printf("!!!Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):Retrying with a bigger buffer.......n");
  719.          manager->deallocate(retVal);//delete [] retVal;
  720.          wLent*=2;
  721.          retVal = (char*) manager->allocate
  722.          (
  723.              (wLent*sizeof(XMLCh) + 1) * sizeof(char)
  724.          );//new char[wLent*sizeof(XMLCh) + 1];
  725.       }
  726.       // If uniconv doesn't complete for any other reason, then return failure.
  727.       else if (retCode < 0) {
  728.          return 0;
  729.       }
  730.       // it was successful so break out of the loop
  731.       else {
  732.          *tmpOutPtr = 0x00;
  733.          break;
  734.       }
  735.    }
  736. //printf("Uniconv390LCPTranscoder::transcode(const XMLCh* const toTranscode):%sn",retVal);
  737.    return retVal;
  738. }
  739. XMLCh* Uniconv390LCPTranscoder::transcode(const char* const toTranscode)
  740. {
  741. DBGPRINTF2("Uniconv390LCPTranscoder::transcode(const char* const toTranscode):%s n",toTranscode);
  742. //printf("transcode handle=%xn",fConverter->fIconv390DescriptorFrom);
  743.    if (!toTranscode)
  744.       return 0;
  745.    XMLCh* retVal = 0;
  746.    const unsigned int len = strlen(toTranscode);
  747.    retVal = new XMLCh[len + 1]; // +1 is for the null terminator!
  748.    if (len == 0) {
  749.       retVal[0] = 0;
  750.       return retVal;
  751.    }
  752.    int retCode;
  753.    char *tmpInPtr = (char*) toTranscode;
  754.    char *tmpOutPtr = (char*) retVal;
  755.    unsigned int inByteLeft = len;
  756.    unsigned int outByteLeft = len*sizeof(XMLCh);
  757.    { // locking scope
  758.       XMLMutexLock lockConverter(&fConverter->fMutex);
  759.       retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  760.    }
  761.    // Because we check the length in the beginning, and we make sure the output buffer
  762.    // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
  763.    // return failure.
  764.    if (retCode < 0) {
  765.       delete [] retVal;
  766.       return 0;
  767.    }
  768.    *tmpOutPtr = 0x00;
  769.    *(tmpOutPtr+1) = 0x00;
  770.    return retVal;
  771. }
  772. XMLCh* Uniconv390LCPTranscoder::transcode(const char* const toTranscode,
  773.                                           MemoryManager* const manager)
  774. {
  775. DBGPRINTF2("Uniconv390LCPTranscoder::transcode(const char* const toTranscode):%s n",toTranscode);
  776. //printf("transcode handle=%xn",fConverter->fIconv390DescriptorFrom);
  777.    if (!toTranscode)
  778.       return 0;
  779.    XMLCh* retVal = 0;
  780.    const unsigned int len = strlen(toTranscode);
  781.    retVal = (XMLCh*) manager->allocate((len + 1) * sizeof(XMLCh));//new XMLCh[len + 1]; // +1 is for the null terminator!
  782.    if (len == 0) {
  783.       retVal[0] = 0;
  784.       return retVal;
  785.    }
  786.    int retCode;
  787.    char *tmpInPtr = (char*) toTranscode;
  788.    char *tmpOutPtr = (char*) retVal;
  789.    unsigned int inByteLeft = len;
  790.    unsigned int outByteLeft = len*sizeof(XMLCh);
  791.    { // locking scope
  792.       XMLMutexLock lockConverter(&fConverter->fMutex);
  793.       retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  794.    }
  795.    // Because we check the length in the beginning, and we make sure the output buffer
  796.    // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
  797.    // return failure.
  798.    if (retCode < 0) {
  799.       manager->deallocate(retVal);//delete [] retVal;
  800.       return 0;
  801.    }
  802.    *tmpOutPtr = 0x00;
  803.    *(tmpOutPtr+1) = 0x00;
  804.    return retVal;
  805. }
  806. bool Uniconv390LCPTranscoder::transcode(const  char* const     toTranscode
  807.                                 ,       XMLCh* const    toFill
  808.                                 , const unsigned int    maxChars)
  809. {
  810. DBGPRINTF1("Uniconv390LCPTranscoder::transcode(const  char* const     toTranscode, etc.... n");
  811. //printf("transcode handle=%xn",fConverter->fIconv390DescriptorFrom);
  812.     // Check for a couple of psycho corner cases
  813.    if (!toTranscode || !maxChars) {
  814.       toFill[0] = 0;
  815.       return true;
  816.    }
  817.    unsigned int  Lent = strlen(toTranscode);
  818.    if (Lent == 0) {
  819.       toFill[0] = 0;
  820.       return true;
  821.    }
  822.    int retCode;
  823.    char *tmpInPtr = (char*) toTranscode;
  824.    char *tmpOutPtr = (char*) toFill;
  825.    unsigned int inByteLeft = Lent;
  826.    unsigned int outByteLeft = maxChars*2;
  827.    { // locking scope
  828.       XMLMutexLock lockConverter(&fConverter->fMutex);
  829.       retCode = uniconv(fConverter->fIconv390DescriptorFrom, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  830.    }
  831.    // Because we check the length in the beginning, and the caller makes sure that the output buffer
  832.    // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
  833.    // return failure.
  834.    if (retCode < 0) {
  835.       return false;
  836.    }
  837.    *tmpOutPtr = 0x00;
  838.    *(tmpOutPtr+1) = 0x00;
  839.    return true;
  840. }
  841. bool Uniconv390LCPTranscoder::transcode(   const   XMLCh* const    toTranscode
  842.                                     ,       char* const     toFill
  843.                                     , const unsigned int    maxBytes)
  844. {
  845. DBGPRINTF1("Uniconv390LCPTranscoder::transcode(const  XMLCh* const     toTranscode, etc.... n");
  846. //printf("transcode handle=%xn",fConverter->fIconv390DescriptorTo);
  847.    // Watch for a couple of pyscho corner cases
  848.    if (!toTranscode || !maxBytes) {
  849.       toFill[0] = 0;
  850.       return true;
  851.    }
  852.    //-------------------
  853.    unsigned int  wLent = getWideCharLength(toTranscode);
  854.    if (wLent == 0) {
  855.       toFill[0] = 0;
  856.       return true;
  857.    }
  858.    int retCode;
  859.    char *tmpInPtr = (char*) toTranscode;
  860.    char *tmpOutPtr = (char*) toFill;
  861.    unsigned int inByteLeft = wLent*sizeof(XMLCh);
  862.    unsigned int outByteLeft = maxBytes;
  863.    { // locking scope
  864.       XMLMutexLock lockConverter(&fConverter->fMutex);
  865.       retCode = uniconv(fConverter->fIconv390DescriptorTo, &tmpInPtr, &inByteLeft, &tmpOutPtr, &outByteLeft);
  866.    }
  867.    // Because we check the length in the beginning, and the caller makes sure that the output buffer
  868.    // is big enough, uniconv should complete the transcoding. If it doesn't for any reason, then
  869.    // return failure.
  870.    if (retCode < 0) {
  871.       return false;
  872.    }
  873.    *tmpOutPtr = 0x00;
  874.    return true;
  875. }
  876. XERCES_CPP_NAMESPACE_END