complextypeinfo.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,129 行 · 第 1/3 页
CPP
1,129 行
// ---------------------------------------------------------------------------// 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 , 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, false, fMemoryManager); 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 && !fContentModel) { fContentModel = makeContentModel(true); if (fContentModel) { fContentModel->checkUniqueParticleAttribution(pGrammar, pGrammarResolver, pStringPool, pValidator, fContentSpecOrgURI, fTypeLocalName); } }}// ---------------------------------------------------------------------------// 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* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec); XMLContentModel* retModel = 0; if (checkUPA) { fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate ( fContentSpecOrgURISize * sizeof(unsigned int) ); //new unsigned int[fContentSpecOrgURISize]; } 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 { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager); } return cmRet;}// ---------------------------------------------------------------------------// SchemaElementDecl: Private helper methods// ---------------------------------------------------------------------------XMLContentModel* ComplexTypeInfo::createChildModel(ContentSpecNode* specNode, const bool isMixed){ if(!specNode) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); 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) 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)) { // 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 { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); } // 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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?