GME  13
XSValue.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  *
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: XSValue.cpp 932887 2010-04-11 13:04:59Z borisk $
00020  */
00021 
00022 #include <limits.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <ctype.h>
00026 #include <math.h>
00027 #include <float.h>
00028 
00029 #include <xercesc/framework/psvi/XSValue.hpp>
00030 
00031 #include <xercesc/util/XMLString.hpp>
00032 #include <xercesc/util/XMLStringTokenizer.hpp>
00033 
00034 #include <xercesc/util/XMLBigDecimal.hpp>
00035 #include <xercesc/util/XMLBigInteger.hpp>
00036 #include <xercesc/util/XMLFloat.hpp>
00037 #include <xercesc/util/XMLDouble.hpp>
00038 #include <xercesc/util/XMLDateTime.hpp>
00039 #include <xercesc/util/HexBin.hpp>
00040 #include <xercesc/util/Base64.hpp>
00041 #include <xercesc/util/XMLUri.hpp>
00042 #include <xercesc/util/XMLChar.hpp>
00043 #include <xercesc/util/Janitor.hpp>
00044 #include <xercesc/util/XMLInitializer.hpp>
00045 #include <xercesc/util/regx/RegularExpression.hpp>
00046 #include <xercesc/validators/schema/SchemaSymbols.hpp>
00047 #include <xercesc/util/OutOfMemoryException.hpp>
00048 #include <xercesc/util/TransService.hpp>
00049 #include <xercesc/util/NumberFormatException.hpp>
00050 
00051 XERCES_CPP_NAMESPACE_BEGIN
00052 
00053 /*** issues
00054  *
00055  *   1. For float, double, datetime family, the validation is almost similar to getActualValue
00056  *
00057  *
00058  *   DataType                   DataGroup
00059  *                             num  dtm  str             validation           canonical      actual-value
00060  *   ======================================================================================================
00061  *    dt_string                          str              [2] Char              NA             content
00062  *    dt_boolean                         str           {true, false, 1, 0}   {true, false}    bool
00063  *    dt_decimal               num                         lexical only         yes            double
00064  *    dt_float                 num                         lexical/value        yes            double
00065  *    dt_double                num                         lexical/value        yes            double
00066  *    ---------------------------------------------------------------------------------------------------------
00067  * 5  dt_duration                   dtm                    yes                  NA             struct datetime
00068  *    dt_dateTime                   dtm                    yes                  yes            struct datetime
00069  *    dt_time                       dtm                    yes                  yes            struct datetime
00070  *    dt_date                       dtm                    yes                  NA             struct datetime
00071  *    dt_gYearMonth                 dtm                    yes                  NA             struct datetime
00072  *    ---------------------------------------------------------------------------------------------------------
00073  * 10 dt_gYear                      dtm                    yes                  NA             struct datetime
00074  *    dt_gMonthDay                  dtm                    yes                  NA             struct datetime
00075  *    dt_gDay                       dtm                    yes                  NA             struct datetime
00076  *    dt_gMonth                     dtm                    yes                  NA             struct datetime
00077  *    dt_hexBinary                        str              decoding            ([a-f])         unsigned long ?
00078  *    ---------------------------------------------------------------------------------------------------------
00079  * 15 dt_base64Binary                     str              decoding             NA (errata?)   unsigned long ?
00080  *    dt_anyURI                           str              yes                  NA             content
00081  *    dt_QName                            str              a:b , [6]QName       NA             content
00082  *    dt_NOTATION                         str              [6]QName             NA             content
00083  *    dt_normalizedString                 str              no #xD #xA #x9       NA             content
00084  *    ---------------------------------------------------------------------------------------------------------
00085  * 20 dt_token                            str              no #xD #xA #x9 traling   NA         content
00086  *    dt_language                         str              language id          NA             content
00087  *    dt_NMTOKEN                          str              [7] Nmtoken          NA             content
00088  *    dt_NMTOKENS                         str              [8] Nmtokens         NA             content
00089  *    dt_Name                             str              [5] Name             NA             content
00090  *    ---------------------------------------------------------------------------------------------------------
00091  * 25 dt_NCName                           str              [4] NCName           NA             content
00092  *    dt_ID                               str              [4] NCName           NA             content
00093  *    dt_IDREF                            str              [4] NCName           NA             content
00094  *    dt_IDREFS                           str              ws seped IDREF       NA             content
00095  *    dt_ENTITY                           str              [4] NCName           NA             content
00096  *    ---------------------------------------------------------------------------------------------------------
00097  * 30 dt_ENTITIES                         str              ws seped ENTITY      NA             content
00098  *    dt_integer               num                         lexical              yes            long
00099  *    dt_nonPositiveInteger    num                         lexical              yes            long
00100  *    dt_negativeInteger       num                         lexical              yes            long
00101  *    dt_long                  num                         lexical              yes            long
00102  *    ---------------------------------------------------------------------------------------------------------
00103  * 35 dt_int                   num                         lexical              yes            int
00104  *    dt_short                 num                         lexical              yes            short
00105  *    dt_byte                  num                         lexical              yes            char
00106  *    dt_nonNegativeInteger    num                         lexical              yes            unsigned long
00107  *    dt_unsignedLong          num                         lexical              yes            unsigned long
00108  *    ---------------------------------------------------------------------------------------------------------
00109  * 40 dt_unsignedInt           num                         lexical              yes            unsigned int
00110  *    dt_unsignedShort         num                         lexical              yes            unsigned short
00111  *    dt_unsignedByte          num                         lexical              yes            unsigned char
00112  *    dt_positiveInteger       num                         lexical              yes            unsigned long
00113  *
00114  ***/
00115 
00116 const XSValue::DataGroup XSValue::inGroup[XSValue::dt_MAXCOUNT] =
00117 {
00118     dg_strings,   dg_strings,   dg_numerics,  dg_numerics,  dg_numerics,
00119     dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes,
00120     dg_datetimes, dg_datetimes, dg_datetimes, dg_datetimes, dg_strings,
00121     dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,
00122     dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,
00123     dg_strings,   dg_strings,   dg_strings,   dg_strings,   dg_strings,
00124     dg_strings,   dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,
00125     dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics,
00126     dg_numerics,  dg_numerics,  dg_numerics,  dg_numerics
00127 };
00128 
00129 const bool XSValue::numericSign[XSValue::dt_MAXCOUNT] =
00130 {
00131     true, true, true, true, true,
00132     true, true, true, true, true,
00133     true, true, true, true, true,
00134     true, true, true, true, true,
00135     true, true, true, true, true,
00136     true, true, true, true, true,
00137     true, true, true, true, true,
00138     true, true, true, false, false,
00139     false, false, false, false
00140 };
00141 
00142 // ---------------------------------------------------------------------------
00143 //  Local static functions
00144 // ---------------------------------------------------------------------------
00145 static RegularExpression* sXSValueRegEx = 0;
00146 ValueHashTableOf<XSValue::DataType>*  XSValue::fDataTypeRegistry = 0;
00147 
00148 void XMLInitializer::initializeXSValue()
00149 {
00150     sXSValueRegEx = new RegularExpression(
00151       XMLUni::fgLangPattern, SchemaSymbols::fgRegEx_XOption);
00152 
00153     XSValue::initializeRegistry();
00154 }
00155 
00156 void XMLInitializer::terminateXSValue()
00157 {
00158     delete XSValue::fDataTypeRegistry;
00159     XSValue::fDataTypeRegistry = 0;
00160 
00161     delete sXSValueRegEx;
00162     sXSValueRegEx = 0;
00163 }
00164 
00165 XSValue::DataType  XSValue::getDataType(const XMLCh* const dtString)
00166 {
00167     if (fDataTypeRegistry->containsKey(dtString)) {
00168         return fDataTypeRegistry->get(dtString);
00169     }
00170 
00171     return dt_MAXCOUNT;
00172 }
00173 
00174 void XSValue::initializeRegistry()
00175 {
00176     //using the XMLPlatformUtils::fgMemoryManager
00177     fDataTypeRegistry  = new ValueHashTableOf<XSValue::DataType>(43);
00178 
00179     if (fDataTypeRegistry) {
00180         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_STRING,             XSValue::dt_string);
00181         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_BOOLEAN,            XSValue::dt_boolean);
00182         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DECIMAL,            XSValue::dt_decimal);
00183         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_FLOAT,              XSValue::dt_float);
00184         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DOUBLE,             XSValue::dt_double);
00185         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DURATION,           XSValue::dt_duration);
00186         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DATETIME,           XSValue::dt_dateTime);
00187         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_TIME,               XSValue::dt_time);
00188         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DATE,               XSValue::dt_date);
00189         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_YEARMONTH,          XSValue::dt_gYearMonth);
00190         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_YEAR,               XSValue::dt_gYear);
00191         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_MONTHDAY,           XSValue::dt_gMonthDay);
00192         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_DAY,                XSValue::dt_gDay);
00193         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_MONTH,              XSValue::dt_gMonth);
00194         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_HEXBINARY,          XSValue::dt_hexBinary);
00195         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_BASE64BINARY,       XSValue::dt_base64Binary);
00196         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_ANYURI,             XSValue::dt_anyURI);
00197         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_QNAME,              XSValue::dt_QName);
00198         fDataTypeRegistry->put((void*) XMLUni::fgNotationString,               XSValue::dt_NOTATION);
00199         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NORMALIZEDSTRING,   XSValue::dt_normalizedString);
00200         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_TOKEN,              XSValue::dt_token);
00201         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_LANGUAGE,           XSValue::dt_language);
00202         fDataTypeRegistry->put((void*) XMLUni::fgNmTokenString,                XSValue::dt_NMTOKEN);
00203         fDataTypeRegistry->put((void*) XMLUni::fgNmTokensString,               XSValue::dt_NMTOKENS);
00204         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NAME,               XSValue::dt_Name);
00205         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NCNAME,             XSValue::dt_NCName);
00206         fDataTypeRegistry->put((void*) XMLUni::fgIDString,                     XSValue::dt_ID);
00207         fDataTypeRegistry->put((void*) XMLUni::fgIDRefString,                  XSValue::dt_IDREF);
00208         fDataTypeRegistry->put((void*) XMLUni::fgIDRefsString,                 XSValue::dt_IDREFS);
00209         fDataTypeRegistry->put((void*) XMLUni::fgEntityString,                 XSValue::dt_ENTITY);
00210         fDataTypeRegistry->put((void*) XMLUni::fgEntitiesString,               XSValue::dt_ENTITIES);
00211         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_INTEGER,            XSValue::dt_integer);
00212         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NONPOSITIVEINTEGER, XSValue::dt_nonPositiveInteger);
00213         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NEGATIVEINTEGER,    XSValue::dt_negativeInteger);
00214         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_LONG,               XSValue::dt_long);
00215         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_INT,                XSValue::dt_int);
00216         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_SHORT,              XSValue::dt_short);
00217         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_BYTE,               XSValue::dt_byte);
00218         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_NONNEGATIVEINTEGER, XSValue::dt_nonNegativeInteger);
00219         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_ULONG,              XSValue::dt_unsignedLong);
00220         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_UINT,               XSValue::dt_unsignedInt);
00221         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_USHORT,             XSValue::dt_unsignedShort);
00222         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_UBYTE,              XSValue::dt_unsignedByte);
00223         fDataTypeRegistry->put((void*) SchemaSymbols::fgDT_POSITIVEINTEGER,    XSValue::dt_positiveInteger);
00224     }
00225 }
00226 
00227 static bool checkTimeZoneError(XSValue::DataType       const &datatype
00228                              , SchemaDateTimeException const &e       )
00229 {
00230     return (((datatype == XSValue::dt_dateTime) || (datatype == XSValue::dt_time) || (datatype == XSValue::dt_date)) &&
00231             ((e.getCode() == XMLExcepts::DateTime_tz_noUTCsign)   ||
00232              (e.getCode() == XMLExcepts::DateTime_tz_stuffAfterZ) ||
00233              (e.getCode() == XMLExcepts::DateTime_tz_invalid)     ||
00234              (e.getCode() == XMLExcepts::DateTime_tz_hh_invalid)));
00235 }
00236 
00237 // ---------------------------------------------------------------------------
00238 //  Local Data
00239 // ---------------------------------------------------------------------------
00240 
00241 static const XMLCh Separator_20[] = {chSpace, chNull};
00242 static const XMLCh Separator_ws[] = {chSpace, chLF, chCR, chHTab, chNull};
00243 
00244 // ---------------------------------------------------------------------------
00245 //  XSValue: Constructors and Destructor
00246 // ---------------------------------------------------------------------------
00247 XSValue::XSValue(DataType        const dt
00248                , MemoryManager*  const manager)
00249     :fMemAllocated(false)
00250     ,fMemoryManager(manager)
00251 {
00252     fData.f_datatype = dt;
00253 }
00254 
00255 XSValue::~XSValue()
00256 {
00257     if (fMemAllocated)
00258         fMemoryManager->deallocate(fData.fValue.f_byteVal);
00259 }
00260 
00261 // ---------------------------------------------------------------------------
00262 //  XSValue: Public Interface
00263 //
00264 //    No exception is thrown from these methods
00265 //
00266 // ---------------------------------------------------------------------------
00267 bool XSValue::validate(const XMLCh*         const content
00268                       ,      DataType             datatype
00269                       ,      Status&              status
00270                       ,      XMLVersion           version
00271                       ,      MemoryManager* const manager)
00272 {
00273     if (!content ||
00274         !*content ||
00275         ((version == ver_10) && (XMLChar1_0::isAllSpaces(content, XMLString::stringLen(content)))) ||
00276         ((version == ver_11) && (XMLChar1_1::isAllSpaces(content, XMLString::stringLen(content)))) ) {
00277 
00278         switch (datatype) {
00279         case XSValue::dt_string:
00280         case XSValue::dt_normalizedString:
00281         case XSValue::dt_token:
00282         case XSValue::dt_anyURI:
00283         case XSValue::dt_hexBinary:
00284         case XSValue::dt_base64Binary:
00285             status = st_Init;
00286             return true;
00287             break;
00288         default:
00289             status = st_NoContent;
00290             return false;
00291             break;
00292         }
00293     }
00294 
00295     status = st_Init;
00296 
00297     switch (inGroup[datatype]) {
00298     case XSValue::dg_numerics:
00299         return validateNumerics(content, datatype, status, manager);
00300         break;
00301     case XSValue::dg_datetimes:
00302         return validateDateTimes(content, datatype, status, manager);
00303         break;
00304     case XSValue::dg_strings:
00305         return validateStrings(content, datatype, status, version, manager);
00306         break;
00307     default:
00308         status = st_UnknownType;
00309 
00310         return false;
00311         break;
00312     }
00313     return false;
00314 }
00315 
00316 XMLCh*
00317 XSValue::getCanonicalRepresentation(const XMLCh*         const content
00318                                    ,      DataType             datatype
00319                                    ,      Status&              status
00320                                    ,      XMLVersion           version
00321                                    ,      bool                 toValidate
00322                                    ,      MemoryManager* const manager)
00323 {
00324     if (!content ||
00325         !*content ||
00326         ((version == ver_10) && (XMLChar1_0::isAllSpaces(content, XMLString::stringLen(content)))) ||
00327         ((version == ver_11) && (XMLChar1_1::isAllSpaces(content, XMLString::stringLen(content)))) ) {
00328         status = st_NoContent;
00329         return 0;
00330     }
00331 
00332     status = st_Init;
00333 
00334     switch (inGroup[datatype]) {
00335     case XSValue::dg_numerics:
00336         return getCanRepNumerics(content, datatype,  status, toValidate, manager);
00337         break;
00338     case XSValue::dg_datetimes:
00339         return getCanRepDateTimes(content, datatype,  status, toValidate, manager);
00340         break;
00341     case XSValue::dg_strings:
00342         return getCanRepStrings(content, datatype,  status, version, toValidate, manager);
00343         break;
00344     default:
00345         status = st_UnknownType;
00346 
00347         return 0;
00348         break;
00349     }
00350     return 0;
00351 }
00352 
00353 XSValue* XSValue::getActualValue(const XMLCh*         const content
00354                                ,       DataType             datatype
00355                                ,       Status&              status
00356                                ,       XMLVersion           version
00357                                ,       bool                 toValidate
00358                                ,       MemoryManager* const manager)
00359 {
00360     if (!content ||
00361         !*content ||
00362         ((version == ver_10) && (XMLChar1_0::isAllSpaces(content, XMLString::stringLen(content)))) ||
00363         ((version == ver_11) && (XMLChar1_1::isAllSpaces(content, XMLString::stringLen(content)))) ) {
00364         status = st_NoContent;
00365         return 0;
00366     }
00367 
00368     status = st_Init;
00369 
00370     switch (inGroup[datatype]) {
00371     case XSValue::dg_numerics:
00372         return getActValNumerics(content, datatype,  status, toValidate, manager);
00373         break;
00374     case XSValue::dg_datetimes:
00375         return getActValDateTimes(content, datatype,  status, manager);
00376         break;
00377     case XSValue::dg_strings:
00378         return getActValStrings(content, datatype,  status, version, toValidate, manager);
00379         break;
00380     default:
00381         status = st_UnknownType;
00382         return 0;
00383         break;
00384     }
00385     return 0;
00386 }
00387 
00388 // ---------------------------------------------------------------------------
00389 //  XSValue: Helpers
00390 // ---------------------------------------------------------------------------
00391 
00392 /***
00393  *
00394  *  Boundary checking is done against Schema Type's lexcial space
00395  ***/
00396 bool
00397 XSValue::validateNumerics(const XMLCh*         const content
00398                         ,       DataType             datatype
00399                         ,       Status&              status
00400                         ,       MemoryManager* const manager)
00401 {
00402 
00403     try {
00404 
00405         switch (datatype) {
00406         case XSValue::dt_decimal:
00407             XMLBigDecimal::parseDecimal(content, manager);
00408             break;
00409         case XSValue::dt_float:
00410             {
00411                 //XMLFloat takes care of 0, -0, -INF, INF and NaN
00412                 //XMLFloat::checkBoundary() handles error and outofbound issues
00413                 XMLFloat data(content, manager);
00414                 break;
00415             }
00416         case XSValue::dt_double:
00417             {
00418                 //XMLDouble takes care of 0, -0, -INF, INF and NaN
00419                 //XMLDouble::checkBoundary() handles error and outofbound issues
00420                 XMLDouble  data(content, manager);
00421                 break;
00422             }
00423         /***
00424          *   For all potentially unrepresentable types
00425          *
00426          *   For dt_long, dt_unsignedLong, doing lexical space
00427          *   checking ensures consistent behaviour on 32/64 boxes
00428          *
00429          ***/
00430         case XSValue::dt_integer:
00431         case XSValue::dt_negativeInteger:
00432         case XSValue::dt_nonPositiveInteger:
00433         case XSValue::dt_nonNegativeInteger:
00434         case XSValue::dt_positiveInteger:
00435         case XSValue::dt_long:
00436         case XSValue::dt_unsignedLong:
00437             {
00438                 XMLCh* compareData = (XMLCh*) manager->allocate((XMLString::stringLen(content) + 1) * sizeof(XMLCh));
00439                 ArrayJanitor<XMLCh> janName(compareData, manager);
00440                 int    signValue = 0;
00441                 XMLBigInteger::parseBigInteger(content, compareData, signValue,  manager);
00442 
00443                 switch (datatype) {
00444                 case XSValue::dt_integer:
00445                     //error: no
00446                     break;
00447                 case XSValue::dt_negativeInteger:
00448                     // error: > -1
00449                     if  (XMLBigInteger::compareValues(compareData
00450                                                     , signValue
00451                                                     , &(XMLUni::fgNegOne[1])
00452                                                     , -1
00453                                                     , manager)
00454                                                     == XMLNumber::GREATER_THAN)
00455                     {
00456                         status = st_FOCA0002;
00457                         return false;
00458                     }
00459                     break;
00460                 case XSValue::dt_nonPositiveInteger:
00461                     // error: > 0
00462                      if (XMLBigInteger::compareValues(compareData
00463                                                    , signValue
00464                                                    , XMLUni::fgValueZero
00465                                                    , 0
00466                                                    , manager)
00467                                                    == XMLNumber::GREATER_THAN)
00468                     {
00469                         status = st_FOCA0002;
00470                         return false;
00471                     }
00472                     break;
00473                 case XSValue::dt_nonNegativeInteger:
00474                     // error: < 0
00475                     if (XMLBigInteger::compareValues(compareData
00476                                                    , signValue
00477                                                    , XMLUni::fgValueZero
00478                                                    , 0
00479                                                    , manager)
00480                                                    == XMLNumber::LESS_THAN)
00481                     {
00482                         status = st_FOCA0002;
00483                         return false;
00484                     }
00485                     break;
00486                 case XSValue::dt_positiveInteger:
00487                     // error: < 1
00488                     if (XMLBigInteger::compareValues(compareData
00489                                                    , signValue
00490                                                    , XMLUni::fgValueOne
00491                                                    , 1
00492                                                    , manager)
00493                                                    == XMLNumber::LESS_THAN)
00494                     {
00495                         status = st_FOCA0002;
00496                         return false;
00497                     }
00498                     break;
00499                 case XSValue::dt_long:
00500                     // error: < -9223372036854775808 || > 9223372036854775807
00501                     if ((XMLBigInteger::compareValues(compareData
00502                                                     , signValue
00503                                                     , &(XMLUni::fgLongMinInc[1])
00504                                                     , -1
00505                                                     , manager)
00506                                                     == XMLNumber::LESS_THAN) ||
00507                         (XMLBigInteger::compareValues(compareData
00508                                                     , signValue
00509                                                     , XMLUni::fgLongMaxInc
00510                                                     , 1
00511                                                     , manager)
00512                                                     == XMLNumber::GREATER_THAN))
00513                     {
00514                         status = st_FOCA0002;
00515                         return false;
00516                     }
00517                     break;
00518                 case XSValue::dt_unsignedLong:
00519                     // error: < 0 || > 18446744073709551615
00520                     if ((XMLBigInteger::compareValues(compareData
00521                                                     , signValue
00522                                                     , XMLUni::fgValueZero
00523                                                     , 0
00524                                                     , manager)
00525                                                     == XMLNumber::LESS_THAN) ||
00526                         (XMLBigInteger::compareValues(compareData
00527                                                     , signValue
00528                                                     , XMLUni::fgULongMaxInc
00529                                                     , 1
00530                                                     , manager)
00531                                                     == XMLNumber::GREATER_THAN))
00532                     {
00533                         status = st_FOCA0002;
00534                         return false;
00535                     }
00536                     break;
00537                 default:
00538                     status = st_NotSupported;
00539                     return false;
00540                     break;
00541                 }
00542                 break;
00543             }
00544         case XSValue::dt_int:
00545         case XSValue::dt_short:
00546         case XSValue::dt_byte:
00547         case XSValue::dt_unsignedInt:
00548         case XSValue::dt_unsignedShort:
00549         case XSValue::dt_unsignedByte:
00550             {
00551                 t_value   actVal;
00552 
00553                 if ( !getActualNumericValue(
00554                                   content
00555                                 , status
00556                                 , actVal
00557                                 , manager
00558                                 , datatype
00559                                  )
00560                 )
00561                 {
00562                     return false;
00563                 }
00564                 break;
00565             }
00566         default:
00567             return false;
00568         } // end switch
00569     }
00570     catch (const NumberFormatException&)
00571     {
00572         //getActValue()/getCanonical() need to know the failure details
00573         //if validation is required
00574         status = st_FOCA0002;
00575         return false;
00576     }
00577     return true;  //both valid chars and within boundary
00578 }
00579 
00580 bool XSValue::validateDateTimes(const XMLCh*         const input_content
00581                               ,       DataType             datatype
00582                               ,       Status&              status
00583                               ,       MemoryManager* const manager)
00584 {
00585     XMLCh* content = XMLString::replicate(input_content, manager);
00586     ArrayJanitor<XMLCh> janTmpName(content, manager);
00587     XMLString::trim(content);
00588     try
00589     {
00590         XMLDateTime coreDate = XMLDateTime(content, manager);
00591 
00592         switch (datatype) {
00593         case XSValue::dt_duration:
00594             coreDate.parseDuration();
00595             break;
00596         case XSValue::dt_dateTime:
00597             coreDate.parseDateTime();
00598             break;
00599         case XSValue::dt_time:
00600             coreDate.parseTime();
00601             break;
00602         case XSValue::dt_date:
00603             coreDate.parseDate();
00604             break;
00605         case XSValue::dt_gYearMonth:
00606             coreDate.parseYearMonth();
00607             break;
00608         case XSValue::dt_gYear:
00609             coreDate.parseYear();
00610             break;
00611         case XSValue::dt_gMonthDay:
00612             coreDate.parseMonthDay();
00613             break;
00614         case XSValue::dt_gDay:
00615             coreDate.parseDay();
00616             break;
00617         case XSValue::dt_gMonth:
00618             coreDate.parseMonth();
00619             break;
00620         default:
00621             return false;
00622             break;
00623         }
00624     }
00625 
00626     catch (const SchemaDateTimeException &e)
00627     {
00628         status = checkTimeZoneError(datatype, e)? XSValue::st_FODT0003 : st_FOCA0002;
00629         return false;
00630     }
00631     catch (const NumberFormatException&)
00632     {
00633         //getActValue()/getCanonical() need to know the failure details
00634         //if validation is required
00635         status = st_FOCA0002;
00636         return false;
00637     }
00638 
00639     return true; //parsing succeed
00640 }
00641 
00642 bool XSValue::validateStrings(const XMLCh*         const content
00643                             ,       DataType             datatype
00644                             ,       Status&              status
00645                             ,       XMLVersion           version
00646                             ,       MemoryManager* const manager)
00647 {
00648     bool isValid = true;
00649 
00650     switch (datatype) {
00651         case XSValue::dt_boolean:
00652             {
00653                 XMLSize_t i = 0;
00654                 XMLCh* tmpStrValue = XMLString::replicate(content, manager);
00655                 ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
00656                 XMLString::trim(tmpStrValue);
00657                 for (; i < XMLUni::fgBooleanValueSpaceArraySize; i++) {
00658                     if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[i]))
00659                         break;
00660                 }
00661 
00662                 if (XMLUni::fgBooleanValueSpaceArraySize == i) {
00663                     isValid = false;
00664                 }
00665                 break;
00666             }
00667         case XSValue::dt_hexBinary:
00668             {
00669             XMLCh* tmpStrValue = XMLString::replicate(content, manager);
00670             ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
00671             XMLString::trim(tmpStrValue);
00672             if (HexBin::getDataLength(tmpStrValue) == -1) {
00673                isValid = false;
00674             }
00675             }
00676             break;
00677         case XSValue::dt_base64Binary:
00678             if (Base64::getDataLength(content, manager) == -1) {
00679                 isValid = false;
00680             }
00681             break;
00682         case XSValue::dt_anyURI:
00683             if (XMLUri::isValidURI(true, content, true) == false) {
00684                 isValid = false;
00685             }
00686             break;
00687         case XSValue::dt_QName:
00688             {
00689             XMLCh* tmpStrValue = XMLString::replicate(content, manager);
00690             ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
00691             XMLString::trim(tmpStrValue);
00692             isValid = (version == ver_10) ?
00693                 XMLChar1_0::isValidQName(tmpStrValue, XMLString::stringLen(tmpStrValue)) :
00694                 XMLChar1_1::isValidQName(tmpStrValue, XMLString::stringLen(tmpStrValue));
00695             }
00696             break;
00697         case XSValue::dt_NOTATION:
00698             {
00699             XMLCh* tmpStrValue = XMLString::replicate(content, manager);
00700             ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
00701             XMLString::trim(tmpStrValue);
00702             if ( XMLString::isValidNOTATION(tmpStrValue, manager) == false) {
00703                 isValid = false;
00704             }
00705             }
00706             break;
00707         case XSValue::dt_string:
00708             {
00709                 const XMLCh*   rawPtr = content;
00710 
00711                 if (version == ver_10) {
00712                     while (*rawPtr)
00713                         if (!XMLChar1_0::isXMLChar(*rawPtr++)) {
00714                             isValid = false;
00715                             break;
00716                         }
00717                 }
00718                 else {
00719                     while (*rawPtr)
00720                         if (!XMLChar1_1::isXMLChar(*rawPtr++)) {
00721                             isValid = false;
00722                             break;
00723                         }
00724                 }
00725                 break;
00726             }
00727         case XSValue::dt_normalizedString:
00728             {
00729                 const XMLCh*   rawPtr = content;
00730 
00731                 if (version == ver_10) {
00732                     while (*rawPtr) {
00733                         if (!XMLChar1_0::isXMLChar(*rawPtr)) {
00734                             isValid = false;
00735                             break;
00736                         }
00737                         else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
00738                             isValid = false;
00739                             break;
00740                         }
00741                         else {
00742                             rawPtr++;
00743                         }
00744                     }
00745                 }
00746                 else {
00747                     while (*rawPtr) {
00748                         if (!XMLChar1_1::isXMLChar(*rawPtr)) {
00749                             isValid = false;
00750                             break;
00751                         }
00752                         else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
00753                             isValid = false;
00754                             break;
00755                         }
00756                         else {
00757                             rawPtr++;
00758                         }
00759 
00760                     }
00761                 }
00762                 break;
00763             }
00764         case XSValue::dt_token:
00765         case XSValue::dt_language:
00766             {
00767                 XMLSize_t     strLen = XMLString::stringLen(content);
00768                 const XMLCh*  rawPtr = content;
00769                 bool     inWS = false;
00770 
00771                 if (version == ver_10) {
00772                     // Check leading/Trailing white space
00773                     if (XMLChar1_0::isWhitespace(content[0])      ||
00774                         XMLChar1_0::isWhitespace(content[strLen - 1])  ) {
00775                         isValid = false;
00776                     }
00777                     else {
00778                         while (*rawPtr) {
00779                             if (!XMLChar1_0::isXMLChar(*rawPtr)) {
00780                                 isValid = false;
00781                                 break;
00782                             }
00783                             else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
00784                                 isValid = false;
00785                                 break;
00786                             }
00787                             else if (XMLChar1_0::isWhitespace(*rawPtr)) {
00788                                 if (inWS) {
00789                                     isValid = false;
00790                                     break;
00791                                 }
00792                                 else {
00793                                     inWS = true;
00794                                 }
00795                             }
00796                             else {
00797                                 inWS = false;
00798                             }
00799 
00800                             rawPtr++;
00801                         }
00802                     }
00803                 }
00804                 else {
00805                     // Check leading/Trailing white space
00806                     if (XMLChar1_1::isWhitespace(content[0])      ||
00807                         XMLChar1_1::isWhitespace(content[strLen - 1])  ) {
00808                         isValid = false;
00809                     }
00810                     else {
00811                         while (*rawPtr) {
00812                             if (!XMLChar1_1::isXMLChar(*rawPtr)) {
00813                                 isValid = false;
00814                                 break;
00815                             }
00816                             else if (*rawPtr == chCR || *rawPtr == chLF || *rawPtr == chHTab) {
00817                                 isValid = false;
00818                                 break;
00819                             }
00820                             else if (XMLChar1_1::isWhitespace(*rawPtr)) {
00821                                 if (inWS) {
00822                                     isValid = false;
00823                                     break;
00824                                 }
00825                                 else {
00826                                     inWS = true;
00827                                 }
00828                             }
00829                             else {
00830                                 inWS = false;
00831                             }
00832                             rawPtr++;
00833                         }
00834                     }
00835                 }
00836                 if (isValid == true && datatype == XSValue::dt_language) {
00837                     if (!sXSValueRegEx) {
00838                         status = st_CantCreateRegEx;
00839                         isValid = false;
00840                     }
00841                     else
00842                     {
00843                         if (sXSValueRegEx->matches(content, manager) == false)
00844                         {
00845                             isValid = false;
00846                         }
00847                     }
00848                 }
00849                 break;
00850             }
00851         case XSValue::dt_NMTOKEN:
00852             isValid = (version == ver_10) ?
00853                 XMLChar1_0::isValidNmtoken(content, XMLString::stringLen(content)) :
00854                 XMLChar1_1::isValidNmtoken(content, XMLString::stringLen(content));
00855             break;
00856         case XSValue::dt_NMTOKENS:
00857             // [8]    Nmtokens   ::=    Nmtoken (#x20 Nmtoken)*
00858             {
00859                 XMLStringTokenizer tokenizer(content, Separator_20, manager);
00860 
00861                 if (version ==  ver_10) {
00862                     while (tokenizer.hasMoreTokens()) {
00863                         const XMLCh* token = tokenizer.nextToken();
00864 
00865                         if (!XMLChar1_0::isValidNmtoken(token, XMLString::stringLen(token))) {
00866                             isValid = false;
00867                             break;
00868                         }
00869                     }
00870                 }
00871                 else {
00872                     while (tokenizer.hasMoreTokens()) {
00873                         const XMLCh* token = tokenizer.nextToken();
00874 
00875                         if (!XMLChar1_1::isValidNmtoken(token, XMLString::stringLen(token))) {
00876                             isValid = false;
00877                             break;
00878                         }
00879                     }
00880                 }
00881                 break;
00882             }
00883         case XSValue::dt_Name:
00884             isValid = (version == ver_10) ?
00885                 XMLChar1_0::isValidName(content) :
00886                 XMLChar1_1::isValidName(content);
00887             break;
00888         case XSValue::dt_NCName:
00889         case XSValue::dt_ID:
00890         case XSValue::dt_IDREF:
00891         case XSValue::dt_ENTITY:
00892             isValid = (version == ver_10) ?
00893                 XMLChar1_0::isValidNCName(content, XMLString::stringLen(content)) :
00894                 XMLChar1_1::isValidNCName(content, XMLString::stringLen(content));
00895             break;
00896         case XSValue::dt_ENTITIES:
00897         case XSValue::dt_IDREFS:
00898             {
00899                 XMLStringTokenizer tokenizer(content, Separator_ws, manager);
00900 
00901                 if (version ==  ver_10 ) {
00902                     while (tokenizer.hasMoreTokens()) {
00903                         const XMLCh* token = tokenizer.nextToken();
00904 
00905                         if (!XMLChar1_0::isValidNCName(token, XMLString::stringLen(token))) {
00906                             isValid = false;
00907                             break;
00908                         }
00909                     }
00910                 }
00911                 else {
00912                     while (tokenizer.hasMoreTokens()) {
00913                         const XMLCh* token = tokenizer.nextToken();
00914 
00915                         if (!XMLChar1_1::isValidNCName(token, XMLString::stringLen(token))) {
00916                             isValid = false;
00917                             break;
00918                         }
00919                     }
00920                 }
00921             }
00922             break;
00923         default:
00924             status = st_NotSupported;
00925             isValid = false;
00926             break;
00927     }
00928 
00929 
00930     if (isValid == false && status == st_Init) {
00931         status = st_FOCA0002;
00932     }
00933 
00934     return isValid;
00935 }
00936 
00937 
00938 XMLCh* XSValue::getCanRepNumerics(const XMLCh*         const content
00939                                 ,       DataType             datatype
00940                                 ,       Status&              status
00941                                 ,       bool                 toValidate
00942                                 ,       MemoryManager* const manager)
00943 {
00944     try
00945     {
00946 
00947         // getCanonicalRepresentation does lexical space validation only
00948         // (no range checking), therefore if validation is required,
00949         // we need to pass the content to the validate interface for complete checking
00950         if (toValidate && !validateNumerics(content, datatype, status, manager))
00951             return 0;
00952 
00953         XMLCh* retVal = 0;
00954 
00955         if (datatype == XSValue::dt_decimal)
00956         {
00957             retVal = XMLBigDecimal::getCanonicalRepresentation(content, manager);
00958 
00959             if (!retVal)
00960                 status = st_FOCA0002;
00961 
00962             return retVal;
00963 
00964         }
00965         else if (datatype == XSValue::dt_float || datatype == XSValue::dt_double  )
00966         {
00967             // In XML4C, no float or double is treated as out of range
00968             // it gets converted to INF, -INF or zero.
00969             // The getCanonical method should treat double & float the
00970             // same way as the rest of XML4C for consistentcy so need
00971             // to getActualValue and see if it was converted.
00972             XSValue* xsval = getActValNumerics(content, datatype, status, false, manager);
00973             if (!xsval) {
00974                 status = st_FOCA0002;
00975                 return retVal;
00976             }
00977 
00978             DoubleFloatType enumVal;
00979             if (datatype == XSValue::dt_float) {
00980                 enumVal = xsval->fData.fValue.f_floatType.f_floatEnum;
00981             }
00982             else {
00983                 enumVal = xsval->fData.fValue.f_doubleType.f_doubleEnum;
00984             }
00985             delete xsval;
00986 
00987             switch(enumVal) {
00988             case DoubleFloatType_NegINF:
00989                 retVal = XMLString::replicate(XMLUni::fgNegINFString, manager);
00990                 break;
00991             case DoubleFloatType_PosINF:
00992                 retVal = XMLString::replicate(XMLUni::fgPosINFString, manager);
00993                 break;
00994             case DoubleFloatType_NaN:
00995                 retVal = XMLString::replicate(XMLUni::fgNaNString, manager);
00996                 break;
00997             case DoubleFloatType_Zero:
00998                 retVal = XMLString::replicate(XMLUni::fgPosZeroString, manager);
00999                 break;
01000             default: //DoubleFloatType_Normal
01001                 retVal = XMLAbstractDoubleFloat::getCanonicalRepresentation(content, manager);
01002 
01003                 if (!retVal)
01004                     status = st_FOCA0002;
01005                 break;
01006             }
01007             return retVal;
01008         }
01009         else
01010         {
01011             retVal = XMLBigInteger::getCanonicalRepresentation(content, manager, datatype == XSValue::dt_nonPositiveInteger);
01012 
01013             if (!retVal)
01014                 status = st_FOCA0002;
01015 
01016             return retVal;
01017         }
01018     }
01019     catch (const NumberFormatException&)
01020     {
01021         status = st_FOCA0002;
01022     }
01023 
01024     return 0;
01025 }
01026 
01027 XMLCh* XSValue::getCanRepDateTimes(const XMLCh*         const input_content
01028                                  ,       DataType             datatype
01029                                  ,       Status&              status
01030                                  ,       bool                 toValidate
01031                                  ,       MemoryManager* const manager)
01032 {
01033     XMLCh* content = XMLString::replicate(input_content, manager);
01034     ArrayJanitor<XMLCh> janTmpName(content, manager);
01035     XMLString::trim(content);
01036     try
01037     {
01038 
01039         XMLDateTime coreDate = XMLDateTime(content, manager);
01040 
01041         switch (datatype) {
01042         case XSValue::dt_dateTime:
01043             //we need this parsing
01044             coreDate.parseDateTime();
01045             return coreDate.getDateTimeCanonicalRepresentation(manager);
01046             break;
01047         case XSValue::dt_time:
01048             // we need this parsing
01049             coreDate.parseTime();
01050             return coreDate.getTimeCanonicalRepresentation(manager);
01051             break;
01052         case XSValue::dt_date:
01053             // we need this parsing
01054             coreDate.parseDate();
01055             return coreDate.getDateCanonicalRepresentation(manager);
01056             break;
01057         case XSValue::dt_duration:
01058         case XSValue::dt_gYearMonth:
01059         case XSValue::dt_gYear:
01060         case XSValue::dt_gMonthDay:
01061         case XSValue::dt_gDay:
01062         case XSValue::dt_gMonth:
01063             {
01064                 if (!(toValidate && !validateDateTimes(content, datatype, status, manager)))
01065                     status = st_NoCanRep;
01066 
01067                 return 0;
01068             }
01069             break;
01070         default:
01071             return 0;
01072             break;
01073         }
01074     }
01075     catch (SchemaDateTimeException &e)
01076     {
01077         status = checkTimeZoneError(datatype, e)? XSValue::st_FODT0003 : st_FOCA0002;
01078     }
01079     catch (const NumberFormatException&)
01080     {
01081         status = st_FOCA0002;
01082     }
01083     return 0;
01084 }
01085 
01086 XMLCh* XSValue::getCanRepStrings(const XMLCh*         const content
01087                                ,       DataType             datatype
01088                                ,       Status&              status
01089                                ,       XMLVersion           version
01090                                ,       bool                 toValidate
01091                                ,       MemoryManager* const manager)
01092 {
01093     switch (datatype) {
01094         case XSValue::dt_boolean:
01095             {
01096             XMLCh* tmpStrValue = XMLString::replicate(content, manager);
01097             ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
01098             XMLString::trim(tmpStrValue);
01099             //always validate before getting canRep
01100             if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[0]) ||
01101                 XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[2])  )
01102             {
01103                 return XMLString::replicate(XMLUni::fgBooleanValueSpace[0], manager);
01104             }
01105             else if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[1]) ||
01106                      XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[3])  )
01107             {
01108                 return XMLString::replicate(XMLUni::fgBooleanValueSpace[1], manager);
01109             }
01110             else
01111             {
01112                 status = st_FOCA0002;
01113                 return 0;
01114             }
01115             }
01116             break;
01117         case XSValue::dt_hexBinary:
01118             {
01119                 //HexBin::getCanonicalRepresentation does validation automatically
01120                 XMLCh* tmpStrValue = XMLString::replicate(content, manager);
01121                 ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
01122                 XMLString::trim(tmpStrValue);
01123 
01124                 XMLCh* canRep = HexBin::getCanonicalRepresentation(tmpStrValue, manager);
01125                 if (!canRep)
01126                     status = st_FOCA0002;
01127 
01128                 return canRep;
01129                 break;
01130             }
01131         case XSValue::dt_base64Binary:
01132             {
01133                 //Base64::getCanonicalRepresentation does validation automatically
01134                 XMLCh* canRep = Base64::getCanonicalRepresentation(content, manager);
01135                 if (!canRep)
01136                     status = st_FOCA0002;
01137 
01138                 return canRep;
01139                 break;
01140             }
01141         case XSValue::dt_anyURI:
01142         case XSValue::dt_QName:
01143         case XSValue::dt_NOTATION:
01144         case XSValue::dt_string:
01145         case XSValue::dt_normalizedString:
01146         case XSValue::dt_token:
01147         case XSValue::dt_language:
01148         case XSValue::dt_NMTOKEN:
01149         case XSValue::dt_NMTOKENS:
01150         case XSValue::dt_Name:
01151         case XSValue::dt_NCName:
01152         case XSValue::dt_ID:
01153         case XSValue::dt_IDREF:
01154         case XSValue::dt_ENTITY:
01155         case XSValue::dt_ENTITIES:
01156         case XSValue::dt_IDREFS:
01157             if (toValidate && !validateStrings(content, datatype, status, version, manager))
01158                 status = st_FOCA0002;
01159             else
01160                 status = st_NoCanRep;
01161 
01162             return 0;
01163             break;
01164         default:
01165             return 0;
01166             break;
01167     }
01168 
01169     return 0;
01170 }
01171 
01172 XSValue*
01173 XSValue::getActValNumerics(const XMLCh*         const content
01174                          ,       DataType             datatype
01175                          ,       Status&              status
01176                          ,       bool                 toValidate
01177                          ,       MemoryManager* const manager)
01178 {
01179 
01180     try {
01181 
01182         switch (datatype) {
01183         case XSValue::dt_decimal:
01184         {
01185             if (toValidate) {
01186                 XMLBigDecimal::parseDecimal(content, manager);
01187             }
01188             //Prepare the double value
01189             XMLDouble  data(content, manager);
01190             if (data.isDataConverted())
01191             {
01192                 status = st_FOCA0001;
01193                 return 0;
01194             }
01195 
01196             XSValue* retVal = new (manager) XSValue(dt_decimal, manager);
01197             retVal->fData.fValue.f_decimal.f_dvalue = data.getValue();
01198 
01199             return retVal;
01200             break;
01201         }
01202         case XSValue::dt_float:
01203         {
01204             //XMLFloat takes care of 0, -0, -INF, INF and NaN
01205             //XMLFloat::checkBoundary() handles error and outofbound issues
01206             XMLFloat data(content, manager);
01207             XSValue* retVal = new (manager) XSValue(dt_float, manager);
01208 
01209             if (data.isDataConverted())
01210             {
01211                 retVal->fData.fValue.f_floatType.f_float = 0.0;
01212                 retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_Zero;
01213 
01214                 switch(data.getType()) {
01215                     case XMLAbstractDoubleFloat::NegINF:
01216                         retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_NegINF;
01217                         break;
01218                     case XMLAbstractDoubleFloat::PosINF:
01219                         retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_PosINF;
01220                         break;
01221                     case XMLAbstractDoubleFloat::NaN:
01222                         retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_NaN;
01223                         break;
01224                     default:
01225                         break;
01226                 }
01227             }
01228             else {
01229                 retVal->fData.fValue.f_floatType.f_floatEnum = DoubleFloatType_Normal;
01230                 retVal->fData.fValue.f_floatType.f_float = (float) data.getValue();
01231             }
01232             return retVal;
01233             break;
01234         }
01235         case XSValue::dt_double:
01236         {
01237             //XMLDouble takes care of 0, -0, -INF, INF and NaN
01238             //XMLDouble::checkBoundary() handles error and outofbound issues
01239             XMLDouble  data(content, manager);
01240             XSValue* retVal = new (manager) XSValue(dt_double, manager);
01241 
01242             if (data.isDataConverted())
01243             {
01244                 retVal->fData.fValue.f_doubleType.f_double = 0.0;
01245                 retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_Zero;
01246 
01247                 switch(data.getType()) {
01248                     case XMLAbstractDoubleFloat::NegINF:
01249                         retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_NegINF;
01250                         break;
01251                     case XMLAbstractDoubleFloat::PosINF:
01252                         retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_PosINF;
01253                         break;
01254                     case XMLAbstractDoubleFloat::NaN:
01255                         retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_NaN;
01256                         break;
01257                     default:
01258                         break;
01259                 }
01260             }
01261             else {
01262                 retVal->fData.fValue.f_doubleType.f_doubleEnum = DoubleFloatType_Normal;
01263                 retVal->fData.fValue.f_doubleType.f_double = data.getValue();
01264             }
01265             return retVal;
01266             break;
01267         }
01268         case XSValue::dt_integer:
01269         case XSValue::dt_negativeInteger:
01270         case XSValue::dt_nonPositiveInteger:
01271         case XSValue::dt_nonNegativeInteger:
01272         case XSValue::dt_positiveInteger:
01273         case XSValue::dt_long:
01274         case XSValue::dt_int:
01275         case XSValue::dt_short:
01276         case XSValue::dt_byte:
01277         case XSValue::dt_unsignedLong:
01278         case XSValue::dt_unsignedInt:
01279         case XSValue::dt_unsignedShort:
01280         case XSValue::dt_unsignedByte:
01281         {
01282             t_value   actVal;
01283 
01284             if ( !getActualNumericValue(
01285                                   content
01286                                 , status
01287                                 , actVal
01288                                 , manager
01289                                 , datatype
01290                                 )
01291                 )
01292             {
01293                 //status has been set by getActualNumericValue
01294                 return 0;
01295             }
01296 
01297             XSValue* retVal = new (manager) XSValue(datatype, manager);
01298 
01299             switch (datatype) {
01300                 case XSValue::dt_integer:
01301                     retVal->fData.fValue.f_long = actVal.f_long;
01302                     break;
01303                 case XSValue::dt_negativeInteger:
01304                     retVal->fData.fValue.f_long = actVal.f_long;
01305                     break;
01306                 case XSValue::dt_nonPositiveInteger:
01307                     retVal->fData.fValue.f_long = actVal.f_long;
01308                     break;
01309                 case XSValue::dt_nonNegativeInteger:
01310                     retVal->fData.fValue.f_long = actVal.f_ulong;
01311                     break;
01312                 case XSValue::dt_positiveInteger:
01313                     retVal->fData.fValue.f_long = actVal.f_ulong;
01314                     break;
01315                 case XSValue::dt_long:
01316                     retVal->fData.fValue.f_long = actVal.f_long;
01317                     break;
01318                 case XSValue::dt_int:
01319                     retVal->fData.fValue.f_int = (int) actVal.f_long;
01320                     break;
01321                 case XSValue::dt_short:
01322                     retVal->fData.fValue.f_short = (short) actVal.f_long;
01323                     break;
01324                 case XSValue::dt_byte:
01325                     retVal->fData.fValue.f_char = (char) actVal.f_long;
01326                     break;
01327                 case XSValue::dt_unsignedLong:
01328                     retVal->fData.fValue.f_ulong = actVal.f_ulong;
01329                     break;
01330                 case XSValue::dt_unsignedInt:
01331                     retVal->fData.fValue.f_uint = (unsigned int) actVal.f_ulong;
01332                     break;
01333                 case XSValue::dt_unsignedShort:
01334                     retVal->fData.fValue.f_ushort = (unsigned short) actVal.f_ulong;
01335                     break;
01336                 case XSValue::dt_unsignedByte:
01337                     retVal->fData.fValue.f_uchar = (unsigned char) actVal.f_ulong;
01338                     break;
01339                 default:
01340                     return 0;
01341                     break;
01342             }
01343             return retVal;
01344             break;
01345         }
01346         default:
01347             return 0;
01348             break;
01349         } // end switch
01350     }
01351     catch (const NumberFormatException&)
01352     {
01353         status = st_FOCA0002;
01354     }
01355     return 0;
01356 }
01357 
01358 XSValue*
01359 XSValue::getActValDateTimes(const XMLCh*         const input_content
01360                           ,       DataType             datatype
01361                           ,       Status&              status
01362                           ,       MemoryManager* const manager)
01363 {
01364     XMLCh* content = XMLString::replicate(input_content, manager);
01365     ArrayJanitor<XMLCh> janTmpName(content, manager);
01366     XMLString::trim(content);
01367     try
01368     {
01369         //Need not check if validation is requested since
01370         //parsing functions below does the validation automatically
01371         XMLDateTime coreDate = XMLDateTime(content, manager);
01372 
01373         switch (datatype) {
01374         case XSValue::dt_duration:
01375             coreDate.parseDuration();
01376             break;
01377         case XSValue::dt_dateTime:
01378             coreDate.parseDateTime();
01379             break;
01380         case XSValue::dt_time:
01381             coreDate.parseTime();
01382             coreDate.fValue[XMLDateTime::CentYear] = 0;
01383             coreDate.fValue[XMLDateTime::Month] = 0;
01384             coreDate.fValue[XMLDateTime::Day] = 0;
01385             break;
01386         case XSValue::dt_date:
01387             coreDate.parseDate();
01388             coreDate.fValue[XMLDateTime::Hour] = 0;
01389             coreDate.fValue[XMLDateTime::Minute] = 0;
01390             break;
01391         case XSValue::dt_gYearMonth:
01392             coreDate.parseYearMonth();
01393             coreDate.fValue[XMLDateTime::Day] = 0;
01394             coreDate.fValue[XMLDateTime::Hour] = 0;
01395             coreDate.fValue[XMLDateTime::Minute] = 0;
01396             break;
01397         case XSValue::dt_gYear:
01398             coreDate.parseYear();
01399             coreDate.fValue[XMLDateTime::Month] = 0;
01400             coreDate.fValue[XMLDateTime::Day] = 0;
01401             coreDate.fValue[XMLDateTime::Hour] = 0;
01402             coreDate.fValue[XMLDateTime::Minute] = 0;
01403             break;
01404         case XSValue::dt_gMonthDay:
01405             coreDate.parseMonthDay();
01406             coreDate.fValue[XMLDateTime::CentYear] = 0;
01407             coreDate.fValue[XMLDateTime::Hour] = 0;
01408             coreDate.fValue[XMLDateTime::Minute] = 0;
01409             break;
01410         case XSValue::dt_gDay:
01411             coreDate.parseDay();
01412             coreDate.fValue[XMLDateTime::CentYear] = 0;
01413             coreDate.fValue[XMLDateTime::Month] = 0;
01414             coreDate.fValue[XMLDateTime::Hour] = 0;
01415             coreDate.fValue[XMLDateTime::Minute] = 0;
01416             break;
01417         case XSValue::dt_gMonth:
01418             coreDate.parseMonth();
01419             coreDate.fValue[XMLDateTime::CentYear] = 0;
01420             coreDate.fValue[XMLDateTime::Day] = 0;
01421             coreDate.fValue[XMLDateTime::Hour] = 0;
01422             coreDate.fValue[XMLDateTime::Minute] = 0;
01423             break;
01424         default:
01425             return 0;
01426             break;
01427         }
01428 
01429         XSValue* retVal = new (manager) XSValue(datatype, manager);
01430 
01431         retVal->fData.fValue.f_datetime.f_year    = coreDate.fValue[XMLDateTime::CentYear];
01432         retVal->fData.fValue.f_datetime.f_month   = coreDate.fValue[XMLDateTime::Month];
01433         retVal->fData.fValue.f_datetime.f_day     = coreDate.fValue[XMLDateTime::Day];
01434         retVal->fData.fValue.f_datetime.f_hour    = coreDate.fValue[XMLDateTime::Hour];
01435         retVal->fData.fValue.f_datetime.f_min     = coreDate.fValue[XMLDateTime::Minute];
01436         retVal->fData.fValue.f_datetime.f_second  = coreDate.fValue[XMLDateTime::Second];
01437         retVal->fData.fValue.f_datetime.f_milisec = coreDate.fMilliSecond;
01438 
01439         return retVal;
01440     }
01441     catch (SchemaDateTimeException const &e)
01442     {
01443         status = checkTimeZoneError(datatype, e)? XSValue::st_FODT0003 : st_FOCA0002;
01444     }
01445     catch (const NumberFormatException&)
01446     {
01447         status = st_FOCA0002;
01448     }
01449     return 0;
01450 
01451 }
01452 
01453 XSValue*
01454 XSValue::getActValStrings(const XMLCh*         const content
01455                         ,       DataType             datatype
01456                         ,       Status&              status
01457                         ,       XMLVersion           version
01458                         ,       bool                 toValidate
01459                         ,       MemoryManager* const manager)
01460 {
01461     switch (datatype) {
01462         case XSValue::dt_boolean:
01463             {
01464             XMLCh* tmpStrValue = XMLString::replicate(content, manager);
01465             ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
01466             XMLString::trim(tmpStrValue);
01467             //do validation here more efficiently
01468             if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[0]) ||
01469                 XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[2])  )
01470             {
01471                 XSValue* retVal = new (manager) XSValue(dt_boolean, manager);
01472                 retVal->fData.fValue.f_bool = false;
01473                 return retVal;
01474             }
01475             else if (XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[1]) ||
01476                      XMLString::equals(tmpStrValue, XMLUni::fgBooleanValueSpace[3])  )
01477             {
01478                 XSValue* retVal = new (manager) XSValue(dt_boolean, manager);
01479                 retVal->fData.fValue.f_bool = true;
01480                 return retVal;
01481             }
01482             else
01483             {
01484                 status = st_FOCA0002;
01485                 return 0;
01486             }
01487             }
01488             break;
01489         case XSValue::dt_hexBinary:
01490             {
01491                 XMLCh* tmpStrValue = XMLString::replicate(content, manager);
01492                 ArrayJanitor<XMLCh> janTmpName(tmpStrValue, manager);
01493                 XMLString::trim(tmpStrValue);
01494 
01495                 XMLByte* decodedData = HexBin::decodeToXMLByte(tmpStrValue, manager);
01496 
01497                 if (!decodedData)
01498                 {
01499                     status = st_FOCA0002;
01500                     return 0;
01501                 }
01502 
01503                 XSValue* retVal = new (manager) XSValue(dt_hexBinary, manager);
01504                 retVal->fData.fValue.f_byteVal = decodedData;
01505                 retVal->fMemAllocated = true;
01506                 return retVal;
01507                 break;
01508             }
01509         case XSValue::dt_base64Binary:
01510             {
01511                 XMLSize_t len = 0;
01512                 XMLByte* decodedData = Base64::decodeToXMLByte(content, &len, manager);
01513 
01514                 if (!decodedData)
01515                 {
01516                     status = st_FOCA0002;
01517                     return 0;
01518                 }
01519 
01520                 XSValue* retVal = new (manager) XSValue(dt_base64Binary, manager);
01521                 retVal->fData.fValue.f_byteVal = decodedData;
01522                 retVal->fMemAllocated = true;
01523                 return retVal;
01524                 break;
01525             }
01526         case XSValue::dt_anyURI:
01527         case XSValue::dt_QName:
01528         case XSValue::dt_NOTATION:
01529         case XSValue::dt_string:
01530         case XSValue::dt_normalizedString:
01531         case XSValue::dt_token:
01532         case XSValue::dt_language:
01533         case XSValue::dt_NMTOKEN:
01534         case XSValue::dt_NMTOKENS:
01535         case XSValue::dt_Name:
01536         case XSValue::dt_NCName:
01537         case XSValue::dt_ID:
01538         case XSValue::dt_IDREF:
01539         case XSValue::dt_ENTITY:
01540         case XSValue::dt_ENTITIES:
01541         case XSValue::dt_IDREFS:
01542             if (toValidate && !validateStrings(content, datatype, status, version, manager))
01543                 status = st_FOCA0002;
01544             else
01545                 status = st_NoActVal;
01546 
01547             return 0;
01548             break;
01549         default:
01550             return 0;
01551             break;
01552     }
01553 
01554     return 0;
01555 }
01556 
01557 // ---------------------------------------------------------------------------
01558 //  Utilities
01559 // ---------------------------------------------------------------------------
01560 bool XSValue::getActualNumericValue(const XMLCh*  const content
01561                            ,       Status&              status
01562                            ,       t_value&             retVal
01563                            ,       MemoryManager* const manager
01564                            ,       DataType             datatype)
01565 {
01566     char *nptr = XMLString::transcode(content, manager);
01567     ArrayJanitor<char> jan(nptr, manager);
01568     char *endptr = 0;
01569     errno = 0;
01570 
01571     if (XSValue::numericSign[datatype])
01572     {
01573         retVal.f_long = strtol(nptr, &endptr, (int)10);
01574     }
01575     else
01576     {
01577         if (XMLString::indexOf(content, chDash) != -1)
01578         {
01579             status = st_FOCA0002; //invalid lexcial value
01580             return false;
01581         }
01582 
01583         retVal.f_ulong = strtoul(nptr, &endptr, (int)10);
01584     }
01585 
01586     // need to check out-of-bounds before checking erange...
01587     switch (datatype) {
01588         case XSValue::dt_nonPositiveInteger:
01589             if (retVal.f_long > 0)
01590             {
01591                 status = st_FOCA0002;
01592                 return false;
01593             }
01594             break;
01595         case XSValue::dt_negativeInteger:
01596             if (retVal.f_long >= 0)
01597             {
01598                 status = st_FOCA0002;
01599                 return false;
01600             }
01601             break;
01602         case XSValue::dt_int:
01603             // strtol will set value to LONG_MIN/LONG_MAX if ERANGE error
01604             if ((retVal.f_long < INT_MIN) ||
01605                 (retVal.f_long > INT_MAX) ||
01606                 (errno == ERANGE))
01607             {
01608                 status = st_FOCA0002;
01609                 return false;
01610             }
01611             break;
01612         case XSValue::dt_short:
01613             if ((retVal.f_long < SHRT_MIN) ||
01614                 (retVal.f_long > SHRT_MAX))
01615             {
01616                 status = st_FOCA0002;
01617                 return false;
01618             }
01619             break;
01620         case XSValue::dt_byte:
01621             if ((retVal.f_long < SCHAR_MIN) ||
01622                 (retVal.f_long > SCHAR_MAX))
01623             {
01624                 status = st_FOCA0002;
01625                 return false;
01626             }
01627             break;
01628         case XSValue::dt_unsignedInt:
01629             // strtoul will set value to LONG_INT if ERANGE error
01630             if ((retVal.f_ulong > UINT_MAX)  ||
01631                 (errno == ERANGE))
01632             {
01633                 status = st_FOCA0002;
01634                 return false;
01635             }
01636             break;
01637         case XSValue::dt_unsignedShort:
01638             if (retVal.f_ulong > USHRT_MAX)
01639             {
01640                 status = st_FOCA0002;
01641                 return false;
01642             }
01643             break;
01644         case XSValue::dt_unsignedByte:
01645             if (retVal.f_ulong > UCHAR_MAX)
01646             {
01647                 status = st_FOCA0002;
01648                 return false;
01649             }
01650             break;
01651         case XSValue::dt_positiveInteger:
01652             if (retVal.f_ulong == 0)
01653             {
01654                 status = st_FOCA0002;
01655                 return false;
01656             }
01657             break;
01658         default:
01659             break;
01660     } // end switch
01661     // check if overflow/underflow occurs
01662     if (errno == ERANGE)
01663     {
01664         status = st_FOCA0003;
01665         return false;
01666     }
01667 
01668     // check if all chars are valid char.  If they are, endptr will
01669     // pointer to the null terminator, or all of the remaining
01670     // characters will be whitespace characters.
01671     while (*endptr != '\0')
01672     {
01673         const char  ch = *endptr;
01674 
01675         if (ch == '\t' || ch == '\n' || ch == '\r' || ch == ' ')
01676         {
01677             ++endptr;
01678         }
01679         else
01680         {
01681             status = st_FOCA0002;
01682             return false;
01683         }
01684 
01685     }
01686     return true;
01687 }
01688 
01689 XERCES_CPP_NAMESPACE_END