diff --git a/Projects/OS2/VACPP40/xerces_util.icc b/Projects/OS2/VACPP40/xerces_util.icc index 49af0075c824bb74ca1b4c3bb419c40ae349267c..8854a37315ca9be63079c05073349cb95daca61f 100644 --- a/Projects/OS2/VACPP40/xerces_util.icc +++ b/Projects/OS2/VACPP40/xerces_util.icc @@ -3,7 +3,7 @@ group xerces_util = BASE_DIR "\\src\\util\\BinInputStream.cpp", BASE_DIR "\\src\\util\\BinMemInputStream.cpp", BASE_DIR "\\src\\util\\BitSet.cpp", - BASE_DIR "\\src\\util\\HashPtr.cpp", + BASE_DIR "\\src\\util\\HashPtr.cpp", BASE_DIR "\\src\\util\\HashXMLCh.cpp", BASE_DIR "\\src\\util\\HeaderDummy.cpp", BASE_DIR "\\src\\util\\KVStringPair.cpp", @@ -15,6 +15,8 @@ group xerces_util = BASE_DIR "\\src\\util\\XML256TableTranscoder.cpp", BASE_DIR "\\src\\util\\XML88591Transcoder.cpp", BASE_DIR "\\src\\util\\XMLASCIITranscoder.cpp", + BASE_DIR "\\src\\util\\XMLBigDecimal.cpp", + BASE_DIR "\\src\\util\\XMLBigInteger.cpp", BASE_DIR "\\src\\util\\XMLChTranscoder.cpp", BASE_DIR "\\src\\util\\XMLEBCDICTranscoder.cpp", BASE_DIR "\\src\\util\\XMLException.cpp", diff --git a/src/util/Makefile.in b/src/util/Makefile.in index 78c79f3968090b2334a13624e2f02a88dca423c3..79da733c322af90b8de669a14435268a63200648 100644 --- a/src/util/Makefile.in +++ b/src/util/Makefile.in @@ -55,6 +55,9 @@ # # # $Log$ +# Revision 1.33 2001/05/10 20:51:18 tng +# Schema: Add DecimalDatatypeValidator and XMLBigDecimal, XMLBigInteger. By Pei Yong Zhang. +# # Revision 1.32 2001/04/19 17:47:56 knoaman # A string tokenizer utility. # @@ -293,6 +296,8 @@ UTIL_CPP_PUBHEADERS = \ XML256TableTranscoder.hpp \ XML88591Transcoder.hpp \ XMLASCIITranscoder.hpp \ + XMLBigDecimal.hpp \ + XMLBigInteger.hpp \ XMLChTranscoder.hpp \ XMLIBM1140Transcoder.hpp \ XMLDeleterFor.hpp \ @@ -350,6 +355,8 @@ UTIL_CPP_OBJECTS = \ XML256TableTranscoder.$(TO) \ XML88591Transcoder.$(TO) \ XMLASCIITranscoder.$(TO) \ + XMLBigDecimal.$(TO) \ + XMLBigInteger.$(TO) \ XMLChTranscoder.$(TO) \ XMLIBM1140Transcoder.$(TO) \ XMLEBCDICTranscoder.$(TO) \ diff --git a/src/util/XMLBigDecimal.cpp b/src/util/XMLBigDecimal.cpp new file mode 100644 index 0000000000000000000000000000000000000000..621a8fcc5fef85cda35021b1711bd78ad4a8fa80 --- /dev/null +++ b/src/util/XMLBigDecimal.cpp @@ -0,0 +1,310 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache\@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation, and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com . For more information + * on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ + +/* + * $Log$ + * Revision 1.1 2001/05/10 20:51:20 tng + * Schema: Add DecimalDatatypeValidator and XMLBigDecimal, XMLBigInteger. By Pei Yong Zhang. + * + */ + +// --------------------------------------------------------------------------- +// Includes +// --------------------------------------------------------------------------- +#include <string.h> +#include <iostream.h> +#include <util/XMLBigDecimal.hpp> +#include <util/PlatformUtils.hpp> +#include <util/XMLString.hpp> +#include <util/XMLUniDefs.hpp> +#include <util/NumberFormatException.hpp> +#include <util/RuntimeException.hpp> +#include <util/TransService.hpp> +#include <util/Janitor.hpp> + +/** + * Constructs a BigDecimal from a string containing an optional minus + * sign followed by a sequence of zero or more decimal digits, optionally + * followed by a fraction, which consists of a decimal point followed by + * zero or more decimal digits. The string must contain at least one + * digit in the integer or fractional part. The scale of the resulting + * BigDecimal will be the number of digits to the right of the decimal + * point in the string, or 0 if the string contains no decimal point. + * Any extraneous characters (including whitespace) will result in + * a NumberFormatException. +*/ +// +// since parseBigDecimal and XMLBigInteger() may +// throw exception, caller of XMLBigDecimal better +// be ready to catch it. +// + +XMLBigDecimal::XMLBigDecimal(const XMLCh* const strValue) +:fIntVal(0) +,fScale(0) +{ + XMLCh* ret_value = new XMLCh[XMLString::stringLen(strValue)+1]; + ArrayJanitor<XMLCh> janName(ret_value); + + parseBigDecimal(strValue, ret_value, fScale); + fIntVal = new XMLBigInteger(ret_value); + +} + +XMLBigDecimal::XMLBigDecimal(const XMLBigDecimal& toCopy) +:fIntVal(0) +,fScale(toCopy.getScale()) +{ + + //invoke XMLBigInteger' copy ctor + fIntVal = new XMLBigInteger(*(toCopy.getValue())); +} + + +/*** + * + * Leading and trailing whitespaces are allowed, and trimmed + * + * Only one and either of (+,-) after the leading whitespace, before + * any other characters are allowed, '+' removed + * + * '.' allowed and removed + + * return status: void + * retBuffer: w/o leading and/or trailing whitespace + * w/o '+' and containning one '-' if any + * w/o leading zero + * w/o '.' + * + * scalevalue: indicate the number of digits, right to + * the '.' + * + * see XMLBigInteger::parseBigInteger(); + * XMLString::textToBin(); + * + * " +000203.456" "203456" + * " -000203.456" "-203456" + * " -000.456" "-456" + * +***/ + +void XMLBigDecimal::parseBigDecimal(const XMLCh* const toConvert + , XMLCh* const retBuffer + , unsigned int & scaleValue) +{ + scaleValue = 0; + + // If no string, then its a failure + if ((!toConvert) || + (!*toConvert)) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLINT_Invalid); + + // Scan past any whitespace. If we hit the end, then return failure + const XMLCh* startPtr = toConvert; + while (XMLPlatformUtils::fgTransService->isSpace(*startPtr)) + startPtr++; + + if (!*startPtr) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLINT_Invalid); + + // Start at the end and work back through any whitespace + const XMLCh* endPtr = toConvert + XMLString::stringLen(toConvert); + while (XMLPlatformUtils::fgTransService->isSpace(*(endPtr - 1))) + endPtr--; + + // + // Work through what remains and convert each char to a digit. + // + XMLCh* retPtr = retBuffer; + // + // '+' or '-' is allowed only at the first position + // + if (*startPtr == chDash) + { + // copy the '-' + *retPtr = chDash; + startPtr++; + retPtr++; + } + else if (*startPtr == chPlus) + { + // skip the '+' + startPtr++; + } + + // Leading zero will be taken care by BigInteger + + bool dotSignFound = false; + + while (startPtr < endPtr) + { + // + // '.' is allowed only once + // + if (*startPtr == chPeriod) + { + if (dotSignFound == false) + { + dotSignFound = true; + scaleValue = endPtr - startPtr - 1; + startPtr++; + continue; + } + else + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLBIGDECIMAL_MANY_DOT); + } + + // If not valid decimal digit, then an error + if ((*startPtr < chDigit_0) || (*startPtr > chDigit_9)) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLBIGDECIMAL_Invalid); + + // copy over + *retPtr = *startPtr; + retPtr++; + startPtr++; + } + + *retPtr = 0; //terminated + return; +} + +/** + * Returns -1, 0 or 1 as lValue is less than, equal to, or greater + * than rValue. Two BigDecimals that are equal in value but have a + * different scale (e.g., 2.0, 2.00) are considered equal by this method. +*/ + +int XMLBigDecimal::compareValues(const XMLBigDecimal* const lValue + , const XMLBigDecimal* const rValue) +{ + // + if ((!lValue) || + (!rValue) ) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLBIGDECIMAL_Null_value); + + /* Optimization: would run fine without the next three lines */ + int sigDiff = lValue->getSign() - rValue->getSign(); + if (sigDiff != 0) + return (sigDiff > 0 ? 1 : -1); + + // + // If signs match, scale and compare intVals + // since matchScale will destructively change the scale + // we make a copy for both + // + if (lValue->getScale() != rValue->getScale()) + { + XMLBigDecimal lTemp = *lValue; + XMLBigDecimal rTemp = *rValue; + + matchScale(&lTemp, &rTemp); + return XMLBigInteger::compareValues(lTemp.getValue(), rTemp.getValue()); + } + + return XMLBigInteger::compareValues(lValue->getValue(), rValue->getValue()); +} + +/* + * If the scales of lValue and rValue differ, rescale (destructively) + * the lower-scaled BigDecimal so they match. + * + * rescale the lower-scaled will not lose precision. + * +*/ +void XMLBigDecimal::matchScale(XMLBigDecimal* const lValue + , XMLBigDecimal* const rValue) +{ + if (lValue->getScale() < rValue->getScale()) + lValue->reScale(rValue->getScale()); + else + if (lValue->getScale() > rValue->getScale()) + rValue->reScale(lValue->getScale()); +} + + +void XMLBigDecimal::reScale(unsigned int newScale) +{ + if (newScale < 0) + return; + + /* Handle the easy cases */ + if (newScale == this->getScale()) + return; + else if (newScale > this->getScale()) + { + fIntVal->multiply(newScale - this->getScale()); + fScale = newScale; + } + else /* scale < this.scale */ + { + fIntVal->divide(this->getScale() - newScale); + fScale = newScale; + } + + return; +} + +void XMLBigDecimal::dumpData() const +{ + cout<<"scale="<<"<"<<fScale<<">"<<endl; + fIntVal->dumpData(); + cout<<endl; +} \ No newline at end of file diff --git a/src/util/XMLBigDecimal.hpp b/src/util/XMLBigDecimal.hpp new file mode 100644 index 0000000000000000000000000000000000000000..61e81dba8591a693426d14fbde6380020cfba785 --- /dev/null +++ b/src/util/XMLBigDecimal.hpp @@ -0,0 +1,177 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache\@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation, and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com . For more information + * on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ + +/* + * $Id$ + */ + +#ifndef XML_BIGDECIMAL_HPP +#define XML_BIGDECIMAL_HPP + +#include <util/XercesDefs.hpp> +#include <util/XMLBigInteger.hpp> + +class XMLUTIL_EXPORT XMLBigDecimal +{ +public: + + /** + * Constructs a newly allocated <code>XMLBigDecimal</code> object that + * represents the value represented by the string. + * + * @param the <code>String</code> to be converted to an + * <code>XMLBigDecimal</code>. + * @exception NumberFormatException if the <code>String</code> does not + * contain a parsable XMLBigDecimal. + */ + + XMLBigDecimal(const XMLCh* const strValue); + + ~XMLBigDecimal(); + + XMLBigDecimal(const XMLBigDecimal& toCopy); + + static void parseBigDecimal(const XMLCh* const strValue + , XMLCh* const retValue + , unsigned int& scaleValue); + + static int compareValues(const XMLBigDecimal* const lValue + , const XMLBigDecimal* const rValue); + + static void matchScale(XMLBigDecimal* const lValue + , XMLBigDecimal* const rValue); + + /** + * Returns the sign of this number + * + * -1 negative + * 0 zero + * 1 positive + * + */ + int getSign() const; + + XMLBigInteger* getValue() const; + + unsigned int getScale() const; + + unsigned int getTotalDigit() const; + + void dumpData() const; + + /** + * Compares this object to the specified object. + * The result is <code>true</code> if and only if the argument is not + * <code>null</code> and is an <code>XMLBigDecimal</code> object that contains + * the same <code>int</code> value as this object. + * + * @param obj the object to compare with. + * @return <code>true</code> if the objects are the same; + * <code>false</code> otherwise. + */ + bool operator==(const XMLBigDecimal& toCompare) const; + +private: + + void reScale(unsigned int newValue); + + // ----------------------------------------------------------------------- + // Private data members + // + // fIntVal + // the XMLBigInteger holding the value of this BigDecimal. + // + // fScale + // the number of digits to the right of the decimal point + // + // ----------------------------------------------------------------------- + + XMLBigInteger* fIntVal; + unsigned int fScale; + +}; + +inline XMLBigDecimal::~XMLBigDecimal() +{ + delete fIntVal; +} + +inline int XMLBigDecimal::getSign() const +{ + return fIntVal->getSign(); +} + +inline XMLBigInteger* XMLBigDecimal::getValue() const +{ + return fIntVal; +} + +inline unsigned int XMLBigDecimal::getScale() const +{ + return fScale; +} + +inline unsigned int XMLBigDecimal::getTotalDigit() const +{ + return fIntVal->getTotalDigit(); +} + +inline bool XMLBigDecimal::operator==(const XMLBigDecimal& toCompare) const +{ + return ( XMLBigInteger::compareValues(this->fIntVal, toCompare.fIntVal) == 0 ? true : false); +} + +#endif diff --git a/src/util/XMLBigInteger.cpp b/src/util/XMLBigInteger.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46947050f5ecbd6c71c09efafbcad69df540a912 --- /dev/null +++ b/src/util/XMLBigInteger.cpp @@ -0,0 +1,337 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache\@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation, and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com . For more information + * on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ + +/* + * $Log$ + * Revision 1.1 2001/05/10 20:51:23 tng + * Schema: Add DecimalDatatypeValidator and XMLBigDecimal, XMLBigInteger. By Pei Yong Zhang. + * + */ + +// --------------------------------------------------------------------------- +// Includes +// --------------------------------------------------------------------------- +#include <string.h> +#include <iostream.h> +#include <util/XMLBigInteger.hpp> +#include <util/XMLString.hpp> +#include <util/NumberFormatException.hpp> +#include <util/RuntimeException.hpp> +#include <util/PlatformUtils.hpp> +#include <util/TransService.hpp> +#include <util/XMLUniDefs.hpp> +#include <util/XMLUni.hpp> +#include <util/Janitor.hpp> + +/*** + * + * Leading and trailing whitespaces are allowed, and trimmed + * + * Only one and either of (+,-) after the leading whitespace, before + * any other characters are allowed, and trimmed + * + * Leading zero, after leading whitespace, (+|-), before any other + * characters are allowed, and trimmed + * + * '.' NOT allowed + + * return status: void + * ret_buf: w/o leading and/or trailing whitespace + * w/o '+' and '-' + * w/o leading zero + * + * see XMLInteger::parseInteger(); + * XMLString::textToBin(); + * + * " +000203456" "203456" + * " -000203456" "203456" + * +***/ + +void XMLBigInteger::parseBigInteger(const XMLCh* const toConvert + , XMLCh* retBuffer + , int& signValue) +{ + // If no string, then its a failure + if ((!toConvert) || + (!*toConvert)) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLINT_Invalid); + + // + // Note: in Java's BigInteger, it seems any leading and/or trailing + // whitespaces are not allowed. If this is the case, we may + // need to skip the trimming below. + // + + // Scan past any whitespace. If we hit the end, then return failure + const XMLCh* startPtr = toConvert; + while (XMLPlatformUtils::fgTransService->isSpace(*startPtr)) + startPtr++; + + if (!*startPtr) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLINT_Invalid); + + // Start at the end and work back through any whitespace + const XMLCh* endPtr = toConvert + XMLString::stringLen(toConvert); + while (XMLPlatformUtils::fgTransService->isSpace(*(endPtr - 1))) + endPtr--; + + // + // Work through what remains and convert each char to a digit. + // anything other than ' + // + XMLCh* retPtr = retBuffer; + signValue = 1; + + // + // '+' or '-' is allowed only at the first position + // + if (*startPtr == chDash) + { + signValue = -1; + startPtr++; + } + else if (*startPtr == chPlus) + { + // skip the '+' + startPtr++; + } + + // Scan past any leading zero. + while (*startPtr == chDigit_0) + startPtr++; + + if (!*startPtr) + { + signValue = 0; + // containning zero, only zero, nothing but zero + // it is a zero, indeed + return; + } + + while (startPtr < endPtr) + { + // If not valid decimal digit, then an error + if ((*startPtr < chDigit_0) || (*startPtr > chDigit_9)) + ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLINT_Invalid); + + // copy over + *retPtr = *startPtr; + retPtr++; + startPtr++; + } + + *retPtr = 0; //terminated + return; +} + +/** + * Translates a string containing an optional minus sign followed by a + * sequence of one or more digits into a BigInteger. + * Any extraneous characters (including whitespace), + * inclusive, will result in a NumberFormatException. + */ +XMLBigInteger::XMLBigInteger(const XMLCh* const strValue) +{ + XMLCh* ret_value = new XMLCh[XMLString::stringLen(strValue)+1]; + ArrayJanitor<XMLCh> janName(ret_value); + + try + { + parseBigInteger(strValue, ret_value, fSign); + } + catch (NumberFormatException) + { + throw; + //ThrowXML(NumberFormatException, XMLExcepts::CM_UnaryOpHadBinType); + //ThrowXML(NumberFormatException, XMLExcepts::XMLBIGDECIMAL_Inv_format); + } + + if (fSign == 0) + fMagnitude = XMLString::replicate(XMLUni::fgZeroLenString); + else + { + unsigned int strLen = XMLString::stringLen(ret_value); + fMagnitude = new XMLCh[strLen+1]; + XMLString::moveChars(fMagnitude, ret_value, strLen); + fMagnitude[strLen]=0; + } + +} + +XMLBigInteger::~XMLBigInteger() +{ + delete[] fMagnitude; +} + +XMLBigInteger::XMLBigInteger(const XMLBigInteger& toCopy) +{ + setSign(toCopy.getSign()); + + int strLen = XMLString::stringLen(toCopy.fMagnitude); + fMagnitude = new XMLCh[strLen+1]; + XMLString::moveChars(fMagnitude, toCopy.fMagnitude, strLen); + fMagnitude[strLen]=0; +} + +/** + * Returns -1, 0 or 1 as lValue is less than, equal to, or greater + * than rValue. +*/ +int XMLBigInteger::compareValues(const XMLBigInteger* const lValue + , const XMLBigInteger* const rValue) +{ + int lSign = lValue->getSign(); + int rSign = rValue->getSign(); + + // + // different sign + // + if (lSign != rSign) + return(lSign > rSign ? 1 : -1); + + // + // same sign + // + if (lSign == 0) // optimization + return 0; + + int lStrLen = XMLString::stringLen(lValue->fMagnitude); + int rStrLen = XMLString::stringLen(rValue->fMagnitude); + + // + // different length + // + if (lStrLen > rStrLen) + return ( lSign > 0 ? 1 : -1 ); + else if (lStrLen < rStrLen) + return ( lSign > 0 ? -1 : 1 ); + + // + // same length + // XMLString::compareString() return > 0, 0 and <0 + // we need to convert it to 1, 0, and -1 + // + int retVal = XMLString::compareString(lValue->fMagnitude, rValue->fMagnitude); + + if ( retVal > 0 ) + { + return ( lSign > 0 ? 1 : -1 ); + } + else if ( retVal < 0 ) + { + return ( lSign > 0 ? -1 : 1 ); + } + else + return 0; + +} + +/** + * Shift the fMagnitude to the left + */ + +void XMLBigInteger::multiply(const unsigned int byteToShift) +{ + if (byteToShift <= 0) + return; + + int strLen = XMLString::stringLen(fMagnitude); + XMLCh* tmp = new XMLCh[strLen+byteToShift+1]; + XMLString::moveChars(tmp, fMagnitude, strLen); + + unsigned int i = 0; + for ( ; i < byteToShift; i++) + tmp[strLen+i] = chDigit_0; + + tmp[strLen+i] = chNull; + + delete[] fMagnitude; + fMagnitude = tmp; +} + +/** + * Shift the fMagnitude to the right + * by doing this, we lose precision. + */ +void XMLBigInteger::divide(const unsigned int byteToShift) +{ + if (byteToShift <= 0) + return; + + int strLen = XMLString::stringLen(fMagnitude); + XMLCh* tmp = new XMLCh[strLen-byteToShift+1]; + XMLString::moveChars(tmp, fMagnitude, strLen-byteToShift); + + tmp[strLen-byteToShift] = chNull; + + delete[] fMagnitude; + fMagnitude = tmp; +} + +void XMLBigInteger::dumpData() const +{ + char *p; + p = XMLString::transcode(fMagnitude); + cout<<"sign="<<"<"<<fSign<<">"<<endl; + cout<<"fMagnitude="<<"<"<<p<<">"<<endl; + cout<<endl; + delete[] p; + +} diff --git a/src/util/XMLBigInteger.hpp b/src/util/XMLBigInteger.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dc01f99a4b1f007b42975c271dd8258c00bae5f4 --- /dev/null +++ b/src/util/XMLBigInteger.hpp @@ -0,0 +1,168 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache\@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation, and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com . For more information + * on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ + +/* + * $Id$ + */ + +#ifndef XML_BIGINTEGER_HPP +#define XML_BIGINTEGER_HPP + +#include <util/XercesDefs.hpp> +#include <util/XMLString.hpp> + +class XMLUTIL_EXPORT XMLBigInteger +{ +public: + + /** + * Constructs a newly allocated <code>XMLBigInteger</code> object that + * represents the value represented by the string. The string is + * converted to an int value as if by the <code>valueOf</code> method. + * + * @param s the <code>String</code> to be converted to an + * <code>XMLBigInteger</code>. + * @exception NumberFormatException if the <code>String</code> does not + * contain a parsable XMLBigInteger. + */ + + XMLBigInteger(const XMLCh* const strValue); + + ~XMLBigInteger(); + + XMLBigInteger(const XMLBigInteger& toCopy); + + static void parseBigInteger(const XMLCh* const toConvert + , XMLCh* const retBuffer + , int& signValue); + + static int compareValues(const XMLBigInteger* const lValue + ,const XMLBigInteger* const rValue); + + + void multiply(const unsigned int byteToShift); + + void divide(const unsigned int byteToShift); + + int getTotalDigit() const; + + void dumpData() const; + + /** + * Compares this object to the specified object. + * The result is <code>true</code> if and only if the argument is not + * <code>null</code> and is an <code>XMLBigInteger</code> object that contains + * the same <code>int</code> value as this object. + * + * @param obj the object to compare with. + * @return <code>true</code> if the objects are the same; + * <code>false</code> otherwise. + */ + bool operator==(const XMLBigInteger& toCompare) const; + + /** + * Returns the signum function of this number (i.e., -1, 0 or 1 as + * the value of this number is negative, zero or positive). + */ + int getSign() const; + +private: + + void setSign(int); + + /* + * The number is internally stored in "minimal" sign-fMagnitude format + * (i.e., no BigIntegers have a leading zero byte in their magnitudes). + * Zero is represented with a signum of 0 (and a zero-length fMagnitude). + * Thus, there is exactly one representation for each value. + */ + // ----------------------------------------------------------------------- + // Private data members + // + // fSign + // to represent the sign of the number. + // + // fMagnitude + // the buffer holding the number. + // + // ----------------------------------------------------------------------- + + int fSign; + XMLCh* fMagnitude; //null terminated + +}; + +inline int XMLBigInteger::getSign() const +{ + return fSign; +} + +inline int XMLBigInteger::getTotalDigit() const +{ + return ((getSign() ==0) ? 0 : XMLString::stringLen(fMagnitude)); +} + +inline bool XMLBigInteger::operator==(const XMLBigInteger& toCompare) const +{ + return ( compareValues(this, &toCompare) ==0 ? true : false); +} + +inline void XMLBigInteger::setSign(int newSign) +{ + fSign = newSign; +} + +#endif diff --git a/src/validators/datatype/DecimalDatatypeValidator.cpp b/src/validators/datatype/DecimalDatatypeValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2c3b838d696bbca2956fa541bf4c5667ad6bb5dc --- /dev/null +++ b/src/validators/datatype/DecimalDatatypeValidator.cpp @@ -0,0 +1,747 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache\@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation, and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com . For more information + * on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ + +/* + * $Log$ + * Revision 1.1 2001/05/10 20:51:29 tng + * Schema: Add DecimalDatatypeValidator and XMLBigDecimal, XMLBigInteger. By Pei Yong Zhang. + * + */ + +// --------------------------------------------------------------------------- +// Includes +// --------------------------------------------------------------------------- +#include <validators/datatype/DecimalDatatypeValidator.hpp> +#include <validators/schema/SchemaSymbols.hpp> +#include <validators/datatype/InvalidDatatypeFacetException.hpp> +#include <validators/datatype/InvalidDatatypeValueException.hpp> +#include <util/NumberFormatException.hpp> + +// --------------------------------------------------------------------------- +// Constructors and Destructor +// --------------------------------------------------------------------------- +DecimalDatatypeValidator::DecimalDatatypeValidator( + DatatypeValidator* const baseValidator + , RefHashTableOf<KVStringPair>* const facets + , const int finalSet) +:DatatypeValidator(baseValidator, facets, finalSet, DatatypeValidator::Decimal) +, fTotalDigits(0) +, fFractionDigits(0) +, fMaxInclusive(0) +, fMaxExclusive(0) +, fMinInclusive(0) +, fMinExclusive(0) +, fEnumeration(0) +{ + try + { + init(baseValidator, facets); + } + + catch (XMLException&) + { + cleanUp(); + throw; + } + +} + +void DecimalDatatypeValidator::init(DatatypeValidator* const baseValidator + , RefHashTableOf<KVStringPair>* const facets) +{ + // Set Facets if any defined + if (facets) + { + XMLCh* key; + XMLCh* value; + RefVectorOf<XMLCh>* fStrEnumeration = 0; // save the literal value + Janitor<RefVectorOf<XMLCh> > janStrEnum(fStrEnumeration); + + RefHashTableOfEnumerator<KVStringPair> e(facets); + + while (e.hasMoreElements()) + { + KVStringPair pair = e.nextElement(); + key = pair.getKey(); + value = pair.getValue(); + + if (XMLString::compareString(key, SchemaSymbols::fgELT_PATTERN)==0) + { + setPattern(value); + if (getPattern()) + setFacetsDefined(DatatypeValidator::FACET_PATTERN); + // do not construct regex until needed + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_ENUMERATION)==0) + { + if (fStrEnumeration) + delete fStrEnumeration; + + fStrEnumeration = XMLString::tokenizeString(value); + setFacetsDefined(DatatypeValidator::FACET_ENUMERATION); + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_MAXINCLUSIVE)==0) + { + try + { + setMaxInclusive(new XMLBigDecimal(value)); + } + catch (NumberFormatException) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Inv_MaxInc); + } + setFacetsDefined(DatatypeValidator::FACET_MAXINCLUSIVE); + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_MAXEXCLUSIVE)==0) + { + try + { + setMaxExclusive(new XMLBigDecimal(value)); + } + catch (NumberFormatException) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Inv_MaxExc); + } + setFacetsDefined(DatatypeValidator::FACET_MAXEXCLUSIVE); + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_MININCLUSIVE)==0) + { + try + { + setMinInclusive(new XMLBigDecimal(value)); + } + catch (NumberFormatException) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Inv_MinInc); + } + setFacetsDefined(DatatypeValidator::FACET_MININCLUSIVE); + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_MINEXCLUSIVE)==0) + { + try + { + setMinExclusive(new XMLBigDecimal(value)); + } + catch (NumberFormatException) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Inv_MinExc); + } + setFacetsDefined(DatatypeValidator::FACET_MINEXCLUSIVE); + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_PRECISION)==0) + { + try + { + setTotalDigits(XMLString::parseInt(value)); + } + catch (NumberFormatException) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Inv_Precision); + } + + // check 4.3.11.c0 must: totalDigits > 0 + if ( fTotalDigits <= 0 ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Neg_Precision); + //InvalidDatatypeFacetException("totalDigits value '"+fTotalDigits+"' must be a positiveInteger."); + + setFacetsDefined(DatatypeValidator::FACET_PRECISSION); + } + else if (XMLString::compareString(key, SchemaSymbols::fgELT_FRACTIONDIGITS)==0) + { + try + { + setFractionDigits(XMLString::parseInt(value)); + } + catch (NumberFormatException) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Inv_Precision); + } + + // check 4.3.12.c0 must: fractionDigits > 0 + if ( fFractionDigits < 0 ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Neg_Fraction); + //InvalidDatatypeFacetException("fractionDigits value '"+fFractionDigits+"' must be a positiveInteger."); + + setFacetsDefined(DatatypeValidator::FACET_SCALE); + } + else + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Invalid_Tag); + } + }//while + + /*** + Schema constraint: Part I -- self checking + ***/ + + if ( getFacetsDefined() != 0 ) + { + // non co-existence checking + // check 4.3.8.c1 error: maxInclusive + maxExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) ) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_max_inc_exc); + // "It is an error for both maxInclusive and maxExclusive to be specified + // for the same datatype." ); + } + + // non co-existence checking + // check 4.3.9.c1 error: minInclusive + minExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) ) + { + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_min_inc_exc); + // "It is an error for both minInclusive and minExclusive to be specified + // for the same datatype." ); + } + + // + // minExclusive < minInclusive <= maxInclusive < maxExclusive + // + // check 4.3.7.c1 must: minInclusive <= maxInclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) ) + { + if ( XMLBigDecimal::compareValues(getMinInclusive(), getMaxInclusive()) == 1 ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_inc_min_max); + // "minInclusive value ='" + getMinInclusive(false) + "'must be <= + // maxInclusive value ='" + getMaxInclusive(false) + "'. " ); + } + + // check 4.3.8.c2 must: minExclusive <= maxExclusive ??? minExclusive < maxExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) ) + { + if ( XMLBigDecimal::compareValues(getMinExclusive(), getMaxExclusive()) == 1 ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_exc_min_max); + // "minExclusive value ='" + getMinExclusive(false) + "'must be <= + // maxExclusive value ='" + getMaxExclusive(false) + "'. " ); + } + + // check 4.3.9.c2 must: minExclusive < maxInclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) ) + { + if ( XMLBigDecimal::compareValues(getMinExclusive(), getMaxInclusive()) != -1 ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxinc_minexc); + // "minExclusive value ='" + getMinExclusive(false) + "'must be > + // maxInclusive value ='" + getMaxInclusive(false) + "'. " ); + } + + // check 4.3.10.c1 must: minInclusive < maxExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) ) + { + if ( XMLBigDecimal::compareValues(getMinInclusive(), getMaxExclusive()) != -1 ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + // ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_maxexc); + // "minInclusive value ='" + getMinInclusive(false) + "'must be < + // maxExclusive value ='" + getMaxExclusive(false) + "'. " ); + } + + // check 4.3.12.c1 must: fractionDigits <= totalDigits + if ( ((getFacetsDefined() & DatatypeValidator::FACET_SCALE) != 0) && + ((getFacetsDefined() & DatatypeValidator::FACET_PRECISSION) != 0) ) + { + if ( fFractionDigits > fTotalDigits ) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_scale_precision); + // "fractionDigits value ='" + this.fFractionDigits + "'must be <= + // totalDigits value ='" + this.fTotalDigits + "'. " ); + } + + } // if getFacetsDefined + + /*** + Schema constraint: Part II -- self vs base + ***/ + + if ( baseValidator != 0 ) + { + DecimalDatatypeValidator* numBase = (DecimalDatatypeValidator*)baseValidator; + + // this + // minExclusive maxExclusive + // minInclusive maxInclusive + // + // base + // minExclusive maxExclusive + // minInclusive maxExclusive + // + if ( getFacetsDefined() != 0 ) + { + // check 4.3.7.c2 error: + // maxInclusive > base.maxInclusive + // maxInclusive >= base.maxExclusive + // maxInclusive < base.minInclusive + // maxInclusive <= base.minExclusive + + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) ) + { + if ( ((numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxInclusive(), numBase->getMaxInclusive()) == 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxinc_base_maxinc); + // "maxInclusive value ='" + getMaxInclusive(false) + "' must be <= + // base.maxInclusive value ='" + getMaxInclusive(true) + "'." ); + + if ( ((numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxInclusive(), numBase->getMaxExclusive()) != -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxinc_base_maxexc); + // "maxInclusive value ='" + getMaxInclusive(false) + "' must be < + // base.maxExclusive value ='" + getMaxExclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxInclusive(), numBase->getMinInclusive()) == -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxinc_base_mininc); + // "maxInclusive value ='" + getMaxInclusive(false) + "' must be >= + // base.minInclusive value ='" + getMinInclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxInclusive(), numBase->getMinExclusive() ) != 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxinc_base_minexc); + // "maxInclusive value ='" + getMaxInclusive(false) + "' must be > + // base.minExclusive value ='" + getMinExclusive(true) + "'." ); + } + + // check 4.3.8.c3 error: + // maxExclusive > base.maxExclusive + // maxExclusive > base.maxInclusive + // maxExclusive <= base.minInclusive + // maxExclusive <= base.minExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) ) + { + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxExclusive(), numBase->getMaxExclusive()) == 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxexc_base_maxexc); + // "maxExclusive value ='" + getMaxExclusive(false) + "' must be + // <= base.maxExclusive value ='" + getMaxExclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxExclusive(), numBase->getMaxInclusive()) == 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxexc_base_maxinc); + // "maxExclusive value ='" + getMaxExclusive(false) + "' must be + // <= base.maxInclusive value ='" + getMaxInclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxExclusive(), numBase->getMinExclusive() ) != 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxexc_base_mininc); + // "maxExclusive value ='" + getMaxExclusive(false) + "' must be + // > base.minExclusive value ='" + getMinExclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMaxExclusive(), numBase->getMinInclusive()) != 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_maxexc_base_minexc); + // "maxExclusive value ='" + getMaxExclusive(false) + "' must be + // > base.minInclusive value ='" + getMinInclusive(true) + "'." ); + } + + // check 4.3.9.c3 error: + // minExclusive < base.minExclusive + // minExclusive > base.maxInclusive ??? minExclusive >= base.maxInclusive + // minExclusive < base.minInclusive + // minExclusive >= base.maxExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) ) + { + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinExclusive(), numBase->getMinExclusive() ) == -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_minexc); + // "minExclusive value ='" + getMinExclusive(false) + "' must be + // >= base.minExclusive value ='" + getMinExclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinExclusive(), numBase->getMaxInclusive()) == 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_maxinc); + // "minExclusive value ='" + getMinExclusive(false) + "' must be + // <= base.maxInclusive value ='" + getMaxInclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinExclusive(), numBase->getMinInclusive()) == -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_mininc); + // "minExclusive value ='" + getMinExclusive(false) + "' must be + // >= base.minInclusive value ='" + getMinInclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinExclusive(), numBase->getMaxExclusive()) != -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_maxexc); + // "minExclusive value ='" + getMinExclusive(false) + "' must be + // < base.maxExclusive value ='" + getMaxExclusive(true) + "'." ); + + } + + // check 4.3.10.c2 error: + // minInclusive < base.minInclusive + // minInclusive > base.maxInclusive + // minInclusive <= base.minExclusive + // minInclusive >= base.maxExclusive + if ( ((getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) ) + { + if ( ((numBase->getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinInclusive(), numBase->getMinInclusive()) == -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_mininc); + // "minInclusive value ='" + getMinInclusive(false) + "' must be + // >= base.minInclusive value ='" + getMinInclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinInclusive(), numBase->getMaxInclusive()) == 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_maxinc); + // "minInclusive value ='" + getMinInclusive(false) + "' must be + // <= base.maxInclusive value ='" + getMaxInclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinInclusive(), numBase->getMinExclusive() ) != 1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_minexc); + // "minInclusive value ='" + getMinInclusive(false) + "' must be + // > base.minExclusive value ='" + getMinExclusive(true) + "'." ); + + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + ( XMLBigDecimal::compareValues(getMinInclusive(), numBase->getMaxExclusive()) != -1 )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_mininc_base_maxexc); + // "minInclusive value ='" + getMinInclusive(false) + "' must be + // < base.maxExclusive value ='" + getMaxExclusive(true) + "'." ); + + } + + // check 4.3.11.c1 error: totalDigits > base.totalDigits + if (( getFacetsDefined() & DatatypeValidator::FACET_PRECISSION) != 0) + { + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_PRECISSION) != 0) && + ( fTotalDigits > numBase->fTotalDigits )) + ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeFacetException, XMLExcepts::FACET_totdigit_base_totdigit); + // "totalDigits value ='" + fTotalDigits + "' must be + // <= base.totalDigits value ='" + numBase.fTotalDigits + "'." ); + + } + + // check question error: fractionDigits > base.fractionDigits ??? + // check question error: fractionDigits > base.totalDigits ??? + // check question error: totalDigits conflicts with bounds ??? + + // check 4.3.5.c0 must: enumeration values from the value space of base + // + // In fact, the values in the enumeration shall go through validation + // of this class as well. + // this->checkContent(value, false); + // + if ( ((getFacetsDefined() & DatatypeValidator::FACET_ENUMERATION) != 0) && + ( fStrEnumeration != 0 )) + { + int i = 0; + int enumLength = fStrEnumeration->size(); + try + { + for ( ; i < enumLength; i++) + // ask parent do a complete check + numBase->checkContent(fStrEnumeration->elementAt(i), false); + } + + catch ( XMLException& ) + { + ThrowXML1(InvalidDatatypeFacetException + , XMLExcepts::FACET_enum_base + , fStrEnumeration->elementAt(i)); + } + + // + // we need to convert from fStrEnumeration to fEnumeration + try + { + fEnumeration = new RefVectorOf<XMLBigDecimal>(enumLength, true); + for ( ; i < enumLength; i++) + fEnumeration->insertElementAt(new XMLBigDecimal(fStrEnumeration->elementAt(i)), i); + } + + catch ( NumberFormatException& ) + { + ThrowXML1(InvalidDatatypeFacetException + , XMLExcepts::FACET_enum_base + , fStrEnumeration->elementAt(i)); + } + + } + + } + + /*** + Schema constraint: Part III -- inherit from base + ***/ + + // inherit enumeration + if ( ((getFacetsDefined() & DatatypeValidator::FACET_ENUMERATION) == 0 ) && + ((numBase->getFacetsDefined() & DatatypeValidator::FACET_ENUMERATION) != 0 )) + { + setFacetsDefined(DatatypeValidator::FACET_ENUMERATION); + // need to adopt the Vector + RefVectorOf<XMLBigDecimal>* fBaseEnumeration = numBase->fEnumeration; + int enumLength = fBaseEnumeration->size(); + fEnumeration = new RefVectorOf<XMLBigDecimal>(enumLength, true); + for ( int i = 0; i < enumLength; i++) + fEnumeration->insertElementAt(fBaseEnumeration->elementAt(i), i); + + } + + // inherit maxExclusive + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) == 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) == 0) ) + { + setMaxExclusive(new XMLBigDecimal(*(numBase->getMaxExclusive()))); + setFacetsDefined(DatatypeValidator::FACET_MAXEXCLUSIVE); + } + + // inherit maxInclusive + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) == 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) == 0) ) + { + setMaxInclusive(new XMLBigDecimal(*(numBase->getMaxInclusive()))); + setFacetsDefined(DatatypeValidator::FACET_MAXINCLUSIVE); + } + + // inherit minExclusive + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) == 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) == 0) ) + { + setMinExclusive(new XMLBigDecimal(*(numBase->getMinExclusive()))); + setFacetsDefined(DatatypeValidator::FACET_MINEXCLUSIVE); + } + + // inherit minExclusive + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) == 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) == 0) ) + { + setMinInclusive(new XMLBigDecimal(*(numBase->getMinInclusive()))); + setFacetsDefined(DatatypeValidator::FACET_MININCLUSIVE); + } + + // inherit totalDigits + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_PRECISSION) != 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_PRECISSION) == 0) ) + { + setTotalDigits(numBase->fTotalDigits); + setFacetsDefined(DatatypeValidator::FACET_PRECISSION); + } + + // inherit fractionDigits + if ( (( numBase->getFacetsDefined() & DatatypeValidator::FACET_SCALE) != 0) && + (( getFacetsDefined() & DatatypeValidator::FACET_SCALE) == 0) ) + { + setFractionDigits(numBase->fFractionDigits); + setFacetsDefined(DatatypeValidator::FACET_SCALE); + } + + // inherit enumeration + if ((( numBase->getFacetsDefined() & DatatypeValidator::FACET_ENUMERATION) !=0) && + (( getFacetsDefined() & DatatypeValidator::FACET_ENUMERATION) == 0)) + { + setFacetsDefined(DatatypeValidator::FACET_ENUMERATION); + // need to adopt the Vector + RefVectorOf<XMLBigDecimal>* fBaseEnumeration = numBase->fEnumeration; + int enumLength = fBaseEnumeration->size(); + fEnumeration = new RefVectorOf<XMLBigDecimal>(enumLength, true); + for ( int i = 0; i < enumLength; i++) + //invoke XMLBigDecimal's copy ctor + fEnumeration->insertElementAt(new XMLBigDecimal(*(fBaseEnumeration->elementAt(i))), i); + } + + } //if baseValidator + + }// End of Facet setting + +} + +void DecimalDatatypeValidator::checkContent( const XMLCh* const content, bool asBase) +{ + + //validate against base validator if any + DecimalDatatypeValidator *pBase = (DecimalDatatypeValidator*) this->getBaseValidator(); + if (pBase !=0) + pBase->checkContent(content, true); + + // we check pattern first + if ( (getFacetsDefined() & DatatypeValidator::FACET_PATTERN ) != 0 ) + { + // lazy construction + if (getRegex() ==0) + setRegex(new RegularExpression(getPattern(), SchemaSymbols::fgRegEx_XOption)); + + if (getRegex()->matches(content) ==false) + { + ThrowXML2(InvalidDatatypeValueException + , XMLExcepts::VALUE_NotMatch_Pattern + , content + , getPattern()); + } + } + + // if this is a base validator, we only need to check pattern facet + // all other facet were inherited by the derived type + if (asBase) + return; + + XMLBigDecimal theValue(content); + XMLBigDecimal *theData = &theValue; + + if (fEnumeration != 0) + { + int i=0; + int enumLength = fEnumeration->size(); + for ( ; i < enumLength; i++) + { + if (XMLBigDecimal::compareValues(theData, fEnumeration->elementAt(i))==0) + break; + } + + if (i == enumLength) + ThrowXML1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content); + } + + + if ( (getFacetsDefined() & DatatypeValidator::FACET_SCALE) != 0 ) + { + if ( theData->getScale() > fFractionDigits ) + ThrowXML(InvalidDatatypeValueException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeValueException, XMLExcepts::VALUE_exceed_scale); + // "'" + content + "'" + " with totalDigits = '"+ totalDigits +"'" + // "'" + fTotalDigits + "'"} )); + } + + if ( (getFacetsDefined() & DatatypeValidator::FACET_PRECISSION) != 0 ) + { + if ( theData->getTotalDigit() > fTotalDigits ) + ThrowXML(InvalidDatatypeValueException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeValueException, XMLExcepts::VALUE_exceed_precision); + // "'" + content + "'" + " with totalDigits = '"+ totalDigits +"'" + // "'" + fTotalDigits + "'"} )); + } + + if ( (getFacetsDefined() & DatatypeValidator::FACET_MAXEXCLUSIVE) != 0 ) + { + // must be < MaxExclusive + if (XMLBigDecimal::compareValues(theData, getMaxExclusive()) != -1) + ThrowXML(InvalidDatatypeValueException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeValueException, XMLExcepts::VALUE_exceed_maxexc); + } + + if ( (getFacetsDefined() & DatatypeValidator::FACET_MAXINCLUSIVE) != 0 ) + { + // must be <= MaxInclusive + if (XMLBigDecimal::compareValues(theData, getMaxInclusive()) == 1) + ThrowXML(InvalidDatatypeValueException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeValueException, XMLExcepts::VALUE_exceed_maxinc); + } + + if ( (getFacetsDefined() & DatatypeValidator::FACET_MININCLUSIVE) != 0 ) + { + // must be >= MinInclusive + if (XMLBigDecimal::compareValues(theData, getMinInclusive()) == -1) + ThrowXML(InvalidDatatypeValueException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeValueException, XMLExcepts::VALUE_exceed_mininc); + } + + if ( (getFacetsDefined() & DatatypeValidator::FACET_MINEXCLUSIVE) != 0 ) + { + // must be > MinExclusive + if (XMLBigDecimal::compareValues(theData, getMinExclusive()) != 1) + ThrowXML(InvalidDatatypeValueException, XMLExcepts::FACET_Len_maxLen); + //ThrowXML(InvalidDatatypeValueException, XMLExcepts::VALUE_exceed_mininc); + } + +} + + + +// --------------------------------------------------------------------------- +// Whitespace handling methods +// --------------------------------------------------------------------------- + + +/** + * End of file DecimalDatatypeValidator::cpp + */ + diff --git a/src/validators/datatype/DecimalDatatypeValidator.hpp b/src/validators/datatype/DecimalDatatypeValidator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2a8a06dde079fabf2dfd1a9c961a362ac7ba14a5 --- /dev/null +++ b/src/validators/datatype/DecimalDatatypeValidator.hpp @@ -0,0 +1,328 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999-2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Xerces" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache\@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation, and was + * originally based on software copyright (c) 1999, International + * Business Machines, Inc., http://www.ibm.com . For more information + * on the Apache Software Foundation, please see + * <http://www.apache.org/>. + */ + +/* + * $Id$ + */ + +#if !defined(DECIMAL_DATATYPEVALIDATOR_HPP) +#define DECIMAL_DATATYPEVALIDATOR_HPP + +#include <validators/datatype/DatatypeValidator.hpp> +#include <util/RefVectorOf.hpp> +#include <util/XMLBigDecimal.hpp> + +class VALIDATORS_EXPORT DecimalDatatypeValidator : public DatatypeValidator +{ +public: + + // ----------------------------------------------------------------------- + // Public ctor/dtor + // ----------------------------------------------------------------------- + /** @name Constructor. */ + //@{ + + DecimalDatatypeValidator(); + + DecimalDatatypeValidator(DatatypeValidator* const baseValidator + , RefHashTableOf<KVStringPair>* const facets + , const int finalSet); + + virtual ~DecimalDatatypeValidator(); + + //@} + + // ----------------------------------------------------------------------- + // Validation methods + // ----------------------------------------------------------------------- + /** @name Validation Function */ + //@{ + + /** + * validate that a string matches the boolean datatype + * @param content A string containing the content to be validated + * + * @exception throws InvalidDatatypeException if the content is + * is not valid. + */ + + void validate(const XMLCh* const content); + + //@} + + // ----------------------------------------------------------------------- + // Compare methods + // ----------------------------------------------------------------------- + /** @name Compare Function */ + //@{ + + /** + * Compare two boolean data types + * + * @param content1 + * @param content2 + * @return + */ + int compare(const XMLCh* const, const XMLCh* const); + + //@} + + /** + * Returns an instance of the base datatype validator class + * Used by the DatatypeValidatorFactory. + */ + DatatypeValidator* newInstance(DatatypeValidator* const baseValidator + , RefHashTableOf<KVStringPair>* const facets + , const int finalSet); + +private: + + void checkContent( const XMLCh* const content, bool asBase); + + void init(DatatypeValidator* const baseValidator + , RefHashTableOf<KVStringPair>* const facets); + + void cleanUp(); + +// ----------------------------------------------------------------------- +// Getter methods +// ----------------------------------------------------------------------- + + unsigned int getTotalDigits() const; + + unsigned int getFractionDigits() const; + + XMLBigDecimal* const getMaxInclusive() const; + + XMLBigDecimal* const getMaxExclusive() const; + + XMLBigDecimal* const getMinInclusive() const; + + XMLBigDecimal* const getMinExclusive() const; + + RefVectorOf<XMLBigDecimal>* getEnumeration() const; + +// ----------------------------------------------------------------------- +// Setter methods +// ----------------------------------------------------------------------- + + void setTotalDigits(unsigned int); + + void setFractionDigits(unsigned int); + + void setMaxInclusive(XMLBigDecimal* const); + + void setMaxExclusive(XMLBigDecimal* const); + + void setMinInclusive(XMLBigDecimal* const); + + void setMinExclusive(XMLBigDecimal* const); + + void setEnumeration(RefVectorOf<XMLBigDecimal>* ); + + // ----------------------------------------------------------------------- + // Private data members + // + // ----------------------------------------------------------------------- + unsigned int fTotalDigits; + unsigned int fFractionDigits; + + XMLBigDecimal* fMaxInclusive; + XMLBigDecimal* fMaxExclusive; + XMLBigDecimal* fMinInclusive; + XMLBigDecimal* fMinExclusive; + + RefVectorOf<XMLBigDecimal>* fEnumeration; // save the actual value + +}; + +inline DecimalDatatypeValidator::DecimalDatatypeValidator() +:DatatypeValidator(0, 0, 0, DatatypeValidator::Decimal) +, fTotalDigits(0) +, fFractionDigits(0) +, fMaxInclusive(0) +, fMaxExclusive(0) +, fMinInclusive(0) +, fMinExclusive(0) +, fEnumeration(0) +{ +} + +inline DecimalDatatypeValidator::~DecimalDatatypeValidator() +{ + cleanUp(); +} + +// ----------------------------------------------------------------------- +// Compare methods +// ----------------------------------------------------------------------- +inline int DecimalDatatypeValidator::compare(const XMLCh* const lValue + , const XMLCh* const rValue) +{ + return XMLBigDecimal::compareValues(new XMLBigDecimal(lValue) + , new XMLBigDecimal(rValue)); +} + +inline DatatypeValidator* DecimalDatatypeValidator::newInstance( + DatatypeValidator* const baseValidator + , RefHashTableOf<KVStringPair>* const facets + , const int finalSet) +{ + return (DatatypeValidator*) new DecimalDatatypeValidator(baseValidator, facets, finalSet); +} + +inline void DecimalDatatypeValidator::validate( const XMLCh* const content) +{ + checkContent(content, false); +} + +inline void DecimalDatatypeValidator::cleanUp() +{ + delete fMaxInclusive; + delete fMaxExclusive; + delete fMinInclusive; + delete fMinExclusive; + + //~RefVectorOf will delete all adopted elements + delete fEnumeration; +} + +// ----------------------------------------------------------------------- +// Getter methods +// ----------------------------------------------------------------------- + +inline unsigned int DecimalDatatypeValidator::getTotalDigits() const +{ + return fTotalDigits; +} + +inline unsigned int DecimalDatatypeValidator::getFractionDigits() const +{ + return fFractionDigits; +} + +inline XMLBigDecimal* const DecimalDatatypeValidator::getMaxInclusive() const +{ + return fMaxInclusive; +} + +inline XMLBigDecimal* const DecimalDatatypeValidator::getMaxExclusive() const +{ + return fMaxExclusive; +} + +inline XMLBigDecimal* const DecimalDatatypeValidator::getMinInclusive() const +{ + return fMinInclusive; +} + +inline XMLBigDecimal* const DecimalDatatypeValidator::getMinExclusive() const +{ + return fMinExclusive; +} + +inline RefVectorOf<XMLBigDecimal>* DecimalDatatypeValidator::getEnumeration() const +{ + return fEnumeration; +} + +// ----------------------------------------------------------------------- +// Setter methods +// ----------------------------------------------------------------------- + +inline void DecimalDatatypeValidator::setTotalDigits(unsigned int newTotalDigits) +{ + fTotalDigits = newTotalDigits; +} + +inline void DecimalDatatypeValidator::setFractionDigits(unsigned int newFractionDigits) +{ + fFractionDigits = newFractionDigits; +} + +inline void DecimalDatatypeValidator::setMaxInclusive(XMLBigDecimal* const newMaxInclusive) +{ + if (fMaxInclusive) delete fMaxInclusive; + fMaxInclusive = newMaxInclusive; +} + +inline void DecimalDatatypeValidator::setMaxExclusive(XMLBigDecimal* const newMaxExclusive) +{ + if (fMaxExclusive) delete fMaxExclusive; + fMaxExclusive = newMaxExclusive; +} + +inline void DecimalDatatypeValidator::setMinInclusive(XMLBigDecimal* const newMinInclusive) +{ + if (fMinInclusive) delete fMinInclusive; + fMinInclusive = newMinInclusive; +} + +inline void DecimalDatatypeValidator::setMinExclusive(XMLBigDecimal* const newMinExclusive) +{ + if (fMinExclusive) delete fMinExclusive; + fMinExclusive = newMinExclusive; +} + +inline void DecimalDatatypeValidator::setEnumeration(RefVectorOf<XMLBigDecimal>* newEnum) +{ + fEnumeration = newEnum; +} + +/** + * End of file DecimalDatatypeValidator.hpp + */ +#endif diff --git a/src/validators/datatype/Makefile.in b/src/validators/datatype/Makefile.in index 59f6031abe9cb3b9fb82d13592dd575635fe4cb2..d8b01330ba277b80eff9b3092af779b583cc1b34 100644 --- a/src/validators/datatype/Makefile.in +++ b/src/validators/datatype/Makefile.in @@ -55,6 +55,9 @@ # # # $Log$ +# Revision 1.4 2001/05/10 20:51:31 tng +# Schema: Add DecimalDatatypeValidator and XMLBigDecimal, XMLBigInteger. By Pei Yong Zhang. +# # Revision 1.3 2001/05/09 18:43:41 tng # Add StringDatatypeValidator and BooleanDatatypeValidator. By Pei Yong Zhang. # @@ -92,6 +95,7 @@ VALIDATORS_DATATYPE_CPP_PUBHEADERS = \ DatatypeValidator.hpp \ DatatypeValidatorFactory.hpp \ BooleanDatatypeValidator.hpp \ + DecimalDatatypeValidator.hpp \ StringDatatypeValidator.hpp VALIDATORS_DATATYPE_CPP_PRIVHEADERS = @@ -102,6 +106,7 @@ VALIDATORS_DATATYPE_CPP_OBJECTS = \ DatatypeValidator.$(TO) \ DatatypeValidatorFactory.$(TO) \ BooleanDatatypeValidator.$(TO) \ + DecimalDatatypeValidator.$(TO) \ StringDatatypeValidator.$(TO)