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: DoubleDatatypeValidator.cpp 676911 2008-07-15 13:27:32Z amassari $
20  */
21 
22 // ---------------------------------------------------------------------------
23 //  Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/validators/datatype/DoubleDatatypeValidator.hpp>
26 #include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
27 #include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
28 
29 XERCES_CPP_NAMESPACE_BEGIN
30 
31 // ---------------------------------------------------------------------------
32 //  Constructors and Destructor
33 // ---------------------------------------------------------------------------
DoubleDatatypeValidator(MemoryManager * const manager)34 DoubleDatatypeValidator::DoubleDatatypeValidator(MemoryManager* const manager)
35 :AbstractNumericValidator(0, 0, 0, DatatypeValidator::Double, manager)
36 {
37     setOrdered(XSSimpleTypeDefinition::ORDERED_PARTIAL);
38     setBounded(true);
39     setFinite(true);
40     setNumeric(true);
41 }
42 
DoubleDatatypeValidator(DatatypeValidator * const baseValidator,RefHashTableOf<KVStringPair> * const facets,RefArrayVectorOf<XMLCh> * const enums,const int finalSet,MemoryManager * const manager)43 DoubleDatatypeValidator::DoubleDatatypeValidator(
44                           DatatypeValidator*            const baseValidator
45                         , RefHashTableOf<KVStringPair>* const facets
46                         , RefArrayVectorOf<XMLCh>*      const enums
47                         , const int                           finalSet
48                         , MemoryManager* const                manager)
49 :AbstractNumericValidator(baseValidator, facets, finalSet, DatatypeValidator::Double, manager)
50 {
51     init(enums, manager);
52 }
53 
~DoubleDatatypeValidator()54 DoubleDatatypeValidator::~DoubleDatatypeValidator()
55 {}
56 
57 // -----------------------------------------------------------------------
58 // Compare methods
59 // -----------------------------------------------------------------------
compare(const XMLCh * const lValue,const XMLCh * const rValue,MemoryManager * const manager)60 int DoubleDatatypeValidator::compare(const XMLCh* const lValue
61                                    , const XMLCh* const rValue
62                                    , MemoryManager* const manager)
63 {
64     XMLDouble lObj(lValue, manager);
65     XMLDouble rObj(rValue, manager);
66 
67     return compareValues(&lObj, &rObj);
68 }
69 
newInstance(RefHashTableOf<KVStringPair> * const facets,RefArrayVectorOf<XMLCh> * const enums,const int finalSet,MemoryManager * const manager)70 DatatypeValidator* DoubleDatatypeValidator::newInstance
71 (
72       RefHashTableOf<KVStringPair>* const facets
73     , RefArrayVectorOf<XMLCh>* const      enums
74     , const int                           finalSet
75     , MemoryManager* const                manager
76 )
77 {
78     return (DatatypeValidator*) new (manager) DoubleDatatypeValidator(this, facets, enums, finalSet, manager);
79 }
80 
81 // -----------------------------------------------------------------------
82 // ctor provided to be used by derived classes
83 // -----------------------------------------------------------------------
DoubleDatatypeValidator(DatatypeValidator * const baseValidator,RefHashTableOf<KVStringPair> * const facets,const int finalSet,const ValidatorType type,MemoryManager * const manager)84 DoubleDatatypeValidator::DoubleDatatypeValidator(DatatypeValidator*            const baseValidator
85                                                , RefHashTableOf<KVStringPair>* const facets
86                                                , const int                           finalSet
87                                                , const ValidatorType                 type
88                                                , MemoryManager* const                manager)
89 :AbstractNumericValidator(baseValidator, facets, finalSet, type, manager)
90 {
91     //do not invoke init here !!!
92 }
93 
compareValues(const XMLNumber * const lValue,const XMLNumber * const rValue)94 int  DoubleDatatypeValidator::compareValues(const XMLNumber* const lValue
95                                           , const XMLNumber* const rValue)
96 {
97     return XMLDouble::compareValues((XMLDouble*) lValue, (XMLDouble*) rValue);
98 }
99 
setMaxInclusive(const XMLCh * const value)100 void  DoubleDatatypeValidator::setMaxInclusive(const XMLCh* const value)
101 {
102     fMaxInclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
103 }
104 
setMaxExclusive(const XMLCh * const value)105 void  DoubleDatatypeValidator::setMaxExclusive(const XMLCh* const value)
106 {
107     fMaxExclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
108 }
109 
setMinInclusive(const XMLCh * const value)110 void  DoubleDatatypeValidator::setMinInclusive(const XMLCh* const value)
111 {
112     fMinInclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
113 }
114 
setMinExclusive(const XMLCh * const value)115 void  DoubleDatatypeValidator::setMinExclusive(const XMLCh* const value)
116 {
117     fMinExclusive = new (fMemoryManager) XMLDouble(value, fMemoryManager);
118 }
119 
setEnumeration(MemoryManager * const manager)120 void  DoubleDatatypeValidator::setEnumeration(MemoryManager* const manager)
121 {
122     // check 4.3.5.c0 must: enumeration values from the value space of base
123     //
124     // 1. shall be from base value space
125     // 2. shall be from current value space as well ( shall go through boundsCheck() )
126     //
127     if (!fStrEnumeration)
128         return;
129 
130     XMLSize_t i = 0;
131     XMLSize_t enumLength = fStrEnumeration->size();
132 
133     DoubleDatatypeValidator *numBase = (DoubleDatatypeValidator*) getBaseValidator();
134     if (numBase)
135     {
136         try
137         {
138             for ( i = 0; i < enumLength; i++)
139             {
140                 numBase->checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
141             }
142         }
143         catch (XMLException&)
144         {
145             ThrowXMLwithMemMgr1(InvalidDatatypeFacetException
146                     , XMLExcepts::FACET_enum_base
147                     , fStrEnumeration->elementAt(i)
148                     , manager);
149 
150         }
151     }
152 
153 #if 0
154 // spec says that only base has to checkContent
155     // We put the this->checkContent in a separate loop
156     // to not block original message with in that method.
157     //
158     for ( i = 0; i < enumLength; i++)
159     {
160         checkContent(fStrEnumeration->elementAt(i), (ValidationContext*)0, false, manager);
161     }
162 #endif
163 
164     fEnumeration = new (manager) RefVectorOf<XMLNumber>(enumLength, true, manager);
165     fEnumerationInherited = false;
166 
167     for ( i = 0; i < enumLength; i++)
168     {
169         fEnumeration->insertElementAt(new (manager) XMLDouble(fStrEnumeration->elementAt(i), manager), i);
170     }
171 }
172 
173 // -----------------------------------------------------------------------
174 // Abstract interface from AbstractNumericValidator
175 // -----------------------------------------------------------------------
176 
checkContent(const XMLCh * const content,ValidationContext * const context,bool asBase,MemoryManager * const manager)177 void DoubleDatatypeValidator::checkContent(const XMLCh*             const content
178                                           ,      ValidationContext* const context
179                                           ,      bool                     asBase
180                                           ,      MemoryManager*     const manager)
181 {
182 
183     //validate against base validator if any
184     DoubleDatatypeValidator *pBase = (DoubleDatatypeValidator*) this->getBaseValidator();
185     if (pBase)
186         pBase->checkContent(content, context, true, manager);
187 
188     // we check pattern first
189     if ( (getFacetsDefined() & DatatypeValidator::FACET_PATTERN ) != 0 )
190     {
191         if (getRegex()->matches(content, manager) ==false)
192         {
193             ThrowXMLwithMemMgr2(InvalidDatatypeValueException
194                     , XMLExcepts::VALUE_NotMatch_Pattern
195                     , content
196                     , getPattern()
197                     , manager);
198         }
199     }
200 
201     // if this is a base validator, we only need to check pattern facet
202     // all other facet were inherited by the derived type
203     if (asBase)
204         return;
205 
206     XMLDouble theValue(content, manager);
207     XMLDouble *theData = &theValue;
208 
209     if (getEnumeration())
210     {
211         XMLSize_t i=0;
212         XMLSize_t enumLength = getEnumeration()->size();
213         for ( ; i < enumLength; i++)
214         {
215             if (compareValues(theData, (XMLDouble*) getEnumeration()->elementAt(i)) ==0 )
216                 break;
217         }
218 
219         if (i == enumLength)
220             ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
221     }
222 
223     boundsCheck(theData, manager);
224 }
225 
226 /***
227  * Support for Serialization/De-serialization
228  ***/
229 
IMPL_XSERIALIZABLE_TOCREATE(DoubleDatatypeValidator)230 IMPL_XSERIALIZABLE_TOCREATE(DoubleDatatypeValidator)
231 
232 void DoubleDatatypeValidator::serialize(XSerializeEngine& serEng)
233 {
234     /***
235      * Note:
236      *
237      *     During storing, we need write the specific number
238      *     type info before calling base::serialize().
239      *
240      *     While loading, we do nothing here
241      ***/
242 
243     if (serEng.isStoring())
244     {
245         serEng<<(int) (XMLNumber::Double);
246     }
247 
248     AbstractNumericValidator::serialize(serEng);
249 
250 }
251 
252 XERCES_CPP_NAMESPACE_END
253 
254 /**
255   * End of file DoubleDatatypeValidator::cpp
256   */
257