Ignore:
Timestamp:
Dec 12, 2012, 6:10:33 PM (6 years ago)
Author:
cameron
Message:

Various fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icXML/icXML-devel/src/xercesc/validators/schema/ComplexTypeInfo.cpp

    r2736 r2774  
    1 /*
    2  * Licensed to the Apache Software Foundation (ASF) under one or more
    3  * contributor license agreements.  See the NOTICE file distributed with
    4  * this work for additional information regarding copyright ownership.
    5  * The ASF licenses this file to You under the Apache License, Version 2.0
    6  * (the "License"); you may not use this file except in compliance with
    7  * the License.  You may obtain a copy of the License at
    8  *
    9  *      http://www.apache.org/licenses/LICENSE-2.0
    10  *
    11  * Unless required by applicable law or agreed to in writing, software
    12  * distributed under the License is distributed on an "AS IS" BASIS,
    13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  * See the License for the specific language governing permissions and
    15  * limitations under the License.
    16  */
    17 
    18 /*
    19  * $Id: ComplexTypeInfo.cpp 901107 2010-01-20 08:45:02Z borisk $
    20  */
    21 
    22 // ---------------------------------------------------------------------------
    23 //  Includes
    24 // ---------------------------------------------------------------------------
    25 #include <icxercesc/framework/XMLBuffer.hpp>
    26 #include <icxercesc/validators/schema/ComplexTypeInfo.hpp>
    27 #include <xercesc/validators/schema/SchemaAttDefList.hpp>
    28 #include <icxercesc/validators/common/AllContentModel.hpp>
    29 #include <xercesc/validators/common/ContentSpecNode.hpp>
    30 #include <icxercesc/validators/common/DFAContentModel.hpp>
    31 #include <icxercesc/validators/common/MixedContentModel.hpp>
    32 #include <icxercesc/validators/common/SimpleContentModel.hpp>
    33 #include <xercesc/validators/schema/XSDLocator.hpp>
    34 #include <xercesc/internal/XTemplateSerializer.hpp>
    35 #include <xercesc/util/XMLInitializer.hpp>
    36 
    37 XERCES_CPP_NAMESPACE_BEGIN
    38 
    39 // ---------------------------------------------------------------------------
    40 //  ComplexTypeInfo: Static member data
    41 // ---------------------------------------------------------------------------
    42 ComplexTypeInfo* ComplexTypeInfo::fAnyType = 0;
    43 
    44 void XMLInitializer::initializeComplexTypeInfo()
    45 {
    46   // create type name
    47   XMLCh typeName[128];
    48   XMLSize_t nsLen = XMLString::stringLen(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
    49 
    50   XMLString::copyString(typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
    51   typeName[nsLen] = chComma;
    52   XMLString::copyString(typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE);
    53 
    54   // Create and initialize 'anyType'
    55   ComplexTypeInfo::fAnyType = new ComplexTypeInfo();
    56 
    57   ContentSpecNode* term = new ContentSpecNode
    58     (
    59       new QName
    60       (
    61         XMLUni::fgZeroLenString
    62         , XMLUni::fgZeroLenString
    63         , 1
    64       )
    65       , false
    66     );
    67   term->setType(ContentSpecNode::Any_Lax);
    68   term->setMinOccurs(0);
    69   term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);
    70 
    71   ContentSpecNode* particle = new ContentSpecNode
    72     (
    73       ContentSpecNode::ModelGroupSequence
    74       , term
    75       , 0
    76     );
    77 
    78   SchemaAttDef* attWildCard = new SchemaAttDef
    79     (
    80       XMLUni::fgZeroLenString
    81       , XMLUni::fgZeroLenString
    82       , 1
    83       , XMLAttDef::Any_Any
    84       , XMLAttDef::ProcessContents_Lax
    85     );
    86 
    87   ComplexTypeInfo::fAnyType->setTypeName(typeName);
    88   ComplexTypeInfo::fAnyType->setBaseComplexTypeInfo(ComplexTypeInfo::fAnyType);
    89   ComplexTypeInfo::fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
    90   ComplexTypeInfo::fAnyType->setContentType(SchemaElementDecl::Mixed_Complex);
    91   ComplexTypeInfo::fAnyType->setContentSpec(particle);
    92   ComplexTypeInfo::fAnyType->setAttWildCard(attWildCard);
    93 }
    94 
    95 void XMLInitializer::terminateComplexTypeInfo()
    96 {
    97   delete ComplexTypeInfo::fAnyType;
    98   ComplexTypeInfo::fAnyType = 0;
    99 }
    100 
    101 ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int /*emptyNSId*/)
    102 {
    103     return fAnyType;
    104 }
    105 
    106 
    107 // ---------------------------------------------------------------------------
    108 //  ComplexTypeInfo: Constructors and Destructor
    109 // ---------------------------------------------------------------------------
    110 ComplexTypeInfo::ComplexTypeInfo(MemoryManager* const manager)
    111     : fAnonymous(false)
    112     , fAbstract(false)
    113     , fAdoptContentSpec(true)
    114     , fAttWithTypeId(false)
    115     , fPreprocessed(false)
    116     , fDerivedBy(0)
    117     , fBlockSet(0)
    118     , fFinalSet(0)
    119     , fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
    120     , fContentType(SchemaElementDecl::Empty)
    121     , fElementId(XMLElementDecl::fgInvalidElemId)
    122     , fUniqueURI(0)
    123     , fContentSpecOrgURISize(16)
    124     , fTypeName(0)
    125     , fTypeLocalName(0)
    126     , fTypeUri(0)
    127     , fBaseDatatypeValidator(0)
    128     , fDatatypeValidator(0)
    129     , fBaseComplexTypeInfo(0)
    130     , fContentSpec(0)
    131     , fAttWildCard(0)
    132     , fAttList(0)
    133     , fElements(0)
    134     , fAttDefs(0)
    135     , fContentModel(0)
    136     , fFormattedModel(0)
    137     , fContentSpecOrgURI(0)
    138     , fLocator(0)
    139     , fMemoryManager(manager)
    140 {
    141     fAttDefs = new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
    142     fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs,fMemoryManager);
    143 }
    144 
    145 
    146 ComplexTypeInfo::~ComplexTypeInfo()
    147 {
    148     fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
    149     fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
    150     fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
    151 
    152     if (fAdoptContentSpec) {
    153         delete fContentSpec;
    154     }
    155 
    156     delete fAttWildCard;
    157     delete fAttDefs;
    158     delete fAttList;
    159     delete fElements;
    160     delete fLocator;
    161 
    162     delete fContentModel;
    163     fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
    164     fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
    165 
    166 }
    167 
    168 // ---------------------------------------------------------------------------
    169 //  ComplexTypeInfo: Setter methods
    170 // ---------------------------------------------------------------------------
    171 void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd) {
    172 
    173     // Tell this guy the element id of its parent (us)
    174     toAdd->setElemId(getElementId());
    175 
    176     fAttDefs->put((void*)(toAdd->getAttName()->getLocalPart()),
    177                           toAdd->getAttName()->getURI(), toAdd);
    178     // update and/or create fAttList
    179     fAttList->addAttDef(toAdd);
    180 }
    181 
    182 void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
    183 
    184     if (fContentSpec && fAdoptContentSpec) {
    185         delete fContentSpec;
    186     }
    187 
    188     fContentSpec = toAdopt;
    189 }
    190 
    191 void ComplexTypeInfo::setLocator(XSDLocator* const aLocator) {
    192 
    193     if (fLocator)
    194         delete fLocator;
    195 
    196     fLocator = aLocator;
    197 }
    198 
    199 // ---------------------------------------------------------------------------
    200 //  ComplexTypeInfo: Getter methods
    201 // ---------------------------------------------------------------------------
    202 XMLAttDefList& ComplexTypeInfo::getAttDefList() const
    203 {
    204     // NOTE: if users plan on using nextElement() to access attributes
    205     //       they need to call Reset() explicitly (i.e attList.Reset()).
    206     //       It's better to get the attribute count and use an index to
    207     //       access attributes (especially if same grammar is used in
    208     //       multiple threads).
    209     return *fAttList;
    210 }
    211 
    212 const XMLCh*
    213 ComplexTypeInfo::getFormattedContentModel() const
    214 {
    215     //
    216     //  If its not already built, then call the protected virtual method
    217     //  to allow the derived class to build it (since only it knows.)
    218     //  Otherwise, just return the previously formatted methods.
    219     //
    220     //  Since we are faulting this in, within a const getter, we have to
    221     //  cast off the const-ness.
    222     //
    223     if (!fFormattedModel)
    224         ((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
    225 
    226     return fFormattedModel;
    227 }
    228 
    229 // ---------------------------------------------------------------------------
    230 //  ComplexTypeInfo: Helper methods
    231 // ---------------------------------------------------------------------------
    232 void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar*    const pGrammar,
    233                                                       GrammarResolver*  const pGrammarResolver,
    234                                                       XMLStringPool*    const pStringPool,
    235                                                       XMLValidator*     const pValidator)
    236 {
    237     if (fContentSpec && !fContentModel)
    238     {
    239         fContentModel = makeContentModel(true);
    240         if (fContentModel) {
    241             fContentModel->checkUniqueParticleAttribution(pGrammar, pGrammarResolver, pStringPool, pValidator, fContentSpecOrgURI, fTypeLocalName);
    242         }
    243     }
    244 }
    245 
    246 // ---------------------------------------------------------------------------
    247 //  ComplexTypeInfo: Private Helper methods
    248 // ---------------------------------------------------------------------------
    249 void ComplexTypeInfo::faultInAttDefList() const
    250 {
    251     // Use a hash modulus of 29 and tell it owns its elements
    252     ((ComplexTypeInfo*)this)->fAttDefs =
    253         new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
    254 }
    255 
    256 XMLCh* ComplexTypeInfo::formatContentModel() const
    257 {
    258     XMLCh* newValue = 0;
    259     if (fContentType == SchemaElementDecl::Any)
    260     {
    261         newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
    262     }
    263     else if (fContentType == SchemaElementDecl::Empty ||
    264              fContentType == SchemaElementDecl::ElementOnlyEmpty)
    265     {
    266         newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
    267     }
    268     else
    269     {
    270         //
    271         //  Use a temp XML buffer to format into. Content models could be
    272         //  pretty long, but very few will be longer than one K. The buffer
    273         //  will expand to handle the more pathological ones.
    274         //
    275         const ContentSpecNode* specNode = fContentSpec;
    276 
    277         if (specNode) {
    278             XMLBuffer bufFmt(1023, fMemoryManager);
    279 
    280             specNode->formatSpec(bufFmt);
    281             newValue = XMLString::replicate
    282             (
    283                 bufFmt.getRawBuffer()
    284                 , fMemoryManager
    285             );
    286         }
    287     }
    288     return newValue;
    289 }
    290 
    291 bool ComplexTypeInfo::useRepeatingLeafNodes(ContentSpecNode* particle)
    292 {
    293     int maxOccurs = particle->getMaxOccurs();
    294     int minOccurs = particle->getMinOccurs();
    295     ContentSpecNode::NodeTypes type = particle->getType();
    296 
    297     if (((type & 0x0f) == ContentSpecNode::Choice) ||  ((type & 0x0f) == ContentSpecNode::Sequence))
    298     {
    299         if (minOccurs != 1 || maxOccurs != 1) {
    300             if(particle->getFirst()!=0 && particle->getSecond()==0)
    301             {
    302                 ContentSpecNode* particle2 = particle->getFirst();
    303                 ContentSpecNode::NodeTypes type2 = particle2->getType();
    304                 return (((type2 == ContentSpecNode::Leaf) ||
    305                         ((type2 & 0x0f) == ContentSpecNode::Any) ||
    306                         ((type2 & 0x0f) == ContentSpecNode::Any_Other) ||
    307                         ((type2 & 0x0f) == ContentSpecNode::Any_NS)) &&
    308                         particle2->getMinOccurs() == 1 &&
    309                         particle2->getMaxOccurs() == 1);
    310             }
    311             return (particle->getFirst()==0 && particle->getSecond()==0);
    312         }
    313         if(particle->getFirst()!=0 && !useRepeatingLeafNodes(particle->getFirst()))
    314             return false;
    315         if(particle->getSecond()!=0 && !useRepeatingLeafNodes(particle->getSecond()))
    316             return false;
    317     }
    318     return true;
    319 }
    320 
    321 XMLContentModel* ComplexTypeInfo::makeContentModel(bool checkUPA)
    322 {
    323     ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
    324 
    325     if (checkUPA) {
    326         fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
    327         (
    328             fContentSpecOrgURISize * sizeof(unsigned int)
    329         ); //new unsigned int[fContentSpecOrgURISize];
    330     }
    331 
    332     aSpecNode = convertContentSpecTree(aSpecNode, checkUPA, useRepeatingLeafNodes(aSpecNode));
    333 
    334     Janitor<ContentSpecNode> janSpecNode(aSpecNode);
    335 
    336     XMLContentModel* cmRet = 0;
    337     if (fContentType == SchemaElementDecl::Simple ||
    338         fContentType == SchemaElementDecl::ElementOnlyEmpty) {
    339        // just return nothing
    340     }
    341     else if (fContentType == SchemaElementDecl::Mixed_Simple)
    342     {
    343         //
    344         //  Just create a mixel content model object. This type of
    345         //  content model is optimized for mixed content validation.
    346         //
    347         cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
    348     }
    349     else if (fContentType == SchemaElementDecl::Mixed_Complex ||
    350              fContentType == SchemaElementDecl::Children)
    351     {
    352         bool isMixed = (fContentType == SchemaElementDecl::Mixed_Complex);
    353 
    354         //
    355         //  This method will create an optimal model for the complexity
    356         //  of the element's defined model. If its simple, it will create
    357         //  a SimpleContentModel object. If its a simple list, it will
    358         //  create a SimpleListContentModel object. If its complex, it
    359         //  will create a DFAContentModel object.
    360         //
    361         if(!aSpecNode)
    362             ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
    363 
    364         ContentSpecNode::NodeTypes specType = aSpecNode->getType();
    365         //
    366         //  Do a sanity check that the node is does not have a PCDATA id. Since,
    367         //  if it was, it should have already gotten taken by the Mixed model.
    368         //
    369         if (aSpecNode->getElement() && aSpecNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
    370             ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager);
    371 
    372         //
    373         //  According to the type of node, we will create the correct type of
    374         //  content model.
    375         //
    376         if (((specType & 0x0f) == ContentSpecNode::Any) ||
    377            ((specType & 0x0f) == ContentSpecNode::Any_Other) ||
    378            ((specType & 0x0f) == ContentSpecNode::Any_NS) ||
    379            specType == ContentSpecNode::Loop) {
    380            // let fall through to build a DFAContentModel
    381         }
    382         else if (isMixed)
    383         {
    384             if (specType == ContentSpecNode::All) {
    385                 // All the nodes under an ALL must be additional ALL nodes and
    386                 // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
    387                 // We collapse the ELEMENTs into a single vector.
    388                 cmRet = new (fMemoryManager) AllContentModel(aSpecNode, true, fMemoryManager);
    389             }
    390             else if (specType == ContentSpecNode::ZeroOrOne) {
    391                 // An ALL node can appear under a ZERO_OR_ONE node.
    392                 if (aSpecNode->getFirst()->getType() == ContentSpecNode::All) {
    393                     cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), true, fMemoryManager);
    394                 }
    395             }
    396 
    397             // otherwise, let fall through to build a DFAContentModel
    398         }
    399          else if (specType == ContentSpecNode::Leaf)
    400         {
    401             // Create a simple content model
    402             cmRet = new (fMemoryManager) SimpleContentModel
    403             (
    404                 false
    405                 , aSpecNode->getElement()
    406                 , 0
    407                 , ContentSpecNode::Leaf
    408                 , fMemoryManager
    409             );
    410         }
    411          else if (((specType & 0x0f) == ContentSpecNode::Choice)
    412               ||  ((specType & 0x0f) == ContentSpecNode::Sequence))
    413         {
    414             //
    415             //  Lets see if both of the children are leafs. If so, then it has to
    416             //  be a simple content model
    417             //
    418             if ((aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
    419             &&  (aSpecNode->getSecond())
    420             &&  (aSpecNode->getSecond()->getType() == ContentSpecNode::Leaf))
    421             {
    422                 cmRet = new (fMemoryManager) SimpleContentModel
    423                 (
    424                     false
    425                     , aSpecNode->getFirst()->getElement()
    426                     , aSpecNode->getSecond()->getElement()
    427                     , specType
    428                     , fMemoryManager
    429                 );
    430             }
    431         }
    432          else if ((specType == ContentSpecNode::OneOrMore)
    433               ||  (specType == ContentSpecNode::ZeroOrMore)
    434               ||  (specType == ContentSpecNode::ZeroOrOne))
    435         {
    436             //
    437             //  Its a repetition, so see if its one child is a leaf. If so its a
    438             //  repetition of a single element, so we can do a simple content
    439             //  model for that.
    440             //
    441             if (aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
    442             {
    443                 cmRet = new (fMemoryManager) SimpleContentModel
    444                 (
    445                     false
    446                     , aSpecNode->getFirst()->getElement()
    447                     , 0
    448                     , specType
    449                     , fMemoryManager
    450                 );
    451             }
    452             else if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
    453                 cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), false, fMemoryManager);
    454 
    455         }
    456         else if (specType == ContentSpecNode::All)
    457             cmRet = new (fMemoryManager) AllContentModel(aSpecNode, false, fMemoryManager);
    458         else
    459         {
    460             ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
    461         }
    462 
    463         // Its not any simple type of content, so create a DFA based content model
    464         if(cmRet==0)
    465             cmRet = new (fMemoryManager) DFAContentModel(false, aSpecNode, isMixed, fMemoryManager);
    466     }
    467      else
    468     {
    469         ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager);
    470     }
    471 
    472     return cmRet;
    473 }
    474 
    475 // ---------------------------------------------------------------------------
    476 //  SchemaElementDecl: Private helper methods
    477 // ---------------------------------------------------------------------------
    478 
    479 ContentSpecNode*
    480 ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
    481                                         bool checkUPA,
    482                                         bool bAllowCompactSyntax) {
    483 
    484     if (!curNode)
    485         return 0;
    486 
    487     const ContentSpecNode::NodeTypes curType = curNode->getType();
    488 
    489     // When checking Unique Particle Attribution, rename leaf elements
    490     if (checkUPA) {
    491         if (curNode->getElement()) {
    492             if (fUniqueURI == fContentSpecOrgURISize) {
    493                 resizeContentSpecOrgURI();
    494             }
    495 
    496             fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
    497             curNode->getElement()->setURI(fUniqueURI);
    498             fUniqueURI++;
    499         }
    500     }
    501 
    502     // Get the spec type of the passed node
    503     int minOccurs = curNode->getMinOccurs();
    504     int maxOccurs = curNode->getMaxOccurs();
    505     ContentSpecNode* retNode = curNode;
    506 
    507     if ((curType & 0x0f) == ContentSpecNode::Any
    508         || (curType & 0x0f) == ContentSpecNode::Any_Other
    509         || (curType & 0x0f) == ContentSpecNode::Any_NS
    510         || curType == ContentSpecNode::Leaf)
    511     {
    512         retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
    513     }
    514     else if (((curType & 0x0f) == ContentSpecNode::Choice)
    515         ||   (curType == ContentSpecNode::All)
    516         ||   ((curType & 0x0f) == ContentSpecNode::Sequence))
    517     {
    518         ContentSpecNode* childNode = curNode->getFirst();
    519         ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
    520         ContentSpecNode* rightNode = curNode->getSecond();
    521 
    522         if (!rightNode) {
    523 
    524             retNode = expandContentModel(leftNode, minOccurs, maxOccurs, bAllowCompactSyntax);
    525             curNode->setAdoptFirst(false);
    526             delete curNode;
    527             return retNode;
    528         }
    529 
    530         if (leftNode != childNode) {
    531 
    532             curNode->setAdoptFirst(false);
    533             curNode->setFirst(leftNode);
    534             curNode->setAdoptFirst(true);
    535         }
    536 
    537         childNode = rightNode;
    538         rightNode =  convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
    539 
    540         if (rightNode != childNode) {
    541 
    542             curNode->setAdoptSecond(false);
    543             curNode->setSecond(rightNode);
    544             curNode->setAdoptSecond(true);
    545         }
    546 
    547         retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
    548     }
    549 
    550     return retNode;
    551 }
    552 
    553 ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
    554                                                      int minOccurs,
    555                                                      int maxOccurs,
    556                                                      bool bAllowCompactSyntax)
    557 {
    558     if (!specNode) {
    559         return 0;
    560     }
    561 
    562     ContentSpecNode* saveNode = specNode;
    563     ContentSpecNode* retNode = specNode;
    564 
    565     if (minOccurs == 1 && maxOccurs == 1) {
    566     }
    567     else if (minOccurs == 0 && maxOccurs == 1) {
    568 
    569         retNode = new (fMemoryManager) ContentSpecNode
    570         (
    571             ContentSpecNode::ZeroOrOne
    572             , retNode
    573             , 0
    574             , true
    575             , true
    576             , fMemoryManager
    577         );
    578     }
    579     else if (minOccurs == 0 && maxOccurs == -1) {
    580         retNode = new (fMemoryManager) ContentSpecNode
    581         (
    582             ContentSpecNode::ZeroOrMore
    583             , retNode
    584             , 0
    585             , true
    586             , true
    587             , fMemoryManager
    588         );
    589     }
    590     else if (minOccurs == 1 && maxOccurs == -1) {
    591         retNode = new (fMemoryManager) ContentSpecNode
    592         (
    593             ContentSpecNode::OneOrMore
    594             , retNode
    595             , 0
    596             , true
    597             , true
    598             , fMemoryManager
    599         );
    600     }
    601     // if what is being repeated is a leaf avoid expanding the tree
    602     else if(bAllowCompactSyntax &&
    603         (saveNode->getType()==ContentSpecNode::Leaf ||
    604         (saveNode->getType() & 0x0f)==ContentSpecNode::Any ||
    605         (saveNode->getType() & 0x0f)==ContentSpecNode::Any_Other ||
    606         (saveNode->getType() & 0x0f)==ContentSpecNode::Any_NS))
    607     {
    608         retNode = new (fMemoryManager) ContentSpecNode
    609         (
    610             ContentSpecNode::Loop
    611             , retNode
    612             , 0
    613             , true
    614             , true
    615             , fMemoryManager
    616         );
    617         retNode->setMinOccurs(minOccurs);
    618         retNode->setMaxOccurs(maxOccurs);
    619 
    620         if(minOccurs==0)
    621             retNode = new (fMemoryManager) ContentSpecNode
    622             (
    623                 ContentSpecNode::ZeroOrMore
    624                 , retNode
    625                 , 0
    626                 , true
    627                 , true
    628                 , fMemoryManager
    629             );
    630         else
    631             retNode = new (fMemoryManager) ContentSpecNode
    632             (
    633                 ContentSpecNode::OneOrMore
    634                 , retNode
    635                 , 0
    636                 , true
    637                 , true
    638                 , fMemoryManager
    639             );
    640 
    641     }
    642     else if (maxOccurs == -1) {
    643 
    644         retNode = new (fMemoryManager) ContentSpecNode
    645         (
    646             ContentSpecNode::OneOrMore
    647             , retNode
    648             , 0
    649             , true
    650             , true
    651             , fMemoryManager
    652         );
    653 
    654         for (int i=0; i < (minOccurs-1); i++) {
    655             retNode = new (fMemoryManager) ContentSpecNode
    656             (
    657                 ContentSpecNode::Sequence
    658                 , saveNode
    659                 , retNode
    660                 , false
    661                 , true
    662                 , fMemoryManager
    663             );
    664         }
    665     }
    666     else {
    667 
    668         if (minOccurs == 0) {
    669 
    670             ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
    671             (
    672                 ContentSpecNode::ZeroOrOne
    673                 , saveNode
    674                 , 0
    675                 , true
    676                 , true
    677                 , fMemoryManager
    678             );
    679 
    680             retNode = optional;
    681 
    682             for (int i=0; i < (maxOccurs-1); i++) {
    683                 retNode = new (fMemoryManager) ContentSpecNode
    684                 (
    685                     ContentSpecNode::Sequence
    686                     , retNode
    687                     , optional
    688                     , true
    689                     , false
    690                     , fMemoryManager
    691                 );
    692             }
    693         }
    694         else {
    695 
    696             if (minOccurs > 1) {
    697 
    698                 retNode = new (fMemoryManager) ContentSpecNode
    699                 (
    700                     ContentSpecNode::Sequence
    701                     , retNode
    702                     , saveNode
    703                     , true
    704                     , false
    705                     , fMemoryManager
    706                 );
    707 
    708                 for (int i=1; i < (minOccurs-1); i++) {
    709                     retNode = new (fMemoryManager) ContentSpecNode
    710                     (
    711                         ContentSpecNode::Sequence
    712                         , retNode
    713                         , saveNode
    714                         , true
    715                         , false
    716                         , fMemoryManager
    717                     );
    718                 }
    719             }
    720 
    721             int counter = maxOccurs-minOccurs;
    722 
    723             if (counter > 0) {
    724 
    725                 ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
    726                 (
    727                     ContentSpecNode::ZeroOrOne
    728                     , saveNode
    729                     , 0
    730                     , false
    731                     , true
    732                     , fMemoryManager
    733                 );
    734 
    735                 retNode = new (fMemoryManager) ContentSpecNode
    736                 (
    737                     ContentSpecNode::Sequence
    738                     , retNode
    739                     , optional
    740                     , true
    741                     , true
    742                     , fMemoryManager
    743                 );
    744 
    745                 for (int j=1; j < counter; j++) {
    746 
    747                     retNode = new (fMemoryManager) ContentSpecNode
    748                     (
    749                         ContentSpecNode::Sequence
    750                         , retNode
    751                         , optional
    752                         , true
    753                         , false
    754                         , fMemoryManager
    755                     );
    756                 }
    757             }
    758         }
    759     }
    760 
    761     return retNode;
    762 }
    763 
    764 void ComplexTypeInfo::resizeContentSpecOrgURI() {
    765 
    766     unsigned int newSize = fContentSpecOrgURISize * 2;
    767     unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
    768     (
    769         newSize * sizeof(unsigned int)
    770     ); //new unsigned int[newSize];
    771 
    772     // Copy the existing values
    773     unsigned int index = 0;
    774     for (; index < fContentSpecOrgURISize; index++)
    775         newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
    776 
    777     for (; index < newSize; index++)
    778         newContentSpecOrgURI[index] = 0;
    779 
    780     // Delete the old array and udpate our members
    781     fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
    782     fContentSpecOrgURI = newContentSpecOrgURI;
    783     fContentSpecOrgURISize = newSize;
    784 }
    785 
    786 /***
    787  * Support for Serialization/De-serialization
    788  ***/
    789 
    790 IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
    791 
    792 void ComplexTypeInfo::serialize(XSerializeEngine& serEng)
    793 {
    794 
    795     if (serEng.isStoring())
    796     {
    797         serEng<<fAnonymous;
    798         serEng<<fAbstract;
    799         serEng<<fAdoptContentSpec;
    800         serEng<<fAttWithTypeId;
    801         serEng<<fPreprocessed;
    802         serEng<<fDerivedBy;
    803         serEng<<fBlockSet;
    804         serEng<<fFinalSet;
    805         serEng<<fScopeDefined;
    806         serEng<<fContentType;
    807 
    808         serEng<<fElementId;
    809 
    810         serEng.writeString(fTypeName);
    811         serEng.writeString(fTypeLocalName);
    812         serEng.writeString(fTypeUri);
    813 
    814         DatatypeValidator::storeDV(serEng, fBaseDatatypeValidator);
    815         DatatypeValidator::storeDV(serEng, fDatatypeValidator);
    816 
    817         serEng<<fBaseComplexTypeInfo;
    818         serEng<<fContentSpec;
    819         serEng<<fAttWildCard;
    820         serEng<<fAttList;
    821 
    822         /***
    823          *
    824          * Serialize RefVectorOf<SchemaElementDecl>*    fElements;
    825          * Serialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
    826          ***/
    827         XTemplateSerializer::storeObject(fElements, serEng);
    828         XTemplateSerializer::storeObject(fAttDefs, serEng);
    829 
    830          /***
    831           *   Don't serialize
    832           *
    833           *   fContentModel;
    834           *   fFormattedModel;
    835           *   fLocator;
    836           *
    837           *   fContentSpecOrgURI:     start of the array
    838           *   fContentSpecOrgURISize: size of the array
    839           *   fUniqueURI:             the current last element in the array
    840           ***/
    841     }
    842     else
    843     {
    844         serEng>>fAnonymous;
    845         serEng>>fAbstract;
    846         serEng>>fAdoptContentSpec;
    847         serEng>>fAttWithTypeId;
    848         serEng>>fPreprocessed;
    849         serEng>>fDerivedBy;
    850         serEng>>fBlockSet;
    851         serEng>>fFinalSet;
    852         serEng>>fScopeDefined;
    853         serEng>>fContentType;
    854 
    855         serEng>>fElementId;
    856 
    857         serEng.readString(fTypeName);
    858         serEng.readString(fTypeLocalName);
    859         serEng.readString(fTypeUri);
    860 
    861         fBaseDatatypeValidator = DatatypeValidator::loadDV(serEng);
    862         fDatatypeValidator     = DatatypeValidator::loadDV(serEng);
    863 
    864         serEng>>fBaseComplexTypeInfo;
    865         serEng>>fContentSpec;
    866         serEng>>fAttWildCard;
    867         delete fAttList; // will recreate it next...
    868         serEng>>fAttList;
    869 
    870         /***
    871          *
    872          * Deserialize RefVectorOf<SchemaElementDecl>*    fElements;
    873          * Deserialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
    874          ***/
    875         XTemplateSerializer::loadObject(&fElements, 8, false, serEng);
    876         delete fAttDefs; // will recreate it next...
    877         XTemplateSerializer::loadObject(&fAttDefs, 29, true, serEng);
    878 
    879          /***
    880           *   Don't deserialize
    881           *
    882           *   fFormattedModel;
    883           *   fLocator;
    884           *
    885           *   fContentSpecOrgURI:     start of the array
    886           *   fContentSpecOrgURISize: size of the array
    887           *   fUniqueURI:             the current last element in the array
    888           ***/
    889 
    890          fFormattedModel = 0;
    891          fLocator = 0;
    892          fContentSpecOrgURI = 0;
    893          fContentSpecOrgURISize = 0;
    894          fUniqueURI = 0;
    895 
    896          // Create the content model by calling getContentModel().  This
    897          // will ensure the grammar can be used concurrently by multiple
    898          // parsers.
    899          // Don't bother to do check unique particle attribution, since
    900          // this will already have been done when the grammar was first
    901          // created (if full schema checking was enabled).
    902          getContentModel(false);
    903     }
    904 }
    905 
    906 
    907 XERCES_CPP_NAMESPACE_END
    908 
    909 /**
    910   * End of file ComplexTypeInfo.cpp
    911   */
     1#include <icxercesc/validators/schema/ComplexTypeInfo.cpp>
Note: See TracChangeset for help on using the changeset viewer.