source: icXML/icXML-devel/src/icxercesc/validators/schema/ComplexTypeInfo.cpp @ 2774

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

Various fixes

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