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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001-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) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: RangeToken.cpp,v $
  58.  * Revision 1.8  2003/05/16 21:37:00  knoaman
  59.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  60.  *
  61.  * Revision 1.7  2003/05/15 21:46:47  knoaman
  62.  * Add missing include.
  63.  *
  64.  * Revision 1.6  2002/11/04 15:17:00  tng
  65.  * C++ Namespace Support.
  66.  *
  67.  * Revision 1.5  2002/10/15 18:15:02  knoaman
  68.  * [Bug 13490]: - new[]/delete mismatch in RangeToken.cpp
  69.  *
  70.  * Revision 1.4  2002/05/27 11:46:53  tng
  71.  * Fix compilation error.  The definition should match declaration.
  72.  *
  73.  * Revision 1.3  2002/05/24 16:42:20  knoaman
  74.  * Performance fixes: eliminate mulitple calls to addRange and sort.
  75.  *
  76.  * Revision 1.2  2002/03/18 19:29:53  knoaman
  77.  * Change constant names to eliminate possible conflict with user defined ones.
  78.  *
  79.  * Revision 1.1.1.1  2002/02/01 22:22:30  peiyongz
  80.  * sane_include
  81.  *
  82.  * Revision 1.4  2001/05/29 19:39:33  knoaman
  83.  * Typo fix
  84.  *
  85.  * Revision 1.3  2001/05/11 13:26:45  tng
  86.  * Copyright update.
  87.  *
  88.  * Revision 1.2  2001/05/03 18:17:37  knoaman
  89.  * Some design changes:
  90.  * o Changed the TokenFactory from a single static instance, to a
  91.  *    normal class. Each RegularExpression object will have its own
  92.  *    instance of TokenFactory, and that instance will be passed to
  93.  *    other classes that need to use a TokenFactory to create Token
  94.  *    objects (with the exception of RangeTokenMap).
  95.  * o Added a new class RangeTokenMap to map a the different ranges
  96.  *    in a given category to a specific RangeFactory object. In the old
  97.  *    design RangeFactory had dual functionality (act as a Map, and as
  98.  *    a factory for creating RangeToken(s)). The RangeTokenMap will
  99.  *    have its own copy of the TokenFactory. There will be only one
  100.  *    instance of the RangeTokenMap class, and that instance will be
  101.  *    lazily deleted when XPlatformUtils::Terminate is called.
  102.  *
  103.  * Revision 1.1  2001/03/02 19:26:46  knoaman
  104.  * Schema: Regular expression handling part II
  105.  *
  106.  */
  107. // ---------------------------------------------------------------------------
  108. //  Includes
  109. // ---------------------------------------------------------------------------
  110. #include <xercesc/util/regx/RangeToken.hpp>
  111. #include <xercesc/util/regx/TokenFactory.hpp>
  112. #include <xercesc/util/IllegalArgumentException.hpp>
  113. XERCES_CPP_NAMESPACE_BEGIN
  114. // ---------------------------------------------------------------------------
  115. //  Static member data initialization
  116. // ---------------------------------------------------------------------------
  117. const int RangeToken::MAPSIZE = 256;
  118. const unsigned int RangeToken::INITIALSIZE = 16;
  119. // ---------------------------------------------------------------------------
  120. //  RangeToken: Constructors and Destructors
  121. // ---------------------------------------------------------------------------
  122. RangeToken::RangeToken(const unsigned short tokType,
  123.                        MemoryManager* const manager) 
  124.     : Token(tokType)
  125.     , fSorted(false)
  126.     , fCompacted(false)
  127.     , fNonMapIndex(0)
  128.     , fElemCount(0)
  129.     , fMaxCount(INITIALSIZE)
  130.     , fMap(0)
  131.     , fRanges(0)
  132.     , fCaseIToken(0)
  133.     , fMemoryManager(manager)
  134. {
  135. }
  136. RangeToken::~RangeToken() {
  137.     fMemoryManager->deallocate(fMap);//delete [] fMap;
  138.     fMemoryManager->deallocate(fRanges);//delete[] fRanges;
  139. }
  140. // ---------------------------------------------------------------------------
  141. //  RangeToken: Getter methods
  142. // ---------------------------------------------------------------------------
  143. RangeToken* RangeToken::getCaseInsensitiveToken(TokenFactory* const tokFactory) {
  144.     // REVIST
  145.     // We will not build a token with case insenstive ranges
  146.     // For now we will return a copy of ourselves.
  147.     if (fCaseIToken == 0 && tokFactory) {
  148.         bool isNRange = (getTokenType() == T_NRANGE) ? true : false;
  149.         RangeToken* lwrToken = tokFactory->createRange(isNRange);
  150.         lwrToken->mergeRanges(this);
  151.         fCaseIToken = lwrToken;
  152.     }
  153.     return fCaseIToken;
  154. }
  155. // ---------------------------------------------------------------------------
  156. //  RangeToken: Setter methods
  157. // ---------------------------------------------------------------------------
  158. void RangeToken::setRangeValues(XMLInt32* const rangeValues, const unsigned int count)
  159. {
  160.     if (fRanges) {
  161.         if (fMap) {
  162.             fMemoryManager->deallocate(fMap);//delete [] fMap;
  163.             fMap = 0;
  164.         }
  165.         fElemCount = 0;
  166.         fMemoryManager->deallocate(fRanges);//delete [] fRanges;
  167.         fRanges = 0;
  168.     }
  169.     fElemCount = fMaxCount = count;
  170.     fRanges = rangeValues;
  171. }
  172. // ---------------------------------------------------------------------------
  173. //  RangeToken: Range manipulation methods
  174. // ---------------------------------------------------------------------------
  175. void RangeToken::addRange(const XMLInt32 start, const XMLInt32 end) {
  176.     XMLInt32 val1, val2;
  177.     fCaseIToken = 0;
  178.     if (start <= end) {
  179.         val1 = start;
  180.         val2 = end;
  181.     }
  182.     else {
  183.         val1 = end;
  184.         val2 = start;
  185.     }
  186.     if (fRanges == 0) {
  187.         fRanges = (XMLInt32*) fMemoryManager->allocate
  188.         (
  189.             fMaxCount * sizeof(XMLInt32)
  190.         );//new XMLInt32[fMaxCount];
  191.         fRanges[0] = val1;
  192.         fRanges[1] = val2;
  193.         fElemCount = 2;
  194.         fSorted = true;
  195.     }
  196.     else {
  197.         if (fRanges[fElemCount-1] + 1 == val1) {
  198.             fRanges[fElemCount-1] = val2;
  199.             return;
  200.         }
  201.         if (fElemCount + 2 >= fMaxCount) {
  202.             expand(2);
  203.         }
  204.         if (fRanges[fElemCount-1] >= val1)
  205.             fSorted = false;
  206.         fRanges[fElemCount++] = val1;
  207.         fRanges[fElemCount++] = val2;
  208.         if (!fSorted) {
  209.             sortRanges();
  210.         }
  211.     }
  212. }
  213. void RangeToken::sortRanges() {
  214.     if (fSorted || fRanges == 0)
  215.         return;
  216.     for (int i = fElemCount - 4; i >= 0; i -= 2) {
  217.         for (int j = 0; j <= i; j +=2) {
  218.             if (fRanges[j] > fRanges[j + 2]
  219.                 || (fRanges[j]==fRanges[j+2] && fRanges[j+1] > fRanges[j+3])) {
  220.                 XMLInt32 tmpVal = fRanges[j+2];
  221.                 fRanges[j+2] = fRanges[j];
  222.                 fRanges[j] = tmpVal;
  223.                 tmpVal = fRanges[j+3];
  224.                 fRanges[j+3] = fRanges[j+1];
  225.                 fRanges[j+1] = tmpVal;
  226.             }
  227.         }
  228.     }
  229.     fSorted = true;
  230. }
  231. void RangeToken::compactRanges() {
  232.     if (fCompacted || fRanges == 0 || fElemCount <= 2)
  233.         return;
  234.     unsigned int base = 0;
  235.     unsigned int target = 0;
  236.     while (target < fElemCount) {
  237.         if (base != target) {
  238.             fRanges[base] = fRanges[target++];
  239.             fRanges[base+1] = fRanges[target++];
  240.         }
  241.         else
  242.             target += 2;
  243.         XMLInt32 baseEnd = fRanges[base + 1];
  244.         while (target < fElemCount) {
  245.             XMLInt32 startRange = fRanges[target];
  246.             if (baseEnd + 1 < startRange)
  247.                 break;
  248.             XMLInt32 endRange = fRanges[target + 1];
  249.             if (baseEnd + 1 == startRange || baseEnd < endRange) {
  250.                 baseEnd = endRange;
  251.                 fRanges[base+1] = baseEnd;
  252.                 target += 2;
  253.             }
  254.             else if (baseEnd >= endRange) {
  255.                 target += 2;
  256.             }
  257.             else {
  258.                 ThrowXML(RuntimeException, XMLExcepts::Regex_CompactRangesError);
  259.             }
  260.         } // inner while
  261.         base += 2;
  262.     }
  263.     fElemCount = base;
  264.     fCompacted = true;
  265. }
  266. void RangeToken::mergeRanges(const Token *const tok) {
  267.     if (tok->getTokenType() != this->getTokenType())
  268.         ThrowXML(IllegalArgumentException, XMLExcepts::Regex_MergeRangesTypeMismatch);
  269.     RangeToken* rangeTok = (RangeToken *) tok;
  270.     if (rangeTok->fRanges == 0)
  271.         return;
  272.     fCaseIToken = 0;
  273.     sortRanges();
  274.     rangeTok->sortRanges();
  275.     if (fRanges == 0) {
  276.         fMaxCount = rangeTok->fMaxCount;
  277.         fRanges = (XMLInt32*) fMemoryManager->allocate
  278.         (
  279.             fMaxCount * sizeof(XMLInt32)
  280.         );//new XMLInt32[fMaxCount];
  281.         for (unsigned int index = 0; index < rangeTok->fElemCount; index++) {
  282.             fRanges[index] = rangeTok->fRanges[index];
  283.         }
  284.         fElemCount = rangeTok->fElemCount;
  285.         return;
  286.     }
  287.     unsigned int newMaxCount = (fElemCount + rangeTok->fElemCount >= fMaxCount)
  288.                                  ? fMaxCount + rangeTok->fMaxCount : fMaxCount;
  289.     XMLInt32* result = (XMLInt32*) fMemoryManager->allocate
  290.     (
  291.         newMaxCount * sizeof(XMLInt32)
  292.     );//new XMLInt32[newMaxCount];
  293.     for (unsigned int i=0, j=0, k=0; i < fElemCount || j < rangeTok->fElemCount;) {
  294.         if (i >= fElemCount) {
  295.             for (int count = 0; count < 2; count++) {
  296.                 result[k++] = rangeTok->fRanges[j++];
  297.             }
  298.         }
  299.         else if (j >= rangeTok->fElemCount) {
  300.             for (int count = 0; count < 2; count++) {
  301.                 result[k++] = fRanges[i++];
  302.             }
  303.         }
  304.         else if (rangeTok->fRanges[j] < fRanges[i]
  305.                  || (rangeTok->fRanges[j] == fRanges[i]
  306.                      && rangeTok->fRanges[j+1] < fRanges[i+1])) {
  307.             for (int count = 0; count < 2; count++) {
  308.                 result[k++] = rangeTok->fRanges[j++];
  309.             }
  310.         }
  311.         else {
  312.             for (int count = 0; count < 2; count++) {
  313.                 result[k++] = fRanges[i++];
  314.             }
  315.         }
  316.     }
  317.     fMemoryManager->deallocate(fRanges);//delete [] fRanges;
  318.     fElemCount += rangeTok->fElemCount;
  319.     fRanges = result;
  320.     fMaxCount = newMaxCount;
  321. }
  322. void RangeToken::subtractRanges(RangeToken* const tok) {
  323.     if (fRanges == 0 || tok->fRanges == 0)
  324.         return;
  325.     if (tok->getTokenType() == T_NRANGE) {
  326.         intersectRanges(tok);
  327.         return;
  328.     }
  329.     fCaseIToken = 0;
  330.     sortRanges();
  331.     compactRanges();
  332.     tok->sortRanges();
  333.     tok->compactRanges();
  334.     unsigned int newMax = (fElemCount + tok->fElemCount >= fMaxCount)
  335.                              ? fMaxCount + tok->fMaxCount : fMaxCount;
  336.     XMLInt32* result = (XMLInt32*) fMemoryManager->allocate
  337.     (
  338.         newMax * sizeof(XMLInt32)
  339.     );//new XMLInt32[newMax];
  340.     unsigned int newElemCount = 0;
  341.     unsigned int srcCount = 0;
  342.     unsigned int subCount = 0;
  343.     while (srcCount < fElemCount && subCount < tok->fElemCount) {
  344.         XMLInt32 srcBegin = fRanges[srcCount];
  345.         XMLInt32 srcEnd = fRanges[srcCount + 1];
  346.         XMLInt32 subBegin = tok->fRanges[subCount];
  347.         XMLInt32 subEnd = tok->fRanges[subCount + 1];
  348.         if (srcEnd < subBegin) { // no overlap
  349.             result[newElemCount++] = fRanges[srcCount++];
  350.             result[newElemCount++] = fRanges[srcCount++];
  351.         }
  352.         else if (srcEnd >= subBegin && srcBegin <= subEnd) {
  353.             if (subBegin <= srcBegin && srcEnd <= subEnd) {
  354.                 srcCount += 2;
  355.             }
  356.             else if (subBegin <= srcBegin) {
  357.                 fRanges[srcCount] = subEnd + 1;
  358.                 subCount += 2;
  359.             }
  360.             else if (srcEnd <= subEnd) {
  361.                 result[newElemCount++] = srcBegin;
  362.                 result[newElemCount++] = subBegin - 1;
  363.                 srcCount += 2;
  364.             }
  365.             else {
  366.                 result[newElemCount++] = srcBegin;
  367.                 result[newElemCount++] = subBegin - 1;
  368.                 fRanges[srcCount] = subEnd + 1;
  369.                 subCount += 2;
  370.             }
  371.         }
  372.         else if (subEnd < srcBegin) {
  373.             subCount += 2;
  374.         }
  375.         else {
  376.             fMemoryManager->deallocate(result);//delete [] result;
  377.             ThrowXML(RuntimeException, XMLExcepts::Regex_SubtractRangesError);
  378.         }
  379.     } //end while
  380.     while (srcCount < fElemCount) {
  381.         result[newElemCount++] = fRanges[srcCount++];
  382.         result[newElemCount++] = fRanges[srcCount++];
  383.     }
  384.     fMemoryManager->deallocate(fRanges);//delete [] fRanges;
  385.     fRanges = result;
  386.     fElemCount = newElemCount;
  387.     fMaxCount = newMax;
  388. }
  389. /**
  390.   * Ignore whether 'tok' is NRANGE or not.
  391.   */
  392. void RangeToken::intersectRanges(RangeToken* const tok) {
  393.     if (fRanges == 0 || tok->fRanges == 0)
  394.         return;
  395.     fCaseIToken = 0;
  396.     sortRanges();
  397.     compactRanges();
  398.     tok->sortRanges();
  399.     tok->compactRanges();
  400.     unsigned int newMax = (fElemCount + tok->fElemCount >= fMaxCount)
  401.                              ? fMaxCount + tok->fMaxCount : fMaxCount;
  402.     XMLInt32* result = (XMLInt32*) fMemoryManager->allocate
  403.     (
  404.         newMax * sizeof(XMLInt32)
  405.     );//new XMLInt32[newMax];
  406.     unsigned int newElemCount = 0;
  407.     unsigned int srcCount = 0;
  408.     unsigned int tokCount = 0;
  409.     while (srcCount < fElemCount && tokCount < tok->fElemCount) {
  410.         XMLInt32 srcBegin = fRanges[srcCount];
  411.         XMLInt32 srcEnd = fRanges[srcCount + 1];
  412.         XMLInt32 tokBegin = tok->fRanges[tokCount];
  413.         XMLInt32 tokEnd = tok->fRanges[tokCount + 1];
  414.         if (srcEnd < tokBegin) {
  415.             srcCount += 2;
  416.         }
  417.         else if (srcEnd >= tokBegin && srcBegin <= tokEnd) {
  418.             if (tokBegin <= srcBegin && srcEnd <= tokEnd) {
  419.                 result[newElemCount++] = srcBegin;
  420.                 result[newElemCount++] = srcEnd;
  421.                 srcCount += 2;
  422.             }
  423.             else if (tokBegin <= srcBegin) {
  424.                 result[newElemCount++] = srcBegin;
  425.                 result[newElemCount++] = tokEnd;
  426.                 tokCount += 2;
  427.                 if (tokCount < tok->fElemCount)
  428.                     fRanges[srcCount] = tokEnd + 1;
  429.                 else
  430.                     srcCount += 2;
  431.             }
  432.             else if (srcEnd <= tokEnd) {
  433.                 result[newElemCount++] = tokBegin;
  434.                 result[newElemCount++] = srcEnd;
  435.                 srcCount += 2;
  436.             }
  437.             else {
  438.                 result[newElemCount++] = tokBegin;
  439.                 result[newElemCount++] = tokEnd;
  440.                 tokCount += 2;
  441.                 if (tokCount < tok->fElemCount)
  442.                     fRanges[srcCount] = tokEnd + 1;
  443.                 else
  444.                     srcCount += 2;
  445.             }
  446.         }
  447.         else if (tokEnd < srcBegin) {
  448.             tokCount += 2;
  449.             if (tokCount >= tok->fElemCount)
  450.                 srcCount += 2;
  451.         }
  452.         else {
  453.             fMemoryManager->deallocate(result);//delete [] result;
  454.             ThrowXML(RuntimeException, XMLExcepts::Regex_IntersectRangesError);
  455.         }
  456.     } //end while
  457.     fMemoryManager->deallocate(fRanges);//delete [] fRanges;
  458.     fRanges = result;
  459.     fElemCount = newElemCount;
  460.     fMaxCount = newMax;
  461. }
  462. /**
  463.   * for RANGE: Creates complement.
  464.   * for NRANGE: Creates the same meaning RANGE.
  465.   */
  466. Token* RangeToken::complementRanges(RangeToken* const tok,
  467.                                     TokenFactory* const tokFactory) {
  468.     if (tok->getTokenType() != T_RANGE && tok->getTokenType() != T_NRANGE)
  469.         ThrowXML(IllegalArgumentException, XMLExcepts::Regex_ComplementRangesInvalidArg);
  470.     tok->sortRanges();
  471.     tok->compactRanges();
  472.     XMLInt32 lastElem = tok->fRanges[tok->fElemCount - 1];
  473.     RangeToken* rangeTok = tokFactory->createRange();
  474.     if (tok->fRanges[0] > 0) {
  475.         rangeTok->addRange(0, tok->fRanges[0] - 1);
  476.     }
  477.     for (unsigned int i= 1; i< tok->fElemCount - 2; i += 2) {
  478.         rangeTok->addRange(tok->fRanges[i] + 1, tok->fRanges[i+1] - 1);
  479.     }
  480.     if (lastElem != UTF16_MAX) {
  481.         rangeTok->addRange(lastElem + 1, UTF16_MAX);
  482.     }
  483.     rangeTok->fCompacted = true;
  484.     return rangeTok;
  485. }
  486. // ---------------------------------------------------------------------------
  487. //  RangeToken: Match methods
  488. // ---------------------------------------------------------------------------
  489. bool RangeToken::match(const XMLInt32 ch) {
  490.     if (fMap == 0)
  491.         createMap();
  492.     bool ret;
  493.     if (getTokenType() == T_RANGE) {
  494.         if (ch < MAPSIZE)
  495.             return ((fMap[ch/32] & (1<<(ch&0x1f))) != 0);
  496.         ret = false;
  497.         for (unsigned int i= fNonMapIndex; i< fElemCount; i +=2) {
  498.             if (fRanges[i] <= ch && ch <= fRanges[i+1])
  499.                 return true;
  500.         }
  501.     }
  502.     else {
  503.         if (ch < MAPSIZE)
  504.             return ((fMap[ch/32] & (1<<(ch&0x1f))) == 0);
  505.         ret = true;
  506.         for (unsigned int i= fNonMapIndex; i< fElemCount; i += 2) {
  507.             if (fRanges[i] <= ch && ch <= fRanges[i+1])
  508.                 return false;
  509.         }
  510.     }
  511.     return ret;
  512. }
  513. // ---------------------------------------------------------------------------
  514. //  RangeToken: Private helpers methods
  515. // ---------------------------------------------------------------------------
  516. void RangeToken::expand(const unsigned int length) {
  517.     unsigned int newMax = fElemCount + length;
  518.     // Avoid too many reallocations by expanding by a percentage
  519.     unsigned int minNewMax = (unsigned int)((double)fElemCount * 1.25);
  520.     if (newMax < minNewMax)
  521.         newMax = minNewMax;
  522.     XMLInt32* newList = (XMLInt32*) fMemoryManager->allocate
  523.     (
  524.         newMax * sizeof(XMLInt32)
  525.     );//new XMLInt32[newMax];
  526.     for (unsigned int index = 0; index < fElemCount; index++)
  527.         newList[index] = fRanges[index];
  528.     fMemoryManager->deallocate(fRanges);//delete [] fRanges;
  529.     fRanges = newList;
  530.     fMaxCount = newMax;
  531. }
  532. void RangeToken::createMap() {
  533.     int asize = MAPSIZE/32;
  534.     fMap = (int*) fMemoryManager->allocate(asize * sizeof(int));//new int[asize];
  535.     fNonMapIndex = fElemCount;
  536.     for (int i = 0; i < asize; i++) {
  537.         fMap[i] = 0;
  538.     }
  539.     for (unsigned int j= 0; j < fElemCount; j += 2) {
  540.         XMLInt32 begin = fRanges[j];
  541.         XMLInt32 end = fRanges[j+1];
  542.         if (begin < MAPSIZE) {
  543.             for (int k = begin; k <= end && k < MAPSIZE; k++) {
  544.                 fMap[k/32] |= 1<<(k&0x1F);
  545.             }
  546.         }
  547.         else {
  548.             fNonMapIndex = j;
  549.             break;
  550.         }
  551.         if (end >= MAPSIZE) {
  552.             fNonMapIndex = j;
  553.             break;
  554.         }
  555.     }
  556. }
  557. XERCES_CPP_NAMESPACE_END
  558. /**
  559.   * End of file RangeToken.cpp
  560.   */