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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: ContentSpecNode.cpp,v 1.8 2003/05/18 14:02:06 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/util/Janitor.hpp>
  63. #include <xercesc/util/XMLUniDefs.hpp>
  64. #include <xercesc/util/XMLUni.hpp>
  65. #include <xercesc/framework/XMLNotationDecl.hpp>
  66. #include <xercesc/framework/XMLBuffer.hpp>
  67. #include <xercesc/validators/common/ContentSpecNode.hpp>
  68. #include <xercesc/validators/DTD/DTDValidator.hpp>
  69. #include <xercesc/validators/schema/SchemaSymbols.hpp>
  70. XERCES_CPP_NAMESPACE_BEGIN
  71. // ---------------------------------------------------------------------------
  72. //  ContentSpecNode: Copy Constructor
  73. //
  74. //  Note: this copy constructor has dependency on various get*() methods
  75. //        and shall be placed after those method's declaration.
  76. //        aka inline function compilation error on AIX 4.2, xlC 3 r ev.1
  77. // ---------------------------------------------------------------------------
  78. ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :
  79.     fMemoryManager(toCopy.fMemoryManager)
  80. {
  81.     const QName* tempElement = toCopy.getElement();
  82.     if (tempElement)
  83.         fElement = new (fMemoryManager) QName(*tempElement);
  84.     else
  85.         fElement = 0;
  86.     const ContentSpecNode *tmp = toCopy.getFirst();
  87.     if (tmp)
  88.         fFirst = new (fMemoryManager) ContentSpecNode(*tmp);
  89.     else
  90.         fFirst = 0;
  91.     tmp = toCopy.getSecond();
  92.     if (tmp)
  93.         fSecond = new (fMemoryManager) ContentSpecNode(*tmp);
  94.     else
  95.         fSecond = 0;
  96.     fType = toCopy.getType();
  97.     fAdoptFirst = true;
  98.     fAdoptSecond = true;
  99.     fMinOccurs = toCopy.getMinOccurs();
  100.     fMaxOccurs = toCopy.getMaxOccurs();
  101. }
  102. // ---------------------------------------------------------------------------
  103. //  Local methods
  104. // ---------------------------------------------------------------------------
  105. static void formatNode( const   ContentSpecNode* const      curNode
  106.                         , const ContentSpecNode::NodeTypes  parentType
  107.                         ,       XMLBuffer&                  bufToFill)
  108. {
  109.     if (!curNode)
  110.         return;
  111.     const ContentSpecNode* first = curNode->getFirst();
  112.     const ContentSpecNode* second = curNode->getSecond();
  113.     const ContentSpecNode::NodeTypes curType = curNode->getType();
  114.     // Get the type of the first node
  115.     const ContentSpecNode::NodeTypes firstType = first ?
  116.                                                  first->getType() :
  117.                                                  ContentSpecNode::Leaf;
  118.     // Calculate the parens flag for the rep nodes
  119.     bool doRepParens = false;
  120.     if (((firstType != ContentSpecNode::Leaf)
  121.             && (parentType != ContentSpecNode::UnknownType))
  122.     ||  ((firstType == ContentSpecNode::Leaf)
  123.             && (parentType == ContentSpecNode::UnknownType)))
  124.     {
  125.         doRepParens = true;
  126.     }
  127.     // Now handle our type
  128.     switch(curType)
  129.     {
  130.         case ContentSpecNode::Leaf :
  131.             if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
  132.                 bufToFill.append(XMLElementDecl::fgPCDataElemName);
  133.             else
  134.                 bufToFill.append(curNode->getElement()->getRawName());
  135.             break;
  136.         case ContentSpecNode::ZeroOrOne :
  137.             if (doRepParens)
  138.                 bufToFill.append(chOpenParen);
  139.             formatNode(first, curType, bufToFill);
  140.             if (doRepParens)
  141.                 bufToFill.append(chCloseParen);
  142.             bufToFill.append(chQuestion);
  143.             break;
  144.         case ContentSpecNode::ZeroOrMore :
  145.             if (doRepParens)
  146.                 bufToFill.append(chOpenParen);
  147.             formatNode(first, curType, bufToFill);
  148.             if (doRepParens)
  149.                 bufToFill.append(chCloseParen);
  150.             bufToFill.append(chAsterisk);
  151.             break;
  152.         case ContentSpecNode::OneOrMore :
  153.             if (doRepParens)
  154.                 bufToFill.append(chOpenParen);
  155.             formatNode(first, curType, bufToFill);
  156.             if (doRepParens)
  157.                 bufToFill.append(chCloseParen);
  158.             bufToFill.append(chPlus);
  159.             break;
  160.         case ContentSpecNode::Choice :
  161.             if (parentType != curType)
  162.                 bufToFill.append(chOpenParen);
  163.             formatNode(first, curType, bufToFill);
  164.             bufToFill.append(chPipe);
  165.             formatNode(second, curType, bufToFill);
  166.             if (parentType != curType)
  167.                 bufToFill.append(chCloseParen);
  168.             break;
  169.         case ContentSpecNode::Sequence :
  170.             if (parentType != curType)
  171.                 bufToFill.append(chOpenParen);
  172.             formatNode(first, curType, bufToFill);
  173.             bufToFill.append(chComma);
  174.             formatNode(second, curType, bufToFill);
  175.             if (parentType != curType)
  176.                 bufToFill.append(chCloseParen);
  177.             break;
  178.         case ContentSpecNode::All :
  179.             if (parentType != curType)
  180. {
  181.                 bufToFill.append(chLatin_A);
  182.                 bufToFill.append(chLatin_l);
  183.                 bufToFill.append(chLatin_l);
  184.                 bufToFill.append(chOpenParen);
  185. }
  186.             formatNode(first, curType, bufToFill);
  187.             bufToFill.append(chComma);
  188.             formatNode(second, curType, bufToFill);
  189.             if (parentType != curType)
  190.                 bufToFill.append(chCloseParen);
  191.             break;
  192.     }
  193. }
  194. // ---------------------------------------------------------------------------
  195. //  ContentSpecNode: Miscellaneous
  196. // ---------------------------------------------------------------------------
  197. void ContentSpecNode::formatSpec(XMLBuffer&      bufToFill) const
  198. {
  199.     // Clean out the buffer first
  200.     bufToFill.reset();
  201.     if (fType == ContentSpecNode::Leaf)
  202.         bufToFill.append(chOpenParen);
  203.     formatNode
  204.     (
  205.         this
  206.         , UnknownType
  207.         , bufToFill
  208.     );
  209.     if (fType == ContentSpecNode::Leaf)
  210.         bufToFill.append(chCloseParen);
  211. }
  212. int ContentSpecNode::getMinTotalRange() const {
  213.     int min = fMinOccurs;
  214.     if (fType == ContentSpecNode::Sequence
  215.         || fType == ContentSpecNode::All
  216.         || fType == ContentSpecNode::Choice) {
  217.         int minFirst = fFirst->getMinTotalRange();
  218.         if (fSecond) {
  219.             int minSecond = fSecond->getMinTotalRange();
  220.             if (fType == ContentSpecNode::Choice) {
  221.                 min = min * ((minFirst < minSecond)? minFirst : minSecond);
  222.             }
  223.             else {
  224.                 min = min * (minFirst + minSecond);
  225.             }
  226.         }
  227.         else
  228.             min = min * minFirst;
  229.     }
  230.     return min;
  231. }
  232. int ContentSpecNode::getMaxTotalRange() const {
  233.     int max = fMaxOccurs;
  234.     if (max == SchemaSymbols::XSD_UNBOUNDED) {
  235.          return SchemaSymbols::XSD_UNBOUNDED;
  236.     }
  237.     if (fType == ContentSpecNode::Sequence
  238.         || fType == ContentSpecNode::All
  239.         || fType == ContentSpecNode::Choice) {
  240.         int maxFirst = fFirst->getMaxTotalRange();
  241.         if (maxFirst == SchemaSymbols::XSD_UNBOUNDED) {
  242.              return SchemaSymbols::XSD_UNBOUNDED;
  243.         }
  244.         if (fSecond) {
  245.             int maxSecond = fSecond->getMaxTotalRange();
  246.             if (maxSecond == SchemaSymbols::XSD_UNBOUNDED) {
  247.                 return SchemaSymbols::XSD_UNBOUNDED;
  248.             }
  249.             else {
  250.                 if (fType == ContentSpecNode::Choice) {
  251.                     max = max * (maxFirst > maxSecond) ? maxFirst : maxSecond;
  252.                 }
  253.                 else {
  254.                     max = max * (maxFirst + maxSecond);
  255.                 }
  256.             }
  257.         }
  258.         else {
  259.             max = max * maxFirst;
  260.         }
  261.     }
  262.     return max;
  263. }
  264. XERCES_CPP_NAMESPACE_END