source: icXML/icXML-devel/src/xercesc/framework/psvi/XSValue.cpp @ 2722

Last change on this file since 2722 was 2722, checked in by cameron, 6 years ago

Original Xerces files with import mods for icxercesc

File size: 66.0 KB
Line 
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: XSValue.cpp 932887 2010-04-11 13:04:59Z borisk $
20 */
21
22#include <limits.h>
23#include <errno.h>
24#include <string.h>
25#include <ctype.h>
26#include <math.h>
27#include <float.h>
28
29#include <xercesc/framework/psvi/XSValue.hpp>
30
31#include <icxercesc/util/XMLString.hpp>
32#include <xercesc/util/XMLStringTokenizer.hpp>
33
34#include <xercesc/util/XMLBigDecimal.hpp>
35#include <xercesc/util/XMLBigInteger.hpp>
36#include <xercesc/util/XMLFloat.hpp>
37#include <xercesc/util/XMLDouble.hpp>
38#include <xercesc/util/XMLDateTime.hpp>
39#include <xercesc/util/HexBin.hpp>
40#include <xercesc/util/Base64.hpp>
41#include <xercesc/util/XMLUri.hpp>
42#include <xercesc/util/XMLChar.hpp>
43#include <xercesc/util/Janitor.hpp>
44#include <xercesc/util/XMLInitializer.hpp>
45#include <icxercesc/util/regx/RegularExpression.hpp>
46#include <xercesc/validators/schema/SchemaSymbols.hpp>
47#include <xercesc/util/OutOfMemoryException.hpp>
48#include <icxercesc/util/TransService.hpp>
49#include <xercesc/util/NumberFormatException.hpp>
50
51XERCES_CPP_NAMESPACE_BEGIN
52
53/*** issues
54 *
55 *   1. For float, double, datetime family, the validation is almost similar to getActualValue
56 *
57 *
58 *   DataType                   DataGroup
59 *                             num  dtm  str             validation           canonical      actual-value
60 *   ======================================================================================================
61 *    dt_string                          str              [2] Char              NA             content
62 *    dt_boolean                         str           {true, false, 1, 0}   {true, false}    bool
63 *    dt_decimal               num                         lexical only         yes            double
64 *    dt_float                 num                         lexical/value        yes            double
65 *    dt_double                num                         lexical/value        yes            double
66 *    ---------------------------------------------------------------------------------------------------------
67 * 5  dt_duration                   dtm                    yes                  NA             struct datetime
68 *    dt_dateTime                   dtm                    yes                  yes            struct datetime
69 *    dt_time                       dtm                    yes                  yes            struct datetime
70 *    dt_date                       dtm                    yes                  NA             struct datetime
71 *    dt_gYearMonth                 dtm                    yes                  NA             struct datetime
72 *    ---------------------------------------------------------------------------------------------------------
73 * 10 dt_gYear                      dtm                    yes                  NA             struct datetime
74 *    dt_gMonthDay                  dtm                    yes                  NA             struct datetime
75 *    dt_gDay                       dtm                    yes                  NA             struct datetime
76 *    dt_gMonth                     dtm                    yes                  NA             struct datetime
77 *    dt_hexBinary                        str              decoding            ([a-f])         unsigned long ?
78 *    ---------------------------------------------------------------------------------------------------------
79 * 15 dt_base64Binary                     str              decoding             NA (errata?)   unsigned long ?
80 *    dt_anyURI                           str              yes                  NA             content
81 *    dt_QName                            str              a:b , [6]QName       NA             content
82 *    dt_NOTATION                         str              [6]QName             NA             content
83 *    dt_normalizedString                 str              no #xD #xA #x9       NA             content
84 *    ---------------------------------------------------------------------------------------------------------
85 * 20 dt_token                            str              no #xD #xA #x9 traling   NA         content
86 *    dt_language                         str              language id          NA             content
87 *    dt_NMTOKEN                          str              [7] Nmtoken          NA             content
88 *    dt_NMTOKENS                         str              [8] Nmtokens         NA             content
89 *    dt_Name                             str              [5] Name             NA             content
90 *    ---------------------------------------------------------------------------------------------------------
91 * 25 dt_NCName                           str              [4] NCName           NA             content
92 *    dt_ID                               str              [4] NCName           NA             content
93 *    dt_IDREF                            str              [4] NCName           NA             content
94 *    dt_IDREFS                           str              ws seped IDREF       NA             content
95 *    dt_ENTITY                           str              [4] NCName           NA             content
96 *    ---------------------------------------------------------------------------------------------------------
97 * 30 dt_ENTITIES                         str              ws seped ENTITY      NA             content
98 *    dt_integer               num                         lexical              yes            long
99 *    dt_nonPositiveInteger    num                         lexical              yes            long
100 *    dt_negativeInteger       num                         lexical              yes            long
101 *    dt_long                  num                         lexical              yes            long
102 *    ---------------------------------------------------------------------------------------------------------
103 * 35 dt_int                   num                         lexical              yes            int
104 *    dt_short                 num                         lexical              yes            short
105 *    dt_byte                  num                         lexical              yes            char
106 *    dt_nonNegativeInteger    num                         lexical              yes            unsigned long
107 *    dt_unsignedLong          num                         lexical              yes            unsigned long
108 *    ---------------------------------------------------------------------------------------------------------
109 * 40 dt_unsignedInt           num                         lexical              yes            unsigned int
110 *    dt_unsignedShort         num                         lexical              yes            unsigned short
111 *    dt_unsignedByte          num                         lexical              yes            unsigned char
112 *    dt_positiveInteger       num                         lexical              yes            unsigned long
113 *
114 ***/
115
116const XSValue::DataGroup XSValue::inGroup[XSValue::dt_MAXCOUNT] =
117{
118    dg_strings,   dg_strings,   dg_numerics,  dg_numerics,  dg_numerics,
119    dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes,
120    dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes, dg_strings,
121    dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,
122    dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,
123    dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,
124    dg_strings,   dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,
125    dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,
126    dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics
127};
128
129const bool XSValue::numericSign[XSValue::dt_MAXCOUNT] =
130{
131    true, true, true, true, true,
132    true, true, true, true, true,
133    true, true, true, true, true,
134    true, true, true, true, true,
135    true, true, true, true, true,
136    true, true, true, true, true,
137    true, true, true, true, true,
138    true, true, true, false, false,
139    false, false, false, false
140};
141
142// ---------------------------------------------------------------------------
143//  Local static functions
144// ---------------------------------------------------------------------------
145static RegularExpression* sXSValueRegEx = 0;
146ValueHashTableOf<XSValue::DataType>*  XSValue::fDataTypeRegistry = 0;
147
148void XMLInitializer::initializeXSValue()
149{
150    sXSValueRegEx = new RegularExpression(
151      XMLUni::fgLangPattern, SchemaSymbols::fgRegEx_XOption);
152
153    XSValue::initializeRegistry();
154}
155
156void XMLInitializer::terminateXSValue()
157{
158    delete XSValue::fDataTypeRegistry;
159    XSValue::fDataTypeRegistry = 0;
160
161    delete sXSValueRegEx;
162    sXSValueRegEx = 0;
163}
164
165XSValue::DataType  XSValue::getDataType(const XMLCh* const dtString)
166{
167    if (fDataTypeRegistry->containsKey(dtString)) {
168        return fDataTypeRegistry->get(dtString);
169    }
170
171    return dt_MAXCOUNT;
172}
173
174void XSValue::initializeRegistry()
175{
176    //using the XMLPlatformUtils::fgMemoryManager
177    fDataTypeRegistry  = new ValueHashTableOf<XSValue::DataType>(43);
178
179    if (fDataTypeRegistry) {
180        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_STRING,             XSValue::dt_string);
181        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_BOOLEAN,            XSValue::dt_boolean);
182        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DECIMAL,            XSValue::dt_decimal);
183        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_FLOAT,              XSValue::dt_float);
184        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DOUBLE,             XSValue::dt_double);
185        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DURATION,           XSValue::dt_duration);
186        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DATETIME,           XSValue::dt_dateTime);
187        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_TIME,               XSValue::dt_time);
188        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DATE,               XSValue::dt_date);
189        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_YEARMONTH,          XSValue::dt_gYearMonth);
190        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_YEAR,               XSValue::dt_gYear);
191        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_MONTHDAY,           XSValue::dt_gMonthDay);
192        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DAY,                XSValue::dt_gDay);
193        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_MONTH,              XSValue::dt_gMonth);
194        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_HEXBINARY,          XSValue::dt_hexBinary);
195        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_BASE64BINARY,       XSValue::dt_base64Binary);
196        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_ANYURI,             XSValue::dt_anyURI);
197        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_QNAME,              XSValue::dt_QName);
198        fDataTypeRegistry->put((void*) XMLUni::fgNotationString,               XSValue::dt_NOTATION);
199        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NORMALIZEDSTRING,   XSValue::dt_normalizedString);
200        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_TOKEN,              XSValue::dt_token);
201        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_LANGUAGE,           XSValue::dt_language);
202        fDataTypeRegistry->put((void*) XMLUni::fgNmTokenString,                XSValue::dt_NMTOKEN);
203        fDataTypeRegistry->put((void*) XMLUni::fgNmTokensString,               XSValue::dt_NMTOKENS);
204        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NAME,               XSValue::dt_Name);
205        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NCNAME,             XSValue::dt_NCName);
206        fDataTypeRegistry->put((void*) XMLUni::fgIDString,                     XSValue::dt_ID);
207        fDataTypeRegistry->put((void*) XMLUni::fgIDRefString,                  XSValue::dt_IDREF);
208        fDataTypeRegistry->put((void*) XMLUni::fgIDRefsString,                 XSValue::dt_IDREFS);
209        fDataTypeRegistry->put((void*) XMLUni::fgEntityString,                 XSValue::dt_ENTITY);
210        fDataTypeRegistry->put((void*) XMLUni::fgEntitiesString,               XSValue::dt_ENTITIES);
211        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_INTEGER,            XSValue::dt_integer);
212        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NONPOSITIVEINTEGER, XSValue::dt_nonPositiveInteger);
213        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NEGATIVEINTEGER,    XSValue::dt_negativeInteger);
214        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_LONG,               XSValue::dt_long);
215        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_INT,                XSValue::dt_int);
216        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_SHORT,              XSValue::dt_short);
217        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_BYTE,               XSValue::dt_byte);
218        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NONNEGATIVEINTEGER, XSValue::dt_nonNegativeInteger);
219        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_ULONG,              XSValue::dt_unsignedLong);
220        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_UINT,               XSValue::dt_unsignedInt);
221        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_USHORT,             XSValue::dt_unsignedShort);
222        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_UBYTE,              XSValue::dt_unsignedByte);
223        fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_POSITIVEINTEGER,    XSValue::dt_positiveInteger);
224    }
225}
226
227static bool checkTimeZoneError(XSValue::DataType       const &datatype
228                             , SchemaDateTimeException const &e       )
229{
230    return (((datatype == XSValue::dt_dateTime) || (datatype == XSValue::dt_time) || (datatype == XSValue::dt_date)) &&
231            ((e.getCode() == XMLExcepts::DateTime_tz_noUTCsign)   ||
232             (e.getCode() == XMLExcepts::DateTime_tz_stuffAfterZ) ||
233             (e.getCode() == XMLExcepts::DateTime_tz_invalid)     ||
234             (e.getCode() == XMLExcepts::DateTime_tz_hh_invalid)));
235}
236
237// ---------------------------------------------------------------------------
238//  Local Data
239// ---------------------------------------------------------------------------
240
241static const XMLCh Separator_20[] = {chSpace, chNull};
242static const XMLCh Separator_ws[] = {chSpace, chLF, chCR, chHTab, chNull};
243
244// ---------------------------------------------------------------------------
245//  XSValue: Constructors and Destructor
246// ---------------------------------------------------------------------------
247XSValue::XSValue(DataType        const dt
248               , MemoryManager*  const manager)
249    :fMemAllocated(false)
250    ,fMemoryManager(manager)
251{
252    fData.f_datatype = dt;
253}
254
255XSValue::~XSValue()
256{
257    if (fMemAllocated)
258        fMemoryManager->deallocate(fData.fValue.f_byteVal);
259}
260
261// ---------------------------------------------------------------------------
262//  XSValue: Public Interface
263//
264//    No exception is thrown from these methods
265//
266// ---------------------------------------------------------------------------
267bool XSValue::validate(const XMLCh*         const content
268                      ,      DataType             datatype
269                      ,      Status&              status
270                      ,      XMLVersion           version
271                      ,      MemoryManager* const manager)
272{
273    if (!content ||
274        !*content ||
275        ((version == ver_10) && (XMLChar1_0::isAllSpaces(content, XMLString::stringLen(content)))) ||
276        ((version == ver_11) && (XMLChar1_1::isAllSpaces(content, XMLString::stringLen(content)))) ) {
277
278        switch (datatype) {
279        case XSValue::dt_string:
280        case XSValue::dt_normalizedString:
281        case XSValue::dt_token:
282        case XSValue::dt_anyURI:
283        case XSValue::dt_hexBinary:
284        case XSValue::dt_base64Binary:
285            status = st_Init;
286            return true;
287            break;
288        default:
289            status = st_NoContent;
290            return false;
291            break;
292        }
293    }
294
295    status = st_Init;
296
297    switch (inGroup[datatype]) {
298    case XSValue::dg_numerics:
299        return validateNumerics(content, datatype, status, manager);
300        break;
301    case XSValue::dg_datetimes:
302        return validateDateTimes(content, datatype, status, manager);
303        break;
304    case XSValue::dg_strings:
305        return validateStrings(content, datatype, status, version, manager);
306        break;
307    default:
308        status = st_UnknownType;
309
310        return false;
311        break;
312    }
313    return false;
314}
315
316XMLCh*
317XSValue::getCanonicalRepresentation(const XMLCh*         const content
318                                   ,      DataType             datatype
319                                   ,      Status&              status
320                                   ,      XMLVersion           version
321                                   ,      bool                 toValidate
322                                   ,      MemoryManager* const manager)
323{
324    if (!content ||
325        !*content ||
326        ((version == ver_10) && (XMLChar1_0::isAllSpaces(content, XMLString::stringLen(content)))) ||
327        ((version == ver_11) && (XMLChar1_1::isAllSpaces(content, XMLString::stringLen(content)))) ) {
328        status = st_NoContent;
329        return 0;
330    }
331
332    status = st_Init;
333
334    switch (inGroup[datatype]) {
335    case XSValue::dg_numerics:
336        return getCanRepNumerics(content, datatype,  status, toValidate, manager);
337        break;
338    case XSValue::dg_datetimes:
339        return getCanRepDateTimes(content, datatype,  status, toValidate, manager);
340        break;
341    case XSValue::dg_strings:
342        return getCanRepStrings(content, datatype,  status, version, toValidate, manager);
343        break;
344    default:
345        status = st_UnknownType;
346
347        return 0;
348        break;
349    }
350    return 0;
351}
352
353XSValue* XSValue::getActualValue(const XMLCh*         const content
354                               ,       DataType             datatype
355                               ,       Status&              status
356                               ,       XMLVersion           version
357                               ,       bool                 toValidate
358                               ,       MemoryManager* const manager)
359{
360    if (!content ||
361        !*content ||
362        ((version == ver_10) && (XMLChar1_0::isAllSpaces(content, XMLString::stringLen(content)))) ||
363        ((version == ver_11) && (XMLChar1_1::isAllSpaces(content, XMLString::stringLen(content)))) ) {
364        status = st_NoContent;
365        return 0;
366    }
367
368    status = st_Init;
369
370    switch (inGroup[datatype]) {
371    case XSValue::dg_numerics:
372        return getActValNumerics(content, datatype,  status, toValidate, manager);
373        break;
374    case XSValue::dg_datetimes:
375        return getActValDateTimes(content, datatype,  status, manager);
376        break;
377    case XSValue::dg_strings:
378        return getActValStrings(content, datatype,  status, version, toValidate, manager);
379        break;
380    default:
381        status = st_UnknownType;
382        return 0;
383        break;
384    }
385    return 0;
386}
387
388// ---------------------------------------------------------------------------
389//  XSValue: Helpers
390// ---------------------------------------------------------------------------
391
392/***
393 *
394 *  Boundary checking is done against Schema Type's lexcial space
395 ***/
396bool
397XSValue::validateNumerics(const XMLCh*         const content
398                        ,       DataType             datatype
399                        ,       Status&              status
400                        ,       MemoryManager* const manager)
401{
402
403    try {
404
405        switch (datatype) {
406        case XSValue::dt_decimal:
407            XMLBigDecimal::parseDecimal(content, manager);
408            break;
409        case XSValue::dt_float:
410            {
411                //XMLFloat takes care of 0, -0, -INF, INF and NaN
412                //XMLFloat::checkBoundary() handles error and outofbound issues
413                XMLFloat data(content, manager);
414                break;
415            }
416        case XSValue::dt_double:
417            {
418                //XMLDouble takes care of 0, -0, -INF, INF and NaN
419                //XMLDouble::checkBoundary() handles error and outofbound issues
420                XMLDouble  data(content, manager);
421                break;
422            }
423        /***
424         *   For all potentially unrepresentable types
425         *
426         *   For dt_long, dt_unsignedLong, doing lexical space
427         *   checking ensures consistent behaviour on 32/64 boxes
428         *
429         ***/
430        case XSValue::dt_integer:
431        case XSValue::dt_negativeInteger:
432        case XSValue::dt_nonPositiveInteger:
433        case XSValue::dt_nonNegativeInteger:
434        case XSValue::dt_positiveInteger:
435        case XSValue::dt_long:
436        case XSValue::dt_unsignedLong:
437            {
438                XMLCh* compareData = (XMLCh*) manager->allocate((XMLString::stringLen(content) + 1) * sizeof(XMLCh));
439                ArrayJanitor<XMLCh> janName(compareData, manager);
440                int    signValue = 0;
441                XMLBigInteger::parseBigInteger(content, compareData, signValue,  manager);
442
443                switch (datatype) {
444                case XSValue::dt_integer:
445                    //error: no
446                    break;
447                case XSValue::dt_negativeInteger:
448                    // error: > -1
449                    if  (XMLBigInteger::compareValues(compareData
450                                                    , signValue
451                                                    , &(XMLUni::fgNegOne[1])
452                                                    , -1
453                                                    , manager)
454                                                    == XMLNumber::GREATER_THAN)
455                    {
456                        status = st_FOCA0002;
457                        return false;
458                    }
459                    break;
460                case XSValue::dt_nonPositiveInteger:
461                    // error: > 0
462                     if (XMLBigInteger::compareValues(compareData
463                                                   , signValue
464                                                   , XMLUni::fgValueZero
465                                                   , 0
466                                                   , manager)
467                                                   == XMLNumber::GREATER_THAN)
468                    {
469                        status = st_FOCA0002;
470                        return false;
471                    }
472                    break;
473                case XSValue::dt_nonNegativeInteger:
474                    // error: < 0
475                    if (XMLBigInteger::compareValues(compareData
476                                                   , signValue
477                                                   , XMLUni::fgValueZero
478                                                   , 0
479                                                   , manager)
480                                                   == XMLNumber::LESS_THAN)
481                    {
482                        status = st_FOCA0002;
483                        return false;
484                    }
485                    break;
486                case XSValue::dt_positiveInteger:
487                    // error: < 1
488                    if (XMLBigInteger::compareValues(compareData
489                                                   , signValue
490                                                   , XMLUni::fgValueOne
491                                                   , 1
492                                                   , manager)
493                                                   == XMLNumber::LESS_THAN)
494                    {
495                        status = st_FOCA0002;
496                        return false;
497                    }
498                    break;
499                case XSValue::dt_long:
500                    // error: < -9223372036854775808 || > 9223372036854775807
501                    if ((XMLBigInteger::compareValues(compareData
502                                                    , signValue
503                                                    , &(XMLUni::fgLongMinInc[1])
504                                                    , -1
505                                                    , manager)
506                                                    == XMLNumber::LESS_THAN) ||
507                        (XMLBigInteger::compareValues(compareData
508                                                    , signValue
509                                                    , XMLUni::fgLongMaxInc
510                                                    , 1
511                                                    , manager)
512                                                    == XMLNumber::GREATER_THAN))
513                    {
514                        status = st_FOCA0002;
515                        return false;
516                    }
517                    break;
518                case XSValue::dt_unsignedLong:
519                    // error: < 0 || > 18446744073709551615
520                    if ((XMLBigInteger::compareValues(compareData
521                                                    , signValue
522                                                    , XMLUni::fgValueZero
523                                                    , 0
524                                                    , manager)
525                                                    == XMLNumber::LESS_THAN) ||
526                        (XMLBigInteger::compareValues(compareData
527                                                    , signValue
528                                                    , XMLUni::fgULongMaxInc
529                                                    , 1
530                                                    , manager)
531                                                    == XMLNumber::GREATER_THAN))
532                    {
533                        status = st_FOCA0002;
534                        return false;
535                    }
536                    break;
537                default:
538                    status = st_NotSupported;
539                    return false;
540                    break;
541                }
542                break;
543            }
544        case XSValue::dt_int:
545        case XSValue::dt_short:
546        case XSValue::dt_byte:
547        case XSValue::dt_unsignedInt:
548        case XSValue::dt_unsignedShort:
549        case XSValue::dt_unsignedByte:
550            {
551                t_value   actVal;
552
553                if ( !getActualNumericValue(
554                                  content
555                                , status
556                                , actVal
557                                , manager
558                                , datatype
559                                 )
560                )
561                {
562                    return false;
563                }
564                break;
565            }
566        default:
567            return false;
568        } // end switch
569    }
570    catch (const NumberFormatException&)
571    {
572        //getActValue()/getCanonical() need to know the failure details
573        //if validation is required
574        status = st_FOCA0002;
575        return false;
576    }
577    return true;  //both valid chars and within boundary
578}
579
580bool XSValue::validateDateTimes(const XMLCh*         const input_content
581                              ,       DataType             datatype
582                              ,       Status&              status
583                              ,       MemoryManager* const manager)
584{
585    XMLCh* content = XMLString::replicate(input_content, manager);
586    ArrayJanitor<XMLCh> janTmpName(content, manager);
587    XMLString::trim(content);
588    try
589    {
590        XMLDateTime coreDate = XMLDateTime(content, manager);
591
592        switch (datatype) {
593        case XSValue::dt_duration:
594            coreDate.parseDuration();
595            break;
596        case XSValue::dt_dateTime:
597            coreDate.parseDateTime();
598            break;
599        case XSValue::dt_time:
600            coreDate.parseTime();
601            break;
602        case XSValue::dt_date:
603            coreDate.parseDate();
604            break;
605        case XSValue::dt_gYearMonth:
606            coreDate.parseYearMonth();
607            break;
608        case XSValue::dt_gYear:
609            coreDate.parseYear();
610            break;
611        case XSValue::dt_gMonthDay:
612            coreDate.parseMonthDay();
613            break;
614        case XSValue::dt_gDay:
615            coreDate.parseDay();
616            break;
617        case XSValue::dt_gMonth:
618            coreDate.parseMonth();
619            break;
620        default:
621            return false;
622            break;
623        }
624    }
625
626    catch (const SchemaDateTimeException &e)
627    {
628        status = checkTimeZoneError(datatype, e)? XSValue::st_FODT0003 : st_FOCA0002;
629        return false;
630    }
631    catch (const NumberFormatException&)
632    {
633        //getActValue()/getCanonical() need to know the failure details
634        //if validation is required
635        status = st_FOCA0002;
636        return false;
637    }
638
639    return true; //parsing succeed
640}
641
642bool XSValue::validateStrings(const XMLCh*         const content
643                            ,       DataType             datatype
644                            ,       Status&              status
645                            ,       XMLVersion           version
646                            ,       MemoryManager* const manager)
647{
648    bool isValid = true;
649
650    switch (datatype) {
651        case XSValue::dt_boolean:
652            {
653                XMLSize_t i = 0;
654                XMLCh* tmpStrValue = XMLString::replicate(content, manager);
655                ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
656                XMLString::trim(tmpStrValue);
657                for (; i < XMLUni::fgBooleanValueSpaceArraySize; i++) {
658                    if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[i]))
659                        break;
660                }
661
662                if (XMLUni::fgBooleanValueSpaceArraySize == i) {
663                    isValid = false;
664                }
665                break;
666            }
667        case XSValue::dt_hexBinary:
668            {
669            XMLCh* tmpStrValue = XMLString::replicate(content, manager);
670            ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
671            XMLString::trim(tmpStrValue);
672            if (HexBin::getDataLength(tmpStrValue) == -1) {
673               isValid = false;
674            }
675            }
676            break;
677        case XSValue::dt_base64Binary:
678            if (Base64::getDataLength(content, manager) == -1) {
679                isValid = false;
680            }
681            break;
682        case XSValue::dt_anyURI:
683            if (XMLUri::isValidURI(true, content, true) == false) {
684                isValid = false;
685            }
686            break;
687        case XSValue::dt_QName:
688            {
689            XMLCh* tmpStrValue = XMLString::replicate(content, manager);
690            ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
691            XMLString::trim(tmpStrValue);
692            isValid = (version == ver_10) ?
693                XMLChar1_0::isValidQName(tmpStrValue, XMLString::stringLen(tmpStrValue)) :
694                XMLChar1_1::isValidQName(tmpStrValue, XMLString::stringLen(tmpStrValue));
695            }
696            break;
697        case XSValue::dt_NOTATION:
698            {
699            XMLCh* tmpStrValue = XMLString::replicate(content, manager);
700            ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
701            XMLString::trim(tmpStrValue);
702            if ( XMLString::isValidNOTATION(tmpStrValue, manager) == false) {
703                isValid = false;
704            }
705            }
706            break;
707        case XSValue::dt_string:
708            {
709                const XMLCh*   rawPtr = content;
710
711                if (version == ver_10) {
712                    while (*rawPtr)
713                        if (!XMLChar1_0::isXMLChar(*rawPtr++)) {
714                            isValid = false;
715                            break;
716                        }
717                }
718                else {
719                    while (*rawPtr)
720                        if (!XMLChar1_1::isXMLChar(*rawPtr++)) {
721                            isValid = false;
722                            break;
723                        }
724                }
725                break;
726            }
727        case XSValue::dt_normalizedString:
728            {
729                const XMLCh*   rawPtr = content;
730
731                if (version == ver_10) {
732                    while (*rawPtr) {
733                        if (!XMLChar1_0::isXMLChar(*rawPtr)) {
734                            isValid = false;
735                            break;
736                        }
737                        else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
738                            isValid = false;
739                            break;
740                        }
741                        else {
742                            rawPtr++;
743                        }
744                    }
745                }
746                else {
747                    while (*rawPtr) {
748                        if (!XMLChar1_1::isXMLChar(*rawPtr)) {
749                            isValid = false;
750                            break;
751                        }
752                        else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
753                            isValid = false;
754                            break;
755                        }
756                        else {
757                            rawPtr++;
758                        }
759
760                    }
761                }
762                break;
763            }
764        case XSValue::dt_token:
765        case XSValue::dt_language:
766            {
767                XMLSize_t     strLen = XMLString::stringLen(content);
768                const XMLCh*  rawPtr = content;
769                bool     inWS = false;
770
771                if (version == ver_10) {
772                    // Check leading/Trailing white space
773                    if (XMLChar1_0::isWhitespace(content[0])      ||
774                        XMLChar1_0::isWhitespace(content[strLen - 1])  ) {
775                        isValid = false;
776                    }
777                    else {
778                        while (*rawPtr) {
779                            if (!XMLChar1_0::isXMLChar(*rawPtr)) {
780                                isValid = false;
781                                break;
782                            }
783                            else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
784                                isValid = false;
785                                break;
786                            }
787                            else if (XMLChar1_0::isWhitespace(*rawPtr)) {
788                                if (inWS) {
789                                    isValid = false;
790                                    break;
791                                }
792                                else {
793                                    inWS = true;
794                                }
795                            }
796                            else {
797                                inWS = false;
798                            }
799
800                            rawPtr++;
801                        }
802                    }
803                }
804                else {
805                    // Check leading/Trailing white space
806                    if (XMLChar1_1::isWhitespace(content[0])      ||
807                        XMLChar1_1::isWhitespace(content[strLen - 1])  ) {
808                        isValid = false;
809                    }
810                    else {
811                        while (*rawPtr) {
812                            if (!XMLChar1_1::isXMLChar(*rawPtr)) {
813                                isValid = false;
814                                break;
815                            }
816                            else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
817                                isValid = false;
818                                break;
819                            }
820                            else if (XMLChar1_1::isWhitespace(*rawPtr)) {
821                                if (inWS) {
822                                    isValid = false;
823                                    break;
824                                }
825                                else {
826                                    inWS = true;
827                                }
828                            }
829                            else {
830                                inWS = false;
831                            }
832                            rawPtr++;
833                        }
834                    }
835                }
836                if (isValid == true && datatype == XSValue::dt_language) {
837                    if (!sXSValueRegEx) {
838                        status = st_CantCreateRegEx;
839                        isValid = false;
840                    }
841                    else
842                    {
843                        if (sXSValueRegEx->matches(content, manager) == false)
844                        {
845                            isValid = false;
846                        }
847                    }
848                }
849                break;
850            }
851        case XSValue::dt_NMTOKEN:
852            isValid = (version == ver_10) ?
853                XMLChar1_0::isValidNmtoken(content, XMLString::stringLen(content)) :
854                XMLChar1_1::isValidNmtoken(content, XMLString::stringLen(content));
855            break;
856        case XSValue::dt_NMTOKENS:
857            // [8]    Nmtokens   ::=    Nmtoken (#x20 Nmtoken)*
858            {
859                XMLStringTokenizer tokenizer(content, Separator_20, manager);
860
861                if (version ==  ver_10) {
862                    while (tokenizer.hasMoreTokens()) {
863                        const XMLCh* token = tokenizer.nextToken();
864
865                        if (!XMLChar1_0::isValidNmtoken(token, XMLString::stringLen(token))) {
866                            isValid = false;
867                            break;
868                        }
869                    }
870                }
871                else {
872                    while (tokenizer.hasMoreTokens()) {
873                        const XMLCh* token = tokenizer.nextToken();
874
875                        if (!XMLChar1_1::isValidNmtoken(token, XMLString::stringLen(token))) {
876                            isValid = false;
877                            break;
878                        }
879                    }
880                }
881                break;
882            }
883        case XSValue::dt_Name:
884            isValid = (version == ver_10) ?
885                XMLChar1_0::isValidName(content) :
886                XMLChar1_1::isValidName(content);
887            break;
888        case XSValue::dt_NCName:
889        case XSValue::dt_ID:
890        case XSValue::dt_IDREF:
891        case XSValue::dt_ENTITY:
892            isValid = (version == ver_10) ?
893                XMLChar1_0::isValidNCName(content, XMLString::stringLen(content)) :
894                XMLChar1_1::isValidNCName(content, XMLString::stringLen(content));
895            break;
896        case XSValue::dt_ENTITIES:
897        case XSValue::dt_IDREFS:
898            {
899                XMLStringTokenizer tokenizer(content, Separator_ws, manager);
900
901                if (version ==  ver_10 ) {
902                    while (tokenizer.hasMoreTokens()) {
903                        const XMLCh* token = tokenizer.nextToken();
904
905                        if (!XMLChar1_0::isValidNCName(token, XMLString::stringLen(token))) {
906                            isValid = false;
907                            break;
908                        }
909                    }
910                }
911                else {
912                    while (tokenizer.hasMoreTokens()) {
913                        const XMLCh* token = tokenizer.nextToken();
914
915                        if (!XMLChar1_1::isValidNCName(token, XMLString::stringLen(token))) {
916                            isValid = false;
917                            break;
918                        }
919                    }
920                }
921            }
922            break;
923        default:
924            status = st_NotSupported;
925            isValid = false;
926            break;
927    }
928
929
930    if (isValid == false && status == st_Init) {
931        status = st_FOCA0002;
932    }
933
934    return isValid;
935}
936
937
938XMLCh* XSValue::getCanRepNumerics(const XMLCh*         const content
939                                ,       DataType             datatype
940                                ,       Status&              status
941                                ,       bool                 toValidate
942                                ,       MemoryManager* const manager)
943{
944    try
945    {
946
947        // getCanonicalRepresentation does lexical space validation only
948        // (no range checking), therefore if validation is required,
949        // we need to pass the content to the validate interface for complete checking
950        if (toValidate && !validateNumerics(content, datatype, status, manager))
951            return 0;
952
953        XMLCh* retVal = 0;
954
955        if (datatype == XSValue::dt_decimal)
956        {
957            retVal = XMLBigDecimal::getCanonicalRepresentation(content, manager);
958
959            if (!retVal)
960                status = st_FOCA0002;
961
962            return retVal;
963
964        }
965        else if (datatype == XSValue::dt_float || datatype == XSValue::dt_double  )
966        {
967            // In XML4C, no float or double is treated as out of range
968            // it gets converted to INF, -INF or zero.
969            // The getCanonical method should treat double & float the
970            // same way as the rest of XML4C for consistentcy so need
971            // to getActualValue and see if it was converted.
972            XSValue* xsval = getActValNumerics(content, datatype, status, false, manager);
973            if (!xsval) {
974                status = st_FOCA0002;
975                return retVal;
976            }
977
978            DoubleFloatType enumVal;
979            if (datatype == XSValue::dt_float) {
980                enumVal = xsval->fData.fValue.f_floatType.f_floatEnum;
981            }
982            else {
983                enumVal = xsval->fData.fValue.f_doubleType.f_doubleEnum;
984            }
985            delete xsval;
986
987            switch(enumVal) {
988            case DoubleFloatType_NegINF:
989                retVal = XMLString::replicate(XMLUni::fgNegINFString, manager);
990                break;
991            case DoubleFloatType_PosINF:
992                retVal = XMLString::replicate(XMLUni::fgPosINFString, manager);
993                break;
994            case DoubleFloatType_NaN:
995                retVal = XMLString::replicate(XMLUni::fgNaNString, manager);
996                break;
997            case DoubleFloatType_Zero:
998                retVal = XMLString::replicate(XMLUni::fgPosZeroString, manager);
999                break;
1000            default: //DoubleFloatType_Normal
1001                retVal = XMLAbstractDoubleFloat::getCanonicalRepresentation(content, manager);
1002
1003                if (!retVal)
1004                    status = st_FOCA0002;
1005                break;
1006            }
1007            return retVal;
1008        }
1009        else
1010        {
1011            retVal = XMLBigInteger::getCanonicalRepresentation(content, manager, datatype == XSValue::dt_nonPositiveInteger);
1012
1013            if (!retVal)
1014                status = st_FOCA0002;
1015
1016            return retVal;
1017        }
1018    }
1019    catch (const NumberFormatException&)
1020    {
1021        status = st_FOCA0002;
1022    }
1023
1024    return 0;
1025}
1026
1027XMLCh* XSValue::getCanRepDateTimes(const XMLCh*         const input_content
1028                                 ,       DataType             datatype
1029                                 ,       Status&              status
1030                                 ,       bool                 toValidate
1031                                 ,       MemoryManager* const manager)
1032{
1033    XMLCh* content = XMLString::replicate(input_content, manager);
1034    ArrayJanitor<XMLCh> janTmpName(content, manager);
1035    XMLString::trim(content);
1036    try
1037    {
1038
1039        XMLDateTime coreDate = XMLDateTime(content, manager);
1040
1041        switch (datatype) {
1042        case XSValue::dt_dateTime:
1043            //we need this parsing
1044            coreDate.parseDateTime();
1045            return coreDate.getDateTimeCanonicalRepresentation(manager);
1046            break;
1047        case XSValue::dt_time:
1048            // we need this parsing
1049            coreDate.parseTime();
1050            return coreDate.getTimeCanonicalRepresentation(manager);
1051            break;
1052        case XSValue::dt_date:
1053            // we need this parsing
1054            coreDate.parseDate();
1055            return coreDate.getDateCanonicalRepresentation(manager);
1056            break;
1057        case XSValue::dt_duration:
1058        case XSValue::dt_gYearMonth:
1059        case XSValue::dt_gYear:
1060        case XSValue::dt_gMonthDay:
1061        case XSValue::dt_gDay:
1062        case XSValue::dt_gMonth:
1063            {
1064                if (!(toValidate && !validateDateTimes(content, datatype, status, manager)))
1065                    status = st_NoCanRep;
1066
1067                return 0;
1068            }
1069            break;
1070        default:
1071            return 0;
1072            break;
1073        }
1074    }
1075    catch (SchemaDateTimeException &e)
1076    {
1077        status = checkTimeZoneError(datatype, e)? XSValue::st_FODT0003 : st_FOCA0002;
1078    }
1079    catch (const NumberFormatException&)
1080    {
1081        status = st_FOCA0002;
1082    }
1083    return 0;
1084}
1085
1086XMLCh* XSValue::getCanRepStrings(const XMLCh*         const content
1087                               ,       DataType             datatype
1088                               ,       Status&              status
1089                               ,       XMLVersion           version
1090                               ,       bool                 toValidate
1091                               ,       MemoryManager* const manager)
1092{
1093    switch (datatype) {
1094        case XSValue::dt_boolean:
1095            {
1096            XMLCh* tmpStrValue = XMLString::replicate(content, manager);
1097            ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
1098            XMLString::trim(tmpStrValue);
1099            //always validate before getting canRep
1100            if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[0]) ||
1101                XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[2])  )
1102            {
1103                return XMLString::replicate(XMLUni::fgBooleanValueSpace[0], manager);
1104            }
1105            else if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[1]) ||
1106                     XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[3])  )
1107            {
1108                return XMLString::replicate(XMLUni::fgBooleanValueSpace[1], manager);
1109            }
1110            else
1111            {
1112                status = st_FOCA0002;
1113                return 0;
1114            }
1115            }
1116            break;
1117        case XSValue::dt_hexBinary:
1118            {
1119                //HexBin::getCanonicalRepresentation does validation automatically
1120                XMLCh* tmpStrValue = XMLString::replicate(content, manager);
1121                ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
1122                XMLString::trim(tmpStrValue);
1123
1124                XMLCh* canRep = HexBin::getCanonicalRepresentation(tmpStrValue, manager);
1125                if (!canRep)
1126                    status = st_FOCA0002;
1127
1128                return canRep;
1129                break;
1130            }
1131        case XSValue::dt_base64Binary:
1132            {
1133                //Base64::getCanonicalRepresentation does validation automatically
1134                XMLCh* canRep = Base64::getCanonicalRepresentation(content, manager);
1135                if (!canRep)
1136                    status = st_FOCA0002;
1137
1138                return canRep;
1139                break;
1140            }
1141        case XSValue::dt_anyURI:
1142        case XSValue::dt_QName:
1143        case XSValue::dt_NOTATION:
1144        case XSValue::dt_string:
1145        case XSValue::dt_normalizedString:
1146        case XSValue::dt_token:
1147        case XSValue::dt_language:
1148        case XSValue::dt_NMTOKEN:
1149        case XSValue::dt_NMTOKENS:
1150        case XSValue::dt_Name:
1151        case XSValue::dt_NCName:
1152        case XSValue::dt_ID:
1153        case XSValue::dt_IDREF:
1154        case XSValue::dt_ENTITY:
1155        case XSValue::dt_ENTITIES:
1156        case XSValue::dt_IDREFS:
1157            if (toValidate && !validateStrings(content, datatype, status, version, manager))
1158                status = st_FOCA0002;
1159            else
1160                status = st_NoCanRep;
1161
1162            return 0;
1163            break;
1164        default:
1165            return 0;
1166            break;
1167    }
1168
1169    return 0;
1170}
1171
1172XSValue*
1173XSValue::getActValNumerics(const XMLCh*         const content
1174                         ,       DataType             datatype
1175                         ,       Status&              status
1176                         ,       bool                 toValidate
1177                         ,       MemoryManager* const manager)
1178{
1179
1180    try {
1181
1182        switch (datatype) {
1183        case XSValue::dt_decimal:
1184        {
1185            if (toValidate) {
1186                XMLBigDecimal::parseDecimal(content, manager);
1187            }
1188            //Prepare the double value
1189            XMLDouble  data(content, manager);
1190            if (data.isDataConverted())
1191            {
1192                status = st_FOCA0001;
1193                return 0;
1194            }
1195
1196            XSValue* retVal = new (manager) XSValue(dt_decimal, manager);
1197            retVal->fData.fValue.f_decimal.f_dvalue = data.getValue();
1198
1199            return retVal;
1200            break;
1201        }
1202        case XSValue::dt_float:
1203        {
1204            //XMLFloat takes care of 0, -0, -INF, INF and NaN
1205            //XMLFloat::checkBoundary() handles error and outofbound issues
1206            XMLFloat data(content, manager);
1207            XSValue* retVal = new (manager) XSValue(dt_float, manager);
1208
1209            if (data.isDataConverted())
1210            {
1211                retVal->fData.fValue.f_floatType.f_float = 0.0;
1212                retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_Zero;
1213
1214                switch(data.getType()) {
1215                    case XMLAbstractDoubleFloat::NegINF:
1216                        retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_NegINF;
1217                        break;
1218                    case XMLAbstractDoubleFloat::PosINF:
1219                        retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_PosINF;
1220                        break;
1221                    case XMLAbstractDoubleFloat::NaN:
1222                        retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_NaN;
1223                        break;
1224                    default:
1225                        break;
1226                }
1227            }
1228            else {
1229                retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_Normal;
1230                retVal->fData.fValue.f_floatType.f_float = (float) data.getValue();
1231            }
1232            return retVal;
1233            break;
1234        }
1235        case XSValue::dt_double:
1236        {
1237            //XMLDouble takes care of 0, -0, -INF, INF and NaN
1238            //XMLDouble::checkBoundary() handles error and outofbound issues
1239            XMLDouble  data(content, manager);
1240            XSValue* retVal = new (manager) XSValue(dt_double, manager);
1241
1242            if (data.isDataConverted())
1243            {
1244                retVal->fData.fValue.f_doubleType.f_double = 0.0;
1245                retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_Zero;
1246
1247                switch(data.getType()) {
1248                    case XMLAbstractDoubleFloat::NegINF:
1249                        retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_NegINF;
1250                        break;
1251                    case XMLAbstractDoubleFloat::PosINF:
1252                        retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_PosINF;
1253                        break;
1254                    case XMLAbstractDoubleFloat::NaN:
1255                        retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_NaN;
1256                        break;
1257                    default:
1258                        break;
1259                }
1260            }
1261            else {
1262                retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_Normal;
1263                retVal->fData.fValue.f_doubleType.f_double = data.getValue();
1264            }
1265            return retVal;
1266            break;
1267        }
1268        case XSValue::dt_integer:
1269        case XSValue::dt_negativeInteger:
1270        case XSValue::dt_nonPositiveInteger:
1271        case XSValue::dt_nonNegativeInteger:
1272        case XSValue::dt_positiveInteger:
1273        case XSValue::dt_long:
1274        case XSValue::dt_int:
1275        case XSValue::dt_short:
1276        case XSValue::dt_byte:
1277        case XSValue::dt_unsignedLong:
1278        case XSValue::dt_unsignedInt:
1279        case XSValue::dt_unsignedShort:
1280        case XSValue::dt_unsignedByte:
1281        {
1282            t_value   actVal;
1283
1284            if ( !getActualNumericValue(
1285                                  content
1286                                , status
1287                                , actVal
1288                                , manager
1289                                , datatype
1290                                )
1291                )
1292            {
1293                //status has been set by getActualNumericValue
1294                return 0;
1295            }
1296
1297            XSValue* retVal = new (manager) XSValue(datatype, manager);
1298
1299            switch (datatype) {
1300                case XSValue::dt_integer:
1301                    retVal->fData.fValue.f_long = actVal.f_long;
1302                    break;
1303                case XSValue::dt_negativeInteger:
1304                    retVal->fData.fValue.f_long = actVal.f_long;
1305                    break;
1306                case XSValue::dt_nonPositiveInteger:
1307                    retVal->fData.fValue.f_long = actVal.f_long;
1308                    break;
1309                case XSValue::dt_nonNegativeInteger:
1310                    retVal->fData.fValue.f_long = actVal.f_ulong;
1311                    break;
1312                case XSValue::dt_positiveInteger:
1313                    retVal->fData.fValue.f_long = actVal.f_ulong;
1314                    break;
1315                case XSValue::dt_long:
1316                    retVal->fData.fValue.f_long = actVal.f_long;
1317                    break;
1318                case XSValue::dt_int:
1319                    retVal->fData.fValue.f_int = (int) actVal.f_long;
1320                    break;
1321                case XSValue::dt_short:
1322                    retVal->fData.fValue.f_short = (short) actVal.f_long;
1323                    break;
1324                case XSValue::dt_byte:
1325                    retVal->fData.fValue.f_char = (char) actVal.f_long;
1326                    break;
1327                case XSValue::dt_unsignedLong:
1328                    retVal->fData.fValue.f_ulong = actVal.f_ulong;
1329                    break;
1330                case XSValue::dt_unsignedInt:
1331                    retVal->fData.fValue.f_uint = (unsigned int) actVal.f_ulong;
1332                    break;
1333                case XSValue::dt_unsignedShort:
1334                    retVal->fData.fValue.f_ushort = (unsigned short) actVal.f_ulong;
1335                    break;
1336                case XSValue::dt_unsignedByte:
1337                    retVal->fData.fValue.f_uchar = (unsigned char) actVal.f_ulong;
1338                    break;
1339                default:
1340                    return 0;
1341                    break;
1342            }
1343            return retVal;
1344            break;
1345        }
1346        default:
1347            return 0;
1348            break;
1349        } // end switch
1350    }
1351    catch (const NumberFormatException&)
1352    {
1353        status = st_FOCA0002;
1354    }
1355    return 0;
1356}
1357
1358XSValue*
1359XSValue::getActValDateTimes(const XMLCh*         const input_content
1360                          ,       DataType             datatype
1361                          ,       Status&              status
1362                          ,       MemoryManager* const manager)
1363{
1364    XMLCh* content = XMLString::replicate(input_content, manager);
1365    ArrayJanitor<XMLCh> janTmpName(content, manager);
1366    XMLString::trim(content);
1367    try
1368    {
1369        //Need not check if validation is requested since
1370        //parsing functions below does the validation automatically
1371        XMLDateTime coreDate = XMLDateTime(content, manager);
1372
1373        switch (datatype) {
1374        case XSValue::dt_duration:
1375            coreDate.parseDuration();
1376            break;
1377        case XSValue::dt_dateTime:
1378            coreDate.parseDateTime();
1379            break;
1380        case XSValue::dt_time:
1381            coreDate.parseTime();
1382            coreDate.fValue[XMLDateTime::CentYear] = 0;
1383            coreDate.fValue[XMLDateTime::Month] = 0;
1384            coreDate.fValue[XMLDateTime::Day] = 0;
1385            break;
1386        case XSValue::dt_date:
1387            coreDate.parseDate();
1388            coreDate.fValue[XMLDateTime::Hour] = 0;
1389            coreDate.fValue[XMLDateTime::Minute] = 0;
1390            break;
1391        case XSValue::dt_gYearMonth:
1392            coreDate.parseYearMonth();
1393            coreDate.fValue[XMLDateTime::Day] = 0;
1394            coreDate.fValue[XMLDateTime::Hour] = 0;
1395            coreDate.fValue[XMLDateTime::Minute] = 0;
1396            break;
1397        case XSValue::dt_gYear:
1398            coreDate.parseYear();
1399            coreDate.fValue[XMLDateTime::Month] = 0;
1400            coreDate.fValue[XMLDateTime::Day] = 0;
1401            coreDate.fValue[XMLDateTime::Hour] = 0;
1402            coreDate.fValue[XMLDateTime::Minute] = 0;
1403            break;
1404        case XSValue::dt_gMonthDay:
1405            coreDate.parseMonthDay();
1406            coreDate.fValue[XMLDateTime::CentYear] = 0;
1407            coreDate.fValue[XMLDateTime::Hour] = 0;
1408            coreDate.fValue[XMLDateTime::Minute] = 0;
1409            break;
1410        case XSValue::dt_gDay:
1411            coreDate.parseDay();
1412            coreDate.fValue[XMLDateTime::CentYear] = 0;
1413            coreDate.fValue[XMLDateTime::Month] = 0;
1414            coreDate.fValue[XMLDateTime::Hour] = 0;
1415            coreDate.fValue[XMLDateTime::Minute] = 0;
1416            break;
1417        case XSValue::dt_gMonth:
1418            coreDate.parseMonth();
1419            coreDate.fValue[XMLDateTime::CentYear] = 0;
1420            coreDate.fValue[XMLDateTime::Day] = 0;
1421            coreDate.fValue[XMLDateTime::Hour] = 0;
1422            coreDate.fValue[XMLDateTime::Minute] = 0;
1423            break;
1424        default:
1425            return 0;
1426            break;
1427        }
1428
1429        XSValue* retVal = new (manager) XSValue(datatype, manager);
1430
1431        retVal->fData.fValue.f_datetime.f_year    = coreDate.fValue[XMLDateTime::CentYear];
1432        retVal->fData.fValue.f_datetime.f_month   = coreDate.fValue[XMLDateTime::Month];
1433        retVal->fData.fValue.f_datetime.f_day     = coreDate.fValue[XMLDateTime::Day];
1434        retVal->fData.fValue.f_datetime.f_hour    = coreDate.fValue[XMLDateTime::Hour];
1435        retVal->fData.fValue.f_datetime.f_min     = coreDate.fValue[XMLDateTime::Minute];
1436        retVal->fData.fValue.f_datetime.f_second  = coreDate.fValue[XMLDateTime::Second];
1437        retVal->fData.fValue.f_datetime.f_milisec = coreDate.fMilliSecond;
1438
1439        return retVal;
1440    }
1441    catch (SchemaDateTimeException const &e)
1442    {
1443        status = checkTimeZoneError(datatype, e)? XSValue::st_FODT0003 : st_FOCA0002;
1444    }
1445    catch (const NumberFormatException&)
1446    {
1447        status = st_FOCA0002;
1448    }
1449    return 0;
1450
1451}
1452
1453XSValue*
1454XSValue::getActValStrings(const XMLCh*         const content
1455                        ,       DataType             datatype
1456                        ,       Status&              status
1457                        ,       XMLVersion           version
1458                        ,       bool                 toValidate
1459                        ,       MemoryManager* const manager)
1460{
1461    switch (datatype) {
1462        case XSValue::dt_boolean:
1463            {
1464            XMLCh* tmpStrValue = XMLString::replicate(content, manager);
1465            ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
1466            XMLString::trim(tmpStrValue);
1467            //do validation here more efficiently
1468            if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[0]) ||
1469                XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[2])  )
1470            {
1471                XSValue* retVal = new (manager) XSValue(dt_boolean, manager);
1472                retVal->fData.fValue.f_bool = false;
1473                return retVal;
1474            }
1475            else if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[1]) ||
1476                     XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[3])  )
1477            {
1478                XSValue* retVal = new (manager) XSValue(dt_boolean, manager);
1479                retVal->fData.fValue.f_bool = true;
1480                return retVal;
1481            }
1482            else
1483            {
1484                status = st_FOCA0002;
1485                return 0;
1486            }
1487            }
1488            break;
1489        case XSValue::dt_hexBinary:
1490            {
1491                XMLCh* tmpStrValue = XMLString::replicate(content, manager);
1492                ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
1493                XMLString::trim(tmpStrValue);
1494
1495                XMLByte* decodedData = HexBin::decodeToXMLByte(tmpStrValue, manager);
1496
1497                if (!decodedData)
1498                {
1499                    status = st_FOCA0002;
1500                    return 0;
1501                }
1502
1503                XSValue* retVal = new (manager) XSValue(dt_hexBinary, manager);
1504                retVal->fData.fValue.f_byteVal = decodedData;
1505                retVal->fMemAllocated = true;
1506                return retVal;
1507                break;
1508            }
1509        case XSValue::dt_base64Binary:
1510            {
1511                XMLSize_t len = 0;
1512                XMLByte* decodedData = Base64::decodeToXMLByte(content, &len, manager);
1513
1514                if (!decodedData)
1515                {
1516                    status = st_FOCA0002;
1517                    return 0;
1518                }
1519
1520                XSValue* retVal = new (manager) XSValue(dt_base64Binary, manager);
1521                retVal->fData.fValue.f_byteVal = decodedData;
1522                retVal->fMemAllocated = true;
1523                return retVal;
1524                break;
1525            }
1526        case XSValue::dt_anyURI:
1527        case XSValue::dt_QName:
1528        case XSValue::dt_NOTATION:
1529        case XSValue::dt_string:
1530        case XSValue::dt_normalizedString:
1531        case XSValue::dt_token:
1532        case XSValue::dt_language:
1533        case XSValue::dt_NMTOKEN:
1534        case XSValue::dt_NMTOKENS:
1535        case XSValue::dt_Name:
1536        case XSValue::dt_NCName:
1537        case XSValue::dt_ID:
1538        case XSValue::dt_IDREF:
1539        case XSValue::dt_ENTITY:
1540        case XSValue::dt_ENTITIES:
1541        case XSValue::dt_IDREFS:
1542            if (toValidate && !validateStrings(content, datatype, status, version, manager))
1543                status = st_FOCA0002;
1544            else
1545                status = st_NoActVal;
1546
1547            return 0;
1548            break;
1549        default:
1550            return 0;
1551            break;
1552    }
1553
1554    return 0;
1555}
1556
1557// ---------------------------------------------------------------------------
1558//  Utilities
1559// ---------------------------------------------------------------------------
1560bool XSValue::getActualNumericValue(const XMLCh*  const content
1561                           ,       Status&              status
1562                           ,       t_value&             retVal
1563                           ,       MemoryManager* const manager
1564                           ,       DataType             datatype)
1565{
1566    char *nptr = XMLString::transcode(content, manager);
1567    ArrayJanitor<char> jan(nptr, manager);
1568    char *endptr = 0;
1569    errno = 0;
1570
1571    if (XSValue::numericSign[datatype])
1572    {
1573        retVal.f_long = strtol(nptr, &endptr, (int)10);
1574    }
1575    else
1576    {
1577        if (XMLString::indexOf(content, chDash) != -1)
1578        {
1579            status = st_FOCA0002; //invalid lexcial value
1580            return false;
1581        }
1582
1583        retVal.f_ulong = strtoul(nptr, &endptr, (int)10);
1584    }
1585
1586    // need to check out-of-bounds before checking erange...
1587    switch (datatype) {
1588        case XSValue::dt_nonPositiveInteger:
1589            if (retVal.f_long > 0)
1590            {
1591                status = st_FOCA0002;
1592                return false;
1593            }
1594            break;
1595        case XSValue::dt_negativeInteger:
1596            if (retVal.f_long >= 0)
1597            {
1598                status = st_FOCA0002;
1599                return false;
1600            }
1601            break;
1602        case XSValue::dt_int:
1603            // strtol will set value to LONG_MIN/LONG_MAX if ERANGE error
1604            if ((retVal.f_long < INT_MIN) ||
1605                (retVal.f_long > INT_MAX) ||
1606                (errno == ERANGE))
1607            {
1608                status = st_FOCA0002;
1609                return false;
1610            }
1611            break;
1612        case XSValue::dt_short:
1613            if ((retVal.f_long < SHRT_MIN) ||
1614                (retVal.f_long > SHRT_MAX))
1615            {
1616                status = st_FOCA0002;
1617                return false;
1618            }
1619            break;
1620        case XSValue::dt_byte:
1621            if ((retVal.f_long < SCHAR_MIN) ||
1622                (retVal.f_long > SCHAR_MAX))
1623            {
1624                status = st_FOCA0002;
1625                return false;
1626            }
1627            break;
1628        case XSValue::dt_unsignedInt:
1629            // strtoul will set value to LONG_INT if ERANGE error
1630            if ((retVal.f_ulong > UINT_MAX)  ||
1631                (errno == ERANGE))
1632            {
1633                status = st_FOCA0002;
1634                return false;
1635            }
1636            break;
1637        case XSValue::dt_unsignedShort:
1638            if (retVal.f_ulong > USHRT_MAX)
1639            {
1640                status = st_FOCA0002;
1641                return false;
1642            }
1643            break;
1644        case XSValue::dt_unsignedByte:
1645            if (retVal.f_ulong > UCHAR_MAX)
1646            {
1647                status = st_FOCA0002;
1648                return false;
1649            }
1650            break;
1651        case XSValue::dt_positiveInteger:
1652            if (retVal.f_ulong == 0)
1653            {
1654                status = st_FOCA0002;
1655                return false;
1656            }
1657            break;
1658        default:
1659            break;
1660    } // end switch
1661    // check if overflow/underflow occurs
1662    if (errno == ERANGE)
1663    {
1664        status = st_FOCA0003;
1665        return false;
1666    }
1667
1668    // check if all chars are valid char.  If they are, endptr will
1669    // pointer to the null terminator, or all of the remaining
1670    // characters will be whitespace characters.
1671    while (*endptr != '\0')
1672    {
1673        const char  ch = *endptr;
1674
1675        if (ch == '\t' || ch == '\n' || ch == '\r' || ch == ' ')
1676        {
1677            ++endptr;
1678        }
1679        else
1680        {
1681            status = st_FOCA0002;
1682            return false;
1683        }
1684
1685    }
1686    return true;
1687}
1688
1689XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.