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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-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: XMLString.cpp,v 1.23 2003/05/18 14:02:05 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <string.h>
  63. #include <ctype.h>
  64. #include <stdlib.h>
  65. #include <errno.h>
  66. #include <xercesc/util/ArrayIndexOutOfBoundsException.hpp>
  67. #include <xercesc/util/IllegalArgumentException.hpp>
  68. #include <xercesc/util/NumberFormatException.hpp>
  69. #include <xercesc/util/Janitor.hpp>
  70. #include <xercesc/util/PlatformUtils.hpp>
  71. #include <xercesc/util/RefArrayVectorOf.hpp>
  72. #include <xercesc/util/RuntimeException.hpp>
  73. #include <xercesc/util/TransService.hpp>
  74. #include <xercesc/util/TranscodingException.hpp>
  75. #include <xercesc/util/XMLString.hpp>
  76. #include <xercesc/util/XMLUniDefs.hpp>
  77. #include <xercesc/util/XMLUni.hpp>
  78. #include <xercesc/internal/XMLReader.hpp>
  79. XERCES_CPP_NAMESPACE_BEGIN
  80. // ---------------------------------------------------------------------------
  81. //  Local static data
  82. //
  83. //  gConverter
  84. //      This is initialized when the user calls the platform init method,
  85. //      which calls our init method. This is the converter used for default
  86. //      conversion to/from the local code page.
  87. // ---------------------------------------------------------------------------
  88. static XMLLCPTranscoder*    gTranscoder = 0;
  89. static XMLCh                gNullStr[] =
  90. {
  91.     chOpenCurly, chLatin_n, chLatin_u, chLatin_l, chLatin_l, chCloseCurly, chNull
  92. };
  93. MemoryManager* XMLString::fgMemoryManager = 0;
  94. // ---------------------------------------------------------------------------
  95. //  XMLString: Public static methods
  96. // ---------------------------------------------------------------------------
  97. void XMLString::binToText(  const   unsigned long   toFormat
  98.                             ,       char* const     toFill
  99.                             , const unsigned int    maxChars
  100.                             , const unsigned int    radix)
  101. {
  102.     static const char digitList[16] =
  103.     {
  104.           '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
  105.         , 'A', 'B', 'C', 'D', 'E', 'F'
  106.     };
  107.     if (!maxChars)
  108.         ThrowXML(IllegalArgumentException, XMLExcepts::Str_ZeroSizedTargetBuf);
  109.     // Handle special case
  110.     if (!toFormat)
  111.     {
  112.         toFill[0] = '0';
  113.         toFill[1] = 0;
  114.         return;
  115.     }
  116.     // This is used to fill the temp buffer
  117.     unsigned int tmpIndex = 0;
  118.     // A copy of the conversion value that we can modify
  119.     unsigned int tmpVal = toFormat;
  120.     //
  121.     //  Convert into a temp buffer that we know is large enough. This avoids
  122.     //  having to check for overflow in the inner loops, and we have to flip
  123.     //  the resulting XMLString anyway.
  124.     //
  125.     char tmpBuf[128];
  126.     //
  127.     //  For each radix, do the optimal thing. For bin and hex, we can special
  128.     //  case them and do shift and mask oriented stuff. For oct and decimal
  129.     //  there isn't much to do but bull through it with divides.
  130.     //
  131.     if (radix == 2)
  132.     {
  133.         while (tmpVal)
  134.         {
  135.             if (tmpVal & 0x1UL)
  136.                 tmpBuf[tmpIndex++] = '1';
  137.             else
  138.                 tmpBuf[tmpIndex++] = '0';
  139.             tmpVal >>= 1;
  140.         }
  141.     }
  142.      else if (radix == 16)
  143.     {
  144.         while (tmpVal)
  145.         {
  146.             const unsigned int charInd = (tmpVal & 0xFUL);
  147.             tmpBuf[tmpIndex++] = digitList[charInd];
  148.             tmpVal >>= 4;
  149.         }
  150.     }
  151.      else if ((radix == 8) || (radix == 10))
  152.     {
  153.         while (tmpVal)
  154.         {
  155.             const unsigned int charInd = (tmpVal % radix);
  156.             tmpBuf[tmpIndex++] = digitList[charInd];
  157.             tmpVal /= radix;
  158.         }
  159.     }
  160.      else
  161.     {
  162.         ThrowXML(RuntimeException, XMLExcepts::Str_UnknownRadix);
  163.     }
  164.     // See if have enough room in the caller's buffer
  165.     if (tmpIndex > maxChars)
  166.         ThrowXML(IllegalArgumentException, XMLExcepts::Str_TargetBufTooSmall);
  167.     // Reverse the tmp buffer into the caller's buffer
  168.     unsigned int outIndex = 0;
  169.     for (; tmpIndex > 0; tmpIndex--)
  170.         toFill[outIndex++] = tmpBuf[tmpIndex-1];
  171.     // And cap off the caller's buffer
  172.     toFill[outIndex] = char(0);
  173. }
  174. void XMLString::binToText(  const   unsigned int    toFormat
  175.                             ,       char* const     toFill
  176.                             , const unsigned int    maxChars
  177.                             , const unsigned int    radix)
  178. {
  179.     // Just call the unsigned long version
  180.     binToText((unsigned long)toFormat, toFill, maxChars, radix);
  181. }
  182. void XMLString::binToText(  const   long            toFormat
  183.                             ,       char* const     toFill
  184.                             , const unsigned int    maxChars
  185.                             , const unsigned int    radix)
  186. {
  187.     //
  188.     //  If its negative, then put a negative sign into the output and flip
  189.     //  the sign of the local temp value.
  190.     //
  191.     unsigned int startInd = 0;
  192.     unsigned long actualVal;
  193.     if (toFormat < 0)
  194.     {
  195.         toFill[0] = '-';
  196.         startInd++;
  197.         actualVal = (unsigned long)(toFormat * -1);
  198.     }
  199.      else
  200.     {
  201.         actualVal = (unsigned long)(toFormat);
  202.     }
  203.     // And now call the unsigned long version
  204.     binToText(actualVal, &toFill[startInd], maxChars, radix);
  205. }
  206. void XMLString::binToText(  const   int             toFormat
  207.                             ,       char* const     toFill
  208.                             , const unsigned int    maxChars
  209.                             , const unsigned int    radix)
  210. {
  211.     //
  212.     //  If its negative, then put a negative sign into the output and flip
  213.     //  the sign of the local temp value.
  214.     //
  215.     unsigned int startInd = 0;
  216.     unsigned long actualVal;
  217.     if (toFormat < 0)
  218.     {
  219.         toFill[0] = '-';
  220.         startInd++;
  221.         actualVal = (unsigned long)(toFormat * -1);
  222.     }
  223.      else
  224.     {
  225.         actualVal = (unsigned long)(toFormat);
  226.     }
  227.     // And now call the unsigned long version
  228.     binToText(actualVal, &toFill[startInd], maxChars, radix);
  229. }
  230. void XMLString::catString(char* const target, const char* const src)
  231. {
  232.     strcat(target, src);
  233. }
  234. int XMLString::compareIString(const char* const str1, const char* const str2)
  235. {
  236.     return stricmp(str1, str2);
  237. }
  238. int XMLString::compareNString(  const   char* const     str1
  239.                                 , const char* const     str2
  240.                                 , const unsigned int    count)
  241. {
  242.     // Watch for pathological secenario
  243.     if (!count)
  244.         return 0;
  245.     return strncmp(str1, str2, count);
  246. }
  247. int XMLString::compareNIString( const   char* const     str1
  248.                                 , const char* const     str2
  249.                                 , const unsigned int    count)
  250. {
  251.     if (!count)
  252.         return 0;
  253.     return strnicmp(str1, str2, count);
  254. }
  255. int XMLString::compareString(   const   char* const    str1
  256.                                 , const char* const    str2)
  257. {
  258.     return strcmp(str1, str2);
  259. }
  260. void XMLString::copyString(         char* const    target
  261.                             , const char* const    src)
  262. {
  263.     strcpy(target, src);
  264. }
  265. void XMLString::cut(        XMLCh* const    toCutFrom
  266.                     , const unsigned int    count)
  267. {
  268.     #if defined(XML_DEBUG)
  269.     if (count > stringLen(toCutFrom))
  270.     {
  271.         // <TBD> This is bad of course
  272.     }
  273.     #endif
  274.     // If count is zero, then nothing to do
  275.     if (!count)
  276.         return;
  277.     XMLCh* targetPtr = toCutFrom;
  278.     XMLCh* srcPtr = toCutFrom + count;
  279.     while (*srcPtr)
  280.         *targetPtr++ = *srcPtr++;
  281.     // Cap it off at the new end
  282.     *targetPtr = 0;
  283. }
  284. unsigned int XMLString::hash(   const   char* const     tohash
  285.                                 , const unsigned int    hashModulus)
  286. {
  287.     if (!hashModulus)
  288.         ThrowXML(IllegalArgumentException, XMLExcepts::Pool_ZeroModulus);
  289.     unsigned int hashVal = 0;
  290.     if (tohash) {
  291.         const char* curCh = tohash;
  292.         while (*curCh)
  293.         {
  294.             unsigned int top = hashVal >> 24;
  295.             hashVal += (hashVal * 37) + top + (unsigned int)(*curCh);
  296.             curCh++;
  297.         }
  298.     }
  299.     // Divide by modulus
  300.     return hashVal % hashModulus;
  301. }
  302. int XMLString::indexOf(const char* const toSearch, const char ch)
  303. {
  304.     const unsigned int len = strlen(toSearch);
  305.     for (unsigned int i = 0; i < len; i++)
  306.     {
  307.         if (toSearch[i] == ch)
  308.             return i;
  309.     }
  310.     return -1;
  311. }
  312. int XMLString::indexOf( const   char* const     toSearch
  313.                         , const char            ch
  314.                         , const unsigned int    fromIndex)
  315. {
  316.     const unsigned int len = strlen(toSearch);
  317.     // Make sure the start index is within the XMLString bounds
  318. if ((int)fromIndex > len-1)
  319.         ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
  320.     for (unsigned int i = fromIndex; i < len; i++)
  321.     {
  322.         if (toSearch[i] == ch)
  323.             return i;
  324.     }
  325.     return -1;
  326. }
  327. int XMLString::lastIndexOf(const char* const toSearch, const char ch)
  328. {
  329.     const int len = strlen(toSearch);
  330.     for (int i = len-1; i >= 0; i--)
  331.     {
  332.         if (toSearch[i] == ch)
  333.             return i;
  334.     }
  335.     return -1;
  336. }
  337. int XMLString::lastIndexOf( const   char* const     toSearch
  338.                             , const char            ch
  339.                             , const unsigned int    fromIndex)
  340. {
  341.     const int len = strlen(toSearch);
  342.     // Make sure the start index is within the XMLString bounds
  343. if ((int)fromIndex > len-1)
  344.         ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
  345.     for (int i = (int)fromIndex; i >= 0; i--)
  346.     {
  347.         if (toSearch[i] == ch)
  348.             return i;
  349.     }
  350.     return -1;
  351. }
  352. unsigned int XMLString::replaceTokens(          XMLCh* const    errText
  353.                                         , const unsigned int    maxChars
  354.                                         , const XMLCh* const    text1
  355.                                         , const XMLCh* const    text2
  356.                                         , const XMLCh* const    text3
  357.                                         , const XMLCh* const    text4)
  358. {
  359.     //
  360.     //  We have to build the string back into the source string, so allocate
  361.     //  a temp string and copy the orignal text to it. We'll then treat the
  362.     //  incoming buffer as a target buffer. Put a janitor on it to make sure
  363.     //  it gets cleaned up.
  364.     //
  365.     XMLCh* orgText = replicate(errText);
  366.     ArrayJanitor<XMLCh> janText(orgText);
  367.     XMLCh* pszSrc = orgText;
  368.     unsigned int curOutInd = 0;
  369.     while (*pszSrc && (curOutInd < maxChars))
  370.     {
  371.         //
  372.         //  Loop until we see a { character. Until we do, just copy chars
  373.         //  from src to target, being sure not to overrun the output buffer.
  374.         //
  375.         while ((*pszSrc != chOpenCurly) && (curOutInd < maxChars))
  376.         {
  377.             if (!*pszSrc)
  378.                 break;
  379.             errText[curOutInd++] = *pszSrc++;
  380.         }
  381.         // If we did not find a curly, then we are done
  382.         if (*pszSrc != chOpenCurly)
  383.             break;
  384.         //
  385.         //  Probe this one to see if it matches our pattern of {x}. If not
  386.         //  then copy over those chars and go back to the first loop.
  387.         //
  388.         if ((*(pszSrc+1) >= chDigit_0)
  389.         &&  (*(pszSrc+1) <= chDigit_3)
  390.         &&  (*(pszSrc+2) == chCloseCurly))
  391.         {
  392.             //
  393.             //  Its one of our guys, so move the source pointer up past the
  394.             //  token we are replacing. First though get out the token number
  395.             //  character.
  396.             //
  397.             XMLCh tokCh = *(pszSrc+1);
  398.             pszSrc += 3;
  399.             // Now copy over the replacement text
  400.             const XMLCh* repText = 0;
  401.             if (tokCh == chDigit_0)
  402.                 repText = text1;
  403.             else if (tokCh == chDigit_1)
  404.                 repText = text2;
  405.             else if (tokCh == chDigit_2)
  406.                 repText = text3;
  407.             else if (tokCh == chDigit_3)
  408.                 repText = text4;
  409.             // If this one is null, copy over a null string
  410.             if (!repText)
  411.                 repText = gNullStr;
  412.             while (*repText && (curOutInd < maxChars))
  413.                 errText[curOutInd++] = *repText++;
  414.         }
  415.          else
  416.         {
  417.             // Escape the curly brace character and continue
  418.             errText[curOutInd++] = *pszSrc++;
  419.         }
  420.     }
  421.     // Copy over a null terminator
  422.     errText[curOutInd] = 0;
  423.     // And return the count of chars we output
  424.     return curOutInd;
  425. }
  426. char* XMLString::replicate(const char* const toRep)
  427. {
  428.     // If a null string, return a null string
  429.     if (!toRep)
  430.         return 0;
  431.     //
  432.     //  Get the len of the source and allocate a new buffer. Make sure to
  433.     //  account for the nul terminator.
  434.     //
  435.     const unsigned int srcLen = strlen(toRep);
  436.     char* ret = new char[srcLen+1];
  437.     // Copy over the text, adjusting for the size of a char
  438.     memcpy(ret, toRep, (srcLen+1) * sizeof(char));
  439.     return ret;
  440. }
  441. char* XMLString::replicate( const char* const    toRep
  442.                           , MemoryManager* const manager)
  443. {
  444.     // If a null string, return a null string
  445.     if (!toRep)
  446.         return 0;
  447.     //
  448.     //  Get the len of the source and allocate a new buffer. Make sure to
  449.     //  account for the nul terminator.
  450.     //
  451.     const unsigned int srcLen = strlen(toRep);
  452.     char* ret = (char*) manager->allocate((srcLen+1) * sizeof(char)); //new char[srcLen+1];
  453.     // Copy over the text, adjusting for the size of a char
  454.     memcpy(ret, toRep, (srcLen+1) * sizeof(char));
  455.     return ret;
  456. }
  457. bool XMLString::startsWith(const char* const toTest, const char* const prefix)
  458. {
  459.     return (strncmp(toTest, prefix, strlen(prefix)) == 0);
  460. }
  461. bool XMLString::startsWithI(const   char* const toTest
  462.                             , const char* const prefix)
  463. {
  464.     return (strnicmp(toTest, prefix, strlen(prefix)) == 0);
  465. }
  466. unsigned int XMLString::stringLen(const char* const src)
  467. {
  468.     return strlen(src);
  469. }
  470. char* XMLString::transcode(const XMLCh* const toTranscode)
  471. {
  472.     return gTranscoder->transcode(toTranscode);
  473. }
  474. char* XMLString::transcode(const XMLCh* const toTranscode,
  475.                            MemoryManager* const manager)
  476. {
  477.     return gTranscoder->transcode(toTranscode, manager);
  478. }
  479. bool XMLString::transcode(  const   XMLCh* const    toTranscode
  480.                             ,       char* const     toFill
  481.                             , const unsigned int    maxChars)
  482. {
  483.     if (!gTranscoder->transcode(toTranscode, toFill, maxChars))
  484.         return false;
  485.     return true;
  486. }
  487. XMLCh* XMLString::transcode(const char* const toTranscode)
  488. {
  489.     return gTranscoder->transcode(toTranscode);
  490. }
  491. XMLCh* XMLString::transcode(const char* const toTranscode,
  492.                             MemoryManager* const manager)
  493. {
  494.     return gTranscoder->transcode(toTranscode, manager);
  495. }
  496. bool XMLString::transcode(  const   char* const     toTranscode
  497.                             ,       XMLCh* const    toFill
  498.                             , const unsigned int    maxChars)
  499. {
  500.     if (!gTranscoder->transcode(toTranscode, toFill, maxChars))
  501.         return false;
  502.     return true;
  503. }
  504. void XMLString::trim(char* const toTrim)
  505. {
  506.     const unsigned int len = strlen(toTrim);
  507.     unsigned int skip, scrape;
  508.     for (skip = 0; skip < len; skip++)
  509.     {
  510.         if (! isspace(toTrim[skip]))
  511.             break;
  512.     }
  513.     for (scrape = len; scrape > skip; scrape--)
  514.     {
  515.         if (! isspace(toTrim[scrape - 1] ))
  516.             break;
  517.     }
  518.     // Cap off at the scrap point
  519.     if (scrape != len)
  520.         toTrim[scrape] = 0;
  521.     if (skip)
  522.     {
  523.         // Copy the chars down
  524.         unsigned int index = 0;
  525.         while (toTrim[skip])
  526.             toTrim[index++] = toTrim[skip++];
  527.         toTrim[index] = 0;
  528.     }
  529. }
  530. void XMLString::subString(char* const targetStr, const char* const srcStr
  531.                           , const int startIndex, const int endIndex)
  532. {
  533.     if (targetStr == 0)
  534.         ThrowXML(IllegalArgumentException, XMLExcepts::Str_ZeroSizedTargetBuf);
  535.     const int srcLen = strlen(srcStr);
  536.     const int copySize = endIndex - startIndex;
  537.     // Make sure the start index is within the XMLString bounds
  538.     if ( startIndex < 0 || startIndex > endIndex || endIndex > srcLen)
  539.         ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
  540.     for (int i= startIndex; i < endIndex; i++) {
  541.         targetStr[i-startIndex] = srcStr[i];
  542.     }
  543.     targetStr[copySize] = 0;
  544. }
  545. /**
  546.   * Deprecated: isValidNCName
  547.   *    Check first char, and then the rest of the name char.
  548.   *    But colon should be excluded
  549.   */
  550. bool XMLString::isValidNCName(const XMLCh* const name) {
  551.     return XMLChar1_0::isValidNCName(name, XMLString::stringLen(name));
  552. }
  553. /**
  554.   * Deprecated: isValidName
  555.   *    Check first char, and then the rest of the name char
  556.   *
  557.   */
  558. bool XMLString::isValidName(const XMLCh* const name) {
  559.     return XMLChar1_0::isValidName(name, XMLString::stringLen(name));
  560. }
  561. /**
  562.   * isValidEncName
  563.   *
  564.   * [80] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
  565.   *
  566.   */
  567. bool XMLString::isValidEncName(const XMLCh* const name)
  568. {
  569.     if ( XMLString::stringLen(name) == 0 )
  570.         return false;
  571.     const XMLCh* tempName = name;
  572.     XMLCh firstChar = *tempName++;
  573.     if (!isAlpha(firstChar))
  574.         return false;
  575.     while(*tempName)
  576.     {
  577.         if (( !isAlpha(*tempName))       &&
  578.             ( !isDigit(*tempName))       &&
  579.             ( *tempName != chPeriod)     &&
  580.             ( *tempName != chUnderscore) &&
  581.             ( *tempName != chDash)        )
  582.             return false;
  583.         tempName++;
  584.     }
  585.     return true;
  586. }
  587. /**
  588.   * Deprecated: isValidQName
  589.   *
  590.   */
  591. bool XMLString::isValidQName(const XMLCh* const name)
  592. {
  593.     return XMLChar1_0::isValidQName(name, XMLString::stringLen(name));
  594. }
  595. bool XMLString::isAlpha(XMLCh const theChar)
  596. {
  597.     if ((( theChar >= chLatin_a ) && ( theChar <= chLatin_z )) ||
  598.         (( theChar >= chLatin_A ) && ( theChar <= chLatin_Z )) )
  599.         return true;
  600.     return false;
  601. }
  602. bool XMLString::isDigit(XMLCh const theChar)
  603. {
  604.     if (( theChar >= chDigit_0 ) && ( theChar <= chDigit_9 ))
  605.         return true;
  606.     return false;
  607. }
  608. bool XMLString::isAlphaNum(XMLCh const theChar)
  609. {
  610.     return (isAlpha(theChar) || isDigit(theChar));
  611. }
  612. bool XMLString::isHex(XMLCh const theChar)
  613. {
  614. return (isDigit(theChar) ||
  615. (theChar >= chLatin_a && theChar <= chLatin_f) ||
  616. (theChar >= chLatin_A && theChar <= chLatin_F));
  617. }
  618. // Deprecated
  619. bool XMLString::isAllWhiteSpace(const XMLCh* const toCheck)
  620. {
  621.     return XMLChar1_0::isAllSpaces(toCheck, XMLString::stringLen(toCheck));
  622. }
  623. // ---------------------------------------------------------------------------
  624. //  Wide char versions of most of the string methods
  625. // ---------------------------------------------------------------------------
  626. void XMLString::binToText(  const   unsigned long   toFormat
  627.                             ,       XMLCh* const    toFill
  628.                             , const unsigned int    maxChars
  629.                             , const unsigned int    radix)
  630. {
  631.     static const XMLCh digitList[16] =
  632.     {
  633.             chDigit_0, chDigit_1, chDigit_2, chDigit_3, chDigit_4, chDigit_5
  634.         ,   chDigit_6, chDigit_7, chDigit_8, chDigit_9, chLatin_A, chLatin_B
  635.         ,   chLatin_C, chLatin_D, chLatin_e, chLatin_F
  636.     };
  637.     if (!maxChars)
  638.         ThrowXML(IllegalArgumentException, XMLExcepts::Str_ZeroSizedTargetBuf);
  639.     // Handle special case
  640.     if (!toFormat)
  641.     {
  642.         toFill[0] = chDigit_0;
  643.         toFill[1] = chNull;
  644.         return;
  645.     }
  646.     // This is used to fill the temp buffer
  647.     unsigned int tmpIndex = 0;
  648.     // A copy of the conversion value that we can modify
  649.     unsigned int tmpVal = toFormat;
  650.     //
  651.     //  Convert into a temp buffer that we know is large enough. This avoids
  652.     //  having to check for overflow in the inner loops, and we have to flip
  653.     //  the resulting sring anyway.
  654.     //
  655.     XMLCh tmpBuf[128];
  656.     //
  657.     //  For each radix, do the optimal thing. For bin and hex, we can special
  658.     //  case them and do shift and mask oriented stuff. For oct and decimal
  659.     //  there isn't much to do but bull through it with divides.
  660.     //
  661.     if (radix == 2)
  662.     {
  663.         while (tmpVal)
  664.         {
  665.             if (tmpVal & 0x1UL)
  666.                 tmpBuf[tmpIndex++] = chDigit_1;
  667.             else
  668.                 tmpBuf[tmpIndex++] = chDigit_0;
  669.             tmpVal >>= 1;
  670.         }
  671.     }
  672.      else if (radix == 16)
  673.     {
  674.         while (tmpVal)
  675.         {
  676.             const unsigned int charInd = (tmpVal & 0xFUL);
  677.             tmpBuf[tmpIndex++] = digitList[charInd];
  678.             tmpVal >>= 4;
  679.         }
  680.     }
  681.      else if ((radix == 8) || (radix == 10))
  682.     {
  683.         while (tmpVal)
  684.         {
  685.             const unsigned int charInd = (tmpVal % radix);
  686.             tmpBuf[tmpIndex++] = digitList[charInd];
  687.             tmpVal /= radix;
  688.         }
  689.     }
  690.      else
  691.     {
  692.         ThrowXML(RuntimeException, XMLExcepts::Str_UnknownRadix);
  693.     }
  694.     // See if have enough room in the caller's buffer
  695.     if (tmpIndex > maxChars)
  696.         ThrowXML(IllegalArgumentException, XMLExcepts::Str_TargetBufTooSmall);
  697.     // Reverse the tmp buffer into the caller's buffer
  698.     unsigned int outIndex = 0;
  699.     for (; tmpIndex > 0; tmpIndex--)
  700.         toFill[outIndex++] = tmpBuf[tmpIndex-1];
  701.     // And cap off the caller's buffer
  702.     toFill[outIndex] = chNull;
  703. }
  704. void XMLString::binToText(  const   unsigned int    toFormat
  705.                             ,       XMLCh* const    toFill
  706.                             , const unsigned int    maxChars
  707.                             , const unsigned int    radix)
  708. {
  709.     // Just call the unsigned long version
  710.     binToText((unsigned long)toFormat, toFill, maxChars, radix);
  711. }
  712. void XMLString::binToText(  const   long            toFormat
  713.                             ,       XMLCh* const    toFill
  714.                             , const unsigned int    maxChars
  715.                             , const unsigned int    radix)
  716. {
  717.     //
  718.     //  If its negative, then put a negative sign into the output and flip
  719.     //  the sign of the local temp value.
  720.     //
  721.     unsigned int startInd = 0;
  722.     unsigned long actualVal;
  723.     if (toFormat < 0)
  724.     {
  725.         toFill[0] = chDash;
  726.         startInd++;
  727.         actualVal = (unsigned long)(toFormat * -1);
  728.     }
  729.      else
  730.     {
  731.         actualVal = (unsigned long)(toFormat);
  732.     }
  733.     // And now call the unsigned long version
  734.     binToText(actualVal, &toFill[startInd], maxChars, radix);
  735. }
  736. void XMLString::binToText(  const   int             toFormat
  737.                             ,       XMLCh* const    toFill
  738.                             , const unsigned int    maxChars
  739.                             , const unsigned int    radix)
  740. {
  741.     //
  742.     //  If its negative, then put a negative sign into the output and flip
  743.     //  the sign of the local temp value.
  744.     //
  745.     unsigned int startInd = 0;
  746.     unsigned long actualVal;
  747.     if (toFormat < 0)
  748.     {
  749.         toFill[0] = chDash;
  750.         startInd++;
  751.         actualVal = (unsigned long)(toFormat * -1);
  752.     }
  753.      else
  754.     {
  755.         actualVal = (unsigned long)(toFormat);
  756.     }
  757.     // And now call the unsigned long version
  758.     binToText(actualVal, &toFill[startInd], maxChars, radix);
  759. }
  760. void XMLString::catString(XMLCh* const target, const XMLCh* const src)
  761. {
  762.     // Get the starting point for the cat on the target XMLString
  763.     unsigned int index = stringLen(target);
  764.     // While the source is not zero, add them to target and bump
  765.     const XMLCh* pszTmp = src;
  766.     while (*pszTmp)
  767.         target[index++] = *pszTmp++;
  768.     // Cap off the target where we ended
  769.     target[index] = chNull;
  770. }
  771. int XMLString::compareIString(  const   XMLCh* const    str1
  772.                                 , const XMLCh* const    str2)
  773. {
  774.     // Refer this one to the transcoding service
  775.     return XMLPlatformUtils::fgTransService->compareIString(str1, str2);
  776. }
  777. int XMLString::compareNString(  const   XMLCh* const    str1
  778.                                 , const XMLCh* const    str2
  779.                                 , const unsigned int    maxChars)
  780. {
  781.     const XMLCh* psz1 = str1;
  782.     const XMLCh* psz2 = str2;
  783.     unsigned int curCount = 0;
  784.     while (true)
  785.     {
  786.         // If an inequality, then return difference
  787.         if (*psz1 != *psz2)
  788.             return int(*psz1) - int(*psz2);
  789.         // If either ended, then both ended, so equal
  790.         if (!*psz1)
  791.             break;
  792.         // Move upwards to next chars
  793.         psz1++;
  794.         psz2++;
  795.         //
  796.         //  Bump the count of chars done. If it equals the max then we are
  797.         //  equal for the requested count, so break out and return equal.
  798.         //
  799.         curCount++;
  800.         if (curCount == maxChars)
  801.             break;
  802.     }
  803.     return 0;
  804. }
  805. int XMLString::compareNIString( const   XMLCh* const    str1
  806.                                 , const XMLCh* const    str2
  807.                                 , const unsigned int    maxChars)
  808. {
  809.     // Refer this oneto the transcoding service
  810.     return XMLPlatformUtils::fgTransService->compareNIString(str1, str2, maxChars);
  811. }
  812. int XMLString::compareString(   const   XMLCh* const    str1
  813.                                 , const XMLCh* const    str2)
  814. {
  815.     const XMLCh* psz1 = str1;
  816.     const XMLCh* psz2 = str2;
  817.     if (psz1 == 0 || psz2 == 0) {
  818.         if (psz1 == 0) {
  819.             return 0 - XMLString::stringLen(psz2);
  820.         }
  821. else if (psz2 == 0) {
  822.             return XMLString::stringLen(psz1);
  823.         }
  824.     }
  825.     while (true)
  826.     {
  827.         // If an inequality, then return the difference
  828.         if (*psz1 != *psz2)
  829.             return int(*psz1) - int(*psz2);
  830.         // If either has ended, then they both ended, so equal
  831.         if (!*psz1)
  832.             break;
  833.         // Move upwards for the next round
  834.         psz1++;
  835.         psz2++;
  836.     }
  837.     return 0;
  838. }
  839. bool XMLString::regionMatches(const   XMLCh* const str1
  840.   , const int offset1
  841.   , const XMLCh* const str2
  842.   , const int offset2
  843.   , const unsigned int charCount)
  844. {
  845. if (!validateRegion(str1, offset1,str2, offset2, charCount))
  846. return false;
  847. if (compareNString(str1+offset1, str2+offset2, charCount) != 0)
  848. return false;
  849. return true;
  850. }
  851. bool XMLString::regionIMatches(const   XMLCh* const str1
  852.      , const int offset1
  853.    , const XMLCh* const str2
  854.    , const int offset2
  855.    , const unsigned int charCount)
  856. {
  857. if (!validateRegion(str1, offset1,str2, offset2, charCount))
  858. return false;
  859. if (compareNIString(str1+offset1, str2+offset2, charCount) != 0)
  860. return false;
  861. return true;
  862. }
  863. void XMLString::copyString(XMLCh* const target, const XMLCh* const src)
  864. {
  865.     if (!src)
  866.     {
  867.         *target = 0;
  868.         return;
  869.     }
  870.     XMLCh* pszOut = target;
  871.     const XMLCh* pszIn = src;
  872.     while (*pszIn)
  873.         *pszOut++ = *pszIn++;
  874.     // Capp off the target where we ended
  875.     *pszOut = 0;
  876. }
  877. bool XMLString::copyNString(        XMLCh* const    target
  878.                             , const XMLCh* const    src
  879.                             , const unsigned int    maxChars)
  880. {
  881.     XMLCh* outPtr = target;
  882.     const XMLCh* srcPtr = src;
  883.     const XMLCh* endPtr = target + maxChars - 1;
  884.     while (*srcPtr && (outPtr <= endPtr))
  885.         *outPtr++ = *srcPtr++;
  886.     // Cap it off here
  887.     *outPtr = 0;
  888.     // Return whether we copied it all or hit the max
  889.     return (*srcPtr == 0);
  890. }
  891. unsigned int XMLString::hash(   const   XMLCh* const    tohash
  892.                                 , const unsigned int    hashModulus)
  893. {
  894.     if (!hashModulus)
  895.         ThrowXML(IllegalArgumentException, XMLExcepts::Pool_ZeroModulus);
  896.     unsigned int hashVal = 0;
  897.     if (tohash) {
  898.         const XMLCh* curCh = tohash;
  899.         while (*curCh)
  900.         {
  901.             unsigned int top = hashVal >> 24;
  902.             hashVal += (hashVal * 37) + top + (unsigned int)(*curCh);
  903.             curCh++;
  904.         }
  905.     }
  906.     // Divide by modulus
  907.     return hashVal % hashModulus;
  908. }
  909. const XMLCh* XMLString::findAny(const   XMLCh* const    toSearch
  910.                                 , const XMLCh* const    searchList)
  911. {
  912.     const XMLCh* srcPtr = toSearch;
  913.     while (*srcPtr)
  914.     {
  915.         const XMLCh* listPtr = searchList;
  916.         const XMLCh  curCh = *srcPtr;
  917.         while (*listPtr)
  918.         {
  919.             if (curCh == *listPtr++)
  920.                 return srcPtr;
  921.         }
  922.         srcPtr++;
  923.     }
  924.     return 0;
  925. }
  926. XMLCh* XMLString::findAny(          XMLCh* const    toSearch
  927.                             , const XMLCh* const    searchList)
  928. {
  929.     XMLCh* srcPtr = toSearch;
  930.     while (*srcPtr)
  931.     {
  932.         const XMLCh* listPtr = searchList;
  933.         const XMLCh  curCh = *srcPtr;
  934.         while (*listPtr)
  935.         {
  936.             if (curCh == *listPtr++)
  937.                 return srcPtr;
  938.         }
  939.         srcPtr++;
  940.     }
  941.     return 0;
  942. }
  943. int XMLString::patternMatch(  const XMLCh* const    toSearch
  944.                             , const XMLCh* const    pattern)
  945. {
  946.     if (!toSearch || !*toSearch )
  947.         return -1;
  948.     const int patnLen = XMLString::stringLen(pattern);
  949. if ( !patnLen )
  950. return -1;
  951.     const XMLCh* srcPtr    = toSearch;
  952.     const XMLCh* patnStart = toSearch;
  953.     int  patnIndex = 0;
  954.     while (*srcPtr)
  955.     {
  956.         if ( !(*srcPtr++ == pattern[patnIndex++]))
  957.         {
  958.             patnIndex = 0;
  959.             srcPtr = ++patnStart;
  960.         }
  961.         else
  962.         {
  963.             if (patnIndex == patnLen)
  964.                 // full pattern match found
  965.                 return (srcPtr - patnLen - toSearch);
  966.         }
  967.     }
  968.     return -1;
  969. }
  970. unsigned int XMLString::hashN(  const   XMLCh* const    tohash
  971.                                 , const unsigned int    n
  972.                                 , const unsigned int    hashModulus)
  973. {
  974.     if (!hashModulus)
  975.         ThrowXML(IllegalArgumentException, XMLExcepts::Pool_ZeroModulus);
  976.     unsigned int hashVal = 0;
  977.     if (tohash) {
  978.         const XMLCh* curCh = tohash;
  979.         int i = n;
  980.         while (i--)
  981.         {
  982.             unsigned int top = hashVal >> 24;
  983.             hashVal += (hashVal * 37) + top + (unsigned int)(*curCh);
  984.             curCh++;
  985.         }
  986.     }
  987.     // Divide by modulus
  988.     return hashVal % hashModulus;
  989. }
  990. int XMLString::indexOf(const XMLCh* const toSearch, const XMLCh ch)
  991. {
  992.     if (toSearch)
  993.     {
  994.         const XMLCh* srcPtr = toSearch;
  995.         while (*srcPtr)
  996.         {
  997.             if (ch == *srcPtr)
  998.                 return (int)(srcPtr - toSearch);
  999.             srcPtr++;
  1000.         }
  1001.     }
  1002.     return -1;
  1003. }
  1004. int XMLString::indexOf( const   XMLCh* const    toSearch
  1005.                         , const XMLCh           ch
  1006.                         , const unsigned int    fromIndex)
  1007. {
  1008.     const int len = stringLen(toSearch);
  1009.     // Make sure the start index is within the XMLString bounds
  1010. if ((int)fromIndex > len-1)
  1011.         ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
  1012.     for (int i = (int)fromIndex; i < len; i++)
  1013.     {
  1014.         if (toSearch[i] == ch)
  1015.             return i;
  1016.     }
  1017.     return -1;
  1018. }
  1019. int XMLString::lastIndexOf(const XMLCh* const toSearch, const XMLCh ch)
  1020. {
  1021.     const int len = stringLen(toSearch);
  1022.     for (int i = len-1; i >= 0; i--)
  1023.     {
  1024.         if (toSearch[i] == ch)
  1025.             return i;
  1026.     }
  1027.     return -1;
  1028. }
  1029. int XMLString::lastIndexOf( const   XMLCh* const    toSearch
  1030.                             , const XMLCh           ch
  1031.                             , const unsigned int    fromIndex)
  1032. {
  1033.     const int len = stringLen(toSearch);
  1034. if ((int)fromIndex > len-1)
  1035.         ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
  1036.     for (int i = (int)fromIndex; i >= 0; i--)
  1037.     {
  1038.         if (toSearch[i] == ch)
  1039.             return i;
  1040.     }
  1041.     return -1;
  1042. }
  1043. XMLCh*
  1044. XMLString::makeUName(const XMLCh* const pszURI, const XMLCh* const pszName)
  1045. {
  1046.     //
  1047.     //  If there is a URI, then format out the full name in the {uri}name
  1048.     //  form. Otherwise, just set it to the same thing as the base name.
  1049.     //
  1050.     XMLCh* pszRet = 0;
  1051.     const unsigned int uriLen = stringLen(pszURI);
  1052.     if (uriLen)
  1053.     {
  1054.         pszRet = new XMLCh[uriLen + stringLen(pszName) + 3];
  1055.         XMLCh szTmp[2];
  1056.         szTmp[1] = 0;
  1057.         szTmp[0] = chOpenCurly;
  1058.         copyString(pszRet, szTmp);
  1059.         catString(pszRet, pszURI);
  1060.         szTmp[0] = chCloseCurly;
  1061.         catString(pszRet, szTmp);
  1062.         catString(pszRet, pszName);
  1063.     }
  1064.      else
  1065.     {
  1066.         pszRet = replicate(pszName);
  1067.     }
  1068.     return pszRet;
  1069. }
  1070. bool XMLString::textToBin(const XMLCh* const toConvert, unsigned int& toFill)
  1071. {
  1072.     toFill = 0;
  1073.     // If no string, then its a failure
  1074.     if ((!toConvert) || (!*toConvert))
  1075.         return false;
  1076. XMLCh* trimmedStr = XMLString::replicate(toConvert);
  1077. ArrayJanitor<XMLCh> jan1(trimmedStr);
  1078. XMLString::trim(trimmedStr);
  1079.     unsigned int trimmedStrLen = XMLString::stringLen(trimmedStr);
  1080. if ( !trimmedStrLen )
  1081. return false;
  1082. // we don't allow '-' sign
  1083. if (XMLString::indexOf(trimmedStr, chDash, 0) != -1)
  1084. return false;
  1085. //the errno set by previous run is NOT automatically cleared
  1086. errno = 0;
  1087. char *nptr = XMLString::transcode(trimmedStr);
  1088.     ArrayJanitor<char> jan2(nptr);
  1089.     char *endptr;
  1090.  //
  1091.      // REVISIT: conversion of (unsigned long) to (unsigned int)
  1092.  //          may truncate value on IA64
  1093.     toFill = (unsigned int) strtoul(nptr, &endptr, 10);
  1094. // check if all chars are valid char
  1095. // check if overflow/underflow occurs
  1096. if ( ( (endptr - nptr) != (int) trimmedStrLen) ||
  1097.          (errno == ERANGE)                      )
  1098. return false;
  1099.     return true;
  1100. }
  1101. int XMLString::parseInt(const XMLCh* const toConvert)
  1102. {
  1103.     // If no string, or empty string, then it is a failure
  1104.     if ((!toConvert) || (!*toConvert))
  1105.         ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_null_ptr);
  1106. XMLCh* trimmedStr = XMLString::replicate(toConvert);
  1107. ArrayJanitor<XMLCh> jan1(trimmedStr);
  1108. XMLString::trim(trimmedStr);
  1109.     unsigned int trimmedStrLen = XMLString::stringLen(trimmedStr);
  1110. if ( !trimmedStrLen )
  1111.         ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_null_ptr);
  1112. //the errno set by previous run is NOT automatically cleared
  1113. errno = 0;
  1114. char *nptr = XMLString::transcode(trimmedStr);
  1115.     ArrayJanitor<char> jan2(nptr);
  1116.     char *endptr;
  1117.     long retVal = strtol(nptr, &endptr, 10);
  1118. // check if all chars are valid char
  1119. if ( (endptr - nptr) != (int) trimmedStrLen)
  1120. ThrowXML(NumberFormatException, XMLExcepts::XMLNUM_Inv_chars);
  1121. // check if overflow/underflow occurs
  1122.     if (errno == ERANGE)
  1123.         ThrowXML(NumberFormatException, XMLExcepts::Str_ConvertOverflow);
  1124.  //
  1125.      // REVISIT: conversion of (long) to (int)
  1126.  //          may truncate value on IA64
  1127. return (int) retVal;
  1128. }
  1129. void XMLString::trim(XMLCh* const toTrim)
  1130. {
  1131.     const unsigned int len = stringLen(toTrim);
  1132.     unsigned int skip, scrape;
  1133.     for (skip = 0; skip < len; skip++)
  1134.     {
  1135.         if (!XMLPlatformUtils::fgTransService->isSpace(toTrim[skip]))
  1136.             break;
  1137.     }
  1138.     for (scrape = len; scrape > skip; scrape--)
  1139.     {
  1140.         if (!XMLPlatformUtils::fgTransService->isSpace(toTrim[scrape - 1]))
  1141.             break;
  1142.     }
  1143.     // Cap off at the scrap point
  1144.     if (scrape != len)
  1145.         toTrim[scrape] = 0;
  1146.     if (skip)
  1147.     {
  1148.         // Copy the chars down
  1149.         unsigned int index = 0;
  1150.         while (toTrim[skip])
  1151.             toTrim[index++] = toTrim[skip++];
  1152.         toTrim[index] = 0;
  1153.     }
  1154. }
  1155. void XMLString::upperCase(XMLCh* const toUpperCase)
  1156. {
  1157.     // Refer this one to the transcoding service
  1158.     XMLPlatformUtils::fgTransService->upperCase(toUpperCase);
  1159. }
  1160. void XMLString::lowerCase(XMLCh* const toLowerCase)
  1161. {
  1162.     // Refer this one to the transcoding service
  1163.     XMLPlatformUtils::fgTransService->lowerCase(toLowerCase);
  1164. }
  1165. void XMLString::subString(XMLCh* const targetStr, const XMLCh* const srcStr
  1166.                           , const int startIndex, const int endIndex)
  1167. {
  1168.     //if (startIndex < 0 || endIndex < 0)
  1169.     //    ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_NegativeIndex);
  1170.     if (targetStr == 0)
  1171.         ThrowXML(IllegalArgumentException, XMLExcepts::Str_ZeroSizedTargetBuf);
  1172.     const int srcLen = stringLen(srcStr);
  1173.     const int copySize = endIndex - startIndex;
  1174.     // Make sure the start index is within the XMLString bounds
  1175.     if ( startIndex < 0 || startIndex > endIndex || endIndex > srcLen)
  1176.         ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd);
  1177.     for (int i= startIndex; i < endIndex; i++) {
  1178.         targetStr[i-startIndex] = srcStr[i];
  1179.     }
  1180.     targetStr[copySize] = 0;
  1181. }
  1182. BaseRefVectorOf<XMLCh>* XMLString::tokenizeString(const XMLCh* const tokenizeSrc)
  1183. {
  1184.     XMLCh* orgText = replicate(tokenizeSrc, fgMemoryManager);
  1185.     ArrayJanitor<XMLCh> janText(orgText, fgMemoryManager);
  1186.     XMLCh* tokenizeStr = orgText;
  1187.     RefArrayVectorOf<XMLCh>* tokenStack = new RefArrayVectorOf<XMLCh>(16, true);
  1188.     unsigned int len = stringLen(tokenizeStr);
  1189.     unsigned int skip;
  1190.     unsigned int index = 0;
  1191.     while (index != len) {
  1192.         // find the first non-space character
  1193.         for (skip = index; skip < len; skip++)
  1194.         {
  1195.             if (!XMLPlatformUtils::fgTransService->isSpace(tokenizeStr[skip]))
  1196.                 break;
  1197.         }
  1198.         index = skip;
  1199.         // find the delimiter (space character)
  1200.         for (; skip < len; skip++)
  1201.         {
  1202.             if (XMLPlatformUtils::fgTransService->isSpace(tokenizeStr[skip]))
  1203.                 break;
  1204.         }
  1205.         // we reached the end of the string
  1206.         if (skip == index)
  1207.             break;
  1208.         // these tokens are adopted in the RefVector and will be deleted
  1209.         // when the vector is deleted by the caller
  1210.         XMLCh* token = (XMLCh*) fgMemoryManager->allocate
  1211.         (
  1212.             (skip+1-index) * sizeof(XMLCh)
  1213.         );//new XMLCh[skip+1-index];
  1214.         XMLString::subString(token, tokenizeStr, index, skip);
  1215.         tokenStack->addElement(token);
  1216.         index = skip;
  1217.     }
  1218.     return tokenStack;
  1219. }
  1220. //
  1221. //  This method is called when we get a notation or enumeration type attribute
  1222. //  to validate. We have to confirm that the passed value to find is one of
  1223. //  the values in the passed list. The list is a space separated string of
  1224. //  values to match against.
  1225. //
  1226. bool XMLString::isInList(const XMLCh* const toFind, const XMLCh* const enumList)
  1227. {
  1228.     //
  1229.     //  We loop through the values in the list via this outer loop. We end
  1230.     //  when we hit the end of the enum list or get a match.
  1231.     //
  1232.     const XMLCh* listPtr = enumList;
  1233.     const unsigned int findLen = XMLString::stringLen(toFind);
  1234.     while (*listPtr)
  1235.     {
  1236.         unsigned int testInd;
  1237.         for (testInd = 0; testInd < findLen; testInd++)
  1238.         {
  1239.             //
  1240.             //  If they don't match, then reset and try again. Note that
  1241.             //  hitting the end of the current item will cause a mismatch
  1242.             //  because there can be no spaces in the toFind string.
  1243.             //
  1244.             if (listPtr[testInd] != toFind[testInd])
  1245.                 break;
  1246.         }
  1247.         //
  1248.         //  If we went the distance, see if we matched. If we did, the current
  1249.         //  list character has to be null or space.
  1250.         //
  1251.         if (testInd == findLen)
  1252.         {
  1253.             if ((listPtr[testInd] == chSpace) || !listPtr[testInd])
  1254.                 return true;
  1255.         }
  1256.         // Run the list pointer up to the next substring
  1257.         while ((*listPtr != chSpace) && *listPtr)
  1258.             listPtr++;
  1259.         // If we hit the end, then we failed
  1260.         if (!*listPtr)
  1261.             return false;
  1262.         // Else move past the space and try again
  1263.         listPtr++;
  1264.     }
  1265.     // We never found it
  1266.     return false;
  1267. }
  1268. //
  1269. // a string is whitespace:replaced, is having no
  1270. //    #xD  Carriage Return
  1271. //    #xA  Line Feed
  1272. //    #x9  TAB
  1273. //
  1274. bool XMLString::isWSReplaced(const XMLCh* const toCheck)
  1275. {
  1276.     // If no string, then its a OK
  1277.     if (( !toCheck ) || ( !*toCheck ))
  1278.         return true;
  1279.     const XMLCh* startPtr = toCheck;
  1280.     while ( *startPtr )
  1281.     {
  1282.         if ( ( *startPtr == chCR) ||
  1283.              ( *startPtr == chLF) ||
  1284.              ( *startPtr == chHTab))
  1285.         return false;
  1286.         startPtr++;
  1287.     }
  1288.     return true;
  1289. }
  1290. //
  1291. //   to replace characters listed below to #x20
  1292. //    #xD  Carriage Return
  1293. //    #xA  Line Feed
  1294. //    #x9  TAB
  1295. //
  1296. void XMLString::replaceWS(XMLCh* const toConvert)
  1297. {
  1298.     int strLen = XMLString::stringLen(toConvert);
  1299.     if (strLen == 0)
  1300.         return;
  1301.     XMLCh* retBuf = (XMLCh*) fgMemoryManager->allocate
  1302.     (
  1303.         (strLen+1) * sizeof(XMLCh)
  1304.     );//new XMLCh[strLen+1];
  1305.     XMLCh* retPtr = &(retBuf[0]);
  1306.     XMLCh* startPtr = toConvert;
  1307.     while ( *startPtr )
  1308.     {
  1309.         if ( ( *startPtr == chCR) ||
  1310.              ( *startPtr == chLF) ||
  1311.              ( *startPtr == chHTab))
  1312.             *retPtr = chSpace;
  1313.         else
  1314.             *retPtr = *startPtr;
  1315.         retPtr++;
  1316.         startPtr++;
  1317.     }
  1318.     retBuf[strLen] = chNull;
  1319.     XMLString::moveChars(toConvert, retBuf, strLen);
  1320.     fgMemoryManager->deallocate(retBuf);//delete[] retBuf;
  1321.     return;
  1322. }
  1323. //
  1324. // a string is whitespace:collapsed, is whitespace::replaced
  1325. // and no
  1326. //    leading space (#x20)
  1327. //    trailing space
  1328. //    no contiguous sequences of spaces
  1329. //
  1330. bool XMLString::isWSCollapsed(const XMLCh* const toCheck)
  1331. {
  1332.     if (( !toCheck ) || ( !*toCheck ))
  1333.         return true;
  1334.     // shall be whitespace::replaced first
  1335.     if ( !isWSReplaced(toCheck) )
  1336.         return false;
  1337.     // no leading or trailing space
  1338.     if ((*toCheck == chSpace) ||
  1339.         (toCheck[XMLString::stringLen(toCheck)-1] == chSpace))
  1340.         return false;
  1341.     const XMLCh* startPtr = toCheck;
  1342.     XMLCh theChar;
  1343.     bool  inSpace = false;
  1344.     while ( (theChar = *startPtr) != 0 )
  1345.     {
  1346.         if ( theChar == chSpace)
  1347.         {
  1348.             if (inSpace)
  1349.                 return false;
  1350.             else
  1351.                 inSpace = true;
  1352.         }
  1353.         else
  1354.             inSpace = false;
  1355.         startPtr++;
  1356.     }
  1357.     return true;
  1358. }
  1359. //
  1360. // no leading and/or trailing spaces
  1361. // no continuous sequences of spaces
  1362. //
  1363. void XMLString::collapseWS(XMLCh* const toConvert)
  1364. {
  1365.     // If no string, then its a failure
  1366.     if (( !toConvert ) || ( !*toConvert ))
  1367.         return;
  1368.     // replace whitespace first
  1369.     replaceWS(toConvert);
  1370.     // remove leading spaces
  1371.     const XMLCh* startPtr = toConvert;
  1372.     while ( *startPtr == chSpace )
  1373.         startPtr++;
  1374.     if (!*startPtr)
  1375.         return;
  1376.     // remove trailing spaces
  1377.     const XMLCh* endPtr = toConvert + stringLen(toConvert);
  1378.     while (*(endPtr - 1) == chSpace)
  1379.         endPtr--;
  1380.     //
  1381.     //  Work through what remains and chop continuous spaces
  1382.     //
  1383.     XMLCh* retBuf = (XMLCh*) fgMemoryManager->allocate
  1384.     (
  1385.         (endPtr - startPtr + 1) * sizeof(XMLCh)
  1386.     );//new XMLCh[endPtr - startPtr + 1];
  1387.     XMLCh* retPtr = &(retBuf[0]);
  1388.     bool  inSpace = false;
  1389.     while (startPtr < endPtr)
  1390.     {
  1391.         if ( *startPtr == chSpace)
  1392.         {
  1393.             if (inSpace)
  1394.             {
  1395.                 //discard it;
  1396.             }
  1397.             else
  1398.             {
  1399.                 inSpace = true;
  1400.                 *retPtr = chSpace;  //copy the first chSpace
  1401.                 retPtr++;
  1402.             }
  1403.         }
  1404.         else
  1405.         {
  1406.             inSpace = false;
  1407.             *retPtr = *startPtr;
  1408.             retPtr++;
  1409.         }
  1410.         startPtr++;
  1411.     }
  1412.     *retPtr = chNull;
  1413.     XMLString::moveChars(toConvert, retBuf, stringLen(retBuf)+1); //copy the last chNull as well
  1414.     fgMemoryManager->deallocate(retBuf);//delete[] retBuf;
  1415.     return;
  1416. }
  1417. //
  1418. // remove whitespace
  1419. //
  1420. void XMLString::removeWS(XMLCh* const toConvert)
  1421. {
  1422.     // If no string, then its a failure
  1423.     if (( !toConvert ) || ( !*toConvert ))
  1424.         return;
  1425.     XMLCh* retBuf = (XMLCh*) fgMemoryManager->allocate
  1426.     (
  1427.         (XMLString::stringLen(toConvert) + 1) * sizeof(XMLCh)
  1428.     );//new XMLCh[ XMLString::stringLen(toConvert) + 1];
  1429.     XMLCh* retPtr = &(retBuf[0]);
  1430.     XMLCh* startPtr = toConvert;
  1431.     while (*startPtr)
  1432.     {
  1433.         if ( ( *startPtr != chCR)    &&
  1434.              ( *startPtr != chLF)    &&
  1435.              ( *startPtr != chHTab)  &&
  1436.              ( *startPtr != chSpace)  )
  1437.         {
  1438.             *retPtr++ = *startPtr;
  1439.         }
  1440.         startPtr++;
  1441.     }
  1442.     *retPtr = chNull;
  1443.     XMLString::moveChars(toConvert, retBuf, stringLen(retBuf)+1); //copy the last chNull as well
  1444.     fgMemoryManager->deallocate(retBuf);//delete[] retBuf;
  1445.     return;
  1446. }
  1447. /**
  1448.  * Fixes a platform dependent absolute path filename to standard URI form.
  1449.  * 1. Windows: fix 'x:' to 'file:///x:' and convert any backslash to forward slash
  1450.  * 2. UNIX: fix '/blah/blahblah' to 'file:///blah/blahblah'
  1451.  */
  1452. void XMLString::fixURI(const XMLCh* const str, XMLCh* const target)
  1453. {
  1454.     if (!str || !*str)
  1455.         return;
  1456.     int colonIdx = XMLString::indexOf(str, chColon);
  1457.     int slashIdx = XMLString::indexOf(str, chForwardSlash);
  1458.     // If starts with a '/' we assume
  1459.     // this is an absolute (UNIX) file path and prefix it with file://
  1460.     if (colonIdx == -1 && XMLString::indexOf(str, chForwardSlash) == 0) {
  1461.         unsigned index = 0;
  1462.         target[index++] = chLatin_f;
  1463.         target[index++] = chLatin_i;
  1464.         target[index++] = chLatin_l;
  1465.         target[index++] = chLatin_e;
  1466.         target[index++] = chColon;
  1467.         target[index++] = chForwardSlash;
  1468.         target[index++] = chForwardSlash;
  1469.         // copy the string
  1470.         const XMLCh* inPtr = str;
  1471.         while (*inPtr)
  1472.             target[index++] = *inPtr++;
  1473.         target[index] = chNull;
  1474.     }
  1475.     else if (colonIdx == 1 && XMLString::isAlpha(*str)) {
  1476.         // If starts with a driver letter 'x:' we assume
  1477.         // this is an absolute (Windows) file path and prefix it with file:///
  1478.         unsigned index = 0;
  1479.         target[index++] = chLatin_f;
  1480.         target[index++] = chLatin_i;
  1481.         target[index++] = chLatin_l;
  1482.         target[index++] = chLatin_e;
  1483.         target[index++] = chColon;
  1484.         target[index++] = chForwardSlash;
  1485.         target[index++] = chForwardSlash;
  1486.         target[index++] = chForwardSlash;
  1487.         // copy the string and fix any backward slash
  1488.         const XMLCh* inPtr = str;
  1489.         while (*inPtr) {
  1490.             if (*inPtr == chYenSign ||
  1491.                 *inPtr == chWonSign ||
  1492.                 *inPtr == chBackSlash)
  1493.                 target[index++] = chForwardSlash;
  1494.             else
  1495.                 target[index++] = *inPtr;
  1496.             inPtr++;
  1497.         }
  1498.         // cap it with null
  1499.         target[index] = chNull;
  1500.     }
  1501.     else {
  1502.         // not specific case, so just copy the string over
  1503.         copyString(target, str);
  1504.     }
  1505. }
  1506. void XMLString::release(char** buf)
  1507. {
  1508.     delete [] *buf;
  1509.     *buf = 0;
  1510. }
  1511. void XMLString::release(XMLCh** buf)
  1512. {
  1513.     delete [] *buf;
  1514.     *buf = 0;
  1515. }
  1516. void XMLString::release(XMLByte** buf)
  1517. {
  1518.     delete [] *buf;
  1519.     *buf = 0;
  1520. }
  1521. // ---------------------------------------------------------------------------
  1522. //  XMLString: Private static methods
  1523. // ---------------------------------------------------------------------------
  1524. void XMLString::initString(XMLLCPTranscoder* const defToUse,
  1525.                            MemoryManager* const manager)
  1526. {
  1527.     // Store away the default transcoder that we are to use
  1528.     gTranscoder = defToUse;
  1529.     // Store memory manager
  1530.     fgMemoryManager = manager;
  1531. }
  1532. void XMLString::termString()
  1533. {
  1534.     // Just clean up our local code page transcoder
  1535.     delete gTranscoder;
  1536.     gTranscoder = 0;
  1537.     // reset memory manager
  1538.     fgMemoryManager = 0;
  1539. }
  1540. XERCES_CPP_NAMESPACE_END