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); }
// --------------------------------------------------------------------------- // AllContentModel: Private helper methods // --------------------------------------------------------------------------- void AllContentModel::buildChildList(ContentSpecNode* const curNode , ValueVectorOf<QName*>& toFill , ValueVectorOf<bool>& toOptional) { // Get the type of spec node our current node is const ContentSpecNode::NodeTypes curType = curNode->getType(); if (curType == ContentSpecNode::All) { // Get both the child node pointers ContentSpecNode* leftNode = curNode->getFirst(); ContentSpecNode* rightNode = curNode->getSecond(); // Recurse on the left and right nodes buildChildList(leftNode, toFill, toOptional); buildChildList(rightNode, toFill, toOptional); } else if (curType == ContentSpecNode::Leaf) { // At leaf, add the element to list of elements permitted in the all toFill.addElement(curNode->getElement()); toOptional.addElement(false); fNumRequired++; } else if (curType == ContentSpecNode::ZeroOrOne) { // At ZERO_OR_ONE node, subtree must be an element // that was specified with minOccurs=0, maxOccurs=1 ContentSpecNode* leftNode = curNode->getFirst(); if (leftNode->getType() != ContentSpecNode::Leaf) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); toFill.addElement(leftNode->getElement()); toOptional.addElement(true); } else ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); }
XMLContentModel* ComplexTypeInfo::makeContentModel(bool checkUPA) { ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec); if (checkUPA) { fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate ( fContentSpecOrgURISize * sizeof(unsigned int) ); //new unsigned int[fContentSpecOrgURISize]; } aSpecNode = convertContentSpecTree(aSpecNode, checkUPA, useRepeatingLeafNodes(aSpecNode)); Janitor<ContentSpecNode> janSpecNode(aSpecNode); XMLContentModel* cmRet = 0; if (fContentType == SchemaElementDecl::Simple || fContentType == SchemaElementDecl::ElementOnlyEmpty) { // 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 || fContentType == SchemaElementDecl::Children) { bool isMixed = (fContentType == SchemaElementDecl::Mixed_Complex); // // 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. // if(!aSpecNode) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); ContentSpecNode::NodeTypes specType = aSpecNode->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 (aSpecNode->getElement() && aSpecNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager); // // 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) || specType == ContentSpecNode::Loop) { // 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. cmRet = new (fMemoryManager) AllContentModel(aSpecNode, true, fMemoryManager); } else if (specType == ContentSpecNode::ZeroOrOne) { // An ALL node can appear under a ZERO_OR_ONE node. if (aSpecNode->getFirst()->getType() == ContentSpecNode::All) { cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), true, fMemoryManager); } } // otherwise, let fall through to build a DFAContentModel } else if (specType == ContentSpecNode::Leaf) { // Create a simple content model cmRet = new (fMemoryManager) SimpleContentModel ( false , aSpecNode->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 ((aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf) && (aSpecNode->getSecond()) && (aSpecNode->getSecond()->getType() == ContentSpecNode::Leaf)) { cmRet = new (fMemoryManager) SimpleContentModel ( false , aSpecNode->getFirst()->getElement() , aSpecNode->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 (aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf) { cmRet = new (fMemoryManager) SimpleContentModel ( false , aSpecNode->getFirst()->getElement() , 0 , specType , fMemoryManager ); } else if (aSpecNode->getFirst()->getType() == ContentSpecNode::All) cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), false, fMemoryManager); } else if (specType == ContentSpecNode::All) cmRet = new (fMemoryManager) AllContentModel(aSpecNode, false, fMemoryManager); else { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); } // Its not any simple type of content, so create a DFA based content model if(cmRet==0) cmRet = new (fMemoryManager) DFAContentModel(false, aSpecNode, isMixed, fMemoryManager); } else { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager); } return cmRet; }
XMLContentModel* DTDElementDecl::createChildModel() { // Get the content spec node of the element ContentSpecNode* specNode = getContentSpec(); if(!specNode) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, getMemoryManager()); // // Do a sanity check that the node 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) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, getMemoryManager()); } // // According to the type of node, we will create the correct type of // content model. // if (specNode->getType() == ContentSpecNode::Leaf) { // Create a simple content model return new (getMemoryManager()) SimpleContentModel ( true , specNode->getElement() , 0 , ContentSpecNode::Leaf , getMemoryManager() ); } else if ((specNode->getType() == ContentSpecNode::Choice) || (specNode->getType() == 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()->getType() == ContentSpecNode::Leaf)) { return new (getMemoryManager()) SimpleContentModel ( true , specNode->getFirst()->getElement() , specNode->getSecond()->getElement() , specNode->getType() , getMemoryManager() ); } } else if ((specNode->getType() == ContentSpecNode::OneOrMore) || (specNode->getType() == ContentSpecNode::ZeroOrMore) || (specNode->getType() == 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 (getMemoryManager()) SimpleContentModel ( true , specNode->getFirst()->getElement() , 0 , specNode->getType() , getMemoryManager() ); } } else { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, getMemoryManager()); } // Its not any simple type of content, so create a DFA based content model return new (getMemoryManager()) DFAContentModel ( true , this->getContentSpec() , getMemoryManager() ); }