GME
13
|
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