blob: a0fa68ce7e02c1d3ad79bb686975f75c5446e3a1 [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: DTDGrammar.cpp 568078 2007-08-21 11:43:25Z amassari $
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/util/XMLRegisterCleanup.hpp>
#include <xercesc/util/XMLInitializer.hpp>
#include <xercesc/validators/DTD/DTDGrammar.hpp>
#include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp>
#include <xercesc/internal/XTemplateSerializer.hpp>
XERCES_CPP_NAMESPACE_BEGIN
// ---------------------------------------------------------------------------
// Local static data
// ---------------------------------------------------------------------------
static bool sEntityPoolMutexRegistered = false;
static XMLMutex* sEntityPoolMutex = 0;
static XMLRegisterCleanup entityPoolRegistryCleanup;
// ---------------------------------------------------------------------------
// DTDGrammar: Static member data
// ---------------------------------------------------------------------------
NameIdPool<DTDEntityDecl>* DTDGrammar::fDefaultEntities = 0;
void XMLInitializer::initializeDTDGrammarDfltEntities()
{
DTDGrammar::fDefaultEntities = new NameIdPool<DTDEntityDecl>(11, 12);
// Add the default entity entries for the character refs that must
// always be present. We indicate that they are from the internal
// subset. They aren't really, but they have to look that way so
// that they are still valid for use within a standalone document.
//
// We also mark them as special char entities, which allows them
// to be used in places whether other non-numeric general entities
// cannot.
//
if (DTDGrammar::fDefaultEntities)
{
DTDGrammar::fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgAmp, chAmpersand, true, true));
DTDGrammar::fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgLT, chOpenAngle, true, true));
DTDGrammar::fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgGT, chCloseAngle, true, true));
DTDGrammar::fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgQuot, chDoubleQuote, true, true));
DTDGrammar::fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgApos, chSingleQuote, true, true));
// register cleanup method
entityPoolRegistryCleanup.registerCleanup(DTDGrammar::reinitDfltEntities);
sEntityPoolMutexRegistered = true;
}
}
//---------------------------------------------------------------------------
// DTDGrammar: Constructors and Destructor
// ---------------------------------------------------------------------------
DTDGrammar::DTDGrammar(MemoryManager* const manager) :
fMemoryManager(manager)
, fElemDeclPool(0)
, fElemNonDeclPool(0)
, fEntityDeclPool(0)
, fNotationDeclPool(0)
, fGramDesc(0)
, fRootElemId(0)
, fValidated(false)
{
//
// Init all the pool members.
//
// <TBD> Investigate what the optimum values would be for the various
// pools.
//
fElemDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(109, 128, fMemoryManager);
// should not need this in the common situation where grammars
// are built once and then read - NG
//fElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128, fMemoryManager);
fEntityDeclPool = new (fMemoryManager) NameIdPool<DTDEntityDecl>(109, 128, fMemoryManager);
fNotationDeclPool = new (fMemoryManager) NameIdPool<XMLNotationDecl>(109, 128, fMemoryManager);
//REVISIT: use grammarPool to create
fGramDesc = new (fMemoryManager) XMLDTDDescriptionImpl(XMLUni::fgDTDEntityString, fMemoryManager);
// Create default entities
resetEntityDeclPool();
}
DTDGrammar::~DTDGrammar()
{
delete fElemDeclPool;
if(fElemNonDeclPool)
{
delete fElemNonDeclPool;
}
delete fEntityDeclPool;
delete fNotationDeclPool;
delete fGramDesc;
}
// -----------------------------------------------------------------------
// Notification that lazy data has been deleted
// -----------------------------------------------------------------------
void DTDGrammar::reinitDfltEntities() {
delete fDefaultEntities;
fDefaultEntities = 0;
// delete local static data
delete sEntityPoolMutex;
sEntityPoolMutex = 0;
sEntityPoolMutexRegistered = false;
}
// -----------------------------------------------------------------------
// Virtual methods
// -----------------------------------------------------------------------
XMLElementDecl* DTDGrammar::findOrAddElemDecl (const unsigned int uriId
, const XMLCh* const baseName
, const XMLCh* const
, const XMLCh* const qName
, unsigned int scope
, bool& wasAdded )
{
// See it it exists
DTDElementDecl* retVal = (DTDElementDecl*) getElemDecl(uriId, baseName, qName, scope);
// if not, then add this in
if (!retVal)
{
retVal = new (fMemoryManager) DTDElementDecl
(
qName
, uriId
, DTDElementDecl::Any
, fMemoryManager
);
if(!fElemNonDeclPool)
fElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128, fMemoryManager);
const unsigned int elemId = fElemNonDeclPool->put(retVal);
retVal->setId(elemId);
wasAdded = true;
}
else
{
wasAdded = false;
}
return retVal;
}
XMLElementDecl* DTDGrammar::putElemDecl (const unsigned int uriId
, const XMLCh* const
, const XMLCh* const
, const XMLCh* const qName
, unsigned int
, const bool notDeclared)
{
DTDElementDecl* retVal = new (fMemoryManager) DTDElementDecl
(
qName
, uriId
, DTDElementDecl::Any
, fMemoryManager
);
if(notDeclared)
{
if(!fElemNonDeclPool)
fElemNonDeclPool = new (fMemoryManager) NameIdPool<DTDElementDecl>(29, 128, fMemoryManager);
retVal->setId(fElemNonDeclPool->put(retVal));
} else
{
retVal->setId(fElemDeclPool->put(retVal));
}
return retVal;
}
void DTDGrammar::reset()
{
//
// We need to reset all of the pools.
//
fElemDeclPool->removeAll();
// now that we have this, no point in deleting it...
if(fElemNonDeclPool)
fElemNonDeclPool->removeAll();
fNotationDeclPool->removeAll();
fEntityDeclPool->removeAll();
fValidated = false;
}
void DTDGrammar::resetEntityDeclPool() {
// Initialize default entities if not initialized
if (!sEntityPoolMutexRegistered)
{
if (!sEntityPoolMutex)
{
XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex);
if (!sEntityPoolMutex)
sEntityPoolMutex = new XMLMutex(XMLPlatformUtils::fgMemoryManager);
}
// Use a faux scope to synchronize while we do this
{
XMLMutexLock lock(sEntityPoolMutex);
// If we got here first, then register it and set the registered flag
if (!sEntityPoolMutexRegistered)
{
fDefaultEntities = new NameIdPool<DTDEntityDecl>(11, 12);
//
// Add the default entity entries for the character refs that must
// always be present. We indicate that they are from the internal
// subset. They aren't really, but they have to look that way so
// that they are still valid for use within a standalone document.
//
// We also mark them as special char entities, which allows them
// to be used in places whether other non-numeric general entities
// cannot.
//
fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgAmp, chAmpersand, true, true));
fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgLT, chOpenAngle, true, true));
fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgGT, chCloseAngle, true, true));
fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgQuot, chDoubleQuote, true, true));
fDefaultEntities->put(new DTDEntityDecl(XMLUni::fgApos, chSingleQuote, true, true));
// register cleanup method
entityPoolRegistryCleanup.registerCleanup(DTDGrammar::reinitDfltEntities);
sEntityPoolMutexRegistered = true;
}
}
}
}
void DTDGrammar::setGrammarDescription( XMLGrammarDescription* gramDesc)
{
if ((!gramDesc) ||
(gramDesc->getGrammarType() != Grammar::DTDGrammarType))
return;
if (fGramDesc)
delete fGramDesc;
//adopt the grammar Description
fGramDesc = (XMLDTDDescription*) gramDesc;
}
XMLGrammarDescription* DTDGrammar::getGrammarDescription() const
{
return fGramDesc;
}
/***
* Support for Serialization/De-serialization
***/
IMPL_XSERIALIZABLE_TOCREATE(DTDGrammar)
void DTDGrammar::serialize(XSerializeEngine& serEng)
{
Grammar::serialize(serEng);
//don't serialize fDefaultEntities
if (serEng.isStoring())
{
/***
*
* Serialize NameIdPool<DTDElementDecl>* fElemDeclPool;
* Serialize NameIdPool<DTDEntityDecl>* fEntityDeclPool;
* Serialize NameIdPool<XMLNotationDecl>* fNotationDeclPool;
***/
XTemplateSerializer::storeObject(fElemDeclPool, serEng);
XTemplateSerializer::storeObject(fEntityDeclPool, serEng);
XTemplateSerializer::storeObject(fNotationDeclPool, serEng);
/***
* serialize() method shall be used to store object
* which has been created in ctor
***/
fGramDesc->serialize(serEng);
serEng<<fRootElemId;
serEng<<fValidated;
}
else
{
/***
*
* Deserialize NameIdPool<DTDElementDecl>* fElemDeclPool;
* Deserialize NameIdPool<DTDEntityDecl>* fEntityDeclPool;
* Deerialize NameIdPool<XMLNotationDecl>* fNotationDeclPool;
***/
XTemplateSerializer::loadObject(&fElemDeclPool, 109, 128, serEng);
fElemNonDeclPool = 0;
XTemplateSerializer::loadObject(&fEntityDeclPool, 109, 128, serEng);
XTemplateSerializer::loadObject(&fNotationDeclPool, 109, 128, serEng);
/***
* serialize() method shall be used to load object
* which has been created in ctor
***/
fGramDesc->serialize(serEng);
serEng>>fRootElemId;
serEng>>fValidated;
}
}
XERCES_CPP_NAMESPACE_END