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 + -
显示快捷键?