source: icXML/icXML-devel/src/xercesc/validators/schema/ComplexTypeInfo.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 29.5 KB
Line 
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 <xercesc/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
37XERCES_CPP_NAMESPACE_BEGIN
38
39// ---------------------------------------------------------------------------
40//  ComplexTypeInfo: Static member data
41// ---------------------------------------------------------------------------
42ComplexTypeInfo* ComplexTypeInfo::fAnyType = 0;
43
44void 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
95void XMLInitializer::terminateComplexTypeInfo()
96{
97  delete ComplexTypeInfo::fAnyType;
98  ComplexTypeInfo::fAnyType = 0;
99}
100
101ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int /*emptyNSId*/)
102{
103    return fAnyType;
104}
105
106
107// ---------------------------------------------------------------------------
108//  ComplexTypeInfo: Constructors and Destructor
109// ---------------------------------------------------------------------------
110ComplexTypeInfo::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
146ComplexTypeInfo::~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// ---------------------------------------------------------------------------
171void 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
182void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
183
184    if (fContentSpec && fAdoptContentSpec) {
185        delete fContentSpec;
186    }
187
188    fContentSpec = toAdopt;
189}
190
191void ComplexTypeInfo::setLocator(XSDLocator* const aLocator) {
192
193    if (fLocator)
194        delete fLocator;
195
196    fLocator = aLocator;
197}
198
199// ---------------------------------------------------------------------------
200//  ComplexTypeInfo: Getter methods
201// ---------------------------------------------------------------------------
202XMLAttDefList& 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
212const XMLCh*
213ComplexTypeInfo::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// ---------------------------------------------------------------------------
232void 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// ---------------------------------------------------------------------------
249void 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
256XMLCh* 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
291bool 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
321XMLContentModel* 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
479ContentSpecNode*
480ComplexTypeInfo::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
553ContentSpecNode* 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
764void 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
790IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
791
792void 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
907XERCES_CPP_NAMESPACE_END
908
909/**
910  * End of file ComplexTypeInfo.cpp
911  */
Note: See TracBrowser for help on using the repository browser.