valuestore.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 384 行
CPP
384 行
/* * Copyright 2001,2004 The Apache Software Foundation. * * Licensed 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. *//* * $Log: ValueStore.cpp,v $ * Revision 1.11 2004/09/08 13:56:59 peiyongz * Apache License Version 2.0 * * Revision 1.10 2004/01/29 11:52:32 cargilld * Code cleanup changes to get rid of various compiler diagnostic messages. * * Revision 1.9 2003/12/17 00:18:41 cargilld * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data. * * Revision 1.8 2003/12/16 18:41:15 knoaman * Make IC_Field stateless * * Revision 1.7 2003/05/18 14:02:09 knoaman * Memory manager implementation: pass per instance manager. * * Revision 1.6 2003/05/15 18:59:34 knoaman * Partial implementation of the configurable memory manager. * * Revision 1.5 2002/12/04 02:32:43 knoaman * #include cleanup. * * Revision 1.4 2002/11/04 14:47:41 tng * C++ Namespace Support. * * Revision 1.3 2002/09/24 19:57:20 tng * Performance: use XMLString::equals instead of XMLString::compareString * * Revision 1.2 2002/02/18 06:26:50 jberry * Quiet codewarrior compiler warnings * * Revision 1.1.1.1 2002/02/01 22:22:51 peiyongz * sane_include * * Revision 1.3 2001/12/06 17:03:37 knoaman * Identity Constraint: fix for xpath expressions containing union operator(s). * * Revision 1.2 2001/11/20 20:32:52 knoaman * Bypass validating element's simple content if it's empty and element is nillable. * * Revision 1.1 2001/11/02 14:08:40 knoaman * Add support for identity constraints. * */// ---------------------------------------------------------------------------// 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// ---------------------------------------------------------------------------// 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) , fKeyValueStore(0) , fScanner(scanner) , fMemoryManager(manager){ fDoReportError = (scanner && scanner->getDoValidation());}ValueStore::~ValueStore(){ delete fValueTuples;}// ---------------------------------------------------------------------------// ValueStore: Helper methods// ---------------------------------------------------------------------------void ValueStore::addValue(IC_Field* const, DatatypeValidator* const, const XMLCh* const) {}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? int index = fValues.indexOf(field); if (index == -1) { 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 == (int) fValues.size()) { // is this value as a group duplicated? if (contains(&fValues)) { duplicateValue(); } // store values if (!fValueTuples) { fValueTuples = new (fMemoryManager) RefVectorOf<FieldValueMap>(4, true, fMemoryManager); } fValueTuples->addElement(new (fMemoryManager) FieldValueMap(fValues)); }}void ValueStore::append(const ValueStore* const other) { if (!other->fValueTuples) { return; } unsigned int tupleSize = other->fValueTuples->size(); for (unsigned int i=0; i<tupleSize; i++) { FieldValueMap* valueMap = other->fValueTuples->elementAt(i); if (!contains(valueMap)) { if (!fValueTuples) { fValueTuples = new (fMemoryManager) RefVectorOf<FieldValueMap>(4, true, fMemoryManager); } fValueTuples->addElement(new (fMemoryManager) FieldValueMap(*valueMap)); } }}void ValueStore::startValueScope() { fValuesCount = 0; int count = fIdentityConstraint->getFieldCount(); for (int i = 0; i < count; i++) { fValues.put(fIdentityConstraint->getFieldAt(i), 0, 0); }}void ValueStore::endValueScope() { if (fValuesCount == 0) { if (fIdentityConstraint->getType() == IdentityConstraint::KEY && fDoReportError) { fScanner->getValidator()->emitError(XMLValid::IC_AbsentKeyValue, fIdentityConstraint->getElementName()); } return; } // do we have enough values? if ((fValuesCount != fIdentityConstraint->getFieldCount()) && fDoReportError) { switch (fIdentityConstraint->getType()) { case IdentityConstraint::UNIQUE: { fScanner->getValidator()->emitError(XMLValid::IC_UniqueNotEnoughValues, fIdentityConstraint->getElementName()); break; } case IdentityConstraint::KEY: { fScanner->getValidator()->emitError(XMLValid::IC_KeyNotEnoughValues, fIdentityConstraint->getElementName(), fIdentityConstraint->getIdentityConstraintName()); break; } case IdentityConstraint::KEYREF: { fScanner->getValidator()->emitError(XMLValid::IC_KeyRefNotEnoughValues, fIdentityConstraint->getElementName(), fIdentityConstraint->getIdentityConstraintName()); break; } } }}bool ValueStore::contains(const FieldValueMap* const other) { if (fValueTuples) { unsigned int otherSize = other->size(); unsigned int tupleSize = fValueTuples->size(); for (unsigned int i=0; i<tupleSize; i++) { FieldValueMap* valueMap = fValueTuples->elementAt(i); if (otherSize == valueMap->size()) { bool matchFound = true; for (unsigned int j=0; j<otherSize; j++) { if (!isDuplicateOf(valueMap->getDatatypeValidatorAt(j), valueMap->getValueAt(j), other->getDatatypeValidatorAt(j), other->getValueAt(j))) { matchFound = false; break; } } if (matchFound) { // found it return true; } } } } return false;}bool ValueStore::isDuplicateOf(DatatypeValidator* const dv1, const XMLCh* const val1, DatatypeValidator* const dv2, const XMLCh* const val2) { // if either validator's null, fall back on string comparison if(!dv1 || !dv2) { return (XMLString::equals(val1, val2)); } unsigned int val1Len = XMLString::stringLen(val1); unsigned int val2Len = XMLString::stringLen(val2); if (!val1Len && !val2Len) { if (dv1 == dv2) { return true; } return false; } if (!val1Len || !val2Len) { return false; } // are the validators equal? // As always we are obliged to compare by reference... if (dv1 == dv2) { return ((dv1->compare(val1, val2, fMemoryManager)) == 0); } // see if this.fValidator is derived from value.fValidator: DatatypeValidator* tempVal = dv1; for(; !tempVal || tempVal == dv2; tempVal = tempVal->getBaseValidator()) ; if (tempVal) { // was derived! return ((dv2->compare(val1, val2, fMemoryManager)) == 0); } // see if value.fValidator is derived from this.fValidator: for(tempVal = dv2; !tempVal || tempVal == dv1; tempVal = tempVal->getBaseValidator()) ; if(tempVal) { // was derived! return ((dv1->compare(val1, val2, fMemoryManager)) == 0); } // if we're here it means the types weren't related. Must fall back to strings: return (XMLString::equals(val1, val2));}// ---------------------------------------------------------------------------// ValueStore: Docuement handling methods// ---------------------------------------------------------------------------void ValueStore::endDcocumentFragment(ValueStoreCache* const valueStoreCache) { if (fIdentityConstraint->getType() == IdentityConstraint::KEYREF) { // verify references // get the key store corresponding (if it exists): fKeyValueStore = valueStoreCache->getGlobalValueStoreFor(((IC_KeyRef*) fIdentityConstraint)->getKey()); if (!fKeyValueStore) { if (fDoReportError) { fScanner->getValidator()->emitError(XMLValid::IC_KeyRefOutOfScope, fIdentityConstraint->getIdentityConstraintName()); } return; } unsigned int count = (fValueTuples) ? fValueTuples->size() : 0; for (unsigned int i = 0; i < count; i++) { FieldValueMap* valueMap = fValueTuples->elementAt(i); if (!fKeyValueStore->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::KEY) { fScanner->getValidator()->emitError(XMLValid::IC_KeyMatchesNillable, ic->getElementName()); }}void ValueStore::duplicateValue() { if (fDoReportError) { switch (fIdentityConstraint->getType()) { case IdentityConstraint::UNIQUE: { fScanner->getValidator()->emitError(XMLValid::IC_DuplicateUnique, fIdentityConstraint->getElementName()); break; } case IdentityConstraint::KEY: { fScanner->getValidator()->emitError(XMLValid::IC_DuplicateKey, fIdentityConstraint->getElementName()); break; } } }}XERCES_CPP_NAMESPACE_END/** * End of file ValueStore.cpp */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?