1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*
19  * $Id: DecimalDatatypeValidator.cpp 932887 2010-04-11 13:04:59Z borisk $
20  */
21 
22 // ---------------------------------------------------------------------------
23 //  Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/validators/datatype/DecimalDatatypeValidator.hpp>
26 #include <xercesc/validators/datatype/XMLCanRepGroup.hpp>
27 #include <xercesc/validators/schema/SchemaSymbols.hpp>
28 #include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
29 #include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
30 
31 #include <xercesc/validators/datatype/DatatypeValidatorFactory.hpp>
32 #include <xercesc/util/NumberFormatException.hpp>
33 #include <xercesc/util/XMLBigDecimal.hpp>
34 #include <xercesc/util/XMLBigInteger.hpp>
35 
36 XERCES_CPP_NAMESPACE_BEGIN
37 
38 static const int BUF_LEN = 64;
39 
40 // ---------------------------------------------------------------------------
41 //  Constructors and Destructor
42 // ---------------------------------------------------------------------------
DecimalDatatypeValidator(MemoryManager * const manager)43 DecimalDatatypeValidator::DecimalDatatypeValidator(MemoryManager* const manager)
44 :AbstractNumericValidator(0, 0, 0, DatatypeValidator::Decimal, manager)
45 , fTotalDigits(0)
46 , fFractionDigits(0)
47 {
48     setOrdered(XSSimpleTypeDefinition::ORDERED_TOTAL);
49     setNumeric(true);
50 }
51 
DecimalDatatypeValidator(DatatypeValidator * const baseValidator,RefHashTableOf<KVStringPair> * const facets,RefArrayVectorOf<XMLCh> * const enums,const int finalSet,MemoryManager * const manager)52 DecimalDatatypeValidator::DecimalDatatypeValidator(
53                           DatatypeValidator*            const baseValidator
54                         , RefHashTableOf<KVStringPair>* const facets
55                         , RefArrayVectorOf<XMLCh>*      const enums
56                         , const int                           finalSet
57                         , MemoryManager*                const manager)
58 :AbstractNumericValidator(baseValidator, facets, finalSet, DatatypeValidator::Decimal, manager)
59 , fTotalDigits(0)
60 , fFractionDigits(0)
61 {
62     init(enums, manager);
63 }
64 
~DecimalDatatypeValidator()65 DecimalDatatypeValidator::~DecimalDatatypeValidator()
66 {
67 }
68 
69 // -----------------------------------------------------------------------
70 // Compare methods
71 // -----------------------------------------------------------------------
compare(const XMLCh * const lValue,const XMLCh * const rValue,MemoryManager * const manager)72 int DecimalDatatypeValidator::compare(const XMLCh* const lValue
73                                     , const XMLCh* const rValue
74                                     , MemoryManager* const manager)
75 {
76     XMLBigDecimal lObj(lValue, manager);
77     XMLBigDecimal rObj(rValue, manager);
78 
79     return compareValues(&lObj, &rObj);
80 }
81 
newInstance(RefHashTableOf<KVStringPair> * const facets,RefArrayVectorOf<XMLCh> * const enums,const int finalSet,MemoryManager * const manager)82 DatatypeValidator* DecimalDatatypeValidator::newInstance
83 (
84       RefHashTableOf<KVStringPair>* const facets
85     , RefArrayVectorOf<XMLCh>* const      enums
86     , const int                           finalSet
87     , MemoryManager* const                manager
88 )
89 {
90     return (DatatypeValidator*) new (manager) DecimalDatatypeValidator(this, facets, enums, finalSet, manager);
91 }
92 
93 // -----------------------------------------------------------------------
94 // ctor provided to be used by derived classes
95 // -----------------------------------------------------------------------
DecimalDatatypeValidator(DatatypeValidator * const baseValidator,RefHashTableOf<KVStringPair> * const facets,const int finalSet,const ValidatorType type,MemoryManager * const manager)96 DecimalDatatypeValidator::DecimalDatatypeValidator(DatatypeValidator*            const baseValidator
97                                                  , RefHashTableOf<KVStringPair>* const facets
98                                                  , const int                           finalSet
99                                                  , const ValidatorType                 type
100                                                  , MemoryManager* const                manager)
101 :AbstractNumericValidator(baseValidator, facets, finalSet, type, manager)
102 , fTotalDigits(0)
103 , fFractionDigits(0)
104 {
105     //do not invoke init here !!!
106 }
107 
assignAdditionalFacet(const XMLCh * const key,const XMLCh * const value,MemoryManager * const manager)108 void DecimalDatatypeValidator::assignAdditionalFacet(const XMLCh* const key
109                                                    , const XMLCh* const value
110                                                    , MemoryManager* const manager)
111 {
112     if (XMLString::equals(key, SchemaSymbols::fgELT_TOTALDIGITS))
113     {
114         int val;
115         try
116         {
117             val = XMLString::parseInt(value, manager);
118         }
119         catch (NumberFormatException&)
120         {
121             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_Invalid_TotalDigit, value, manager);
122         }
123 
124         // check 4.3.11.c0 must: totalDigits > 0
125         if ( val <= 0 )
126             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_PosInt_TotalDigit, value, manager);
127 
128         setTotalDigits(val);
129         setFacetsDefined(DatatypeValidator::FACET_TOTALDIGITS);
130     }
131     else if (XMLString::equals(key, SchemaSymbols::fgELT_FRACTIONDIGITS))
132     {
133         int val;
134         try
135         {
136             val = XMLString::parseInt(value, manager);
137         }
138         catch (NumberFormatException&)
139         {
140             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_Invalid_FractDigit, value, manager);
141         }
142 
143         // check 4.3.12.c0 must: fractionDigits > 0
144         if ( val < 0 )
145             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException, XMLExcepts::FACET_NonNeg_FractDigit, value, manager);
146 
147         setFractionDigits(val);
148         setFacetsDefined(DatatypeValidator::FACET_FRACTIONDIGITS);
149     }
150     else
151     {
152         ThrowXMLwithMemMgr1(InvalidDatatypeFacetException
153                 , XMLExcepts::FACET_Invalid_Tag
154                 , key
155                 , manager);
156     }
157 }
158 
inheritAdditionalFacet()159 void DecimalDatatypeValidator::inheritAdditionalFacet()
160 {
161 
162     DecimalDatatypeValidator *numBase = (DecimalDatatypeValidator*) getBaseValidator();
163 
164     if (!numBase)
165         return;
166 
167     int thisFacetsDefined = getFacetsDefined();
168     int baseFacetsDefined = numBase->getFacetsDefined();
169 
170     // inherit totalDigits
171     if ((( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
172         (( thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) == 0) )
173     {
174         setTotalDigits(numBase->fTotalDigits);
175         setFacetsDefined(DatatypeValidator::FACET_TOTALDIGITS);
176     }
177 
178     // inherit fractionDigits
179     if ((( baseFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
180         (( thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) == 0) )
181     {
182         setFractionDigits(numBase->fFractionDigits);
183         setFacetsDefined(DatatypeValidator::FACET_FRACTIONDIGITS);
184     }
185 }
186 
checkAdditionalFacetConstraints(MemoryManager * const manager) const187 void DecimalDatatypeValidator::checkAdditionalFacetConstraints(MemoryManager* const manager) const
188 {
189     int thisFacetsDefined = getFacetsDefined();
190 
191     // check 4.3.12.c1 must: fractionDigits <= totalDigits
192     if ( ((thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
193          ((thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) )
194     {
195         if ( fFractionDigits > fTotalDigits )
196         {
197             XMLCh value1[BUF_LEN+1];
198             XMLCh value2[BUF_LEN+1];
199             XMLString::binToText(getFractionDigits(), value1, BUF_LEN, 10, manager);
200             XMLString::binToText(getTotalDigits(), value2, BUF_LEN, 10, manager);
201             ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
202                                  , XMLExcepts::FACET_TotDigit_FractDigit
203                                  , value2
204                                  , value1
205                                  , manager);
206         }
207     }
208 
209 }
210 
checkAdditionalFacetConstraintsBase(MemoryManager * const manager) const211 void DecimalDatatypeValidator::checkAdditionalFacetConstraintsBase(MemoryManager* const manager) const
212 {
213 
214     DecimalDatatypeValidator *numBase = (DecimalDatatypeValidator*) getBaseValidator();
215 
216     if (!numBase)
217         return;
218 
219     int thisFacetsDefined = getFacetsDefined();
220     int baseFacetsDefined = numBase->getFacetsDefined();
221 
222     // check 4.3.11.c1 error: totalDigits > base.totalDigits
223     // totalDigits != base.totalDigits if (base.fixed)
224     if (( thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0)
225     {
226         if ( (( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
227             ( fTotalDigits > numBase->fTotalDigits ))
228         {
229             XMLCh value1[BUF_LEN+1];
230             XMLCh value2[BUF_LEN+1];
231             XMLString::binToText(fTotalDigits, value1, BUF_LEN, 10, manager);
232             XMLString::binToText(numBase->fTotalDigits, value2, BUF_LEN, 10, manager);
233             ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
234                                  , XMLExcepts::FACET_totalDigit_base_totalDigit
235                                  , value1
236                                  , value2
237                                  , manager);
238         }
239 
240         if ( (( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
241             (( numBase->getFixed() & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
242             ( fTotalDigits != numBase->fTotalDigits ))
243         {
244             XMLCh value1[BUF_LEN+1];
245             XMLCh value2[BUF_LEN+1];
246             XMLString::binToText(fTotalDigits, value1, BUF_LEN, 10, manager);
247             XMLString::binToText(numBase->fTotalDigits, value2, BUF_LEN, 10, manager);
248             ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
249                                  , XMLExcepts::FACET_totalDigit_base_fixed
250                                  , value1
251                                  , value2
252                                  , manager);
253         }
254     }
255 
256     if (( thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0)
257     {
258         // check question error: fractionDigits > base.fractionDigits ???
259         if ( (( baseFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
260             ( fFractionDigits > numBase->fFractionDigits ))
261         {
262             XMLCh value1[BUF_LEN+1];
263             XMLCh value2[BUF_LEN+1];
264             XMLString::binToText(fFractionDigits, value1, BUF_LEN, 10, manager);
265             XMLString::binToText(numBase->fFractionDigits, value2, BUF_LEN, 10, manager);
266             ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
267                                  , XMLExcepts::FACET_fractDigit_base_fractDigit
268                                  , value1
269                                  , value2
270                                  , manager);
271                         }
272 
273         // check question error: fractionDigits > base.totalDigits ???
274         if ( (( baseFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0) &&
275             ( fFractionDigits > numBase->fTotalDigits ))
276         {
277             XMLCh value1[BUF_LEN+1];
278             XMLCh value2[BUF_LEN+1];
279             XMLString::binToText(fFractionDigits, value1, BUF_LEN, 10, manager);
280             XMLString::binToText(numBase->fTotalDigits, value2, BUF_LEN, 10, manager);
281             ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
282                                  , XMLExcepts::FACET_fractDigit_base_totalDigit
283                                  , value1
284                                  , value2
285                                  , manager);
286         }
287 
288         // fractionDigits != base.fractionDigits if (base.fixed)
289         if ( (( baseFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
290             (( numBase->getFixed() & DatatypeValidator::FACET_FRACTIONDIGITS) != 0) &&
291             ( fFractionDigits != numBase->fFractionDigits ))
292         {
293             XMLCh value1[BUF_LEN+1];
294             XMLCh value2[BUF_LEN+1];
295             XMLString::binToText(fFractionDigits, value1, BUF_LEN, 10, manager);
296             XMLString::binToText(numBase->fFractionDigits, value2, BUF_LEN, 10, manager);
297             ThrowXMLwithMemMgr2(InvalidDatatypeFacetException
298                                  , XMLExcepts::FACET_fractDigit_base_fixed
299                                  , value1
300                                  , value2
301                                  , manager);
302         }
303     }
304 
305 }
306 
compareValues(const XMLNumber * const lValue,const XMLNumber * const rValue)307 int  DecimalDatatypeValidator::compareValues(const XMLNumber* const lValue
308                                            , const XMLNumber* const rValue)
309 {
310     return XMLBigDecimal::compareValues((XMLBigDecimal*) lValue, (XMLBigDecimal*) rValue,
311                                         ((XMLBigDecimal*)lValue)->getMemoryManager());
312 }
313 
setMaxInclusive(const XMLCh * const value)314 void  DecimalDatatypeValidator::setMaxInclusive(const XMLCh* const value)
315 {
316     fMaxInclusive = new (fMemoryManager) XMLBigDecimal(value, fMemoryManager);
317 }
318 
setMaxExclusive(const XMLCh * const value)319 void  DecimalDatatypeValidator::setMaxExclusive(const XMLCh* const value)
320 {
321     fMaxExclusive = new (fMemoryManager) XMLBigDecimal(value, fMemoryManager);
322 }
323 
setMinInclusive(const XMLCh * const value)324 void  DecimalDatatypeValidator::setMinInclusive(const XMLCh* const value)
325 {
326     fMinInclusive = new (fMemoryManager) XMLBigDecimal(value, fMemoryManager);
327 }
328 
setMinExclusive(const XMLCh * const value)329 void  DecimalDatatypeValidator::setMinExclusive(const XMLCh* const value)
330 {
331     fMinExclusive = new (fMemoryManager) XMLBigDecimal(value, fMemoryManager);
332 }
333 
setEnumeration(MemoryManager * const manager)334 void DecimalDatatypeValidator::setEnumeration(MemoryManager* const manager)
335 {
336     // check 4.3.5.c0 must: enumeration values from the value space of base
337     //
338     // 1. shall be from base value space
339     // 2. shall be from current value space as well ( shall go through boundsCheck() )
340     //
341     if (!fStrEnumeration)
342         return;
343 
344     XMLSize_t i = 0;
345     XMLSize_t enumLength = fStrEnumeration->size();
346 
347     DecimalDatatypeValidator *numBase = (DecimalDatatypeValidator*) getBaseValidator();
348     if (numBase)
349     {
350         try
351         {
352             for ( i = 0; i < enumLength; i++)
353             {
354                 numBase->checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
355             }
356         }
357         catch (XMLException&)
358         {
359             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException
360                     , XMLExcepts::FACET_enum_base
361                     , fStrEnumeration->elementAt(i)
362                     , manager);
363         }
364     }
365 #if 0
366 // spec says that only base has to checkContent
367     // We put the this->checkContent in a separate loop
368     // to not block original message with in that method.
369     //
370     for ( i = 0; i < enumLength; i++)
371     {
372         checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
373     }
374 #endif
375     fEnumeration = new (manager) RefVectorOf<XMLNumber>(enumLength, true, manager);
376     fEnumerationInherited = false;
377 
378     for ( i = 0; i < enumLength; i++)
379     {
380         fEnumeration->insertElementAt(new (manager) XMLBigDecimal(fStrEnumeration->elementAt(i), manager), i);
381     }
382 
383 }
384 
385 // -----------------------------------------------------------------------
386 // Abstract interface from AbstractNumericValidator
387 // -----------------------------------------------------------------------
checkContent(const XMLCh * const content,ValidationContext * const context,bool asBase,MemoryManager * const manager)388 void DecimalDatatypeValidator::checkContent(const XMLCh*             const content
389                                            ,      ValidationContext* const context
390                                            ,      bool                     asBase
391                                            ,      MemoryManager*     const manager)
392 {
393     //validate against base validator if any
394     DecimalDatatypeValidator *pBase = (DecimalDatatypeValidator*) this->getBaseValidator();
395     if (pBase)
396         pBase->checkContent(content, context, true, manager);
397 
398     int thisFacetsDefined = getFacetsDefined();
399 
400     // we check pattern first
401     if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 )
402     {
403         if (getRegex()->matches(content, manager) ==false)
404         {
405             ThrowXMLwithMemMgr2(InvalidDatatypeValueException
406                     , XMLExcepts::VALUE_NotMatch_Pattern
407                     , content
408                     , getPattern()
409                     , manager);
410         }
411     }
412 
413     // if this is a base validator, we only need to check pattern facet
414     // all other facet were inherited by the derived type
415     if (asBase)
416         return;
417 
418     XMLBigDecimal  compareDataValue(content, manager);
419     XMLBigDecimal* compareData = &compareDataValue;
420 
421     if (getEnumeration())
422     {
423         XMLSize_t i=0;
424         XMLSize_t enumLength = getEnumeration()->size();
425         for ( ; i < enumLength; i++)
426         {
427             if (compareValues(compareData, (XMLBigDecimal*) getEnumeration()->elementAt(i)) ==0 )
428                 break;
429         }
430 
431         if (i == enumLength)
432             ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
433     }
434 
435     boundsCheck(compareData, manager);
436 
437     if ( (thisFacetsDefined & DatatypeValidator::FACET_FRACTIONDIGITS) != 0 )
438     {
439         if ( compareData->getScale() > fFractionDigits )
440         {
441             XMLCh value1[BUF_LEN+1];
442             XMLCh value2[BUF_LEN+1];
443             XMLString::binToText(compareData->getScale(), value1, BUF_LEN, 10, manager);
444             XMLString::binToText(fFractionDigits, value2, BUF_LEN, 10, manager);
445             ThrowXMLwithMemMgr3(InvalidDatatypeFacetException
446                               , XMLExcepts::VALUE_exceed_fractDigit
447                               , compareData->getRawData()
448                               , value1
449                               , value2
450                               , manager);
451         }
452     }
453 
454     if ( (thisFacetsDefined & DatatypeValidator::FACET_TOTALDIGITS) != 0 )
455     {
456         if ( compareData->getTotalDigit() > fTotalDigits )
457         {
458             XMLCh value1[BUF_LEN+1];
459             XMLCh value2[BUF_LEN+1];
460             XMLString::binToText(compareData->getTotalDigit(), value1, BUF_LEN, 10, manager);
461             XMLString::binToText(fTotalDigits, value2, BUF_LEN, 10, manager);
462             ThrowXMLwithMemMgr3(InvalidDatatypeFacetException
463                               , XMLExcepts::VALUE_exceed_totalDigit
464                               , compareData->getRawData()
465                               , value1
466                               , value2
467                               , manager);
468         }
469 
470         /***
471          E2-44 totalDigits
472          ... by restricting it to numbers that are expressible as i x 10^-n
473          where i and n are integers such that |i| < 10^totalDigits and 0 <= n <= totalDigits.
474          ***/
475 
476         if ( compareData->getScale() > fTotalDigits )
477         {
478             XMLCh value1[BUF_LEN+1];
479             XMLCh value2[BUF_LEN+1];
480             XMLString::binToText(compareData->getScale(), value1, BUF_LEN, 10, manager);
481             XMLString::binToText(fTotalDigits, value2, BUF_LEN, 10, manager);
482             ThrowXMLwithMemMgr3(InvalidDatatypeFacetException
483                               , XMLExcepts::VALUE_exceed_totalDigit
484                               , compareData->getRawData()
485                               , value1
486                               , value2
487                               , manager);
488         }
489     }
490 }
491 
492 /***
493  * 3.2.3 decimal
494  *
495  * . the preceding optional "+" sign is prohibited.
496  * . The decimal point is required.
497  * . Leading and trailing zeroes are prohibited subject to the following:
498  *   there must be at least one digit to the right and to the left of the decimal point which may be a zero.
499  *
500  *
501  *  3.3.13 integer
502  *  3.3.16 long
503  *  3.3.17 int
504  *  3.3.18 short
505  *  3.3.19 byte
506  *  3.3.20 nonNegativeInteger
507  *  3.3.25 positiveInteger
508  *
509  *   . the preceding optional "+" sign is prohibited and
510  *   . leading zeroes are prohibited.
511  *
512  *
513  *  E2-27
514  *  3.3.14 nonPositiveInteger
515  *
516  *   . In the canonical form for zero, the sign must be omitted.
517  *   . leading zeroes are prohibited.
518  *
519  *  3.3.15 negativeInteger
520  *  3.3.21 unsignedLong
521  *  3.3.22 unsignedInt
522  *  3.3.23 unsignedShort
523  *  3.3.24 unsignedByte
524  *
525  *  . leading zeroes are prohibited.
526  *
527  *  Summary:
528  *  . leading zeros are prohibited for all three groups
529  *  . '-' is required for nonPositiveInteger if it is zero
530  *
531  ***/
532 
getCanonicalRepresentation(const XMLCh * const rawData,MemoryManager * const memMgr,bool toValidate) const533 const XMLCh* DecimalDatatypeValidator::getCanonicalRepresentation(const XMLCh*         const rawData
534                                                                  ,      MemoryManager* const memMgr
535                                                                  ,      bool                 toValidate) const
536 {
537     MemoryManager* toUse = memMgr? memMgr : fMemoryManager;
538     DecimalDatatypeValidator* temp = (DecimalDatatypeValidator*) this;
539 
540     if (toValidate)
541     {
542         try
543         {
544             temp->checkContent(rawData, 0, false, toUse);
545         }
546         catch (...)
547         {
548             return 0;
549         }
550     }
551 
552     // XMLBigInteger::getCanonicalRepresentation and
553     // XMLBigDecimal::getCanonicalRepresentation will handle exceptional cases
554     XMLCanRepGroup::CanRepGroup dvType = DatatypeValidatorFactory::getCanRepGroup(temp);
555 
556     if ((dvType == XMLCanRepGroup::Decimal_Derived_signed)   ||
557         (dvType == XMLCanRepGroup::Decimal_Derived_unsigned) ||
558         (dvType == XMLCanRepGroup::Decimal_Derived_npi)        )
559     {
560         return XMLBigInteger::getCanonicalRepresentation(rawData, toUse, dvType == XMLCanRepGroup::Decimal_Derived_npi);
561     }
562     else if (dvType == XMLCanRepGroup::Decimal)
563     {
564         return XMLBigDecimal::getCanonicalRepresentation(rawData, toUse);
565     }
566     else //in case?
567     {
568         return XMLString::replicate(rawData, toUse);
569     }
570 
571 }
572 
573 /***
574  * Support for Serialization/De-serialization
575  ***/
576 
IMPL_XSERIALIZABLE_TOCREATE(DecimalDatatypeValidator)577 IMPL_XSERIALIZABLE_TOCREATE(DecimalDatatypeValidator)
578 
579 void DecimalDatatypeValidator::serialize(XSerializeEngine& serEng)
580 {
581     /***
582      * Note:
583      *
584      *     During storing, we need write the specific number
585      *     type info before calling base::serialize().
586      *
587      *     While loading, we do nothing here
588      ***/
589 
590     if (serEng.isStoring())
591     {
592         serEng<<(int) (XMLNumber::BigDecimal);
593     }
594 
595     AbstractNumericValidator::serialize(serEng);
596 
597     //don't serialize XMLBigDecimal*
598     if (serEng.isStoring())
599     {
600         serEng<<fTotalDigits;
601         serEng<<fFractionDigits;
602     }
603     else
604     {
605         serEng>>fTotalDigits;
606         serEng>>fFractionDigits;
607     }
608 
609 }
610 
611 XERCES_CPP_NAMESPACE_END
612 
613 /**
614   * End of file DecimalDatatypeValidator::cpp
615   */
616