dbertoni    01/06/14 12:17:28

  Modified:    c/src/XSLT ElemNumber.cpp ElemNumber.hpp
  Log:
  Drastically improved performance.
  
  Revision  Changes    Path
  1.43      +423 -220  xml-xalan/c/src/XSLT/ElemNumber.cpp
  
  Index: ElemNumber.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemNumber.cpp,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- ElemNumber.cpp    2001/03/09 16:20:00     1.42
  +++ ElemNumber.cpp    2001/06/14 19:17:23     1.43
  @@ -217,8 +217,14 @@
   {
        ElemTemplateElement::execute(executionContext);
   
  -     const XalanDOMString    countString = getCountString(executionContext);
  +     typedef XPathExecutionContext::GetAndReleaseCachedString        
GetAndReleaseCachedString;
   
  +     GetAndReleaseCachedString       theGuard(executionContext);
  +
  +     XalanDOMString&                         countString = theGuard.get();
  +
  +     getCountString(executionContext, countString);
  +
        if (!isEmpty(countString))
        {
                executionContext.characters(toCharArray(countString), 0, 
length(countString));
  @@ -314,6 +320,7 @@
                                contextCopy = prevSibling;
                }
        }
  +
        return contextCopy;
   }
   
  @@ -371,15 +378,45 @@
   
   
   
  -XalanDOMString
  -ElemNumber::getCountString(StylesheetExecutionContext&               
executionContext) const
  +inline void
  +ElemNumber::getCountString(
  +                     StylesheetExecutionContext&             
executionContext,
  +                     XalanNode*                                              
sourceNode,
  +                     const MutableNodeRefList&               ancestors,
  +                     CountersTable&                                  ctable,
  +                     int                                                     
        numberList[],
  +                     unsigned int                                    
numberListLength,
  +                     XalanDOMString&                                 
theResult) const
  +{
  +     for(unsigned int i = 0; i < numberListLength; i++)
  +     {
  +             XalanNode* const target = ancestors.item(numberListLength - i - 
1);
  +
  +             numberList[i] = ctable.countNode(
  +                                                     executionContext,
  +                                                     this,
  +                                                     target);
  +     }
  +
  +     formatNumberList(
  +                     executionContext,
  +                     numberList,
  +                     numberListLength,
  +                     sourceNode,
  +                     theResult);
  +}
  +
  +
  +
  +void
  +ElemNumber::getCountString(
  +                     StylesheetExecutionContext&             
executionContext,
  +                     XalanDOMString&                                 
theResult) const
   {
        XalanNode* sourceNode = executionContext.getCurrentNode();
   
        assert(sourceNode != 0);
   
  -     IntArrayType    numberList;
  -
        if(0 != m_valueExpr)
        {
                const XObjectPtr        
countObj(m_valueExpr->execute(sourceNode, *this, executionContext));
  @@ -387,14 +424,19 @@
   
                const double    theValue = countObj->num();
   
  -             if (DoubleSupport::isNaN(theValue) == true)
  -             {
  -                     numberList.push_back(0);
  -             }
  -             else
  +             int     theNumber = 0;
  +
  +             if (DoubleSupport::isNaN(theValue) == false)
                {
  -                     
numberList.push_back(int(DoubleSupport::round(theValue)));
  +                     theNumber = int(DoubleSupport::round(theValue));
                }
  +
  +             formatNumberList(
  +                             executionContext,
  +                             &theNumber,
  +                             1,
  +                             sourceNode,
  +                             theResult);
        }
        else
        {
  @@ -402,34 +444,65 @@
   
                if(Constants::NUMBERLEVEL_ANY == m_level)
                {
  -                     numberList.push_back(ctable.countNode(
  -                                             executionContext, 
  -                                             this,
  -                                             sourceNode));
  +                     const int       theNumber =
  +                             ctable.countNode(executionContext, this, 
sourceNode);
  +
  +                     formatNumberList(
  +                             executionContext,
  +                             &theNumber,
  +                             1,
  +                             sourceNode,
  +                             theResult);
                }
                else
                {
  -                     const MutableNodeRefList        ancestors = 
getMatchingAncestors(executionContext, sourceNode,
  -                             Constants::NUMBERLEVEL_SINGLE == m_level);
  +                     typedef 
XPathExecutionContext::BorrowReturnMutableNodeRefList   
BorrowReturnMutableNodeRefList;
   
  -                     const unsigned int      lastIndex = 
ancestors.getLength();
  +                     BorrowReturnMutableNodeRefList  
ancestors(executionContext);
  +
  +                     getMatchingAncestors(
  +                             executionContext,
  +                             sourceNode,
  +                             Constants::NUMBERLEVEL_SINGLE == m_level,
  +                             *ancestors.get());
   
  +                     const unsigned int      lastIndex = 
ancestors->getLength();
  +
                        if(lastIndex > 0)
                        {
  -                             for(unsigned int i = 0; i < lastIndex; i++)
  +                             const unsigned int      theStackArrayThreshold 
= 100;
  +
  +                             if (lastIndex < theStackArrayThreshold)
                                {
  -                                     XalanNode* const target = 
ancestors.item(lastIndex - i - 1);
  +                                     int             
numberList[theStackArrayThreshold];
   
  -                                     numberList.push_back(ctable.countNode(
  +                                     getCountString(
                                                executionContext,
  -                                             this,
  -                                             target));
  +                                             sourceNode,
  +                                             *ancestors.get(),
  +                                             ctable,
  +                                             numberList,
  +                                             lastIndex,
  +                                             theResult);
                                }
  +                             else
  +                             {
  +                                     IntArrayType    numberList;
  +
  +                                     numberList.resize(lastIndex);
  +
  +                                     getCountString(
  +                                             executionContext,
  +                                             sourceNode,
  +                                             *ancestors.get(),
  +                                             ctable,
  +                                             &*numberList.begin(),
  +                                             lastIndex,
  +                                             theResult);
  +                             }
                        }
                }
        }
  -
  -     return numberList.size() > 0 ? formatNumberList(executionContext, 
numberList, sourceNode) : XalanDOMString();
   }
   
   
  @@ -456,7 +529,7 @@
   
        if(Constants::NUMBERLEVEL_ANY == m_level)
        {
  -             const XPath* fromMatchPattern = m_fromMatchPattern;
  +             const XPath* const      fromMatchPattern = m_fromMatchPattern;
   
                // Do a backwards document-order walk 'till a node is found 
that matches 
                // the 'from' pattern, or a node is found that matches the 
'count' pattern, 
  @@ -467,16 +540,21 @@
                        // then count the parent, but if there is a previous 
sibling, 
                        // dive down to the lowest right-hand (last) child of 
that sibling.
                        XalanNode* next = pos->getPreviousSibling();
  +
                        if(0 == next)
                        {
                                next = pos->getParentNode();
  -                             if((0 != next) && ((((0 != fromMatchPattern) &&
  -                                             
(fromMatchPattern->getMatchScore(next, *this,
  -                                             executionContext) !=
  -                                                                      
XPath::s_MatchScoreNone))) || 
  -                                                     (next->getNodeType() == 
XalanNode::DOCUMENT_NODE)))
  +
  +                             if(0 != next &&
  +                                next->getNodeType() == 
XalanNode::DOCUMENT_NODE ||
  +                                (0 != fromMatchPattern &&
  +                                             fromMatchPattern->getMatchScore(
  +                                                     next,
  +                                                     *this,
  +                                                     executionContext) != 
XPath::s_MatchScoreNone))
                                {
                                        pos = 0; // return 0 from function.
  +
                                        break; // from while loop
                                }
                        }
  @@ -484,19 +562,24 @@
                        {
                                // dive down to the lowest right child.
                                XalanNode* child = next;
  +
                                while(0 != child)
                                {
                                        child = next->getLastChild();
  +
                                        if(0 != child)
                                                next = child;
                                }
                        }
  +
                        pos = next;
   
  -                     if((0 != pos) && ((0 == countMatchPattern) ||
  -                                             
(countMatchPattern->getMatchScore(pos, *this,
  -                                             executionContext) !=
  -                                              XPath::s_MatchScoreNone)))
  +                     if(0 != pos &&
  +                        (0 == countMatchPattern ||
  +                             countMatchPattern->getMatchScore(
  +                                             pos,
  +                                             *this,
  +                                             executionContext) != 
XPath::s_MatchScoreNone))
                        {
                                break;
                        }
  @@ -507,19 +590,24 @@
                while(0 != pos)
                {            
                        pos = pos->getPreviousSibling();
  -                     if((0 != pos) && ((0 == countMatchPattern) ||
  -                                             
(countMatchPattern->getMatchScore(pos, *this,
  -                                             executionContext) !=
  -                                              XPath::s_MatchScoreNone)))
  +
  +                     if(0 != pos &&
  +                        (0 == countMatchPattern ||
  +                             countMatchPattern->getMatchScore(
  +                                             pos,
  +                                             *this,
  +                                             executionContext) != 
XPath::s_MatchScoreNone))
                        {
                                break;
                        }
                }
        }
  +
        return pos;
   }
   
   
  +
   XalanNode*
   ElemNumber::getTargetNode(
                StylesheetExecutionContext&             executionContext,
  @@ -564,23 +652,15 @@
        return target;
   }
   
  +
   
  -/**
  - * Get the ancestors, up to the root, that match the
  - * pattern.
  - * @param patterns if non-0, count only nodes
  - * that match this pattern, if 0 count all ancestors.
  - * @param node Count this node and it's ancestors.
  - * @return The number of ancestors that match the pattern.
  - */
  -MutableNodeRefList
  +void
   ElemNumber::getMatchingAncestors(
  -             StylesheetExecutionContext&             executionContext,
  -             XalanNode* node, 
  -             bool stopAtFirstFound) const
  +                     StylesheetExecutionContext&             
