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); }
XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // AllContentModel: Constructors and Destructor // --------------------------------------------------------------------------- AllContentModel::AllContentModel( ContentSpecNode* const parentContentSpec , const bool isMixed , MemoryManager* const manager) : fMemoryManager(manager) , fCount(0) , fChildren(0) , fChildOptional(0) , fNumRequired(0) , fIsMixed(isMixed) , fHasOptionalContent(false) { // // Create a vector of unsigned ints that will be filled in with the // ids of the child nodes. It will be expanded as needed but we give // it an initial capacity of 64 which should be more than enough for // 99% of the scenarios. // ValueVectorOf<QName*> children(64, fMemoryManager); ValueVectorOf<bool> childOptional(64, fMemoryManager); // // Get the parent element's content spec. This is the head of the tree // of nodes that describes the content model. We will iterate this // tree. // ContentSpecNode* curNode = parentContentSpec; if (!curNode) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoParentCSN, fMemoryManager); // And now call the private recursive method that iterates the tree if (curNode->getType() == ContentSpecNode::All && curNode->getMinOccurs() == 0) { fHasOptionalContent = true; } buildChildList(curNode, children, childOptional); // // And now we know how many elements we need in our member list. So // fill them in. // fCount = children.size(); fChildren = (QName**) fMemoryManager->allocate(fCount * sizeof(QName*)); //new QName*[fCount]; fChildOptional = (bool*) fMemoryManager->allocate(fCount * sizeof(bool)); //new bool[fCount]; for (unsigned int index = 0; index < fCount; index++) { fChildren[index] = new (fMemoryManager) QName(*(children.elementAt(index))); fChildOptional[index] = childOptional.elementAt(index); } }
void XMLInitializer::initializeComplexTypeInfo() { // create type name XMLCh typeName[128]; XMLSize_t nsLen = XMLString::stringLen(SchemaSymbols::fgURI_SCHEMAFORSCHEMA); XMLString::copyString(typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA); typeName[nsLen] = chComma; XMLString::copyString(typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE); // Create and initialize 'anyType' ComplexTypeInfo::fAnyType = new ComplexTypeInfo(); ContentSpecNode* term = new ContentSpecNode ( new QName ( XMLUni::fgZeroLenString , XMLUni::fgZeroLenString , 1 ) , false ); term->setType(ContentSpecNode::Any_Lax); term->setMinOccurs(0); term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED); ContentSpecNode* particle = new ContentSpecNode ( ContentSpecNode::ModelGroupSequence , term , 0 ); SchemaAttDef* attWildCard = new SchemaAttDef ( XMLUni::fgZeroLenString , XMLUni::fgZeroLenString , 1 , XMLAttDef::Any_Any , XMLAttDef::ProcessContents_Lax ); ComplexTypeInfo::fAnyType->setTypeName(typeName); ComplexTypeInfo::fAnyType->setBaseComplexTypeInfo(ComplexTypeInfo::fAnyType); ComplexTypeInfo::fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION); ComplexTypeInfo::fAnyType->setContentType(SchemaElementDecl::Mixed_Complex); ComplexTypeInfo::fAnyType->setContentSpec(particle); ComplexTypeInfo::fAnyType->setAttWildCard(attWildCard); }
// --------------------------------------------------------------------------- // 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); }
ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode, int minOccurs, int maxOccurs, bool bAllowCompactSyntax) { 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 ); } // if what is being repeated is a leaf avoid expanding the tree else if(bAllowCompactSyntax && (saveNode->getType()==ContentSpecNode::Leaf || (saveNode->getType() & 0x0f)==ContentSpecNode::Any || (saveNode->getType() & 0x0f)==ContentSpecNode::Any_Other || (saveNode->getType() & 0x0f)==ContentSpecNode::Any_NS)) { retNode = new (fMemoryManager) ContentSpecNode ( ContentSpecNode::Loop , retNode , 0 , true , true , fMemoryManager ); retNode->setMinOccurs(minOccurs); retNode->setMaxOccurs(maxOccurs); if(minOccurs==0) retNode = new (fMemoryManager) ContentSpecNode ( ContentSpecNode::ZeroOrMore , retNode , 0 , true , true , fMemoryManager ); else 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 < (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 < (maxOccurs-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 < (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; }
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; }
ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int emptyNSId) { if (!sAnyTypeMutexRegistered) { if (!sAnyTypeMutex) { XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex); if (!sAnyTypeMutex) sAnyTypeMutex = new XMLMutex; } // Use a faux scope to synchronize while we do this { XMLMutexLock lock(sAnyTypeMutex); // If we got here first, then register it and set the registered flag if (!sAnyTypeMutexRegistered) { // create type name XMLCh typeName[128]; unsigned int nsLen = XMLString::stringLen( SchemaSymbols::fgURI_SCHEMAFORSCHEMA); XMLString::copyString( typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA); typeName[nsLen] = chComma; XMLString::copyString( typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE); // Create and initialize 'anyType' fAnyType = new ComplexTypeInfo(); ContentSpecNode* term = new ContentSpecNode ( new QName ( XMLUni::fgZeroLenString , XMLUni::fgZeroLenString , emptyNSId ) , false ); term->setType(ContentSpecNode::Any_Lax); term->setMinOccurs(0); term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED); ContentSpecNode* particle = new ContentSpecNode ( ContentSpecNode::ModelGroupSequence , term , 0 ); SchemaAttDef* attWildCard = new SchemaAttDef ( XMLUni::fgZeroLenString , XMLUni::fgZeroLenString , emptyNSId , XMLAttDef::Any_Any , XMLAttDef::ProcessContents_Lax ); fAnyType->setTypeName(typeName); fAnyType->setBaseComplexTypeInfo(fAnyType); fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION); fAnyType->setContentType(SchemaElementDecl::Mixed_Complex); fAnyType->setContentSpec(particle); fAnyType->setAttWildCard(attWildCard); // register cleanup method anyTypeCleanup.registerCleanup(ComplexTypeInfo::reinitAnyType); sAnyTypeMutexRegistered = true; } } } return fAnyType; }
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() ); }