void DecimalDatatypeValidator::inheritAdditionalFacet()
{

    DecimalDatatypeValidator *numBase = (DecimalDatatypeValidator*) getBaseValidator();

    if (!numBase)
        return;

    int thisFacetsDefined = getFacetsDefined();
    int baseFacetsDefined = numBase->getFacetsDefined();

    // inherit totalDigits
    if ((( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
        (( thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) == 0) )
    {
        setTotalDigits(numBase->fTotalDigits);
        setFacetsDefined(DatatypeValidator::FACET_TOTALDIGITS);
    }

    // inherit fractionDigits
    if ((( baseFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
        (( thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) == 0) )
    {
        setFractionDigits(numBase->fFractionDigits);
        setFacetsDefined(DatatypeValidator::FACET_FRACTIONDIGITS);
    }
}
void DecimalDatatypeValidator::setEnumeration(MemoryManager* const manager)
{
    // check 4.3.5.c0 must: enumeration values from the value space of base
    //
    // 1. shall be from base value space
    // 2. shall be from current value space as well ( shall go through boundsCheck() )
    //
    if (!fStrEnumeration)
        return;

    XMLSize_t i = 0;
    XMLSize_t enumLength = fStrEnumeration->size();

    DecimalDatatypeValidator *numBase = (DecimalDatatypeValidator*) getBaseValidator();
    if (numBase)
    {
        try
        {
            for ( i = 0; i < enumLength; i++)
            {
                numBase->checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
            }
        }
        catch (XMLException&)
        {
            ThrowXMLwithMemMgr1(InvalidDatatypeFacetException
                    , XMLExcepts::FACET_enum_base
                    , fStrEnumeration->elementAt(i)
                    , manager);
        }
    }
#if 0
// spec says that only base has to checkContent
    // We put the this->checkContent in a separate loop
    // to not block original message with in that method.
    //
    for ( i = 0; i < enumLength; i++)
    {
        checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
    }
#endif
    fEnumeration = new (manager) RefVectorOf<XMLNumber>(enumLength, true, manager);
    fEnumerationInherited = false;

    for ( i = 0; i < enumLength; i++)
    {
        fEnumeration->insertElementAt(new (manager) XMLBigDecimal(fStrEnumeration->elementAt(i), manager), i);
    }

}
const XMLCh* DecimalDatatypeValidator::getCanonicalRepresentation(const XMLCh*         const rawData
                                                                 ,      MemoryManager* const memMgr
                                                                 ,      bool                 toValidate) const
{
    MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
    DecimalDatatypeValidator* temp = (DecimalDatatypeValidator*) this;

    if (toValidate)
    {
        try
        {
            temp->checkContent(rawData, 0, false, toUse);   
        }
        catch (...)
        {
            return 0;
        }
    }

    // XMLBigInteger::getCanonicalRepresentation and
    // XMLBigDecimal::getCanonicalRepresentation will handle exceptional cases
    XMLCanRepGroup::CanRepGroup dvType = DatatypeValidatorFactory::getCanRepGroup(temp);

    if ((dvType == XMLCanRepGroup::Decimal_Derivated_signed)   ||
        (dvType == XMLCanRepGroup::Decimal_Derivated_unsigned) ||
        (dvType == XMLCanRepGroup::Decimal_Derivated_npi)        )
    {          
        return XMLBigInteger::getCanonicalRepresentation(rawData, toUse, dvType == XMLCanRepGroup::Decimal_Derivated_npi);
    }
    else if (dvType == XMLCanRepGroup::Decimal) 
    {
        return XMLBigDecimal::getCanonicalRepresentation(rawData, toUse);
    }
    else //in case?
    {
        return XMLString::replicate(rawData, toUse);
    }

}
// -----------------------------------------------------------------------
// Abstract interface from AbstractNumericValidator
// -----------------------------------------------------------------------
void DecimalDatatypeValidator::checkContent(const XMLCh*             const content
                                           ,      ValidationContext* const context
                                           ,      bool                     asBase
                                           ,      MemoryManager*     const manager)
{
    //validate against base validator if any
    DecimalDatatypeValidator *pBase = (DecimalDatatypeValidator*) this->getBaseValidator();
    if (pBase)
        pBase->checkContent(content, context, true, manager);

    int thisFacetsDefined = getFacetsDefined();

    // we check pattern first
    if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 )
    {
        // lazy construction
        if (getRegex() ==0) {
            try {
                // REVISIT: cargillmem fMemoryManager vs manager
                setRegex(new (fMemoryManager) RegularExpression(getPattern(), SchemaSymbols::fgRegEx_XOption, fMemoryManager));                
            }
            catch (XMLException &e)
            {
                ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::RethrowError, e.getMessage(), manager);
            }
        }

        if (getRegex()->matches(content, manager) ==false)
        {
            ThrowXMLwithMemMgr2(InvalidDatatypeValueException
                    , XMLExcepts::VALUE_NotMatch_Pattern
                    , content
                    , getPattern()
                    , manager);
        }
    }

    // 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;
    XMLCh *errorMsg = 0;
    try {
        XMLBigDecimal  compareDataValue(content, manager);
        XMLBigDecimal* compareData = &compareDataValue;        
        
        if (getEnumeration())
        {
            int i=0;
            int enumLength = getEnumeration()->size();
            for ( ; i < enumLength; i++)
            {
                if (compareValues(compareData, (XMLBigDecimal*) getEnumeration()->elementAt(i)) ==0 )
                    break;
            }

            if (i == enumLength)
                ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
        }

        boundsCheck(compareData, manager);

        if ( (thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0 )
        {
            if ( compareData->getScale() > fFractionDigits )
            {                
                XMLCh value1[BUF_LEN+1];
                XMLCh value2[BUF_LEN+1];
                XMLString::binToText(compareData->getScale(), value1, BUF_LEN, 10, manager);
                XMLString::binToText(fFractionDigits, value2, BUF_LEN, 10, manager);
                ThrowXMLwithMemMgr3(InvalidDatatypeFacetException
                                 , XMLExcepts::VALUE_exceed_fractDigit
                                 , compareData->getRawData()
                                 , value1
                                 , value2
                                 , manager);
            }
        }

        if ( (thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0 )
        {
            if ( compareData->getTotalDigit() > fTotalDigits )
            {                
                XMLCh value1[BUF_LEN+1];
                XMLCh value2[BUF_LEN+1];
                XMLString::binToText(compareData->getTotalDigit(), value1, BUF_LEN, 10, manager);
                XMLString::binToText(fTotalDigits, value2, BUF_LEN, 10, manager);
                ThrowXMLwithMemMgr3(InvalidDatatypeFacetException
                                 , XMLExcepts::VALUE_exceed_totalDigit
                                 , compareData->getRawData()
                                 , value1
                                 , value2
                                 , manager);
            }

            /***
             E2-44 totalDigits

             ... by restricting it to numbers that are expressible as i � 10^-n
             where i and n are integers such that |i| < 10^totalDigits and 0 <= n <= totalDigits.
            ***/

            if ( compareData->getScale() > fTotalDigits )  
            {                
                XMLCh value1[BUF_LEN+1];
                XMLCh value2[BUF_LEN+1];
                XMLString::binToText(compareData->getScale(), value1, BUF_LEN, 10, manager);
                XMLString::binToText(fTotalDigits, value2, BUF_LEN, 10, manager);
                ThrowXMLwithMemMgr3(InvalidDatatypeFacetException
                                 , XMLExcepts::VALUE_exceed_totalDigit
                                 , compareData->getRawData()
                                 , value1
                                 , value2
                                 , manager);
            }        
        }
    }
    catch (XMLException &e)
    {
       errorMsg = XMLString::replicate(e.getMessage(), manager);
    }
    if(errorMsg)
    {
       ArrayJanitor<XMLCh> jan(errorMsg, manager);
       ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::RethrowError, errorMsg, manager);
    }
}
void DecimalDatatypeValidator::checkAdditionalFacetConstraintsBase(MemoryManager* const manager) const
{

    DecimalDatatypeValidator *numBase = (DecimalDatatypeValidator*) getBaseValidator();

    if (!numBase)
        return;

    int thisFacetsDefined = getFacetsDefined();
    int baseFacetsDefined = numBase->getFacetsDefined();

    // check 4.3.11.c1 error: totalDigits > base.totalDigits
    // totalDigits != base.totalDigits if (base.fixed)
    if (( thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0)
    {
        if ( (( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
            ( fTotalDigits > numBase->fTotalDigits ))
        {
            XMLCh value1[BUF_LEN+1];
            XMLCh value2[BUF_LEN+1];
            XMLString::binToText(fTotalDigits, value1, BUF_LEN, 10, manager);
            XMLString::binToText(numBase->fTotalDigits, value2, BUF_LEN, 10, manager);
            ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
                                 , XMLExcepts::FACET_totalDigit_base_totalDigit
                                 , value1
                                 , value2
                                 , manager);
        }

        if ( (( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
            (( numBase->getFixed() & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
            ( fTotalDigits != numBase->fTotalDigits ))
        {
            XMLCh value1[BUF_LEN+1];
            XMLCh value2[BUF_LEN+1];
            XMLString::binToText(fTotalDigits, value1, BUF_LEN, 10, manager);
            XMLString::binToText(numBase->fTotalDigits, value2, BUF_LEN, 10, manager);
            ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
                                 , XMLExcepts::FACET_totalDigit_base_fixed
                                 , value1
                                 , value2
                                 , manager);
        }
    }

    if (( thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0)
    {
        // check question error: fractionDigits > base.fractionDigits ???
        if ( (( baseFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
            ( fFractionDigits > numBase->fFractionDigits ))
        {
            XMLCh value1[BUF_LEN+1];
            XMLCh value2[BUF_LEN+1];
            XMLString::binToText(fFractionDigits, value1, BUF_LEN, 10, manager);
            XMLString::binToText(numBase->fFractionDigits, value2, BUF_LEN, 10, manager);
            ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
                                 , XMLExcepts::FACET_fractDigit_base_fractDigit
                                 , value1
                                 , value2
                                 , manager);
                        }

        // check question error: fractionDigits > base.totalDigits ???
        if ( (( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
            ( fFractionDigits > numBase->fTotalDigits ))
        {
            XMLCh value1[BUF_LEN+1];
            XMLCh value2[BUF_LEN+1];
            XMLString::binToText(fFractionDigits, value1, BUF_LEN, 10, manager);
            XMLString::binToText(numBase->fTotalDigits, value2, BUF_LEN, 10, manager);
            ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
                                 , XMLExcepts::FACET_fractDigit_base_totalDigit
                                 , value1
                                 , value2
                                 , manager);
        }

        // fractionDigits != base.fractionDigits if (base.fixed)
        if ( (( baseFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
            (( numBase->getFixed() & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
            ( fFractionDigits != numBase->fFractionDigits ))
        {
            XMLCh value1[BUF_LEN+1];
            XMLCh value2[BUF_LEN+1];
            XMLString::binToText(fFractionDigits, value1, BUF_LEN, 10, manager);
            XMLString::binToText(numBase->fFractionDigits, value2, BUF_LEN, 10, manager);
            ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
                                 , XMLExcepts::FACET_fractDigit_base_fixed
                                 , value1
                                 , value2
                                 , manager);
        }
    }

}