executionContext,
  +                     XalanNode*                                              
node, 
  +                     bool                                                    
stopAtFirstFound,
  +                     MutableNodeRefList&                             
ancestors) const
   {
  -     MutableNodeRefList ancestors;
  -
        // Create an XPathGuard, since we may need to
        // create a new XPath...
        StylesheetExecutionContext::XPathGuard  xpathGuard(
  @@ -596,7 +676,7 @@
                countMatchPattern = xpathGuard.get();
        }
   
  -     while( 0 != node )
  +     while(0 != node)
        {
                if((0 != m_fromMatchPattern) &&
                                (m_fromMatchPattern->getMatchScore(node, *this, 
executionContext) !=
  @@ -619,13 +699,14 @@
                                XPath::s_MatchScoreNone)
                {
                        ancestors.addNode(node);
  +
                        if(stopAtFirstFound)
                                break;
                }
  +
                node = DOMServices::getParentOfNode(*node);
        }
  -     return ancestors;
  -} // end getMatchingAncestors method
  +}
   
   
   
  @@ -636,13 +717,22 @@
   {
       // Helper to format local specific numbers to strings.
        XalanAutoPtr<XalanNumberFormat>         
formatter(executionContext.createXalanNumberFormat());
  +
  +     typedef XPathExecutionContext::GetAndReleaseCachedString        
GetAndReleaseCachedString;
  +
  +     GetAndReleaseCachedString       theGuard1(executionContext);
  +
  +     XalanDOMString&                         digitGroupSepValue = 
theGuard1.get();
   
  -     XalanDOMString  digitGroupSepValue;
        if (0 != m_groupingSeparator_avt)
                 m_groupingSeparator_avt->evaluate(digitGroupSepValue, 
contextNode,
                                 *this, executionContext);
                                                                         
  -     XalanDOMString  nDigitsPerGroupValue;
  +
  +     GetAndReleaseCachedString       theGuard2(executionContext);
  +
  +     XalanDOMString&                         nDigitsPerGroupValue = 
theGuard2.get();
  +
        if (0 != m_groupingSize_avt)
                m_groupingSize_avt->evaluate(nDigitsPerGroupValue, contextNode, 
*this,
                                executionContext);
  @@ -660,69 +750,98 @@
   }
   
   
  -//@@ JMD: this is different from the java version, but seems to work, so I'll
  -//leave it alone
  -XalanDOMString
  +
  +void
   ElemNumber::formatNumberList(
                        StylesheetExecutionContext&             
executionContext,
  -                     const IntArrayType&                             theList,
  -                     XalanNode*                                              
contextNode) const
  +                     const int                                               
