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$
20 */
21
22 // ---------------------------------------------------------------------------
23 // Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/framework/XMLBuffer.hpp>
26 #include <xercesc/validators/schema/ComplexTypeInfo.hpp>
27 #include <xercesc/validators/schema/SchemaAttDefList.hpp>
28 #include <xercesc/validators/common/AllContentModel.hpp>
29 #include <xercesc/validators/common/ContentSpecNode.hpp>
30 #include <xercesc/validators/common/DFAContentModel.hpp>
31 #include <xercesc/validators/common/MixedContentModel.hpp>
32 #include <xercesc/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
initializeComplexTypeInfo()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
terminateComplexTypeInfo()95 void XMLInitializer::terminateComplexTypeInfo()
96 {
97 delete ComplexTypeInfo::fAnyType;
98 ComplexTypeInfo::fAnyType = 0;
99 }
100
getAnyType(unsigned int)101 ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int /*emptyNSId*/)
102 {
103 return fAnyType;
104 }
105
106
107 // ---------------------------------------------------------------------------
108 // ComplexTypeInfo: Constructors and Destructor
109 // ---------------------------------------------------------------------------
ComplexTypeInfo(MemoryManager * const manager)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
~ComplexTypeInfo()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 // ---------------------------------------------------------------------------
addAttDef(SchemaAttDef * const toAdd)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
setContentSpec(ContentSpecNode * const toAdopt)182 void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
183
184 if (fContentSpec && fAdoptContentSpec) {
185 delete fContentSpec;
186 }
187
188 fContentSpec = toAdopt;
189 }
190
setLocator(XSDLocator * const aLocator)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 // ---------------------------------------------------------------------------
getAttDefList() const202 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*
getFormattedContentModel() const213 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 // ---------------------------------------------------------------------------
checkUniqueParticleAttribution(SchemaGrammar * const pGrammar,GrammarResolver * const pGrammarResolver,XMLStringPool * const pStringPool,XMLValidator * const pValidator)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 // ---------------------------------------------------------------------------
faultInAttDefList() const249 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
formatContentModel() const256 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
useRepeatingLeafNodes(ContentSpecNode * particle)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
makeContentModel(bool checkUPA)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*
convertContentSpecTree(ContentSpecNode * const curNode,bool checkUPA,bool bAllowCompactSyntax)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
expandContentModel(ContentSpecNode * const specNode,int minOccurs,int maxOccurs,bool bAllowCompactSyntax)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
resizeContentSpecOrgURI()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
IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)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 */
912