blob: 28c455eba1005f56b6319479536684858109af15 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: ComplexTypeInfo.cpp 568078 2007-08-21 11:43:25Z amassari $
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/validators/schema/ComplexTypeInfo.hpp>
#include <xercesc/validators/schema/SchemaAttDefList.hpp>
#include <xercesc/validators/common/AllContentModel.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/common/DFAContentModel.hpp>
#include <xercesc/validators/common/MixedContentModel.hpp>
#include <xercesc/validators/common/SimpleContentModel.hpp>
#include <xercesc/validators/schema/XSDLocator.hpp>
#include <xercesc/internal/XTemplateSerializer.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLInitializer.hpp>
XERCES_CPP_NAMESPACE_BEGIN
// ---------------------------------------------------------------------------
// Local static data
// ---------------------------------------------------------------------------
static bool sAnyTypeMutexRegistered = false;
static XMLMutex* sAnyTypeMutex = 0;
static XMLRegisterCleanup anyTypeCleanup;
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Static member data
// ---------------------------------------------------------------------------
ComplexTypeInfo* ComplexTypeInfo::fAnyType = 0;
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Static meber methods
// ---------------------------------------------------------------------------
void ComplexTypeInfo::reinitAnyType() {
delete fAnyType;
fAnyType = 0;
// delete local static data
delete sAnyTypeMutex;
sAnyTypeMutex = 0;
sAnyTypeMutexRegistered = false;
}
void XMLInitializer::initializeAnyType()
{
ComplexTypeInfo::getAnyType(1);
}
ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int emptyNSId)
{
if (!sAnyTypeMutexRegistered)
{
if (!sAnyTypeMutex)
{
XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);
if (!sAnyTypeMutex)
sAnyTypeMutex = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
}
// Use a faux scope to synchronize while we do this
{
XMLMutexLock lock(sAnyTypeMutex);
// If we got here first, then register it and set the registered flag
if (!sAnyTypeMutexRegistered)
{
// create type name
XMLCh typeName[128];
unsigned int nsLen = XMLString::stringLen(
SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
XMLString::copyString(
typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
typeName[nsLen] = chComma;
XMLString::copyString(
typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE);
// Create and initialize 'anyType'
fAnyType = new ComplexTypeInfo();
ContentSpecNode* term = new ContentSpecNode
(
new QName
(
XMLUni::fgZeroLenString
, XMLUni::fgZeroLenString
, emptyNSId
)
, false
);
term->setType(ContentSpecNode::Any_Lax);
term->setMinOccurs(0);
term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);
ContentSpecNode* particle = new ContentSpecNode
(
ContentSpecNode::ModelGroupSequence
, term
, 0
);
SchemaAttDef* attWildCard = new SchemaAttDef
(
XMLUni::fgZeroLenString
, XMLUni::fgZeroLenString
, emptyNSId
, XMLAttDef::Any_Any
, XMLAttDef::ProcessContents_Lax
);
fAnyType->setTypeName(typeName);
fAnyType->setBaseComplexTypeInfo(fAnyType);
fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
fAnyType->setContentType(SchemaElementDecl::Mixed_Complex);
fAnyType->setContentSpec(particle);
fAnyType->setAttWildCard(attWildCard);
// register cleanup method
anyTypeCleanup.registerCleanup(ComplexTypeInfo::reinitAnyType);
sAnyTypeMutexRegistered = true;
}
}
}
return fAnyType;
}
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Constructors and Destructor
// ---------------------------------------------------------------------------
ComplexTypeInfo::ComplexTypeInfo(MemoryManager* const manager)
: fAnonymous(false)
, fAbstract(false)
, fAdoptContentSpec(true)
, fAttWithTypeId(false)
, fPreprocessed(false)
, fDerivedBy(0)
, fBlockSet(0)
, fFinalSet(0)
, fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
, fContentType(SchemaElementDecl::Empty)
, fElementId(XMLElementDecl::fgInvalidElemId)
, fUniqueURI(0)
, fContentSpecOrgURISize(16)
, fTypeName(0)
, fTypeLocalName(0)
, fTypeUri(0)
, fBaseDatatypeValidator(0)
, fDatatypeValidator(0)
, fBaseComplexTypeInfo(0)
, fContentSpec(0)
, fAttWildCard(0)
, fAttList(0)
, fElements(0)
, fAttDefs(0)
, fContentModel(0)
, fFormattedModel(0)
, fContentSpecOrgURI(0)
, fLocator(0)
, fMemoryManager(manager)
{
fAttDefs = new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs,fMemoryManager);
}
ComplexTypeInfo::~ComplexTypeInfo()
{
fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
if (fAdoptContentSpec) {
delete fContentSpec;
}
delete fAttWildCard;
delete fAttDefs;
delete fAttList;
delete fElements;
delete fLocator;
delete fContentModel;
fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
}
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Setter methods
// ---------------------------------------------------------------------------
void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd) {
// Tell this guy the element id of its parent (us)
toAdd->setElemId(getElementId());
fAttDefs->put((void*)(toAdd->getAttName()->getLocalPart()),
toAdd->getAttName()->getURI(), toAdd);
// update and/or create fAttList
fAttList->addAttDef(toAdd);
}
void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
if (fContentSpec && fAdoptContentSpec) {
delete fContentSpec;
}
fContentSpec = toAdopt;
//reset Content Model
setContentModel(0);
}
void ComplexTypeInfo::setLocator(XSDLocator* const aLocator) {
if (fLocator)
delete fLocator;
fLocator = aLocator;
}
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Getter methods
// ---------------------------------------------------------------------------
XMLAttDefList& ComplexTypeInfo::getAttDefList() const
{
// NOTE: if users plan on using nextElement() to access attributes
// they need to call Reset() explicitly (i.e attList.Reset()).
// It's better to get the attribute count and use an index to
// access attributes (especially if same grammar is used in
// multiple threads).
return *fAttList;
}
const XMLCh*
ComplexTypeInfo::getFormattedContentModel() const
{
//
// If its not already built, then call the protected virtual method
// to allow the derived class to build it (since only it knows.)
// Otherwise, just return the previously formatted methods.
//
// Since we are faulting this in, within a const getter, we have to
// cast off the const-ness.
//
if (!fFormattedModel)
((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
return fFormattedModel;
}
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Helper methods
// ---------------------------------------------------------------------------
XMLAttDef* ComplexTypeInfo::findAttr(const XMLCh* const
, const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const prefix
, const XMLElementDecl::LookupOpts options
, bool& wasAdded) const
{
SchemaAttDef* retVal = fAttDefs->get(baseName, uriId);
// Fault it in if not found and ask to add it
if (!retVal && (options == XMLElementDecl::AddIfNotFound))
{
// And add a default attribute for this name
retVal = new (fMemoryManager) SchemaAttDef
(
prefix
, baseName
, uriId
, XMLAttDef::CData
, XMLAttDef::Implied
, fMemoryManager
);
retVal->setElemId(getElementId());
fAttDefs->put((void*)retVal->getAttName()->getLocalPart(), uriId, retVal);
// update fAttList
fAttList->addAttDef(retVal);
wasAdded = true;
}
else
{
wasAdded = false;
}
return retVal;
}
bool ComplexTypeInfo::resetDefs() {
// Ok, run through them and clear the 'provided' flag on each of them.
// This lets the scanner use them to track which has been provided and
// which have not.
RefHash2KeysTableOfEnumerator<SchemaAttDef> enumDefs(fAttDefs, false, fMemoryManager);
while (enumDefs.hasMoreElements())
enumDefs.nextElement().setProvided(false);
return true;
}
void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar* const pGrammar,
GrammarResolver* const pGrammarResolver,
XMLStringPool* const pStringPool,
XMLValidator* const pValidator)
{
if (fContentSpec && !fContentModel)
{
fContentModel = makeContentModel(true);
if (fContentModel) {
fContentModel->checkUniqueParticleAttribution(pGrammar, pGrammarResolver, pStringPool, pValidator, fContentSpecOrgURI, fTypeLocalName);
}
}
}
// ---------------------------------------------------------------------------
// ComplexTypeInfo: Private Helper methods
// ---------------------------------------------------------------------------
void ComplexTypeInfo::faultInAttDefList() const
{
// Use a hash modulus of 29 and tell it owns its elements
((ComplexTypeInfo*)this)->fAttDefs =
new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
}
XMLCh* ComplexTypeInfo::formatContentModel() const
{
XMLCh* newValue = 0;
if (fContentType == SchemaElementDecl::Any)
{
newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
}
else if (fContentType == SchemaElementDecl::Empty)
{
newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
}
else
{
//
// Use a temp XML buffer to format into. Content models could be
// pretty long, but very few will be longer than one K. The buffer
// will expand to handle the more pathological ones.
//
const ContentSpecNode* specNode = fContentSpec;
if (specNode) {
XMLBuffer bufFmt(1023, fMemoryManager);
specNode->formatSpec(bufFmt);
newValue = XMLString::replicate
(
bufFmt.getRawBuffer()
, fMemoryManager
);
}
}
return newValue;
}
XMLContentModel* ComplexTypeInfo::makeContentModel(const bool checkUPA)
{
ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
XMLContentModel* retModel = 0;
if (checkUPA) {
fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
(
fContentSpecOrgURISize * sizeof(unsigned int)
); //new unsigned int[fContentSpecOrgURISize];
}
aSpecNode = convertContentSpecTree(aSpecNode, checkUPA);
retModel = buildContentModel(aSpecNode);
delete aSpecNode;
return retModel;
}
XMLContentModel* ComplexTypeInfo::buildContentModel(ContentSpecNode* const aSpecNode)
{
XMLContentModel* cmRet = 0;
if (fContentType == SchemaElementDecl::Simple) {
// just return nothing
}
else if (fContentType == SchemaElementDecl::Mixed_Simple)
{
//
// Just create a mixel content model object. This type of
// content model is optimized for mixed content validation.
//
cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
}
else if (fContentType == SchemaElementDecl::Mixed_Complex) {
cmRet = createChildModel(aSpecNode, true);
}
else if (fContentType == SchemaElementDecl::Children)
{
//
// This method will create an optimal model for the complexity
// of the element's defined model. If its simple, it will create
// a SimpleContentModel object. If its a simple list, it will
// create a SimpleListContentModel object. If its complex, it
// will create a DFAContentModel object.
//
cmRet = createChildModel(aSpecNode, false);
}
else
{
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager);
}
return cmRet;
}
// ---------------------------------------------------------------------------
// SchemaElementDecl: Private helper methods
// ---------------------------------------------------------------------------
XMLContentModel* ComplexTypeInfo::createChildModel(ContentSpecNode* specNode, const bool isMixed)
{
if(!specNode)
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
ContentSpecNode::NodeTypes specType = specNode->getType();
//
// Do a sanity check that the node is does not have a PCDATA id. Since,
// if it was, it should have already gotten taken by the Mixed model.
//
if (specNode->getElement()) {
if (specNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager);
}
//
// According to the type of node, we will create the correct type of
// content model.
//
if (((specType & 0x0f) == ContentSpecNode::Any) ||
((specType & 0x0f) == ContentSpecNode::Any_Other) ||
((specType & 0x0f) == ContentSpecNode::Any_NS)) {
// let fall through to build a DFAContentModel
}
else if (isMixed)
{
if (specType == ContentSpecNode::All) {
// All the nodes under an ALL must be additional ALL nodes and
// ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
// We collapse the ELEMENTs into a single vector.
return new (fMemoryManager) AllContentModel(specNode, true, fMemoryManager);
}
else if (specType == ContentSpecNode::ZeroOrOne) {
// An ALL node can appear under a ZERO_OR_ONE node.
if (specNode->getFirst()->getType() == ContentSpecNode::All) {
return new (fMemoryManager) AllContentModel(specNode->getFirst(), true, fMemoryManager);
}
}
// otherwise, let fall through to build a DFAContentModel
}
else if (specType == ContentSpecNode::Leaf)
{
// Create a simple content model
return new (fMemoryManager) SimpleContentModel
(
false
, specNode->getElement()
, 0
, ContentSpecNode::Leaf
, fMemoryManager
);
}
else if (((specType & 0x0f) == ContentSpecNode::Choice)
|| ((specType & 0x0f) == ContentSpecNode::Sequence))
{
//
// Lets see if both of the children are leafs. If so, then it has to
// be a simple content model
//
if ((specNode->getFirst()->getType() == ContentSpecNode::Leaf)
&& (specNode->getSecond())
&& (specNode->getSecond()->getType() == ContentSpecNode::Leaf))
{
return new (fMemoryManager) SimpleContentModel
(
false
, specNode->getFirst()->getElement()
, specNode->getSecond()->getElement()
, specType
, fMemoryManager
);
}
}
else if ((specType == ContentSpecNode::OneOrMore)
|| (specType == ContentSpecNode::ZeroOrMore)
|| (specType == ContentSpecNode::ZeroOrOne))
{
//
// Its a repetition, so see if its one child is a leaf. If so its a
// repetition of a single element, so we can do a simple content
// model for that.
//
if (specNode->getFirst()->getType() == ContentSpecNode::Leaf)
{
return new (fMemoryManager) SimpleContentModel
(
false
, specNode->getFirst()->getElement()
, 0
, specType
, fMemoryManager
);
}
else if (specNode->getFirst()->getType() == ContentSpecNode::All)
return new (fMemoryManager) AllContentModel(specNode->getFirst(), false, fMemoryManager);
}
else if (specType == ContentSpecNode::All)
return new (fMemoryManager) AllContentModel(specNode, false, fMemoryManager);
else
{
ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
}
// Its not any simple type of content, so create a DFA based content model
return new (fMemoryManager) DFAContentModel(false, specNode, isMixed, fMemoryManager);
}
ContentSpecNode*
ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
const bool checkUPA) {
if (!curNode)
return 0;
const ContentSpecNode::NodeTypes curType = curNode->getType();
// When checking Unique Particle Attribution, rename leaf elements
if (checkUPA) {
if (curNode->getElement()) {
if (fUniqueURI == fContentSpecOrgURISize) {
resizeContentSpecOrgURI();
}
fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
curNode->getElement()->setURI(fUniqueURI);
fUniqueURI++;
}
}
// Get the spec type of the passed node
int minOccurs = curNode->getMinOccurs();
int maxOccurs = curNode->getMaxOccurs();
ContentSpecNode* retNode = curNode;
if ((curType & 0x0f) == ContentSpecNode::Any
|| (curType & 0x0f) == ContentSpecNode::Any_Other
|| (curType & 0x0f) == ContentSpecNode::Any_NS
|| curType == ContentSpecNode::Leaf)
{
retNode = expandContentModel(curNode, minOccurs, maxOccurs);
}
else if (((curType & 0x0f) == ContentSpecNode::Choice)
|| (curType == ContentSpecNode::All)
|| ((curType & 0x0f) == ContentSpecNode::Sequence))
{
ContentSpecNode* childNode = curNode->getFirst();
ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA);
ContentSpecNode* rightNode = curNode->getSecond();
if (!rightNode) {
retNode = expandContentModel(leftNode, minOccurs, maxOccurs);
curNode->setAdoptFirst(false);
delete curNode;
return retNode;
}
if (leftNode != childNode) {
curNode->setAdoptFirst(false);
curNode->setFirst(leftNode);
curNode->setAdoptFirst(true);
}
childNode = rightNode;
rightNode = convertContentSpecTree(childNode, checkUPA);
if (rightNode != childNode) {
curNode->setAdoptSecond(false);
curNode->setSecond(rightNode);
curNode->setAdoptSecond(true);
}
retNode = expandContentModel(curNode, minOccurs, maxOccurs);
}
return retNode;
}
ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
const int minOccurs,
const int maxOccurs)
{
if (!specNode) {
return 0;
}
ContentSpecNode* saveNode = specNode;
ContentSpecNode* retNode = specNode;
if (minOccurs == 1 && maxOccurs == 1) {
}
else if (minOccurs == 0 && maxOccurs == 1) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::ZeroOrOne
, retNode
, 0
, true
, true
, fMemoryManager
);
}
else if (minOccurs == 0 && maxOccurs == -1) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::ZeroOrMore
, retNode
, 0
, true
, true
, fMemoryManager
);
}
else if (minOccurs == 1 && maxOccurs == -1) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::OneOrMore
, retNode
, 0
, true
, true
, fMemoryManager
);
}
else if (maxOccurs == -1) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::OneOrMore
, retNode
, 0
, true
, true
, fMemoryManager
);
for (int i=0; i < (int)(minOccurs-1); i++) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::Sequence
, saveNode
, retNode
, false
, true
, fMemoryManager
);
}
}
else {
if (minOccurs == 0) {
ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::ZeroOrOne
, saveNode
, 0
, true
, true
, fMemoryManager
);
retNode = optional;
for (int i=0; i < (int)(maxOccurs-minOccurs-1); i++) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::Sequence
, retNode
, optional
, true
, false
, fMemoryManager
);
}
}
else {
if (minOccurs > 1) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::Sequence
, retNode
, saveNode
, true
, false
, fMemoryManager
);
for (int i=1; i < (int)(minOccurs-1); i++) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::Sequence
, retNode
, saveNode
, true
, false
, fMemoryManager
);
}
}
int counter = maxOccurs-minOccurs;
if (counter > 0) {
ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::ZeroOrOne
, saveNode
, 0
, false
, true
, fMemoryManager
);
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::Sequence
, retNode
, optional
, true
, true
, fMemoryManager
);
for (int j=1; j < counter; j++) {
retNode = new (fMemoryManager) ContentSpecNode
(
ContentSpecNode::Sequence
, retNode
, optional
, true
, false
, fMemoryManager
);
}
}
}
}
return retNode;
}
void ComplexTypeInfo::resizeContentSpecOrgURI() {
unsigned int newSize = fContentSpecOrgURISize * 2;
unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
(
newSize * sizeof(unsigned int)
); //new unsigned int[newSize];
// Copy the existing values
unsigned int index = 0;
for (; index < fContentSpecOrgURISize; index++)
newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
for (; index < newSize; index++)
newContentSpecOrgURI[index] = 0;
// Delete the old array and udpate our members
fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
fContentSpecOrgURI = newContentSpecOrgURI;
fContentSpecOrgURISize = newSize;
}
/***
* Support for Serialization/De-serialization
***/
IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
void ComplexTypeInfo::serialize(XSerializeEngine& serEng)
{
if (serEng.isStoring())
{
serEng<<fAnonymous;
serEng<<fAbstract;
serEng<<fAdoptContentSpec;
serEng<<fAttWithTypeId;
serEng<<fPreprocessed;
serEng<<fDerivedBy;
serEng<<fBlockSet;
serEng<<fFinalSet;
serEng<<fScopeDefined;
serEng<<fContentType;
serEng<<fElementId;
serEng.writeString(fTypeName);
serEng.writeString(fTypeLocalName);
serEng.writeString(fTypeUri);
DatatypeValidator::storeDV(serEng, fBaseDatatypeValidator);
DatatypeValidator::storeDV(serEng, fDatatypeValidator);
serEng<<fBaseComplexTypeInfo;
serEng<<fContentSpec;
serEng<<fAttWildCard;
serEng<<fAttList;
/***
*
* Serialize RefVectorOf<SchemaElementDecl>* fElements;
* Serialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
***/
XTemplateSerializer::storeObject(fElements, serEng);
XTemplateSerializer::storeObject(fAttDefs, serEng);
/***
* Don't serialize
*
* fContentModel;
* fFormattedModel;
* fLocator;
*
* fContentSpecOrgURI: start of the array
* fContentSpecOrgURISize: size of the array
* fUniqueURI: the current last element in the array
***/
}
else
{
serEng>>fAnonymous;
serEng>>fAbstract;
serEng>>fAdoptContentSpec;
serEng>>fAttWithTypeId;
serEng>>fPreprocessed;
serEng>>fDerivedBy;
serEng>>fBlockSet;
serEng>>fFinalSet;
serEng>>fScopeDefined;
serEng>>fContentType;
serEng>>fElementId;
serEng.readString(fTypeName);
serEng.readString(fTypeLocalName);
serEng.readString(fTypeUri);
fBaseDatatypeValidator = DatatypeValidator::loadDV(serEng);
fDatatypeValidator = DatatypeValidator::loadDV(serEng);
serEng>>fBaseComplexTypeInfo;
serEng>>fContentSpec;
serEng>>fAttWildCard;
delete fAttList; // will recreate it next...
serEng>>fAttList;
/***
*
* Deserialize RefVectorOf<SchemaElementDecl>* fElements;
* Deserialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
***/
XTemplateSerializer::loadObject(&fElements, 8, false, serEng);
delete fAttDefs; // will recreate it next...
XTemplateSerializer::loadObject(&fAttDefs, 29, true, serEng);
/***
* Don't deserialize
*
* fFormattedModel;
* fLocator;
*
* fContentSpecOrgURI: start of the array
* fContentSpecOrgURISize: size of the array
* fUniqueURI: the current last element in the array
***/
fFormattedModel = 0;
fLocator = 0;
fContentSpecOrgURI = 0;
fContentSpecOrgURISize = 0;
fUniqueURI = 0;
// Create the content model by calling getContentModel(). This
// will ensure the grammar can be used concurrently by multiple
// parsers.
// Don't bother to do check unique particle attribution, since
// this will already have been done when the grammar was first
// created (if full schema checking was enabled).
getContentModel(false);
}
}
XERCES_CPP_NAMESPACE_END
/**
* End of file ComplexTypeInfo.cpp
*/