theList[],
  +                     unsigned int                                    
theListLength,
  +                     XalanNode*                                              
contextNode,
  +                     XalanDOMString&                                 
theResult) const
   {
  -     const IntArrayType::size_type   nNumbers = theList.size();
  -     XalanDOMChar    numberType(XalanUnicode::charDigit_1);
  -     int                     numberWidth = 1;
  +     assert(theListLength > 0);
   
  -     XalanDOMString  formattedNumber;
  -     XalanDOMString  formatToken;
  -     XalanDOMString  sepString(XALAN_STATIC_UCODE_STRING("."));
  -     XalanDOMString  lastSepString;
  -
        // Pathological cases
  -     if (nNumbers == 0) return formattedNumber;
  -     if (contextNode == 0) return formattedNumber;
  -
  -     XalanDOMString  formatValue;
  -     if (m_format_avt != 0)
  -              m_format_avt->evaluate(formatValue, contextNode, *this, 
executionContext);
  +     if (contextNode == 0) return;
   
  -     if(isEmpty(formatValue)) 
  -             formatValue = XALAN_STATIC_UCODE_STRING("1");
  +     XalanDOMChar    numberType = XalanUnicode::charDigit_1;
   
  -     NumberFormatStringTokenizer             formatTokenizer(formatValue);
  +     int                     numberWidth = 1;
   
        typedef vector<XalanDOMString>          StringVectorType;
        typedef StringVectorType::iterator      StringVectorTypeIterator;
   
        // Construct an array of tokens.  We need to be able to check if the 
last
        // token in non-alphabetic, in which case the penultimate 
non-alphabetic is
  -     // the repeating separator
  -     StringVectorType tokenVector;
  -     while(formatTokenizer.hasMoreTokens())
  -             tokenVector.push_back(formatTokenizer.nextToken());
  -
  -     // Get rid of the leading and trailing non-alphabetics, save for later
  -     XalanDOMString leaderStr;
  -     XalanDOMString trailerStr;
  -     StringVectorTypeIterator it;
  +     // the repeating separator.
  +     //
  +     // We should be able to replace this with a vector of the indexes in
  +     // the evaluated string where the tokens start.  But for now, this will
  +     // have to do...
  +     StringVectorType        tokenVector;
   
  -     if (tokenVector.size() > 0)
        {
  -             it = tokenVector.begin();
  +             typedef XPathExecutionContext::GetAndReleaseCachedString        
GetAndReleaseCachedString;
   
  -             if(!isXMLLetterOrDigit(charAt(*it, 0)))
  +             GetAndReleaseCachedString       theGuard1(executionContext);
  +
  +             XalanDOMString&                         formatValue = 
theGuard1.get();
  +
  +             if (m_format_avt != 0)
  +             {
  +                      m_format_avt->evaluate(formatValue, contextNode, 
*this, executionContext);
  +             }
  +
  +             if(isEmpty(formatValue) == true)
                {
  -                     leaderStr = *it;
  -                     tokenVector.erase(it);
  +                     formatValue = XalanUnicode::charDigit_1;
                }
  +
  +             NumberFormatStringTokenizer             
formatTokenizer(formatValue);
  +
  +             const unsigned int      theTokenCount = 
formatTokenizer.countTokens();
  +
  +             tokenVector.resize(theTokenCount);
   
  -             if (tokenVector.size() > 0)
  +             // Tokenize directly into the vector...
  +             for(unsigned int i = 0; i < theTokenCount; ++i)
                {
  -                     it = tokenVector.end() - 1;
  +                     formatTokenizer.nextToken(tokenVector[i]);
  +             }
  +
  +             assert(theTokenCount == tokenVector.size());
  +     }
   
  -                     if(!isXMLLetterOrDigit(charAt(*it, 0)))
  +     // These are iterators which will either point to tokenVector.end(),
  +     // or the appropriate string in the vector...
  +     StringVectorTypeIterator                leaderStrIt = tokenVector.end();
  +     StringVectorTypeIterator                trailerStrIt = leaderStrIt;
  +     StringVectorTypeIterator                sepStringIt = leaderStrIt;
  +     const StringVectorTypeIterator  endIt = leaderStrIt;
  +
  +     StringVectorTypeIterator        it = tokenVector.begin();
  +
  +     const StringVectorType::size_type       theVectorSize =
  +             tokenVector.size();
  +
  +     if (theVectorSize > 0)
  +     {
  +             if(!isXMLLetterOrDigit(charAt(*it, 0)))
  +             {
  +                     leaderStrIt = it;
  +
  +                     // Move the iterator up one, so it
  +                     // points at the first numbering token...
  +                     ++it;
  +             }
  +
  +             if (theVectorSize > 1)
  +             {
  +                     if(!isXMLLetterOrDigit(charAt(tokenVector.back(), 0)))
                        {
  -                             trailerStr = *it;
  -                             tokenVector.erase(it);
  +                             // Move the iterator back one, so it's pointing
  +                             // at the trailing string...
  +                             --trailerStrIt;
                        }
                }
        }
  @@ -730,35 +849,70 @@
        // Now we're left with a sequence of alpha,non-alpha tokens, format them
        // with the corresponding entry in the format string, or the last one 
if no
        // more matching ones
  -     formattedNumber = leaderStr;
  -     it = tokenVector.begin();
  -     for(unsigned int i = 0; i < nNumbers; i++)
  -     {
  -             if (it != tokenVector.end())
  -             {
  -                     // $$$ ToDo: This assert is commented out until we get
  -                     // out character classification problems fixed.
  -                     // assert(isXMLLetterOrDigit(charAt((*it), 0)));
  -                     formatToken = *it++;
  -                     numberWidth = length(formatToken);
  -                     numberType = charAt(formatToken, numberWidth - 1);
  -             }
  -             if (it != tokenVector.end())
  -             {
  -                     // $$$ ToDo: This assert is commented out until we get
  -                     // out character classification problems fixed.
  -                     //assert(!isXMLLetterOrDigit(charAt((*it), 0)));
  -                     sepString = *it++;
  +
  +     if (leaderStrIt != endIt)
  +     {
  +             theResult += *leaderStrIt;
  +     }
  +
  +     typedef XPathExecutionContext::GetAndReleaseCachedString        
GetAndReleaseCachedString;
  +
  +     GetAndReleaseCachedString       theGuard2(executionContext);
  +
  +     XalanDOMString&                         theIntermediateResult = 
theGuard2.get();
  +
  +     for(unsigned int i = 0; i < theListLength; i++)
  +     {
  +             if (it != trailerStrIt)
  +             {
  +                     assert(isXMLLetterOrDigit(charAt(*it, 0)));
  +
  +                     numberWidth = length(*it);
  +
  +                     numberType = charAt(*it, numberWidth - 1);
  +
  +                     ++it;
                }
  -             formattedNumber += getFormattedNumber(executionContext, 
contextNode,
  -                             numberType, numberWidth, theList[i]);
  +
  +             if (it != trailerStrIt)
  +             {
  +                     assert(!isXMLLetterOrDigit(charAt(*it, 0)));
  +
  +                     sepStringIt = it;
  +
  +                     ++it;
  +             }
  +
  +             getFormattedNumber(
  +                             executionContext,
  +                             contextNode,
  +                             numberType,
  +                             numberWidth,
  +                             theList[i],
  +                             theIntermediateResult);
  +
  +             theResult += theIntermediateResult;
  +
                // All but the last one
  -             if (i < nNumbers-1)
  -                     formattedNumber += sepString;
  +             if (i < theListLength - 1)
  +             {
  +                     if (sepStringIt != endIt)
  +                     {
  +                             theResult += *sepStringIt;
  +                     }
  +                     else
  +                     {
  +                             theResult += s_defaultSeparatorString;
  +                     }
  +
  +                     clear(theIntermediateResult);
  +             }
        }
  -     formattedNumber += trailerStr;
   
  -     return formattedNumber;  
  +     if (trailerStrIt != endIt)
  +     {
  +             theResult += *trailerStrIt;
  +     }
   }
   
   
  @@ -790,16 +944,19 @@
   
   
   
  -XalanDOMString
  +void
   ElemNumber::traditionalAlphaCount(
                        int                                                     
                        theValue,
  -                     const XalanNumberingResourceBundle&             
theResourceBundle) const
  +                     const XalanNumberingResourceBundle&             
theResourceBundle,
  +                     XalanDOMString&                                         
        theResult) const
   {
        typedef XalanNumberingResourceBundle::IntVectorType                     
IntVectorType;
        typedef XalanNumberingResourceBundle::DigitsTableVectorType     
DigitsTableVectorType;
        typedef XalanNumberingResourceBundle::eNumberingMethod          
eNumberingMethod;
        typedef XalanNumberingResourceBundle::eMultiplierOrder          
eMultiplierOrder;
   
  +     bool    fError = false;
  +
        // if this number is larger than the largest number we can represent, 
error!
        //if (val > theResourceBundle.getMaxNumericalValue())
        //return XSLTErrorResources.ERROR_STRING;
  @@ -809,7 +966,7 @@
        IntVectorType::size_type        lookupIndex = 1;  // start off with 
anything other than zero to make correction work
   
        // Create a buffer to hold the result
  -     // TODO:  size of the table can be detereined by computing
  +     // TODO:  size of the table can be determined by computing
        // logs of the radix.  For now, we fake it.
        XalanDOMChar    buf[100];
   
  @@ -954,17 +1111,19 @@
                                                                }
                                                                else
                                                                {
  -                                                                     
buf[charPos++] =  table[lookupIndex];
  +                                                                     
buf[charPos++] = table[lookupIndex];
                                                                }
   
  -                                                             buf[charPos++] 
=        multiplierChar ;
  +                                                             buf[charPos++] 
= multiplierChar;
                                                        }
   
                                                        break;           // all 
