contentspecnode.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 306 行

CPP
306
字号
/* * Copyright 1999-2001,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: ContentSpecNode.cpp,v 1.13 2004/09/08 13:56:51 peiyongz Exp $ */// ---------------------------------------------------------------------------//  Includes// ---------------------------------------------------------------------------#include <xercesc/framework/XMLBuffer.hpp>#include <xercesc/validators/common/ContentSpecNode.hpp>#include <xercesc/validators/schema/SchemaSymbols.hpp>XERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------//  ContentSpecNode: Copy Constructor////  Note: this copy constructor has dependency on various get*() methods//        and shall be placed after those method's declaration.//        aka inline function compilation error on AIX 4.2, xlC 3 r ev.1// ---------------------------------------------------------------------------ContentSpecNode::ContentSpecNode(const ContentSpecNode& toCopy) :    fMemoryManager(toCopy.fMemoryManager)    , fElement(0)    , fElementDecl(toCopy.fElementDecl)    , fFirst(0)    , fSecond(0)    , fType(toCopy.fType)    , fAdoptFirst(true)    , fAdoptSecond(true)    , fMinOccurs(toCopy.fMinOccurs)    , fMaxOccurs(toCopy.fMaxOccurs){    const QName* tempElement = toCopy.getElement();    if (tempElement)        fElement = new (fMemoryManager) QName(*tempElement);    const ContentSpecNode *tmp = toCopy.getFirst();    if (tmp)        fFirst = new (fMemoryManager) ContentSpecNode(*tmp);    tmp = toCopy.getSecond();    if (tmp)        fSecond = new (fMemoryManager) ContentSpecNode(*tmp);}// ---------------------------------------------------------------------------//  Local methods// ---------------------------------------------------------------------------static void formatNode( const   ContentSpecNode* const      curNode                        , const ContentSpecNode::NodeTypes  parentType                        ,       XMLBuffer&                  bufToFill){    if (!curNode)        return;    const ContentSpecNode* first = curNode->getFirst();    const ContentSpecNode* second = curNode->getSecond();    const ContentSpecNode::NodeTypes curType = curNode->getType();    // Get the type of the first node    const ContentSpecNode::NodeTypes firstType = first ?                                                 first->getType() :                                                 ContentSpecNode::Leaf;    // Calculate the parens flag for the rep nodes    bool doRepParens = false;    if (((firstType != ContentSpecNode::Leaf)            && (parentType != ContentSpecNode::UnknownType))    ||  ((firstType == ContentSpecNode::Leaf)            && (parentType == ContentSpecNode::UnknownType)))    {        doRepParens = true;    }    // Now handle our type    switch(curType & 0x0f)    {        case ContentSpecNode::Leaf :            if (curNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)                bufToFill.append(XMLElementDecl::fgPCDataElemName);            else                bufToFill.append(curNode->getElement()->getRawName());            break;        case ContentSpecNode::ZeroOrOne :            if (doRepParens)                bufToFill.append(chOpenParen);            formatNode(first, curType, bufToFill);            if (doRepParens)                bufToFill.append(chCloseParen);            bufToFill.append(chQuestion);            break;        case ContentSpecNode::ZeroOrMore :            if (doRepParens)                bufToFill.append(chOpenParen);            formatNode(first, curType, bufToFill);            if (doRepParens)                bufToFill.append(chCloseParen);            bufToFill.append(chAsterisk);            break;        case ContentSpecNode::OneOrMore :            if (doRepParens)                bufToFill.append(chOpenParen);            formatNode(first, curType, bufToFill);            if (doRepParens)                bufToFill.append(chCloseParen);            bufToFill.append(chPlus);            break;        case ContentSpecNode::Choice :            if (parentType != curType)                bufToFill.append(chOpenParen);            formatNode(first, curType, bufToFill);            bufToFill.append(chPipe);            formatNode(second, curType, bufToFill);            if (parentType != curType)                bufToFill.append(chCloseParen);            break;        case ContentSpecNode::Sequence :            if (parentType != curType)                bufToFill.append(chOpenParen);            formatNode(first, curType, bufToFill);            bufToFill.append(chComma);            formatNode(second, curType, bufToFill);            if (parentType != curType)                bufToFill.append(chCloseParen);            break;        case ContentSpecNode::All :            if (parentType != curType)			{                bufToFill.append(chLatin_A);                bufToFill.append(chLatin_l);                bufToFill.append(chLatin_l);                bufToFill.append(chOpenParen);			}            formatNode(first, curType, bufToFill);            bufToFill.append(chComma);            formatNode(second, curType, bufToFill);            if (parentType != curType)                bufToFill.append(chCloseParen);            break;    }}// ---------------------------------------------------------------------------//  ContentSpecNode: Miscellaneous// ---------------------------------------------------------------------------void ContentSpecNode::formatSpec(XMLBuffer&      bufToFill) const{    // Clean out the buffer first    bufToFill.reset();    if (fType == ContentSpecNode::Leaf)        bufToFill.append(chOpenParen);    formatNode    (        this        , UnknownType        , bufToFill    );    if (fType == ContentSpecNode::Leaf)        bufToFill.append(chCloseParen);}int ContentSpecNode::getMinTotalRange() const {    int min = fMinOccurs;    if ((fType & 0x0f) == ContentSpecNode::Sequence        || fType == ContentSpecNode::All        || (fType & 0x0f) == ContentSpecNode::Choice) {        int minFirst = fFirst->getMinTotalRange();        if (fSecond) {            int minSecond = fSecond->getMinTotalRange();            if ((fType & 0x0f) == ContentSpecNode::Choice) {                min = min * ((minFirst < minSecond)? minFirst : minSecond);            }            else {                min = min * (minFirst + minSecond);            }        }        else            min = min * minFirst;    }    return min;}int ContentSpecNode::getMaxTotalRange() const {    int max = fMaxOccurs;    if (max == SchemaSymbols::XSD_UNBOUNDED) {         return SchemaSymbols::XSD_UNBOUNDED;    }    if ((fType & 0x0f) == ContentSpecNode::Sequence        || fType == ContentSpecNode::All        || (fType & 0x0f) == ContentSpecNode::Choice) {        int maxFirst = fFirst->getMaxTotalRange();        if (maxFirst == SchemaSymbols::XSD_UNBOUNDED) {             return SchemaSymbols::XSD_UNBOUNDED;        }        if (fSecond) {            int maxSecond = fSecond->getMaxTotalRange();            if (maxSecond == SchemaSymbols::XSD_UNBOUNDED) {                return SchemaSymbols::XSD_UNBOUNDED;            }            else {                if ((fType & 0x0f) == ContentSpecNode::Choice) {                    max = max * (maxFirst > maxSecond) ? maxFirst : maxSecond;                }                else {                    max = max * (maxFirst + maxSecond);                }            }        }        else {            max = max * maxFirst;        }    }    return max;}/*** * Support for Serialization/De-serialization ***/IMPL_XSERIALIZABLE_TOCREATE(ContentSpecNode)void ContentSpecNode::serialize(XSerializeEngine& serEng){    /***     *  Since fElement, fFirst, fSecond are NOT created by the default      *  constructor, we need to create them dynamically.     ***/    if (serEng.isStoring())    {        serEng<<fElement;        XMLElementDecl::storeElementDecl(serEng, fElementDecl);        serEng<<fFirst;        serEng<<fSecond;        serEng<<(int)fType;        serEng<<fAdoptFirst;        serEng<<fAdoptSecond;        serEng<<fMinOccurs;        serEng<<fMaxOccurs;    }    else    {        serEng>>fElement;        fElementDecl = XMLElementDecl::loadElementDecl(serEng);        serEng>>fFirst;        serEng>>fSecond;        int type;        serEng>>type;        fType = (NodeTypes)type;        serEng>>fAdoptFirst;        serEng>>fAdoptSecond;        serEng>>fMinOccurs;        serEng>>fMaxOccurs;    }}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?