Added Xerces-C++ 3.1.2
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* 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: ValueStore.cpp 804209 2009-08-14 13:15:05Z amassari $
|
||||
*/
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Includes
|
||||
// ---------------------------------------------------------------------------
|
||||
#include <xercesc/internal/XMLScanner.hpp>
|
||||
#include <xercesc/framework/XMLValidator.hpp>
|
||||
#include <xercesc/validators/datatype/DatatypeValidator.hpp>
|
||||
#include <xercesc/validators/schema/identity/FieldActivator.hpp>
|
||||
#include <xercesc/validators/schema/identity/ValueStore.hpp>
|
||||
#include <xercesc/validators/schema/identity/IC_Field.hpp>
|
||||
#include <xercesc/validators/schema/identity/IC_KeyRef.hpp>
|
||||
#include <xercesc/validators/schema/identity/ValueStoreCache.hpp>
|
||||
|
||||
XERCES_CPP_NAMESPACE_BEGIN
|
||||
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
// ICValueHasher: the hasher for identity constraints values
|
||||
// ---------------------------------------------------------------------------
|
||||
XMLSize_t ICValueHasher::getHashVal(const void* key, XMLSize_t mod) const
|
||||
{
|
||||
const FieldValueMap* valueMap=(const FieldValueMap*)key;
|
||||
XMLSize_t hashVal = 0;
|
||||
|
||||
XMLSize_t size = valueMap->size();
|
||||
for (XMLSize_t j=0; j<size; j++) {
|
||||
// reach the most generic datatype validator
|
||||
DatatypeValidator* dv = valueMap->getDatatypeValidatorAt(j);
|
||||
while(dv && dv->getBaseValidator())
|
||||
dv = dv->getBaseValidator();
|
||||
const XMLCh* const val = valueMap->getValueAt(j);
|
||||
const XMLCh* canonVal = (dv && val)?dv->getCanonicalRepresentation(val, fMemoryManager):0;
|
||||
if(canonVal)
|
||||
{
|
||||
hashVal += XMLString::hash(canonVal, mod);
|
||||
fMemoryManager->deallocate((void*)canonVal);
|
||||
}
|
||||
else if(val)
|
||||
hashVal += XMLString::hash(val, mod);
|
||||
}
|
||||
|
||||
return hashVal % mod;
|
||||
}
|
||||
|
||||
bool ICValueHasher::equals(const void *const key1, const void *const key2) const
|
||||
{
|
||||
const FieldValueMap* left=(const FieldValueMap*)key1;
|
||||
const FieldValueMap* right=(const FieldValueMap*)key2;
|
||||
|
||||
XMLSize_t lSize = left->size();
|
||||
XMLSize_t rSize = right->size();
|
||||
if (lSize == rSize)
|
||||
{
|
||||
bool matchFound = true;
|
||||
|
||||
for (XMLSize_t j=0; j<rSize; j++) {
|
||||
if (!isDuplicateOf(left->getDatatypeValidatorAt(j), left->getValueAt(j),
|
||||
right->getDatatypeValidatorAt(j), right->getValueAt(j))) {
|
||||
matchFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matchFound) { // found it
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ICValueHasher::isDuplicateOf(DatatypeValidator* const dv1, const XMLCh* const val1,
|
||||
DatatypeValidator* const dv2, const XMLCh* const val2) const
|
||||
{
|
||||
|
||||
// if either validator's null, fall back on string comparison
|
||||
if(!dv1 || !dv2) {
|
||||
return (XMLString::equals(val1, val2));
|
||||
}
|
||||
|
||||
bool val1IsEmpty = (val1==0 || *val1==0);
|
||||
bool val2IsEmpty = (val2==0 || *val2==0);
|
||||
|
||||
if (val1IsEmpty && val2IsEmpty) {
|
||||
|
||||
if (dv1 == dv2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val1IsEmpty || val2IsEmpty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the common ancestor, if there is one
|
||||
DatatypeValidator* tempVal1 = dv1;
|
||||
while(tempVal1)
|
||||
{
|
||||
DatatypeValidator* tempVal2 = dv2;
|
||||
for(; tempVal2 != NULL && tempVal2 != tempVal1; tempVal2 = tempVal2->getBaseValidator()) ;
|
||||
if (tempVal2)
|
||||
return ((tempVal2->compare(val1, val2, fMemoryManager)) == 0);
|
||||
tempVal1=tempVal1->getBaseValidator();
|
||||
}
|
||||
|
||||
// if we're here it means the types weren't related. They are different:
|
||||
return false;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ValueStore: Constructors and Destructor
|
||||
// ---------------------------------------------------------------------------
|
||||
ValueStore::ValueStore(IdentityConstraint* const ic,
|
||||
XMLScanner* const scanner,
|
||||
MemoryManager* const manager)
|
||||
: fDoReportError(false)
|
||||
, fValuesCount(0)
|
||||
, fIdentityConstraint(ic)
|
||||
, fValues(manager)
|
||||
, fValueTuples(0)
|
||||
, fScanner(scanner)
|
||||
, fMemoryManager(manager)
|
||||
{
|
||||
fDoReportError = (scanner && (scanner->getValidationScheme() == XMLScanner::Val_Always));
|
||||
}
|
||||
|
||||
|
||||
ValueStore::~ValueStore()
|
||||
{
|
||||
delete fValueTuples;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ValueStore: Helper methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void ValueStore::addValue(FieldActivator* const fieldActivator,
|
||||
IC_Field* const field,
|
||||
DatatypeValidator* const dv,
|
||||
const XMLCh* const value) {
|
||||
|
||||
if (!fieldActivator->getMayMatch(field) && fDoReportError) {
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_FieldMultipleMatch);
|
||||
}
|
||||
|
||||
// do we even know this field?
|
||||
XMLSize_t index;
|
||||
bool bFound = fValues.indexOf(field, index);
|
||||
|
||||
if (!bFound) {
|
||||
|
||||
if (fDoReportError) {
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_UnknownField);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// store value
|
||||
if (!fValues.getDatatypeValidatorAt(index) &&
|
||||
!fValues.getValueAt(index)) {
|
||||
fValuesCount++;
|
||||
}
|
||||
|
||||
fValues.put(field, dv, value);
|
||||
|
||||
if (fValuesCount == fValues.size()) {
|
||||
|
||||
// is this value as a group duplicated?
|
||||
if (contains(&fValues)) {
|
||||
duplicateValue();
|
||||
}
|
||||
|
||||
// store values
|
||||
if (!fValueTuples) {
|
||||
fValueTuples = new (fMemoryManager) RefHashTableOf<FieldValueMap, ICValueHasher>(107, true, ICValueHasher(fMemoryManager), fMemoryManager);
|
||||
}
|
||||
|
||||
FieldValueMap* pICItem = new (fMemoryManager) FieldValueMap(fValues);
|
||||
fValueTuples->put(pICItem, pICItem);
|
||||
}
|
||||
}
|
||||
|
||||
void ValueStore::append(const ValueStore* const other) {
|
||||
|
||||
if (!other->fValueTuples) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefHashTableOfEnumerator<FieldValueMap, ICValueHasher> iter(other->fValueTuples, false, fMemoryManager);
|
||||
while(iter.hasMoreElements())
|
||||
{
|
||||
FieldValueMap& valueMap = iter.nextElement();
|
||||
|
||||
if (!contains(&valueMap)) {
|
||||
|
||||
if (!fValueTuples) {
|
||||
fValueTuples = new (fMemoryManager) RefHashTableOf<FieldValueMap, ICValueHasher>(107, true, ICValueHasher(fMemoryManager), fMemoryManager);
|
||||
}
|
||||
|
||||
FieldValueMap* pICItem = new (fMemoryManager) FieldValueMap(valueMap);
|
||||
fValueTuples->put(pICItem, pICItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ValueStore::startValueScope() {
|
||||
|
||||
fValuesCount = 0;
|
||||
|
||||
XMLSize_t count = fIdentityConstraint->getFieldCount();
|
||||
|
||||
for (XMLSize_t i = 0; i < count; i++) {
|
||||
fValues.put(fIdentityConstraint->getFieldAt(i), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ValueStore::endValueScope() {
|
||||
|
||||
if (fValuesCount == 0) {
|
||||
|
||||
if (fIdentityConstraint->getType() == IdentityConstraint::ICType_KEY && fDoReportError) {
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_AbsentKeyValue,
|
||||
fIdentityConstraint->getElementName());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// do we have enough values?
|
||||
if ((fValuesCount != fIdentityConstraint->getFieldCount()) && fDoReportError) {
|
||||
|
||||
if(fIdentityConstraint->getType()==IdentityConstraint::ICType_KEY)
|
||||
{
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_KeyNotEnoughValues,
|
||||
fIdentityConstraint->getElementName(), fIdentityConstraint->getIdentityConstraintName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ValueStore::contains(const FieldValueMap* const other) {
|
||||
|
||||
if (fValueTuples)
|
||||
return fValueTuples->get(other)!=0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ValueStore::clear()
|
||||
{
|
||||
fValuesCount=0;
|
||||
fValues.clear();
|
||||
if(fValueTuples)
|
||||
fValueTuples->removeAll();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ValueStore: Document handling methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void ValueStore::endDocumentFragment(ValueStoreCache* const valueStoreCache) {
|
||||
|
||||
if (fIdentityConstraint->getType() == IdentityConstraint::ICType_KEYREF) {
|
||||
|
||||
// verify references
|
||||
// get the key store corresponding (if it exists):
|
||||
ValueStore* keyValueStore = valueStoreCache->getGlobalValueStoreFor(((IC_KeyRef*) fIdentityConstraint)->getKey());
|
||||
|
||||
if (!keyValueStore) {
|
||||
|
||||
if (fDoReportError) {
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_KeyRefOutOfScope,
|
||||
fIdentityConstraint->getIdentityConstraintName());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(fValueTuples)
|
||||
{
|
||||
RefHashTableOfEnumerator<FieldValueMap, ICValueHasher> iter(fValueTuples, false, fMemoryManager);
|
||||
while(iter.hasMoreElements())
|
||||
{
|
||||
FieldValueMap& valueMap = iter.nextElement();
|
||||
|
||||
if (!keyValueStore->contains(&valueMap) && fDoReportError) {
|
||||
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_KeyNotFound,
|
||||
fIdentityConstraint->getElementName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ValueStore: Error reporting methods
|
||||
// ---------------------------------------------------------------------------
|
||||
void ValueStore::reportNilError(IdentityConstraint* const ic) {
|
||||
|
||||
if (fDoReportError && ic->getType() == IdentityConstraint::ICType_KEY) {
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_KeyMatchesNillable,
|
||||
ic->getElementName());
|
||||
}
|
||||
}
|
||||
|
||||
void ValueStore::duplicateValue() {
|
||||
|
||||
if (fDoReportError) {
|
||||
|
||||
switch (fIdentityConstraint->getType()) {
|
||||
case IdentityConstraint::ICType_UNIQUE:
|
||||
{
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_DuplicateUnique,
|
||||
fIdentityConstraint->getElementName());
|
||||
break;
|
||||
}
|
||||
case IdentityConstraint::ICType_KEY:
|
||||
{
|
||||
fScanner->getValidator()->emitError(XMLValid::IC_DuplicateKey,
|
||||
fIdentityConstraint->getElementName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XERCES_CPP_NAMESPACE_END
|
||||
|
||||
/**
|
||||
* End of file ValueStore.cpp
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user