done!
                                                }
                                                else
                                                {
  -                                                     return 
XALAN_STATIC_UCODE_STRING("#error");
  +                                                     fError = true;
  +
  +                                                     break;
                                                }
                                        } //end else
                                } // end while  
  @@ -973,11 +1132,10 @@
   
                        } // end else if
                } // end do while
  -             while ( i < multiplierSize);            
  +             while (i < multiplierSize && fError == false);          
        }
   
        // Now do additive part...
  -
        IntVectorType::size_type        count = 0;
   
        // do this for each table of hundreds, tens, digits...
  @@ -1027,15 +1185,23 @@
                        }
                        else
                        {
  -                             return XALAN_STATIC_UCODE_STRING("#error");
  +                             fError = true;
  +
  +                             break;
                        }
   
                        count++;
                }
        } // end while
   
  -     // String s = new String(buf, 0, charPos);
  -     return XalanDOMString(buf, charPos);
  +     if (fError == true)
  +     {
  +             theResult = XALAN_STATIC_UCODE_STRING("#error");
  +     }
  +     else
  +     {
  +             assign(theResult, buf, charPos);
  +     }
   }
   
   
  @@ -1044,30 +1210,35 @@
   
   
   
  -XalanDOMString
  +void
   ElemNumber::getFormattedNumber(
                        StylesheetExecutionContext&             
executionContext,
                        XalanNode*                                              
contextNode,
                        XalanDOMChar                                    
numberType,
                        int                                                     
        numberWidth,
  -                     int                                                     
        listElement) const
  +                     int                                                     
        listElement,
  +                     XalanDOMString&                                 
