/ATF2/control-software/epics-3.14.8/extensions/src/ChannelArchiver/ThirdParty/xerces-c-src2_4_0/src/xercesc/validators/schema/ComplexTypeInfo.cpp
C++ | 1069 lines | 605 code | 121 blank | 343 comment | 149 complexity | b7925b907079be8389196a8dcf87be07 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
- /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache\@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com . For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- /*
- * $Log: ComplexTypeInfo.cpp,v $
- * Revision 1.1.1.1 2009/03/14 06:43:13 whitegr
- * epics channel archiver
- *
- * Revision 1.20 2003/11/20 18:05:16 knoaman
- * PSVI: Use a copy of the content spec node when creating the content model.
- *
- * Revision 1.19 2003/11/13 23:20:47 peiyongz
- * initSize
- *
- * Revision 1.18 2003/11/10 21:54:51 neilg
- * implementation for new stateless means of traversing attribute definition lists
- *
- * Revision 1.17 2003/11/07 17:08:12 knoaman
- * For PSVI support, distinguish wildcard elements with namespace lists.
- *
- * Revision 1.16 2003/10/29 16:22:58 peiyongz
- * allow proper recreation of ContentModel from deserialization
- *
- * Revision 1.15 2003/10/21 10:23:53 amassari
- * When creating a new list of attributes, use the assigned memory manager
- *
- * Revision 1.14 2003/10/17 21:17:12 peiyongz
- * using XTemplateSerializer
- *
- * Revision 1.13 2003/10/14 15:22:28 peiyongz
- * Implementation of Serialization/Deserialization
- *
- * Revision 1.12 2003/10/10 16:25:40 peiyongz
- * Implementation of Serialization/Deserialization
- *
- * Revision 1.11 2003/10/08 21:33:48 peiyongz
- * Synchronize ContentSpec/ContentModel/FormattedModel
- *
- * Revision 1.10 2003/09/26 18:31:05 peiyongz
- * Synchronize ContentSpecNode and formattedModel
- *
- * Revision 1.9 2003/05/18 14:02:07 knoaman
- * Memory manager implementation: pass per instance manager.
- *
- * Revision 1.8 2003/05/16 21:43:21 knoaman
- * Memory manager implementation: Modify constructors to pass in the memory manager.
- *
- * Revision 1.7 2003/05/15 18:57:27 knoaman
- * Partial implementation of the configurable memory manager.
- *
- * Revision 1.6 2003/01/29 19:57:30 gareth
- * API to retrive local and uri part of the type name
- *
- * Revision 1.5 2002/12/19 14:04:05 gareth
- * get/set methods to see if the represented type is anonymous. Patch by Peter Volchek.
- *
- * Revision 1.4 2002/11/04 14:49:41 tng
- * C++ Namespace Support.
- *
- * Revision 1.3 2002/03/21 15:34:40 knoaman
- * Add support for reporting line/column numbers of schema errors.
- *
- * Revision 1.2 2002/02/06 22:29:24 knoaman
- * Remove unnecessary data/methods.
- *
- * Revision 1.1.1.1 2002/02/01 22:22:45 peiyongz
- * sane_include
- *
- * Revision 1.27 2002/01/15 19:09:16 knoaman
- * Fix for bug 5807.
- *
- * Revision 1.26 2002/01/02 15:20:22 tng
- * Schema Fix: should not store a temp value as the key in the element pool and the attribute pool.
- *
- * Revision 1.25 2001/12/17 21:38:59 tng
- * Fix dangling pointer.
- *
- * Revision 1.24 2001/11/21 14:30:13 knoaman
- * Fix for UPA checking.
- *
- * Revision 1.23 2001/11/15 17:10:19 knoaman
- * Particle derivation checking support.
- *
- * Revision 1.22 2001/11/07 21:50:28 tng
- * Fix comment log that lead to error.
- *
- * Revision 1.21 2001/11/07 21:12:15 tng
- * Performance: Create QName in ContentSpecNode only if it is a leaf/Any/PCDataNode.
- *
- * Revision 1.20 2001/10/12 18:08:57 tng
- * make sure the second node exists before calling getType
- *
- * Revision 1.19 2001/10/04 15:08:56 knoaman
- * Add support for circular import.
- *
- * Revision 1.18 2001/09/05 20:49:11 knoaman
- * Fix for complexTypes with mixed content model.
- *
- * Revision 1.17 2001/08/29 21:27:07 knoaman
- * no message
- *
- * Revision 1.16 2001/08/28 20:43:52 knoaman
- * Fix for content spec node adoption.
- *
- * Revision 1.15 2001/08/27 23:04:02 knoaman
- * Handle deletion of spec node tree created during UPA checking.
- *
- * Revision 1.14 2001/08/27 20:48:45 knoaman
- * Make the UPA rename before the content model expansion.
- *
- * Revision 1.13 2001/08/27 20:14:42 knoaman
- * Validate attributes in <all>, <redefine>, <group> and <attributeGroup> declarations.
- * Misc. fixes.
- *
- * Revision 1.12 2001/08/24 12:48:48 tng
- * Schema: AllContentModel
- *
- * Revision 1.11 2001/08/23 11:54:26 tng
- * Add newline at the end and various typo fixes.
- *
- * Revision 1.10 2001/08/21 18:14:55 knoaman
- * Defer creation of spec node.
- *
- * Revision 1.9 2001/08/21 16:06:11 tng
- * Schema: Unique Particle Attribution Constraint Checking.
- *
- * Revision 1.8 2001/08/09 15:23:16 knoaman
- * add support for <anyAttribute> declaration.
- *
- * Revision 1.7 2001/07/24 18:33:46 knoaman
- * Added support for <group> + extra constraint checking for complexType
- *
- * Revision 1.6 2001/06/05 13:59:53 knoaman
- * Fixes to include and import.
- *
- * Revision 1.5 2001/05/11 13:27:32 tng
- * Copyright update.
- *
- * Revision 1.4 2001/05/10 17:49:40 tng
- * Schema: SchemaValidator fixes
- *
- * Revision 1.3 2001/05/10 16:33:12 knoaman
- * Traverse Schema Part III + error messages.
- *
- * Revision 1.2 2001/05/03 20:34:41 tng
- * Schema: SchemaValidator update
- *
- * Revision 1.1 2001/04/19 17:43:14 knoaman
- * More schema implementation classes.
- *
- */
- // ---------------------------------------------------------------------------
- // Includes
- // ---------------------------------------------------------------------------
- #include <xercesc/framework/XMLBuffer.hpp>
- #include <xercesc/validators/schema/ComplexTypeInfo.hpp>
- #include <xercesc/validators/schema/SchemaAttDefList.hpp>
- #include <xercesc/validators/common/AllContentModel.hpp>
- #include <xercesc/validators/common/ContentSpecNode.hpp>
- #include <xercesc/validators/common/DFAContentModel.hpp>
- #include <xercesc/validators/common/MixedContentModel.hpp>
- #include <xercesc/validators/common/SimpleContentModel.hpp>
- #include <xercesc/validators/schema/XSDLocator.hpp>
- #include <xercesc/internal/XTemplateSerializer.hpp>
- XERCES_CPP_NAMESPACE_BEGIN
- // ---------------------------------------------------------------------------
- // ComplexTypeInfo: Constructors and Destructor
- // ---------------------------------------------------------------------------
- ComplexTypeInfo::ComplexTypeInfo(MemoryManager* const manager)
- : fAnonymous(false)
- , fAbstract(false)
- , fAdoptContentSpec(true)
- , fAttWithTypeId(false)
- , fPreprocessed(false)
- , fDerivedBy(0)
- , fBlockSet(0)
- , fFinalSet(0)
- , fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
- , fElementId(XMLElementDecl::fgInvalidElemId)
- , fContentType(SchemaElementDecl::Empty)
- , fTypeName(0)
- , fTypeLocalName(0)
- , fTypeUri(0)
- , fBaseDatatypeValidator(0)
- , fDatatypeValidator(0)
- , fBaseComplexTypeInfo(0)
- , fContentSpec(0)
- , fAttWildCard(0)
- , fAttDefs(0)
- , fAttList(0)
- , fElements(0)
- , fContentModel(0)
- , fFormattedModel(0)
- , fContentSpecOrgURI(0)
- , fUniqueURI(0)
- , fContentSpecOrgURISize(16)
- , fSpecNodesToDelete(0)
- , fLocator(0)
- , fMemoryManager(manager)
- {
- }
- ComplexTypeInfo::~ComplexTypeInfo()
- {
- fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
- fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
- fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
- if (fAdoptContentSpec) {
- delete fContentSpec;
- }
- delete fAttWildCard;
- delete fAttDefs;
- delete fAttList;
- delete fElements;
- delete fSpecNodesToDelete;
- delete fLocator;
- delete fContentModel;
- fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
- fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
- }
- // ---------------------------------------------------------------------------
- // ComplexTypeInfo: Setter methods
- // ---------------------------------------------------------------------------
- void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd) {
- // Fault in the att list if required
- if (!fAttDefs)
- faultInAttDefList();
- // Tell this guy the element id of its parent (us)
- toAdd->setElemId(getElementId());
- fAttDefs->put((void*)(toAdd->getAttName()->getLocalPart()),
- toAdd->getAttName()->getURI(), toAdd);
- // update and/or create fAttList
- if(!fAttList)
- ((ComplexTypeInfo*)this)->fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs,fMemoryManager);
- fAttList->addAttDef(toAdd);
- }
- void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
- if (fContentSpec && fAdoptContentSpec) {
- delete fContentSpec;
- }
- fContentSpec = toAdopt;
- //reset Content Model
- setContentModel(0);
- }
- void ComplexTypeInfo::setLocator(XSDLocator* const aLocator) {
- if (fLocator)
- delete fLocator;
- fLocator = aLocator;
- }
- // ---------------------------------------------------------------------------
- // ComplexTypeInfo: Getter methods
- // ---------------------------------------------------------------------------
- XMLAttDefList& ComplexTypeInfo::getAttDefList() const
- {
- if (!fAttList)
- {
- // If the att def list is not made yet, then fault it in too
- if (!fAttDefs)
- faultInAttDefList();
- ((ComplexTypeInfo*)this)->fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs, fMemoryManager);
- }
- // Reset it before we return it
- fAttList->Reset();
- return *fAttList;
- }
- const XMLCh*
- ComplexTypeInfo::getFormattedContentModel() const
- {
- //
- // If its not already built, then call the protected virtual method
- // to allow the derived class to build it (since only it knows.)
- // Otherwise, just return the previously formatted methods.
- //
- // Since we are faulting this in, within a const getter, we have to
- // cast off the const-ness.
- //
- if (!fFormattedModel)
- ((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
- return fFormattedModel;
- }
- // ---------------------------------------------------------------------------
- // ComplexTypeInfo: Helper methods
- // ---------------------------------------------------------------------------
- XMLAttDef* ComplexTypeInfo::findAttr(const XMLCh* const qName
- , const unsigned int uriId
- , const XMLCh* const baseName
- , const XMLCh* const prefix
- , const XMLElementDecl::LookupOpts options
- , bool& wasAdded) const
- {
- SchemaAttDef* retVal = 0;
- // If no att list faulted in yet, then it cannot exist
- if (fAttDefs)
- retVal = fAttDefs->get(baseName, uriId);
- // Fault it in if not found and ask to add it
- if (!retVal && (options == XMLElementDecl::AddIfNotFound))
- {
- // Fault in the list itself if not already
- if (!fAttDefs)
- faultInAttDefList();
- // And add a default attribute for this name
- retVal = new (fMemoryManager) SchemaAttDef
- (
- prefix
- , baseName
- , uriId
- , XMLAttDef::CData
- , XMLAttDef::Implied
- , fMemoryManager
- );
- retVal->setElemId(getElementId());
- fAttDefs->put((void*)retVal->getAttName()->getLocalPart(), uriId, retVal);
- // update and/or create fAttList
- if(!fAttList)
- ((ComplexTypeInfo*)this)->fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs,fMemoryManager);
- fAttList->addAttDef(retVal);
- wasAdded = true;
- }
- else
- {
- wasAdded = false;
- }
- return retVal;
- }
- bool ComplexTypeInfo::resetDefs() {
- // If the collection hasn't been faulted in, then no att defs
- if (!fAttDefs)
- return false;
- //
- // Ok, run through them and clear the 'provided' flag on each of them.
- // This lets the scanner use them to track which has been provided and
- // which have not.
- //
- RefHash2KeysTableOfEnumerator<SchemaAttDef> enumDefs(fAttDefs);
- while (enumDefs.hasMoreElements())
- enumDefs.nextElement().setProvided(false);
- return true;
- }
- void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar* const pGrammar,
- GrammarResolver* const pGrammarResolver,
- XMLStringPool* const pStringPool,
- XMLValidator* const pValidator)
- {
- if (fContentSpec) {
- ContentSpecNode* specNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
- XMLContentModel* cm = makeContentModel(true, specNode);
- if (cm) {
- cm->checkUniqueParticleAttribution(pGrammar, pGrammarResolver, pStringPool, pValidator, fContentSpecOrgURI);
- delete cm;
- }
- fSpecNodesToDelete->removeAllElements();
- }
- }
- // ---------------------------------------------------------------------------
- // ComplexTypeInfo: Private Helper methods
- // ---------------------------------------------------------------------------
- void ComplexTypeInfo::faultInAttDefList() const
- {
- // Use a hash modulus of 29 and tell it owns its elements
- ((ComplexTypeInfo*)this)->fAttDefs =
- new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
- }
- XMLCh* ComplexTypeInfo::formatContentModel() const
- {
- XMLCh* newValue = 0;
- if (fContentType == SchemaElementDecl::Any)
- {
- newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
- }
- else if (fContentType == SchemaElementDecl::Empty)
- {
- newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
- }
- else
- {
- //
- // Use a temp XML buffer to format into. Content models could be
- // pretty long, but very few will be longer than one K. The buffer
- // will expand to handle the more pathological ones.
- //
- const ContentSpecNode* specNode = fContentSpec;
- if (specNode) {
- XMLBuffer bufFmt(1023, fMemoryManager);
- specNode->formatSpec(bufFmt);
- newValue = XMLString::replicate
- (
- bufFmt.getRawBuffer()
- , fMemoryManager
- );
- }
- }
- return newValue;
- }
- XMLContentModel* ComplexTypeInfo::makeContentModel(const bool checkUPA, ContentSpecNode* const specNode)
- {
- if ((specNode || fContentSpec) && !fSpecNodesToDelete) {
- fSpecNodesToDelete = new (fMemoryManager) RefVectorOf<ContentSpecNode>(8, true, fMemoryManager);
- }
- // expand the content spec first
- ContentSpecNode* aSpecNode = specNode;
- XMLContentModel* retModel = 0;
- if (aSpecNode) {
- fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
- (
- fContentSpecOrgURISize * sizeof(unsigned int)
- ); //new unsigned int[fContentSpecOrgURISize];
- aSpecNode = convertContentSpecTree(aSpecNode, checkUPA);
- retModel = buildContentModel(aSpecNode);
- fSpecNodesToDelete->addElement(aSpecNode);
- }
- else {
- // building content model for the complex type
- aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
- aSpecNode = convertContentSpecTree(aSpecNode, checkUPA);
- retModel = buildContentModel(aSpecNode);
- delete aSpecNode;
- }
- return retModel;
- }
- XMLContentModel* ComplexTypeInfo::buildContentModel(ContentSpecNode* const aSpecNode)
- {
- XMLContentModel* cmRet = 0;
- if (fContentType == SchemaElementDecl::Simple) {
- // just return nothing
- }
- else if (fContentType == SchemaElementDecl::Mixed_Simple)
- {
- //
- // Just create a mixel content model object. This type of
- // content model is optimized for mixed content validation.
- //
- cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
- }
- else if (fContentType == SchemaElementDecl::Mixed_Complex) {
- cmRet = createChildModel(aSpecNode, true);
- }
- else if (fContentType == SchemaElementDecl::Children)
- {
- //
- // This method will create an optimal model for the complexity
- // of the element's defined model. If its simple, it will create
- // a SimpleContentModel object. If its a simple list, it will
- // create a SimpleListContentModel object. If its complex, it
- // will create a DFAContentModel object.
- //
- cmRet = createChildModel(aSpecNode, false);
- }
- else
- {
- ThrowXML(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren);
- }
- return cmRet;
- }
- // ---------------------------------------------------------------------------
- // SchemaElementDecl: Private helper methods
- // ---------------------------------------------------------------------------
- XMLContentModel* ComplexTypeInfo::createChildModel(ContentSpecNode* specNode, const bool isMixed)
- {
- if(!specNode)
- ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
- ContentSpecNode::NodeTypes specType = specNode->getType();
- //
- // Do a sanity check that the node is does not have a PCDATA id. Since,
- // if it was, it should have already gotten taken by the Mixed model.
- //
- if (specNode->getElement()) {
- if (specNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
- ThrowXML(RuntimeException, XMLExcepts::CM_NoPCDATAHere);
- }
- //
- // According to the type of node, we will create the correct type of
- // content model.
- //
- if (((specType & 0x0f) == ContentSpecNode::Any) ||
- ((specType & 0x0f) == ContentSpecNode::Any_Other) ||
- ((specType & 0x0f) == ContentSpecNode::Any_NS)) {
- // let fall through to build a DFAContentModel
- }
- else if (isMixed)
- {
- if (specType == ContentSpecNode::All) {
- // All the nodes under an ALL must be additional ALL nodes and
- // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
- // We collapse the ELEMENTs into a single vector.
- return new (fMemoryManager) AllContentModel(specNode, true, fMemoryManager);
- }
- else if (specType == ContentSpecNode::ZeroOrOne) {
- // An ALL node can appear under a ZERO_OR_ONE node.
- if (specNode->getFirst()->getType() == ContentSpecNode::All) {
- return new (fMemoryManager) AllContentModel(specNode->getFirst(), true, fMemoryManager);
- }
- }
- // otherwise, let fall through to build a DFAContentModel
- }
- else if (specType == ContentSpecNode::Leaf)
- {
- // Create a simple content model
- return new (fMemoryManager) SimpleContentModel
- (
- false
- , specNode->getElement()
- , 0
- , ContentSpecNode::Leaf
- , fMemoryManager
- );
- }
- else if (((specType & 0x0f) == ContentSpecNode::Choice)
- || ((specType & 0x0f) == ContentSpecNode::Sequence))
- {
- //
- // Lets see if both of the children are leafs. If so, then it has to
- // be a simple content model
- //
- if ((specNode->getFirst()->getType() == ContentSpecNode::Leaf)
- && (specNode->getSecond())
- && (specNode->getSecond()->getType() == ContentSpecNode::Leaf))
- {
- return new (fMemoryManager) SimpleContentModel
- (
- false
- , specNode->getFirst()->getElement()
- , specNode->getSecond()->getElement()
- , specType
- , fMemoryManager
- );
- }
- }
- else if ((specType == ContentSpecNode::OneOrMore)
- || (specType == ContentSpecNode::ZeroOrMore)
- || (specType == ContentSpecNode::ZeroOrOne))
- {
- //
- // Its a repetition, so see if its one child is a leaf. If so its a
- // repetition of a single element, so we can do a simple content
- // model for that.
- //
- if (specNode->getFirst()->getType() == ContentSpecNode::Leaf)
- {
- return new (fMemoryManager) SimpleContentModel
- (
- false
- , specNode->getFirst()->getElement()
- , 0
- , specType
- , fMemoryManager
- );
- }
- else if (specNode->getFirst()->getType() == ContentSpecNode::All)
- return new (fMemoryManager) AllContentModel(specNode->getFirst(), false, fMemoryManager);
- }
- else if (specType == ContentSpecNode::All)
- return new (fMemoryManager) AllContentModel(specNode, false, fMemoryManager);
- else
- {
- ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
- }
- // Its not any simple type of content, so create a DFA based content model
- return new (fMemoryManager) DFAContentModel(false, specNode, isMixed, fMemoryManager);
- }
- ContentSpecNode*
- ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
- const bool checkUPA) {
- if (!curNode)
- return 0;
- const ContentSpecNode::NodeTypes curType = curNode->getType();
- // When checking Unique Particle Attribution, rename leaf elements
- if (checkUPA) {
- if (curNode->getElement()) {
- fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
- curNode->getElement()->setURI(fUniqueURI);
- fUniqueURI++;
- }
- if (fUniqueURI == fContentSpecOrgURISize)
- resizeContentSpecOrgURI();
- }
- // Get the spec type of the passed node
- int minOccurs = curNode->getMinOccurs();
- int maxOccurs = curNode->getMaxOccurs();
- ContentSpecNode* retNode = curNode;
- if ((curType & 0x0f) == ContentSpecNode::Any
- || (curType & 0x0f) == ContentSpecNode::Any_Other
- || (curType & 0x0f) == ContentSpecNode::Any_NS
- || curType == ContentSpecNode::Leaf)
- {
- retNode = expandContentModel(curNode, minOccurs, maxOccurs);
- }
- else if (((curType & 0x0f) == ContentSpecNode::Choice)
- || (curType == ContentSpecNode::All)
- || ((curType & 0x0f) == ContentSpecNode::Sequence))
- {
- ContentSpecNode* childNode = curNode->getFirst();
- ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA);
- ContentSpecNode* rightNode = curNode->getSecond();
- if (!rightNode) {
- retNode = expandContentModel(leftNode, minOccurs, maxOccurs);
- curNode->setAdoptFirst(false);
- delete curNode;
- return retNode;
- }
- if (leftNode != childNode) {
- curNode->setAdoptFirst(false);
- curNode->setFirst(leftNode);
- curNode->setAdoptFirst(true);
- }
- childNode = rightNode;
- rightNode = convertContentSpecTree(childNode, checkUPA);
- if (rightNode != childNode) {
- curNode->setAdoptSecond(false);
- curNode->setSecond(rightNode);
- curNode->setAdoptSecond(true);
- }
- retNode = expandContentModel(curNode, minOccurs, maxOccurs);
- }
- return retNode;
- }
- ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
- const int minOccurs,
- const int maxOccurs)
- {
- if (!specNode) {
- return 0;
- }
- ContentSpecNode* saveNode = specNode;
- ContentSpecNode* retNode = specNode;
- if (minOccurs == 1 && maxOccurs == 1) {
- }
- else if (minOccurs == 0 && maxOccurs == 1) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::ZeroOrOne
- , retNode
- , 0
- , true
- , true
- , fMemoryManager
- );
- }
- else if (minOccurs == 0 && maxOccurs == -1) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::ZeroOrMore
- , retNode
- , 0
- , true
- , true
- , fMemoryManager
- );
- }
- else if (minOccurs == 1 && maxOccurs == -1) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::OneOrMore
- , retNode
- , 0
- , true
- , true
- , fMemoryManager
- );
- }
- else if (maxOccurs == -1) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::OneOrMore
- , retNode
- , 0
- , true
- , true
- , fMemoryManager
- );
- for (int i=0; i < (int)(minOccurs-1); i++) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::Sequence
- , saveNode
- , retNode
- , false
- , true
- , fMemoryManager
- );
- }
- }
- else {
- if (minOccurs == 0) {
- ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::ZeroOrOne
- , saveNode
- , 0
- , true
- , true
- , fMemoryManager
- );
- retNode = optional;
- for (int i=0; i < (int)(maxOccurs-minOccurs-1); i++) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::Sequence
- , retNode
- , optional
- , true
- , false
- , fMemoryManager
- );
- }
- }
- else {
- if (minOccurs > 1) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::Sequence
- , retNode
- , saveNode
- , true
- , false
- , fMemoryManager
- );
- for (int i=1; i < (int)(minOccurs-1); i++) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::Sequence
- , retNode
- , saveNode
- , true
- , false
- , fMemoryManager
- );
- }
- }
- int counter = maxOccurs-minOccurs;
- if (counter > 0) {
- ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::ZeroOrOne
- , saveNode
- , 0
- , false
- , true
- , fMemoryManager
- );
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::Sequence
- , retNode
- , optional
- , true
- , true
- , fMemoryManager
- );
- for (int j=1; j < counter; j++) {
- retNode = new (fMemoryManager) ContentSpecNode
- (
- ContentSpecNode::Sequence
- , retNode
- , optional
- , true
- , false
- , fMemoryManager
- );
- }
- }
- }
- }
- return retNode;
- }
- void ComplexTypeInfo::resizeContentSpecOrgURI() {
- unsigned int newSize = fContentSpecOrgURISize * 2;
- unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
- (
- newSize * sizeof(unsigned int)
- ); //new unsigned int[newSize];
- // Copy the existing values
- unsigned int index = 0;
- for (; index < fContentSpecOrgURISize; index++)
- newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
- for (; index < newSize; index++)
- newContentSpecOrgURI[index] = 0;
- // Delete the old array and udpate our members
- fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
- fContentSpecOrgURI = newContentSpecOrgURI;
- fContentSpecOrgURISize = newSize;
- }
- /***
- * Support for Serialization/De-serialization
- ***/
- IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
- void ComplexTypeInfo::serialize(XSerializeEngine& serEng)
- {
-
- if (serEng.isStoring())
- {
- serEng<<fAnonymous;
- serEng<<fAbstract;
- serEng<<fAdoptContentSpec;
- serEng<<fAttWithTypeId;
- serEng<<fPreprocessed;
- serEng<<fDerivedBy;
- serEng<<fBlockSet;
- serEng<<fFinalSet;
- serEng<<fScopeDefined;
- serEng<<fElementId;
- serEng<<fContentType;
- serEng.writeString(fTypeName);
- serEng.writeString(fTypeLocalName);
- serEng.writeString(fTypeUri);
- DatatypeValidator::storeDV(serEng, fBaseDatatypeValidator);
- DatatypeValidator::storeDV(serEng, fDatatypeValidator);
- serEng<<fBaseComplexTypeInfo;
- serEng<<fContentSpec;
- // we need to save a flag to specify
- // if this content spce has been expanded or not
- if (fContentModel)
- serEng<<true;
- else
- serEng<<false;
- serEng<<fAttWildCard;
- serEng<<fAttList;
- /***
- *
- * Serialize RefVectorOf<SchemaElementDecl>* fElements;
- * Serialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
- ***/
- XTemplateSerializer::storeObject(fElements, serEng);
- XTemplateSerializer::storeObject(fAttDefs, serEng);
- /***
- * Don't serialize
- *
- * fContentModel;
- * fFormattedModel;
- * fLocator;
- * fSpecNodesToDelete
- *
- * fContentSpecOrgURI: start of the array
- * fContentSpecOrgURISize: size of the array
- * fUniqueURI: the current last element in the array
- ***/
- }
- else
- {
- serEng>>fAnonymous;
- serEng>>fAbstract;
- serEng>>fAdoptContentSpec;
- serEng>>fAttWithTypeId;
- serEng>>fPreprocessed;
- serEng>>fDerivedBy;
- serEng>>fBlockSet;
- serEng>>fFinalSet;
- serEng>>fScopeDefined;
- serEng>>fElementId;
- serEng>>fContentType;
- serEng.readString(fTypeName);
- serEng.readString(fTypeLocalName);
- serEng.readString(fTypeUri);
- fBaseDatatypeValidator = DatatypeValidator::loadDV(serEng);
- fDatatypeValidator = DatatypeValidator::loadDV(serEng);
- serEng>>fBaseComplexTypeInfo;
- serEng>>fContentSpec;
- //read the expanded flag
- bool expanded = false;
- serEng>>expanded;
- if (expanded)
- {
- fContentModel = buildContentModel(fContentSpec);
- }
- //else
- // if contentSpec has NOT been expanded yet,
- // leave the building to makeContentModel
- serEng>>fAttWildCard;
- serEng>>fAttList;
- /***
- *
- * Deserialize RefVectorOf<SchemaElementDecl>* fElements;
- * Deserialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
- ***/
- XTemplateSerializer::loadObject(&fElements, 8, false, serEng);
- XTemplateSerializer::loadObject(&fAttDefs, 29, true, serEng);
- /***
- * Don't deserialize
- *
- * fFormattedModel;
- * fLocator;
- * fSpecNodesToDelete
- *
- * fContentSpecOrgURI: start of the array
- * fContentSpecOrgURISize: size of the array
- * fUniqueURI: the current last element in the array
- ***/
- fFormattedModel = 0;
- fLocator = 0;
- fSpecNodesToDelete = 0;
- fContentSpecOrgURI = 0;
- fContentSpecOrgURISize = 0;
- fUniqueURI = 0;
- }
- }
- XERCES_CPP_NAMESPACE_END
- /**
- * End of file ComplexTypeInfo.cpp
- */