theResult) const
   {
        switch(numberType)
        {
                case XalanUnicode::charLetter_A:
  -                     return int2alphaCount(listElement, s_alphaCountTable);
  +                     int2alphaCount(listElement, s_alphaCountTable, 
theResult);
                        break;
   
                case XalanUnicode::charLetter_a:
  -                     return toLowerCase(int2alphaCount(listElement, 
s_alphaCountTable));
  +                     int2alphaCount(listElement, s_alphaCountTable, 
theResult);
  +
  +                     theResult = toLowerCase(theResult);
                        break;
   
                case XalanUnicode::charLetter_I:
  -                     return long2roman(listElement, true);
  +                     long2roman(listElement, true, theResult);
                        break;
   
                case XalanUnicode::charLetter_i:
  -                     return toLowerCase(long2roman(listElement, true));
  +                     long2roman(listElement, true, theResult);
  +
  +                     theResult = toLowerCase(theResult);
                        break;
   
                case 0x3042:
  @@ -1081,7 +1252,6 @@
                case 0x10D0:
                case 0x0430:
                        executionContext.error(LongToDOMString(numberType) + " 
format not supported yet!");
  -                     return XalanDOMString();
                        break;
   
                // Handle the special case of Greek letters for now
  @@ -1091,17 +1261,13 @@
                                NumberingResourceBundleMapType::const_iterator  
i = s_resourceBundles.find(0x03B1);
   
                                if (i != s_resourceBundles.end())
  -                             {
  -                                     return 
traditionalAlphaCount(listElement, (*i).second);
  -                             }
  -                             else
                                {
  -                                     return XalanDOMString();
  +                                     traditionalAlphaCount(listElement, 
(*i).second, theResult);
                                }
                        }
                        else
                        {
  -                             return int2alphaCount(listElement, 
s_elalphaCountTable);
  +                             int2alphaCount(listElement, 
s_elalphaCountTable, theResult);
                        }
                        break;
   
  @@ -1110,10 +1276,9 @@
                                
StylesheetExecutionContext::XalanNumberFormatAutoPtr    formatter(
                                                
getNumberFormatter(executionContext, contextNode));
   
  -                             XalanDOMString  numString =
  -                                     formatter->format(listElement);
  +                             formatter->format(listElement, theResult);
   
  -                             const unsigned int      lengthNumString = 
length(numString);
  +                             const unsigned int      lengthNumString = 
length(theResult);
   
                                const int       nPadding = numberWidth - 
lengthNumString;
   
  @@ -1121,15 +1286,13 @@
                                {
                                        const XalanDOMString    padString = 
formatter->format(0);
   
  -                                     reserve(numString, nPadding * 
length(padString) + lengthNumString + 1);
  +                                     reserve(theResult, nPadding * 
length(padString) + lengthNumString + 1);
   
                                        for(int i = 0; i < nPadding; i++)
                                        {
  -                                             insert(numString, 0, padString);
  +                                             insert(theResult, 0, padString);
                                        }
                                }
  -
  -                             return numString;
                        }
                        break;
        }
  @@ -1137,17 +1300,18 @@
   
   
   
  -XalanDOMString
  +void
   ElemNumber::int2singlealphaCount(
                int                                             val, 
  -             const XalanDOMString&   table)
  +             const XalanDOMString&   table,
  +             XalanDOMString&                 theResult)
   {
        const int               radix = length(table);
   
        // TODO:  throw error on out of range input
        if (val > radix)
        {
  -             return XalanDOMString(XALAN_STATIC_UCODE_STRING("#E(") +
  +             theResult = XalanDOMString(XALAN_STATIC_UCODE_STRING("#E(") +
                                LongToDOMString(val) +
                                XALAN_STATIC_UCODE_STRING(")"));
        }
  @@ -1155,16 +1319,17 @@
        {
                const XalanDOMChar      theChar = charAt(table, val - 1);
   
  -             return XalanDOMString(&theChar, 1);
  +             assign(theResult, &theChar, 1);
        }
   }
   
   
   
  -XalanDOMString
  +void
   ElemNumber::int2alphaCount(
                        int                                             val,
  -                     const XalanDOMString&   table)
  +                     const XalanDOMString&   table,
  +                     XalanDOMString&                 theResult)
   {
        const int               radix = length(table);
   
  @@ -1234,157 +1399,188 @@
        }
        while (val > 0);
   
  -     const XalanDOMString    retStr(buf + charPos + 1, (buflen - charPos - 
1));
  -
  -     return retStr;
  +     assign(theResult, buf + charPos + 1, buflen - charPos - 1);
   }
  +
   
  -XalanDOMString ElemNumber::tradAlphaCount(int        /* val */)
  +
  +void
  +ElemNumber::tradAlphaCount(
  +                     int                                     /* val */,
  +                     XalanDOMString&         /* theResult */)
   {
   //   @@ JMD: We don't do languages yet, so this is just a placeholder
  -     assert(0);
  -     return XalanDOMString();        // To keep compiler happy
  +     assert(false);
   }
   
   
  -XalanDOMString
  +
  +void
   ElemNumber::long2roman(
  -                     long    val,
  -                     bool    prefixesAreOK)
  +                     long                            val,
  +                     bool                            prefixesAreOK,
  +                     XalanDOMString&         theResult)
   {
        if(val < 0)
        {
  -             return XalanDOMString(XALAN_STATIC_UCODE_STRING("#E(") +
  +             theResult = XalanDOMString(XALAN_STATIC_UCODE_STRING("#E(") +
                                                                
LongToDOMString(val) +
                                                                
XALAN_STATIC_UCODE_STRING(")"));
        }
  -     // Make this match the conformance test
        else if(val == 0)
        {
  -             return XalanDOMString(XALAN_STATIC_UCODE_STRING("0"));
  +             theResult = XALAN_STATIC_UCODE_STRING("0");
        }
  -
  -
  -     XalanDOMString  roman;
  +     else if (val <= 3999L)
  +     {
  +             clear(theResult);
   
  -     int                     place = 0;
  +             int     place = 0;
   
  -     if (val <= 3999L)
  -     {
                do      
                {
  -                     while (val >= s_romanConvertTable[place].m_postValue)   
         
  +                     while (val >= s_romanConvertTable[place].m_postValue)
                        {
  -                             roman += 
s_romanConvertTable[place].m_postLetter;
  +                             theResult += 
s_romanConvertTable[place].m_postLetter;
                                val -= s_romanConvertTable[place].m_postValue;
                        }
  -                     if (prefixesAreOK)            
  +
  +                     if (prefixesAreOK)
                        {
  -                             if (val >= 
s_romanConvertTable[place].m_preValue)                  
  +                             if (val >= 
s_romanConvertTable[place].m_preValue)
                                {
  -                                     roman += 
s_romanConvertTable[place].m_preLetter;
  +                                     theResult += 
s_romanConvertTable[place].m_preLetter;
                                        val -= 
s_romanConvertTable[place].m_preValue;
                                }
                        } 
  -                     place++;      
  +
  +                     ++place;      
                }
                while (val > 0);
        }
        else
        {
  -             roman = XALAN_STATIC_UCODE_STRING("#error");
  +             theResult = XALAN_STATIC_UCODE_STRING("#error");
        }
  -
  -     return roman;
   }
   
   
  -/*
  - *                           NumberFormatStringTokenizer Class Implementation
  - */
   
   ElemNumber::NumberFormatStringTokenizer::NumberFormatStringTokenizer(
  -                     const XalanDOMString&   theStr) :
  +                     const XalanDOMString&   theString) :
        m_currentPosition(0),
  -     m_maxPosition(length(theStr)),
  -     m_str(theStr)
  +     m_maxPosition(length(theString)),
  +     m_string(&theString)
   {
   }
   
   
   
  -/*
  -@@ Obsolete ??
   void
   ElemNumber::NumberFormatStringTokenizer::setString(const XalanDOMString&     
theString)
   {
  -     m_str = theString;
  +     m_string = &theString;
   
        m_currentPosition = 0;
        m_maxPosition = length(theString);
   }
   
  -*/
   
  -// @@ JMD: This seemed to be working OK in previous version and is
  -// functionally equivalent to java, so I left it alone.  Other java methods 
do
  -// not seem to be needed in this implementation
   
   XalanDOMString
   ElemNumber::NumberFormatStringTokenizer::nextToken() 
   {
        if (m_currentPosition >= m_maxPosition) 
  +     {
  +             return XalanDOMString();
  +     }
  +
  +     const unsigned int      start = m_currentPosition;
  +
  +     if (isXMLLetterOrDigit(charAt(*m_string, m_currentPosition)))
  +     {
  +             while (m_currentPosition < m_maxPosition &&
  +                        isXMLLetterOrDigit(charAt(*m_string, 
m_currentPosition)))
  +             {
  +                     m_currentPosition++;
  +             }
  +     }
  +     else
  +     {
  +             while (m_currentPosition < m_maxPosition &&
  +                        !isXMLLetterOrDigit(charAt(*m_string, 
m_currentPosition)))
  +             {
  +                     m_currentPosition++;
  +             }
  +     }
  +
  +     return substring(*m_string, start, m_currentPosition);
  +}
  +
  +
  +
  +void
  +ElemNumber::NumberFormatStringTokenizer::nextToken(XalanDOMString&   
theToken)
  +{
  +     if (m_currentPosition >= m_maxPosition) 
        {
  -             // $$$ Todo: Implement!
  -//                           throw new NoSuchElementException();
  +             clear(theToken);
        }
   
  -     const int       start = m_currentPosition;
  +     const unsigned int      start = m_currentPosition;
   
  -     if (isXMLLetterOrDigit(charAt(m_str, m_currentPosition)))
  +     if (isXMLLetterOrDigit(charAt(*m_string, m_currentPosition)))
        {
  -             while ((m_currentPosition < m_maxPosition) &&
  -                             isXMLLetterOrDigit(charAt(m_str, 
m_currentPosition))) 
  +             while (m_currentPosition < m_maxPosition &&
  +                        isXMLLetterOrDigit(charAt(*m_string, 
m_currentPosition)))
  +             {
                        m_currentPosition++;
  +             }
        }
        else
        {
  -             while ((m_currentPosition < m_maxPosition) &&
  -                             !isXMLLetterOrDigit(charAt(m_str, 
m_currentPosition))) 
  +             while (m_currentPosition < m_maxPosition &&
  +                        !isXMLLetterOrDigit(charAt(*m_string, 
m_currentPosition)))
  +             {
                        m_currentPosition++;
  +             }
        }
   
  -     // @@ This wasn't working right when start=current=0 with DOMStrings
  -     // need to check it with XalanDOMString's
  -     return substring(m_str, start, m_currentPosition);
  +     substring(*m_string, theToken, start, m_currentPosition);
   }
   
   
   
  -int
  +unsigned int
   ElemNumber::NumberFormatStringTokenizer::countTokens() const
   {
  -     int     count = 0;
  -     int     currpos = m_currentPosition;
  +     unsigned int    count = 0;
  +     unsigned int    currpos = m_currentPosition;
   
        // Tokens consist of sequences of alphabetic characters and sequences of
        // non-alphabetic characters
        while (currpos < m_maxPosition) 
        {
  -             if (isXMLLetterOrDigit(charAt(m_str, currpos)))
  +             if (isXMLLetterOrDigit(charAt(*m_string, currpos)))
                {
  -                     while ((currpos < m_maxPosition) &&
  -                                     isXMLLetterOrDigit(charAt(m_str, 
currpos))) 
  +                     while (currpos < m_maxPosition &&
  +                                isXMLLetterOrDigit(charAt(*m_string, 
currpos)))
  +                     {
                                currpos++;
  +                     }
                }
                else
                {
  -                     while ((currpos < m_maxPosition) &&
  -                                     !isXMLLetterOrDigit(charAt(m_str, 
currpos))) 
  +                     while (currpos < m_maxPosition &&
  +                                !isXMLLetterOrDigit(charAt(*m_string, 
currpos)))
  +                     {
                                currpos++;
  +                     }
                }
  +
                count++;
        }
  +
        return count;
   }
   
  @@ -1471,6 +1667,8 @@
   
   static XalanDOMString                                                        
        s_oneString;
   
  +static XalanDOMString                                                        
        s_defaultSeparatorString;
  +
   static XalanDOMString                                                        
        s_alphaCountTable;
   
   static XalanDOMString                                                        
        s_elalphaCountTable;
  @@ -1498,6 +1696,8 @@
   
   const XalanDOMString&        ElemNumber::s_oneString = ::s_oneString;
   
  +const XalanDOMString&        ElemNumber::s_defaultSeparatorString = 
::s_defaultSeparatorString;
  +
   const XalanDOMString&        ElemNumber::s_alphaCountTable = 
::s_alphaCountTable;
   
   const XalanDOMString&        ElemNumber::s_elalphaCountTable = 
::s_elalphaCountTable;
  @@ -1634,6 +1834,8 @@
   
        ::s_oneString = XALAN_STATIC_UCODE_STRING("1");
   
  +     ::s_defaultSeparatorString = XALAN_STATIC_UCODE_STRING(".");
  +
        ::s_alphaCountTable = alphaCountTable;
   
        ::s_elalphaCountTable = elalphaCountTable;
  @@ -1705,6 +1907,7 @@
        releaseMemory(::s_leftParenString);
        releaseMemory(::s_dotString);
        releaseMemory(::s_oneString);
  +     releaseMemory(::s_defaultSeparatorString);
   
        releaseMemory(::s_alphaCountTable);
        releaseMemory(::s_elalphaCountTable);
  
  
  
  1.29      +136 -102  xml-xalan/c/src/XSLT/ElemNumber.hpp
  
  Index: ElemNumber.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemNumber.hpp,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- ElemNumber.hpp    2001/03/09 16:19:59     1.28
  +++ ElemNumber.hpp    2001/06/14 19:17:25     1.29
  @@ -57,14 +57,8 @@
   #if !defined(XALAN_ELEMNUMBER_HEADER_GUARD)
   #define XALAN_ELEMNUMBER_HEADER_GUARD 
   
  -/**
  - * $Id: ElemNumber.hpp,v 1.28 2001/03/09 16:19:59 auriemma Exp $
  - * 
  - * $State: Exp $
  - * 
  - * @author Myriam Midy (Myriam_Midy @lotus.com 
  - */
   
  +
   // Base include file.  Must be first.
   #include <XSLT/XSLTDefinitions.hpp>
   
  @@ -85,6 +79,7 @@
   
   
   class AVT;
  +class CountersTable;
   class QName;
   class XalanNumberFormat;
   class XPath;
  @@ -96,7 +91,7 @@
   {
   private:
   
  -struct Counter;
  +     struct Counter;
   
   public:
   
  @@ -214,8 +209,20 @@
         * Given an XML source node, get the count according to the 
         * parameters set up by the xsl:number attributes.
         */
  -     XalanDOMString
  -     getCountString(StylesheetExecutionContext&              
executionContext) const;
  +     void
  +     getCountString(
  +                     StylesheetExecutionContext&             
executionContext,
  +                     XalanDOMString&                                 
theResult) const;
  +
  +     void
  +     getCountString(
  +                     StylesheetExecutionContext&             
executionContext,
  +                     XalanNode*                                              
sourceNode,
  +                     const MutableNodeRefList&               ancestors,
  +                     CountersTable&                                  ctable,
  +                     int                                                     
        numberList[],
  +                     unsigned int                                    
numberListLength,
  +                     XalanDOMString&                                 
theResult) const;
   
        /**
         * Get the ancestors, up to the root, that match the
  @@ -223,12 +230,15 @@
         * @param patterns if non-0, count only nodes
         * that match this pattern, if 0 count all ancestors.
         * @param node Count this node and it's ancestors.
  -      * @return The number of ancestors that match the pattern.
  +      * @param stopAtFirstFound If true, only get the first matching ancestor
  +      * @param ancestors The ancestors that match the pattern.
         */
  -     MutableNodeRefList getMatchingAncestors(
  +     void
  +     getMatchingAncestors(
                        StylesheetExecutionContext&             
executionContext,
                        XalanNode*                                              
node, 
  -                     bool                                                    
stopAtFirstFound) const;
  +                     bool                                                    
stopAtFirstFound,
  +                     MutableNodeRefList&                             
ancestors) const;
   
        /**
         * Get a formatter.
  @@ -242,50 +252,55 @@
                        XalanNode*                                              
contextNode) const;
   
        /**
  -      * Format a vector of numbers into a formatted string.
  +      * Format an array of integers into a formatted string.
  +      *
         * @param executionContext The current execution context.
  -      * @param xslNumberElement Element that takes %conversion-atts; 
attributes.
  -      * @param list Array of one or more integer numbers.
  -      * @return String that represents list according to 
  -      * %conversion-atts; attributes.
  -      * TODO: Optimize formatNumberList so that it caches the last count and
  -      * reuses that info for the next count.
  +      * @param theList Array of one or more integer numbers.
  +      * @param theListLength The length of the array.
  +      * @param contextNode The context node.
  +      * @param formattedNumber The formatted number result.
         */
  -     XalanDOMString
  +     void
        formatNumberList(       
                        StylesheetExecutionContext&             
executionContext,
  -                     const IntArrayType&                             theList,
  -                     XalanNode*                                              
contextNode) const;
  +                     const int                                               
theList[],
  +                     unsigned int                                    
theListLength,
  +                     XalanNode*                                              
contextNode,
  +                     XalanDOMString&                                 
formattedNumber) const;
   
        /**
         * Convert a long integer into alphabetic counting, in other words
         * count using the sequence A B C ... Z.
         * @param val Value to convert -- must be greater than zero.
         * @param table a table containing one character for each digit in the 
radix
  -      * @return String representing alpha count of number.
  +      * @param theResult A string representing alpha count of number.
         * @see XSLTEngineImpl#DecimalToRoman
         *
         * Note that the radix of the conversion is inferred from the size
         * of the table.
         */
  -     XalanDOMString int2singlealphaCount(int val, 
  -                     const XalanDOMString&   table);
  +     static void
  +     int2singlealphaCount(
  +                     int                                             val,
  +                     const XalanDOMString&   table,
  +                     XalanDOMString&                 theResult);
                
        /**
         * Convert a long integer into alphabetic counting, in other words 
         * count using the sequence A B C ... Z AA AB AC.... etc.
         * @param val Value to convert -- must be greater than zero.
         * @param table a table containing one character for each digit in the 
radix
  -      * @return String representing alpha count of number.
  +      * @param result returns the stringrepresenting alpha count of number.
         * @see XSLTEngineImpl#DecimalToRoman
         * 
         * Note that the radix of the conversion is inferred from the size
         * of the table.
         */
  -     static XalanDOMString
  +     static void
        int2alphaCount(
                        int                                             val,
  -                     const XalanDOMString&   table);
  +                     const XalanDOMString&   table,
  +                     XalanDOMString&                 theResult);
   
        /**
         * Convert a long integer into traditional alphabetic counting, in 
other words
  @@ -298,22 +313,24 @@
         * Note that the radix of the conversion is inferred from the size
         * of the table.
         */
  -     static XalanDOMString
  -     tradAlphaCount(int val);
  +     static void
  +     tradAlphaCount(
  +                     int                                     val,
  +                     XalanDOMString&         theResult);
   
        /**
         * Convert a long integer into roman numerals.
         * @param val Value to convert.
  -      * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
  -      * false_ to disable prefix notation (e.g. 4 = "IIII").
  -      * @return Roman numeral string.
  +      * @param prefixesAreOK true to enable prefix notation (e.g. 4 = "IV"), 
false to disable prefix notation (e.g. 4 = "IIII").
  +      * @param theResult The formatted Roman numeral string.
         * @see DecimalToRoman
         * @see m_romanConvertTable
         */
  -     static XalanDOMString
  +     static void
        long2roman(
  -                     long    val,
  -                     bool    prefixesAreOK);
  +                     long                            val,
  +                     bool                            prefixesAreOK,
  +                     XalanDOMString&         theResult);
   
   private:
   
  @@ -323,21 +340,23 @@
                        XalanNode*                                              
contextNode,
                        const XalanDOMString&                   compareValue) 
const;
   
  -     XalanDOMString
  +     void
        traditionalAlphaCount(
                        int                                                     
                        theValue,
  -                     const XalanNumberingResourceBundle&             
theResourceBundle) const;
  +                     const XalanNumberingResourceBundle&             
theResourceBundle,
  +                     XalanDOMString&                                         
        theResult) const;
   
        /*
         * Get Formatted number
         */
  -     XalanDOMString 
  +     void
        getFormattedNumber(
                        StylesheetExecutionContext&             
executionContext,
                        XalanNode*                                              
contextNode,
                        XalanDOMChar                                    
numberType,
                        int                                                     
        numberWidth,
  -                     int                                                     
        listElement) const;
  +                     int                                                     
        listElement,
  +                     XalanDOMString&                                 
theResult) const;
   
        const XPath*    m_countMatchPattern;
        const XPath*    m_fromMatchPattern;
  @@ -392,6 +411,11 @@
        static const XalanDOMString&                    s_oneString;
   
        /**
  +      * The string ".".
  +      */
  +     static const XalanDOMString&                    
s_defaultSeparatorString;
  +
  +     /**
        * Chars for converting integers into alpha counts.
        * @see XSLTEngineImpl#int2alphaCount
        */
  @@ -418,68 +442,78 @@
         */
        class NumberFormatStringTokenizer
        {
  -             public:
  +     public:
  +
  +             /**
  +              * Construct a NumberFormatStringTokenizer.
  +              *
  +              * @param theString string to tokenize
  +              */
  +             NumberFormatStringTokenizer(const XalanDOMString&       
theString);
  +
  +             /**
  +              * Sets the string to tokenize.
  +              *
  +              * @param theString  new string to tokenize
  +              */
  +             void
  +             setString(const XalanDOMString& theString);
  +
  +             /**
  +              * Reset tokenizer so that nextToken() starts from the 
beginning.
  +              */
  +             void
  +             reset()
  +             {
  +                     m_currentPosition = 0;
  +             }
  +
  +             /**
  +              * Retrieve the next token to be parsed; behavior is undefined 
if there
  +              * are no more tokens
  +              * 
  +              * @return next token string
  +              */
  +             XalanDOMString
  +             nextToken();
  +
  +             /**
  +              * Retrieve the next token to be parsed.
  +              * 
  +              * @param theToken The next token string
  +              */
  +             void
  +             nextToken(XalanDOMString&       theToken);
  +
  +             /**
  +              * Determine if there are tokens remaining
  +              * 
  +              * @return true if there are more tokens
  +              */
  +             bool
  +             hasMoreTokens() const
  +             {
  +                     return m_currentPosition >= m_maxPosition ? false : 
true;
  +             }
  +
  +             /**
  +              * Count the number of tokens yet to be parsed
  +              * 
  +              * @return number of remaining tokens
  +              */
  +             unsigned int
  +             countTokens() const;
  +
  +     private:
  +
  +             unsigned int                    m_currentPosition;
  +
  +             unsigned int                    m_maxPosition;
  +
  +             const XalanDOMString*   m_string;
  +     };
  +};
   
  -                     /**
  -                      * Construct a NumberFormatStringTokenizer.
  -                      *
  -                      * @param theStr string to tokenize
  -                      */
  -                     explicit
  -                             NumberFormatStringTokenizer(const 
XalanDOMString&       theStr = XalanDOMString());
  -
  -                     /**
  -                      * Sets the string to tokenize.
  -                      *
  -                      * @param theString  new string to tokenize
  -                      */
  -                     void
  -                             setString(const XalanDOMString& theString);
  -
  -                     /**
  -                      * Reset tokenizer so that nextToken() starts from the 
beginning.
  -                      */
  -                     void
  -                             reset()
  -                             {
  -                                     m_currentPosition = 0;
  -                             }
  -
  -                     /**
  -                      * Retrieve the next token to be parsed; behavior is 
undefined if there
  -                      * are no more tokens
  -                      * 
  -                      * @return next token string
  -                      */
  -                     XalanDOMString
  -                             nextToken();
  -
  -                     /**
  -                      * Determine if there are tokens remaining
  -                      * 
  -                      * @return true if there are more tokens
  -                      */
  -                     bool
  -                             hasMoreTokens() const
  -                             {
  -                                     return (m_currentPosition >= 
m_maxPosition) ? false : true;
  -                             }
  -
  -                     /**
  -                      * Count the number of tokens yet to be parsed
  -                      * 
  -                      * @return number of remaining tokens
  -                      */
  -                     int
  -                             countTokens() const;
  -
  -             private:
  -
  -                     int                             m_currentPosition;
  -                     int                             m_maxPosition;
  -                     XalanDOMString  m_str;
  -     }; // end NumberFormatStringTokenizer
   
  -}; // end ElemNumber
   
   #endif       // XALAN_ELEMNUMBER_HEADER_GUARD
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to