Paul Cercueil / libxml2

Dependents:   libiio

Committer:
pcercuei
Date:
Thu Aug 25 10:07:34 2016 +0000
Revision:
1:26f20484cbdc
Parent:
0:03b5121a232e
Add config.h and dummy.c containing empty functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pcercuei 0:03b5121a232e 1 /*
pcercuei 0:03b5121a232e 2 * schemastypes.c : implementation of the XML Schema Datatypes
pcercuei 0:03b5121a232e 3 * definition and validity checking
pcercuei 0:03b5121a232e 4 *
pcercuei 0:03b5121a232e 5 * See Copyright for the status of this software.
pcercuei 0:03b5121a232e 6 *
pcercuei 0:03b5121a232e 7 * Daniel Veillard <veillard@redhat.com>
pcercuei 0:03b5121a232e 8 */
pcercuei 0:03b5121a232e 9
pcercuei 0:03b5121a232e 10 #define IN_LIBXML
pcercuei 0:03b5121a232e 11 #include "libxml.h"
pcercuei 0:03b5121a232e 12
pcercuei 0:03b5121a232e 13 #ifdef LIBXML_SCHEMAS_ENABLED
pcercuei 0:03b5121a232e 14
pcercuei 0:03b5121a232e 15 #include <string.h>
pcercuei 0:03b5121a232e 16 #include <libxml/xmlmemory.h>
pcercuei 0:03b5121a232e 17 #include <libxml/parser.h>
pcercuei 0:03b5121a232e 18 #include <libxml/parserInternals.h>
pcercuei 0:03b5121a232e 19 #include <libxml/hash.h>
pcercuei 0:03b5121a232e 20 #include <libxml/valid.h>
pcercuei 0:03b5121a232e 21 #include <libxml/xpath.h>
pcercuei 0:03b5121a232e 22 #include <libxml/uri.h>
pcercuei 0:03b5121a232e 23
pcercuei 0:03b5121a232e 24 #include <libxml/xmlschemas.h>
pcercuei 0:03b5121a232e 25 #include <libxml/schemasInternals.h>
pcercuei 0:03b5121a232e 26 #include <libxml/xmlschemastypes.h>
pcercuei 0:03b5121a232e 27
pcercuei 0:03b5121a232e 28 #ifdef HAVE_MATH_H
pcercuei 0:03b5121a232e 29 #include <math.h>
pcercuei 0:03b5121a232e 30 #endif
pcercuei 0:03b5121a232e 31 #ifdef HAVE_FLOAT_H
pcercuei 0:03b5121a232e 32 #include <float.h>
pcercuei 0:03b5121a232e 33 #endif
pcercuei 0:03b5121a232e 34
pcercuei 0:03b5121a232e 35 #define DEBUG
pcercuei 0:03b5121a232e 36
pcercuei 0:03b5121a232e 37 #ifndef LIBXML_XPATH_ENABLED
pcercuei 0:03b5121a232e 38 extern double xmlXPathNAN;
pcercuei 0:03b5121a232e 39 extern double xmlXPathPINF;
pcercuei 0:03b5121a232e 40 extern double xmlXPathNINF;
pcercuei 0:03b5121a232e 41 #endif
pcercuei 0:03b5121a232e 42
pcercuei 0:03b5121a232e 43 #define TODO \
pcercuei 0:03b5121a232e 44 xmlGenericError(xmlGenericErrorContext, \
pcercuei 0:03b5121a232e 45 "Unimplemented block at %s:%d\n", \
pcercuei 0:03b5121a232e 46 __FILE__, __LINE__);
pcercuei 0:03b5121a232e 47
pcercuei 0:03b5121a232e 48 #define XML_SCHEMAS_NAMESPACE_NAME \
pcercuei 0:03b5121a232e 49 (const xmlChar *)"http://www.w3.org/2001/XMLSchema"
pcercuei 0:03b5121a232e 50
pcercuei 0:03b5121a232e 51 #define IS_WSP_REPLACE_CH(c) ((((c) == 0x9) || ((c) == 0xa)) || \
pcercuei 0:03b5121a232e 52 ((c) == 0xd))
pcercuei 0:03b5121a232e 53
pcercuei 0:03b5121a232e 54 #define IS_WSP_SPACE_CH(c) ((c) == 0x20)
pcercuei 0:03b5121a232e 55
pcercuei 0:03b5121a232e 56 #define IS_WSP_BLANK_CH(c) IS_BLANK_CH(c)
pcercuei 0:03b5121a232e 57
pcercuei 0:03b5121a232e 58 /* Date value */
pcercuei 0:03b5121a232e 59 typedef struct _xmlSchemaValDate xmlSchemaValDate;
pcercuei 0:03b5121a232e 60 typedef xmlSchemaValDate *xmlSchemaValDatePtr;
pcercuei 0:03b5121a232e 61 struct _xmlSchemaValDate {
pcercuei 0:03b5121a232e 62 long year;
pcercuei 0:03b5121a232e 63 unsigned int mon :4; /* 1 <= mon <= 12 */
pcercuei 0:03b5121a232e 64 unsigned int day :5; /* 1 <= day <= 31 */
pcercuei 0:03b5121a232e 65 unsigned int hour :5; /* 0 <= hour <= 23 */
pcercuei 0:03b5121a232e 66 unsigned int min :6; /* 0 <= min <= 59 */
pcercuei 0:03b5121a232e 67 double sec;
pcercuei 0:03b5121a232e 68 unsigned int tz_flag :1; /* is tzo explicitely set? */
pcercuei 0:03b5121a232e 69 signed int tzo :12; /* -1440 <= tzo <= 1440;
pcercuei 0:03b5121a232e 70 currently only -840 to +840 are needed */
pcercuei 0:03b5121a232e 71 };
pcercuei 0:03b5121a232e 72
pcercuei 0:03b5121a232e 73 /* Duration value */
pcercuei 0:03b5121a232e 74 typedef struct _xmlSchemaValDuration xmlSchemaValDuration;
pcercuei 0:03b5121a232e 75 typedef xmlSchemaValDuration *xmlSchemaValDurationPtr;
pcercuei 0:03b5121a232e 76 struct _xmlSchemaValDuration {
pcercuei 0:03b5121a232e 77 long mon; /* mon stores years also */
pcercuei 0:03b5121a232e 78 long day;
pcercuei 0:03b5121a232e 79 double sec; /* sec stores min and hour also */
pcercuei 0:03b5121a232e 80 };
pcercuei 0:03b5121a232e 81
pcercuei 0:03b5121a232e 82 typedef struct _xmlSchemaValDecimal xmlSchemaValDecimal;
pcercuei 0:03b5121a232e 83 typedef xmlSchemaValDecimal *xmlSchemaValDecimalPtr;
pcercuei 0:03b5121a232e 84 struct _xmlSchemaValDecimal {
pcercuei 0:03b5121a232e 85 /* would use long long but not portable */
pcercuei 0:03b5121a232e 86 unsigned long lo;
pcercuei 0:03b5121a232e 87 unsigned long mi;
pcercuei 0:03b5121a232e 88 unsigned long hi;
pcercuei 0:03b5121a232e 89 unsigned int extra;
pcercuei 0:03b5121a232e 90 unsigned int sign:1;
pcercuei 0:03b5121a232e 91 unsigned int frac:7;
pcercuei 0:03b5121a232e 92 unsigned int total:8;
pcercuei 0:03b5121a232e 93 };
pcercuei 0:03b5121a232e 94
pcercuei 0:03b5121a232e 95 typedef struct _xmlSchemaValQName xmlSchemaValQName;
pcercuei 0:03b5121a232e 96 typedef xmlSchemaValQName *xmlSchemaValQNamePtr;
pcercuei 0:03b5121a232e 97 struct _xmlSchemaValQName {
pcercuei 0:03b5121a232e 98 xmlChar *name;
pcercuei 0:03b5121a232e 99 xmlChar *uri;
pcercuei 0:03b5121a232e 100 };
pcercuei 0:03b5121a232e 101
pcercuei 0:03b5121a232e 102 typedef struct _xmlSchemaValHex xmlSchemaValHex;
pcercuei 0:03b5121a232e 103 typedef xmlSchemaValHex *xmlSchemaValHexPtr;
pcercuei 0:03b5121a232e 104 struct _xmlSchemaValHex {
pcercuei 0:03b5121a232e 105 xmlChar *str;
pcercuei 0:03b5121a232e 106 unsigned int total;
pcercuei 0:03b5121a232e 107 };
pcercuei 0:03b5121a232e 108
pcercuei 0:03b5121a232e 109 typedef struct _xmlSchemaValBase64 xmlSchemaValBase64;
pcercuei 0:03b5121a232e 110 typedef xmlSchemaValBase64 *xmlSchemaValBase64Ptr;
pcercuei 0:03b5121a232e 111 struct _xmlSchemaValBase64 {
pcercuei 0:03b5121a232e 112 xmlChar *str;
pcercuei 0:03b5121a232e 113 unsigned int total;
pcercuei 0:03b5121a232e 114 };
pcercuei 0:03b5121a232e 115
pcercuei 0:03b5121a232e 116 struct _xmlSchemaVal {
pcercuei 0:03b5121a232e 117 xmlSchemaValType type;
pcercuei 0:03b5121a232e 118 struct _xmlSchemaVal *next;
pcercuei 0:03b5121a232e 119 union {
pcercuei 0:03b5121a232e 120 xmlSchemaValDecimal decimal;
pcercuei 0:03b5121a232e 121 xmlSchemaValDate date;
pcercuei 0:03b5121a232e 122 xmlSchemaValDuration dur;
pcercuei 0:03b5121a232e 123 xmlSchemaValQName qname;
pcercuei 0:03b5121a232e 124 xmlSchemaValHex hex;
pcercuei 0:03b5121a232e 125 xmlSchemaValBase64 base64;
pcercuei 0:03b5121a232e 126 float f;
pcercuei 0:03b5121a232e 127 double d;
pcercuei 0:03b5121a232e 128 int b;
pcercuei 0:03b5121a232e 129 xmlChar *str;
pcercuei 0:03b5121a232e 130 } value;
pcercuei 0:03b5121a232e 131 };
pcercuei 0:03b5121a232e 132
pcercuei 0:03b5121a232e 133 static int xmlSchemaTypesInitialized = 0;
pcercuei 0:03b5121a232e 134 static xmlHashTablePtr xmlSchemaTypesBank = NULL;
pcercuei 0:03b5121a232e 135
pcercuei 0:03b5121a232e 136 /*
pcercuei 0:03b5121a232e 137 * Basic types
pcercuei 0:03b5121a232e 138 */
pcercuei 0:03b5121a232e 139 static xmlSchemaTypePtr xmlSchemaTypeStringDef = NULL;
pcercuei 0:03b5121a232e 140 static xmlSchemaTypePtr xmlSchemaTypeAnyTypeDef = NULL;
pcercuei 0:03b5121a232e 141 static xmlSchemaTypePtr xmlSchemaTypeAnySimpleTypeDef = NULL;
pcercuei 0:03b5121a232e 142 static xmlSchemaTypePtr xmlSchemaTypeDecimalDef = NULL;
pcercuei 0:03b5121a232e 143 static xmlSchemaTypePtr xmlSchemaTypeDatetimeDef = NULL;
pcercuei 0:03b5121a232e 144 static xmlSchemaTypePtr xmlSchemaTypeDateDef = NULL;
pcercuei 0:03b5121a232e 145 static xmlSchemaTypePtr xmlSchemaTypeTimeDef = NULL;
pcercuei 0:03b5121a232e 146 static xmlSchemaTypePtr xmlSchemaTypeGYearDef = NULL;
pcercuei 0:03b5121a232e 147 static xmlSchemaTypePtr xmlSchemaTypeGYearMonthDef = NULL;
pcercuei 0:03b5121a232e 148 static xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL;
pcercuei 0:03b5121a232e 149 static xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL;
pcercuei 0:03b5121a232e 150 static xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL;
pcercuei 0:03b5121a232e 151 static xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL;
pcercuei 0:03b5121a232e 152 static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL;
pcercuei 0:03b5121a232e 153 static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL;
pcercuei 0:03b5121a232e 154 static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL;
pcercuei 0:03b5121a232e 155 static xmlSchemaTypePtr xmlSchemaTypeHexBinaryDef = NULL;
pcercuei 0:03b5121a232e 156 static xmlSchemaTypePtr xmlSchemaTypeBase64BinaryDef = NULL;
pcercuei 0:03b5121a232e 157 static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL;
pcercuei 0:03b5121a232e 158
pcercuei 0:03b5121a232e 159 /*
pcercuei 0:03b5121a232e 160 * Derived types
pcercuei 0:03b5121a232e 161 */
pcercuei 0:03b5121a232e 162 static xmlSchemaTypePtr xmlSchemaTypePositiveIntegerDef = NULL;
pcercuei 0:03b5121a232e 163 static xmlSchemaTypePtr xmlSchemaTypeNonPositiveIntegerDef = NULL;
pcercuei 0:03b5121a232e 164 static xmlSchemaTypePtr xmlSchemaTypeNegativeIntegerDef = NULL;
pcercuei 0:03b5121a232e 165 static xmlSchemaTypePtr xmlSchemaTypeNonNegativeIntegerDef = NULL;
pcercuei 0:03b5121a232e 166 static xmlSchemaTypePtr xmlSchemaTypeIntegerDef = NULL;
pcercuei 0:03b5121a232e 167 static xmlSchemaTypePtr xmlSchemaTypeLongDef = NULL;
pcercuei 0:03b5121a232e 168 static xmlSchemaTypePtr xmlSchemaTypeIntDef = NULL;
pcercuei 0:03b5121a232e 169 static xmlSchemaTypePtr xmlSchemaTypeShortDef = NULL;
pcercuei 0:03b5121a232e 170 static xmlSchemaTypePtr xmlSchemaTypeByteDef = NULL;
pcercuei 0:03b5121a232e 171 static xmlSchemaTypePtr xmlSchemaTypeUnsignedLongDef = NULL;
pcercuei 0:03b5121a232e 172 static xmlSchemaTypePtr xmlSchemaTypeUnsignedIntDef = NULL;
pcercuei 0:03b5121a232e 173 static xmlSchemaTypePtr xmlSchemaTypeUnsignedShortDef = NULL;
pcercuei 0:03b5121a232e 174 static xmlSchemaTypePtr xmlSchemaTypeUnsignedByteDef = NULL;
pcercuei 0:03b5121a232e 175 static xmlSchemaTypePtr xmlSchemaTypeNormStringDef = NULL;
pcercuei 0:03b5121a232e 176 static xmlSchemaTypePtr xmlSchemaTypeTokenDef = NULL;
pcercuei 0:03b5121a232e 177 static xmlSchemaTypePtr xmlSchemaTypeLanguageDef = NULL;
pcercuei 0:03b5121a232e 178 static xmlSchemaTypePtr xmlSchemaTypeNameDef = NULL;
pcercuei 0:03b5121a232e 179 static xmlSchemaTypePtr xmlSchemaTypeQNameDef = NULL;
pcercuei 0:03b5121a232e 180 static xmlSchemaTypePtr xmlSchemaTypeNCNameDef = NULL;
pcercuei 0:03b5121a232e 181 static xmlSchemaTypePtr xmlSchemaTypeIdDef = NULL;
pcercuei 0:03b5121a232e 182 static xmlSchemaTypePtr xmlSchemaTypeIdrefDef = NULL;
pcercuei 0:03b5121a232e 183 static xmlSchemaTypePtr xmlSchemaTypeIdrefsDef = NULL;
pcercuei 0:03b5121a232e 184 static xmlSchemaTypePtr xmlSchemaTypeEntityDef = NULL;
pcercuei 0:03b5121a232e 185 static xmlSchemaTypePtr xmlSchemaTypeEntitiesDef = NULL;
pcercuei 0:03b5121a232e 186 static xmlSchemaTypePtr xmlSchemaTypeNotationDef = NULL;
pcercuei 0:03b5121a232e 187 static xmlSchemaTypePtr xmlSchemaTypeNmtokenDef = NULL;
pcercuei 0:03b5121a232e 188 static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL;
pcercuei 0:03b5121a232e 189
pcercuei 0:03b5121a232e 190 /************************************************************************
pcercuei 0:03b5121a232e 191 * *
pcercuei 0:03b5121a232e 192 * Datatype error handlers *
pcercuei 0:03b5121a232e 193 * *
pcercuei 0:03b5121a232e 194 ************************************************************************/
pcercuei 0:03b5121a232e 195 /**
pcercuei 0:03b5121a232e 196 * xmlSchemaTypeErrMemory:
pcercuei 0:03b5121a232e 197 * @extra: extra informations
pcercuei 0:03b5121a232e 198 *
pcercuei 0:03b5121a232e 199 * Handle an out of memory condition
pcercuei 0:03b5121a232e 200 */
pcercuei 0:03b5121a232e 201 static void
pcercuei 0:03b5121a232e 202 xmlSchemaTypeErrMemory(xmlNodePtr node, const char *extra)
pcercuei 0:03b5121a232e 203 {
pcercuei 0:03b5121a232e 204 __xmlSimpleError(XML_FROM_DATATYPE, XML_ERR_NO_MEMORY, node, NULL, extra);
pcercuei 0:03b5121a232e 205 }
pcercuei 0:03b5121a232e 206
pcercuei 0:03b5121a232e 207 /************************************************************************
pcercuei 0:03b5121a232e 208 * *
pcercuei 0:03b5121a232e 209 * Base types support *
pcercuei 0:03b5121a232e 210 * *
pcercuei 0:03b5121a232e 211 ************************************************************************/
pcercuei 0:03b5121a232e 212
pcercuei 0:03b5121a232e 213 /**
pcercuei 0:03b5121a232e 214 * xmlSchemaNewValue:
pcercuei 0:03b5121a232e 215 * @type: the value type
pcercuei 0:03b5121a232e 216 *
pcercuei 0:03b5121a232e 217 * Allocate a new simple type value
pcercuei 0:03b5121a232e 218 *
pcercuei 0:03b5121a232e 219 * Returns a pointer to the new value or NULL in case of error
pcercuei 0:03b5121a232e 220 */
pcercuei 0:03b5121a232e 221 static xmlSchemaValPtr
pcercuei 0:03b5121a232e 222 xmlSchemaNewValue(xmlSchemaValType type) {
pcercuei 0:03b5121a232e 223 xmlSchemaValPtr value;
pcercuei 0:03b5121a232e 224
pcercuei 0:03b5121a232e 225 value = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
pcercuei 0:03b5121a232e 226 if (value == NULL) {
pcercuei 0:03b5121a232e 227 return(NULL);
pcercuei 0:03b5121a232e 228 }
pcercuei 0:03b5121a232e 229 memset(value, 0, sizeof(xmlSchemaVal));
pcercuei 0:03b5121a232e 230 value->type = type;
pcercuei 0:03b5121a232e 231 return(value);
pcercuei 0:03b5121a232e 232 }
pcercuei 0:03b5121a232e 233
pcercuei 0:03b5121a232e 234 static xmlSchemaFacetPtr
pcercuei 0:03b5121a232e 235 xmlSchemaNewMinLengthFacet(int value)
pcercuei 0:03b5121a232e 236 {
pcercuei 0:03b5121a232e 237 xmlSchemaFacetPtr ret;
pcercuei 0:03b5121a232e 238
pcercuei 0:03b5121a232e 239 ret = xmlSchemaNewFacet();
pcercuei 0:03b5121a232e 240 if (ret == NULL) {
pcercuei 0:03b5121a232e 241 return(NULL);
pcercuei 0:03b5121a232e 242 }
pcercuei 0:03b5121a232e 243 ret->type = XML_SCHEMA_FACET_MINLENGTH;
pcercuei 0:03b5121a232e 244 ret->val = xmlSchemaNewValue(XML_SCHEMAS_NNINTEGER);
pcercuei 0:03b5121a232e 245 if (ret->val == NULL) {
pcercuei 0:03b5121a232e 246 xmlFree(ret);
pcercuei 0:03b5121a232e 247 return(NULL);
pcercuei 0:03b5121a232e 248 }
pcercuei 0:03b5121a232e 249 ret->val->value.decimal.lo = value;
pcercuei 0:03b5121a232e 250 return (ret);
pcercuei 0:03b5121a232e 251 }
pcercuei 0:03b5121a232e 252
pcercuei 0:03b5121a232e 253 /*
pcercuei 0:03b5121a232e 254 * xmlSchemaInitBasicType:
pcercuei 0:03b5121a232e 255 * @name: the type name
pcercuei 0:03b5121a232e 256 * @type: the value type associated
pcercuei 0:03b5121a232e 257 *
pcercuei 0:03b5121a232e 258 * Initialize one primitive built-in type
pcercuei 0:03b5121a232e 259 */
pcercuei 0:03b5121a232e 260 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 261 xmlSchemaInitBasicType(const char *name, xmlSchemaValType type,
pcercuei 0:03b5121a232e 262 xmlSchemaTypePtr baseType) {
pcercuei 0:03b5121a232e 263 xmlSchemaTypePtr ret;
pcercuei 0:03b5121a232e 264
pcercuei 0:03b5121a232e 265 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
pcercuei 0:03b5121a232e 266 if (ret == NULL) {
pcercuei 0:03b5121a232e 267 xmlSchemaTypeErrMemory(NULL, "could not initialize basic types");
pcercuei 0:03b5121a232e 268 return(NULL);
pcercuei 0:03b5121a232e 269 }
pcercuei 0:03b5121a232e 270 memset(ret, 0, sizeof(xmlSchemaType));
pcercuei 0:03b5121a232e 271 ret->name = (const xmlChar *)name;
pcercuei 0:03b5121a232e 272 ret->targetNamespace = XML_SCHEMAS_NAMESPACE_NAME;
pcercuei 0:03b5121a232e 273 ret->type = XML_SCHEMA_TYPE_BASIC;
pcercuei 0:03b5121a232e 274 ret->baseType = baseType;
pcercuei 0:03b5121a232e 275 ret->contentType = XML_SCHEMA_CONTENT_BASIC;
pcercuei 0:03b5121a232e 276 /*
pcercuei 0:03b5121a232e 277 * Primitive types.
pcercuei 0:03b5121a232e 278 */
pcercuei 0:03b5121a232e 279 switch (type) {
pcercuei 0:03b5121a232e 280 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 281 case XML_SCHEMAS_DECIMAL:
pcercuei 0:03b5121a232e 282 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 283 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 284 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 285 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 286 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 287 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 288 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 289 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 290 case XML_SCHEMAS_DURATION:
pcercuei 0:03b5121a232e 291 case XML_SCHEMAS_FLOAT:
pcercuei 0:03b5121a232e 292 case XML_SCHEMAS_DOUBLE:
pcercuei 0:03b5121a232e 293 case XML_SCHEMAS_BOOLEAN:
pcercuei 0:03b5121a232e 294 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 295 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 296 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 297 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 298 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 299 ret->flags |= XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE;
pcercuei 0:03b5121a232e 300 break;
pcercuei 0:03b5121a232e 301 default:
pcercuei 0:03b5121a232e 302 break;
pcercuei 0:03b5121a232e 303 }
pcercuei 0:03b5121a232e 304 /*
pcercuei 0:03b5121a232e 305 * Set variety.
pcercuei 0:03b5121a232e 306 */
pcercuei 0:03b5121a232e 307 switch (type) {
pcercuei 0:03b5121a232e 308 case XML_SCHEMAS_ANYTYPE:
pcercuei 0:03b5121a232e 309 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 310 break;
pcercuei 0:03b5121a232e 311 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 312 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 313 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 314 ret->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
pcercuei 0:03b5121a232e 315 ret->facets = xmlSchemaNewMinLengthFacet(1);
pcercuei 0:03b5121a232e 316 ret->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
pcercuei 0:03b5121a232e 317 break;
pcercuei 0:03b5121a232e 318 default:
pcercuei 0:03b5121a232e 319 ret->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
pcercuei 0:03b5121a232e 320 break;
pcercuei 0:03b5121a232e 321 }
pcercuei 0:03b5121a232e 322 xmlHashAddEntry2(xmlSchemaTypesBank, ret->name,
pcercuei 0:03b5121a232e 323 XML_SCHEMAS_NAMESPACE_NAME, ret);
pcercuei 0:03b5121a232e 324 ret->builtInType = type;
pcercuei 0:03b5121a232e 325 return(ret);
pcercuei 0:03b5121a232e 326 }
pcercuei 0:03b5121a232e 327
pcercuei 0:03b5121a232e 328 /*
pcercuei 0:03b5121a232e 329 * WARNING: Those type reside normally in xmlschemas.c but are
pcercuei 0:03b5121a232e 330 * redefined here locally in oder of being able to use them for xs:anyType-
pcercuei 0:03b5121a232e 331 * TODO: Remove those definition if we move the types to a header file.
pcercuei 0:03b5121a232e 332 * TODO: Always keep those structs up-to-date with the originals.
pcercuei 0:03b5121a232e 333 */
pcercuei 0:03b5121a232e 334 #define UNBOUNDED (1 << 30)
pcercuei 0:03b5121a232e 335
pcercuei 0:03b5121a232e 336 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
pcercuei 0:03b5121a232e 337 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
pcercuei 0:03b5121a232e 338 struct _xmlSchemaTreeItem {
pcercuei 0:03b5121a232e 339 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 340 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 341 xmlSchemaTreeItemPtr next;
pcercuei 0:03b5121a232e 342 xmlSchemaTreeItemPtr children;
pcercuei 0:03b5121a232e 343 };
pcercuei 0:03b5121a232e 344
pcercuei 0:03b5121a232e 345 typedef struct _xmlSchemaParticle xmlSchemaParticle;
pcercuei 0:03b5121a232e 346 typedef xmlSchemaParticle *xmlSchemaParticlePtr;
pcercuei 0:03b5121a232e 347 struct _xmlSchemaParticle {
pcercuei 0:03b5121a232e 348 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 349 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 350 xmlSchemaTreeItemPtr next;
pcercuei 0:03b5121a232e 351 xmlSchemaTreeItemPtr children;
pcercuei 0:03b5121a232e 352 int minOccurs;
pcercuei 0:03b5121a232e 353 int maxOccurs;
pcercuei 0:03b5121a232e 354 xmlNodePtr node;
pcercuei 0:03b5121a232e 355 };
pcercuei 0:03b5121a232e 356
pcercuei 0:03b5121a232e 357 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
pcercuei 0:03b5121a232e 358 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
pcercuei 0:03b5121a232e 359 struct _xmlSchemaModelGroup {
pcercuei 0:03b5121a232e 360 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 361 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 362 xmlSchemaTreeItemPtr next;
pcercuei 0:03b5121a232e 363 xmlSchemaTreeItemPtr children;
pcercuei 0:03b5121a232e 364 xmlNodePtr node;
pcercuei 0:03b5121a232e 365 };
pcercuei 0:03b5121a232e 366
pcercuei 0:03b5121a232e 367 static xmlSchemaParticlePtr
pcercuei 0:03b5121a232e 368 xmlSchemaAddParticle(void)
pcercuei 0:03b5121a232e 369 {
pcercuei 0:03b5121a232e 370 xmlSchemaParticlePtr ret = NULL;
pcercuei 0:03b5121a232e 371
pcercuei 0:03b5121a232e 372 ret = (xmlSchemaParticlePtr)
pcercuei 0:03b5121a232e 373 xmlMalloc(sizeof(xmlSchemaParticle));
pcercuei 0:03b5121a232e 374 if (ret == NULL) {
pcercuei 0:03b5121a232e 375 xmlSchemaTypeErrMemory(NULL, "allocating particle component");
pcercuei 0:03b5121a232e 376 return (NULL);
pcercuei 0:03b5121a232e 377 }
pcercuei 0:03b5121a232e 378 memset(ret, 0, sizeof(xmlSchemaParticle));
pcercuei 0:03b5121a232e 379 ret->type = XML_SCHEMA_TYPE_PARTICLE;
pcercuei 0:03b5121a232e 380 ret->minOccurs = 1;
pcercuei 0:03b5121a232e 381 ret->maxOccurs = 1;
pcercuei 0:03b5121a232e 382 return (ret);
pcercuei 0:03b5121a232e 383 }
pcercuei 0:03b5121a232e 384
pcercuei 0:03b5121a232e 385 /*
pcercuei 0:03b5121a232e 386 * xmlSchemaInitTypes:
pcercuei 0:03b5121a232e 387 *
pcercuei 0:03b5121a232e 388 * Initialize the default XML Schemas type library
pcercuei 0:03b5121a232e 389 */
pcercuei 0:03b5121a232e 390 void
pcercuei 0:03b5121a232e 391 xmlSchemaInitTypes(void)
pcercuei 0:03b5121a232e 392 {
pcercuei 0:03b5121a232e 393 if (xmlSchemaTypesInitialized != 0)
pcercuei 0:03b5121a232e 394 return;
pcercuei 0:03b5121a232e 395 xmlSchemaTypesBank = xmlHashCreate(40);
pcercuei 0:03b5121a232e 396
pcercuei 0:03b5121a232e 397
pcercuei 0:03b5121a232e 398 /*
pcercuei 0:03b5121a232e 399 * 3.4.7 Built-in Complex Type Definition
pcercuei 0:03b5121a232e 400 */
pcercuei 0:03b5121a232e 401 xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType",
pcercuei 0:03b5121a232e 402 XML_SCHEMAS_ANYTYPE,
pcercuei 0:03b5121a232e 403 NULL);
pcercuei 0:03b5121a232e 404 xmlSchemaTypeAnyTypeDef->baseType = xmlSchemaTypeAnyTypeDef;
pcercuei 0:03b5121a232e 405 xmlSchemaTypeAnyTypeDef->contentType = XML_SCHEMA_CONTENT_MIXED;
pcercuei 0:03b5121a232e 406 /*
pcercuei 0:03b5121a232e 407 * Init the content type.
pcercuei 0:03b5121a232e 408 */
pcercuei 0:03b5121a232e 409 xmlSchemaTypeAnyTypeDef->contentType = XML_SCHEMA_CONTENT_MIXED;
pcercuei 0:03b5121a232e 410 {
pcercuei 0:03b5121a232e 411 xmlSchemaParticlePtr particle;
pcercuei 0:03b5121a232e 412 xmlSchemaModelGroupPtr sequence;
pcercuei 0:03b5121a232e 413 xmlSchemaWildcardPtr wild;
pcercuei 0:03b5121a232e 414 /* First particle. */
pcercuei 0:03b5121a232e 415 particle = xmlSchemaAddParticle();
pcercuei 0:03b5121a232e 416 if (particle == NULL)
pcercuei 0:03b5121a232e 417 return;
pcercuei 0:03b5121a232e 418 xmlSchemaTypeAnyTypeDef->subtypes = (xmlSchemaTypePtr) particle;
pcercuei 0:03b5121a232e 419 /* Sequence model group. */
pcercuei 0:03b5121a232e 420 sequence = (xmlSchemaModelGroupPtr)
pcercuei 0:03b5121a232e 421 xmlMalloc(sizeof(xmlSchemaModelGroup));
pcercuei 0:03b5121a232e 422 if (sequence == NULL) {
pcercuei 0:03b5121a232e 423 xmlSchemaTypeErrMemory(NULL, "allocating model group component");
pcercuei 0:03b5121a232e 424 return;
pcercuei 0:03b5121a232e 425 }
pcercuei 0:03b5121a232e 426 memset(sequence, 0, sizeof(xmlSchemaModelGroup));
pcercuei 0:03b5121a232e 427 sequence->type = XML_SCHEMA_TYPE_SEQUENCE;
pcercuei 0:03b5121a232e 428 particle->children = (xmlSchemaTreeItemPtr) sequence;
pcercuei 0:03b5121a232e 429 /* Second particle. */
pcercuei 0:03b5121a232e 430 particle = xmlSchemaAddParticle();
pcercuei 0:03b5121a232e 431 if (particle == NULL)
pcercuei 0:03b5121a232e 432 return;
pcercuei 0:03b5121a232e 433 particle->minOccurs = 0;
pcercuei 0:03b5121a232e 434 particle->maxOccurs = UNBOUNDED;
pcercuei 0:03b5121a232e 435 sequence->children = (xmlSchemaTreeItemPtr) particle;
pcercuei 0:03b5121a232e 436 /* The wildcard */
pcercuei 0:03b5121a232e 437 wild = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
pcercuei 0:03b5121a232e 438 if (wild == NULL) {
pcercuei 0:03b5121a232e 439 xmlSchemaTypeErrMemory(NULL, "allocating wildcard component");
pcercuei 0:03b5121a232e 440 return;
pcercuei 0:03b5121a232e 441 }
pcercuei 0:03b5121a232e 442 memset(wild, 0, sizeof(xmlSchemaWildcard));
pcercuei 0:03b5121a232e 443 wild->type = XML_SCHEMA_TYPE_ANY;
pcercuei 0:03b5121a232e 444 wild->any = 1;
pcercuei 0:03b5121a232e 445 wild->processContents = XML_SCHEMAS_ANY_LAX;
pcercuei 0:03b5121a232e 446 particle->children = (xmlSchemaTreeItemPtr) wild;
pcercuei 0:03b5121a232e 447 /*
pcercuei 0:03b5121a232e 448 * Create the attribute wildcard.
pcercuei 0:03b5121a232e 449 */
pcercuei 0:03b5121a232e 450 wild = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
pcercuei 0:03b5121a232e 451 if (wild == NULL) {
pcercuei 0:03b5121a232e 452 xmlSchemaTypeErrMemory(NULL, "could not create an attribute "
pcercuei 0:03b5121a232e 453 "wildcard on anyType");
pcercuei 0:03b5121a232e 454 return;
pcercuei 0:03b5121a232e 455 }
pcercuei 0:03b5121a232e 456 memset(wild, 0, sizeof(xmlSchemaWildcard));
pcercuei 0:03b5121a232e 457 wild->any = 1;
pcercuei 0:03b5121a232e 458 wild->processContents = XML_SCHEMAS_ANY_LAX;
pcercuei 0:03b5121a232e 459 xmlSchemaTypeAnyTypeDef->attributeWildcard = wild;
pcercuei 0:03b5121a232e 460 }
pcercuei 0:03b5121a232e 461 xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType",
pcercuei 0:03b5121a232e 462 XML_SCHEMAS_ANYSIMPLETYPE,
pcercuei 0:03b5121a232e 463 xmlSchemaTypeAnyTypeDef);
pcercuei 0:03b5121a232e 464 /*
pcercuei 0:03b5121a232e 465 * primitive datatypes
pcercuei 0:03b5121a232e 466 */
pcercuei 0:03b5121a232e 467 xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string",
pcercuei 0:03b5121a232e 468 XML_SCHEMAS_STRING,
pcercuei 0:03b5121a232e 469 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 470 xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal",
pcercuei 0:03b5121a232e 471 XML_SCHEMAS_DECIMAL,
pcercuei 0:03b5121a232e 472 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 473 xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date",
pcercuei 0:03b5121a232e 474 XML_SCHEMAS_DATE,
pcercuei 0:03b5121a232e 475 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 476 xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime",
pcercuei 0:03b5121a232e 477 XML_SCHEMAS_DATETIME,
pcercuei 0:03b5121a232e 478 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 479 xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time",
pcercuei 0:03b5121a232e 480 XML_SCHEMAS_TIME,
pcercuei 0:03b5121a232e 481 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 482 xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear",
pcercuei 0:03b5121a232e 483 XML_SCHEMAS_GYEAR,
pcercuei 0:03b5121a232e 484 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 485 xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth",
pcercuei 0:03b5121a232e 486 XML_SCHEMAS_GYEARMONTH,
pcercuei 0:03b5121a232e 487 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 488 xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth",
pcercuei 0:03b5121a232e 489 XML_SCHEMAS_GMONTH,
pcercuei 0:03b5121a232e 490 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 491 xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay",
pcercuei 0:03b5121a232e 492 XML_SCHEMAS_GMONTHDAY,
pcercuei 0:03b5121a232e 493 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 494 xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay",
pcercuei 0:03b5121a232e 495 XML_SCHEMAS_GDAY,
pcercuei 0:03b5121a232e 496 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 497 xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration",
pcercuei 0:03b5121a232e 498 XML_SCHEMAS_DURATION,
pcercuei 0:03b5121a232e 499 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 500 xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float",
pcercuei 0:03b5121a232e 501 XML_SCHEMAS_FLOAT,
pcercuei 0:03b5121a232e 502 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 503 xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double",
pcercuei 0:03b5121a232e 504 XML_SCHEMAS_DOUBLE,
pcercuei 0:03b5121a232e 505 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 506 xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType("boolean",
pcercuei 0:03b5121a232e 507 XML_SCHEMAS_BOOLEAN,
pcercuei 0:03b5121a232e 508 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 509 xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType("anyURI",
pcercuei 0:03b5121a232e 510 XML_SCHEMAS_ANYURI,
pcercuei 0:03b5121a232e 511 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 512 xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType("hexBinary",
pcercuei 0:03b5121a232e 513 XML_SCHEMAS_HEXBINARY,
pcercuei 0:03b5121a232e 514 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 515 xmlSchemaTypeBase64BinaryDef
pcercuei 0:03b5121a232e 516 = xmlSchemaInitBasicType("base64Binary", XML_SCHEMAS_BASE64BINARY,
pcercuei 0:03b5121a232e 517 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 518 xmlSchemaTypeNotationDef = xmlSchemaInitBasicType("NOTATION",
pcercuei 0:03b5121a232e 519 XML_SCHEMAS_NOTATION,
pcercuei 0:03b5121a232e 520 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 521 xmlSchemaTypeQNameDef = xmlSchemaInitBasicType("QName",
pcercuei 0:03b5121a232e 522 XML_SCHEMAS_QNAME,
pcercuei 0:03b5121a232e 523 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 524
pcercuei 0:03b5121a232e 525 /*
pcercuei 0:03b5121a232e 526 * derived datatypes
pcercuei 0:03b5121a232e 527 */
pcercuei 0:03b5121a232e 528 xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType("integer",
pcercuei 0:03b5121a232e 529 XML_SCHEMAS_INTEGER,
pcercuei 0:03b5121a232e 530 xmlSchemaTypeDecimalDef);
pcercuei 0:03b5121a232e 531 xmlSchemaTypeNonPositiveIntegerDef =
pcercuei 0:03b5121a232e 532 xmlSchemaInitBasicType("nonPositiveInteger",
pcercuei 0:03b5121a232e 533 XML_SCHEMAS_NPINTEGER,
pcercuei 0:03b5121a232e 534 xmlSchemaTypeIntegerDef);
pcercuei 0:03b5121a232e 535 xmlSchemaTypeNegativeIntegerDef =
pcercuei 0:03b5121a232e 536 xmlSchemaInitBasicType("negativeInteger", XML_SCHEMAS_NINTEGER,
pcercuei 0:03b5121a232e 537 xmlSchemaTypeNonPositiveIntegerDef);
pcercuei 0:03b5121a232e 538 xmlSchemaTypeLongDef =
pcercuei 0:03b5121a232e 539 xmlSchemaInitBasicType("long", XML_SCHEMAS_LONG,
pcercuei 0:03b5121a232e 540 xmlSchemaTypeIntegerDef);
pcercuei 0:03b5121a232e 541 xmlSchemaTypeIntDef = xmlSchemaInitBasicType("int", XML_SCHEMAS_INT,
pcercuei 0:03b5121a232e 542 xmlSchemaTypeLongDef);
pcercuei 0:03b5121a232e 543 xmlSchemaTypeShortDef = xmlSchemaInitBasicType("short",
pcercuei 0:03b5121a232e 544 XML_SCHEMAS_SHORT,
pcercuei 0:03b5121a232e 545 xmlSchemaTypeIntDef);
pcercuei 0:03b5121a232e 546 xmlSchemaTypeByteDef = xmlSchemaInitBasicType("byte",
pcercuei 0:03b5121a232e 547 XML_SCHEMAS_BYTE,
pcercuei 0:03b5121a232e 548 xmlSchemaTypeShortDef);
pcercuei 0:03b5121a232e 549 xmlSchemaTypeNonNegativeIntegerDef =
pcercuei 0:03b5121a232e 550 xmlSchemaInitBasicType("nonNegativeInteger",
pcercuei 0:03b5121a232e 551 XML_SCHEMAS_NNINTEGER,
pcercuei 0:03b5121a232e 552 xmlSchemaTypeIntegerDef);
pcercuei 0:03b5121a232e 553 xmlSchemaTypeUnsignedLongDef =
pcercuei 0:03b5121a232e 554 xmlSchemaInitBasicType("unsignedLong", XML_SCHEMAS_ULONG,
pcercuei 0:03b5121a232e 555 xmlSchemaTypeNonNegativeIntegerDef);
pcercuei 0:03b5121a232e 556 xmlSchemaTypeUnsignedIntDef =
pcercuei 0:03b5121a232e 557 xmlSchemaInitBasicType("unsignedInt", XML_SCHEMAS_UINT,
pcercuei 0:03b5121a232e 558 xmlSchemaTypeUnsignedLongDef);
pcercuei 0:03b5121a232e 559 xmlSchemaTypeUnsignedShortDef =
pcercuei 0:03b5121a232e 560 xmlSchemaInitBasicType("unsignedShort", XML_SCHEMAS_USHORT,
pcercuei 0:03b5121a232e 561 xmlSchemaTypeUnsignedIntDef);
pcercuei 0:03b5121a232e 562 xmlSchemaTypeUnsignedByteDef =
pcercuei 0:03b5121a232e 563 xmlSchemaInitBasicType("unsignedByte", XML_SCHEMAS_UBYTE,
pcercuei 0:03b5121a232e 564 xmlSchemaTypeUnsignedShortDef);
pcercuei 0:03b5121a232e 565 xmlSchemaTypePositiveIntegerDef =
pcercuei 0:03b5121a232e 566 xmlSchemaInitBasicType("positiveInteger", XML_SCHEMAS_PINTEGER,
pcercuei 0:03b5121a232e 567 xmlSchemaTypeNonNegativeIntegerDef);
pcercuei 0:03b5121a232e 568 xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType("normalizedString",
pcercuei 0:03b5121a232e 569 XML_SCHEMAS_NORMSTRING,
pcercuei 0:03b5121a232e 570 xmlSchemaTypeStringDef);
pcercuei 0:03b5121a232e 571 xmlSchemaTypeTokenDef = xmlSchemaInitBasicType("token",
pcercuei 0:03b5121a232e 572 XML_SCHEMAS_TOKEN,
pcercuei 0:03b5121a232e 573 xmlSchemaTypeNormStringDef);
pcercuei 0:03b5121a232e 574 xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType("language",
pcercuei 0:03b5121a232e 575 XML_SCHEMAS_LANGUAGE,
pcercuei 0:03b5121a232e 576 xmlSchemaTypeTokenDef);
pcercuei 0:03b5121a232e 577 xmlSchemaTypeNameDef = xmlSchemaInitBasicType("Name",
pcercuei 0:03b5121a232e 578 XML_SCHEMAS_NAME,
pcercuei 0:03b5121a232e 579 xmlSchemaTypeTokenDef);
pcercuei 0:03b5121a232e 580 xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType("NMTOKEN",
pcercuei 0:03b5121a232e 581 XML_SCHEMAS_NMTOKEN,
pcercuei 0:03b5121a232e 582 xmlSchemaTypeTokenDef);
pcercuei 0:03b5121a232e 583 xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType("NCName",
pcercuei 0:03b5121a232e 584 XML_SCHEMAS_NCNAME,
pcercuei 0:03b5121a232e 585 xmlSchemaTypeNameDef);
pcercuei 0:03b5121a232e 586 xmlSchemaTypeIdDef = xmlSchemaInitBasicType("ID", XML_SCHEMAS_ID,
pcercuei 0:03b5121a232e 587 xmlSchemaTypeNCNameDef);
pcercuei 0:03b5121a232e 588 xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType("IDREF",
pcercuei 0:03b5121a232e 589 XML_SCHEMAS_IDREF,
pcercuei 0:03b5121a232e 590 xmlSchemaTypeNCNameDef);
pcercuei 0:03b5121a232e 591 xmlSchemaTypeEntityDef = xmlSchemaInitBasicType("ENTITY",
pcercuei 0:03b5121a232e 592 XML_SCHEMAS_ENTITY,
pcercuei 0:03b5121a232e 593 xmlSchemaTypeNCNameDef);
pcercuei 0:03b5121a232e 594 /*
pcercuei 0:03b5121a232e 595 * Derived list types.
pcercuei 0:03b5121a232e 596 */
pcercuei 0:03b5121a232e 597 /* ENTITIES */
pcercuei 0:03b5121a232e 598 xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType("ENTITIES",
pcercuei 0:03b5121a232e 599 XML_SCHEMAS_ENTITIES,
pcercuei 0:03b5121a232e 600 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 601 xmlSchemaTypeEntitiesDef->subtypes = xmlSchemaTypeEntityDef;
pcercuei 0:03b5121a232e 602 /* IDREFS */
pcercuei 0:03b5121a232e 603 xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType("IDREFS",
pcercuei 0:03b5121a232e 604 XML_SCHEMAS_IDREFS,
pcercuei 0:03b5121a232e 605 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 606 xmlSchemaTypeIdrefsDef->subtypes = xmlSchemaTypeIdrefDef;
pcercuei 0:03b5121a232e 607
pcercuei 0:03b5121a232e 608 /* NMTOKENS */
pcercuei 0:03b5121a232e 609 xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType("NMTOKENS",
pcercuei 0:03b5121a232e 610 XML_SCHEMAS_NMTOKENS,
pcercuei 0:03b5121a232e 611 xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 612 xmlSchemaTypeNmtokensDef->subtypes = xmlSchemaTypeNmtokenDef;
pcercuei 0:03b5121a232e 613
pcercuei 0:03b5121a232e 614 xmlSchemaTypesInitialized = 1;
pcercuei 0:03b5121a232e 615 }
pcercuei 0:03b5121a232e 616
pcercuei 0:03b5121a232e 617 /**
pcercuei 0:03b5121a232e 618 * xmlSchemaCleanupTypes:
pcercuei 0:03b5121a232e 619 *
pcercuei 0:03b5121a232e 620 * Cleanup the default XML Schemas type library
pcercuei 0:03b5121a232e 621 */
pcercuei 0:03b5121a232e 622 void
pcercuei 0:03b5121a232e 623 xmlSchemaCleanupTypes(void) {
pcercuei 0:03b5121a232e 624 if (xmlSchemaTypesInitialized == 0)
pcercuei 0:03b5121a232e 625 return;
pcercuei 0:03b5121a232e 626 /*
pcercuei 0:03b5121a232e 627 * Free xs:anyType.
pcercuei 0:03b5121a232e 628 */
pcercuei 0:03b5121a232e 629 {
pcercuei 0:03b5121a232e 630 xmlSchemaParticlePtr particle;
pcercuei 0:03b5121a232e 631 /* Attribute wildcard. */
pcercuei 0:03b5121a232e 632 xmlSchemaFreeWildcard(xmlSchemaTypeAnyTypeDef->attributeWildcard);
pcercuei 0:03b5121a232e 633 /* Content type. */
pcercuei 0:03b5121a232e 634 particle = (xmlSchemaParticlePtr) xmlSchemaTypeAnyTypeDef->subtypes;
pcercuei 0:03b5121a232e 635 /* Wildcard. */
pcercuei 0:03b5121a232e 636 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr)
pcercuei 0:03b5121a232e 637 particle->children->children->children);
pcercuei 0:03b5121a232e 638 xmlFree((xmlSchemaParticlePtr) particle->children->children);
pcercuei 0:03b5121a232e 639 /* Sequence model group. */
pcercuei 0:03b5121a232e 640 xmlFree((xmlSchemaModelGroupPtr) particle->children);
pcercuei 0:03b5121a232e 641 xmlFree((xmlSchemaParticlePtr) particle);
pcercuei 0:03b5121a232e 642 xmlSchemaTypeAnyTypeDef->subtypes = NULL;
pcercuei 0:03b5121a232e 643 }
pcercuei 0:03b5121a232e 644 xmlHashFree(xmlSchemaTypesBank, (xmlHashDeallocator) xmlSchemaFreeType);
pcercuei 0:03b5121a232e 645 xmlSchemaTypesInitialized = 0;
pcercuei 0:03b5121a232e 646 }
pcercuei 0:03b5121a232e 647
pcercuei 0:03b5121a232e 648 /**
pcercuei 0:03b5121a232e 649 * xmlSchemaIsBuiltInTypeFacet:
pcercuei 0:03b5121a232e 650 * @type: the built-in type
pcercuei 0:03b5121a232e 651 * @facetType: the facet type
pcercuei 0:03b5121a232e 652 *
pcercuei 0:03b5121a232e 653 * Evaluates if a specific facet can be
pcercuei 0:03b5121a232e 654 * used in conjunction with a type.
pcercuei 0:03b5121a232e 655 *
pcercuei 0:03b5121a232e 656 * Returns 1 if the facet can be used with the given built-in type,
pcercuei 0:03b5121a232e 657 * 0 otherwise and -1 in case the type is not a built-in type.
pcercuei 0:03b5121a232e 658 */
pcercuei 0:03b5121a232e 659 int
pcercuei 0:03b5121a232e 660 xmlSchemaIsBuiltInTypeFacet(xmlSchemaTypePtr type, int facetType)
pcercuei 0:03b5121a232e 661 {
pcercuei 0:03b5121a232e 662 if (type == NULL)
pcercuei 0:03b5121a232e 663 return (-1);
pcercuei 0:03b5121a232e 664 if (type->type != XML_SCHEMA_TYPE_BASIC)
pcercuei 0:03b5121a232e 665 return (-1);
pcercuei 0:03b5121a232e 666 switch (type->builtInType) {
pcercuei 0:03b5121a232e 667 case XML_SCHEMAS_BOOLEAN:
pcercuei 0:03b5121a232e 668 if ((facetType == XML_SCHEMA_FACET_PATTERN) ||
pcercuei 0:03b5121a232e 669 (facetType == XML_SCHEMA_FACET_WHITESPACE))
pcercuei 0:03b5121a232e 670 return (1);
pcercuei 0:03b5121a232e 671 else
pcercuei 0:03b5121a232e 672 return (0);
pcercuei 0:03b5121a232e 673 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 674 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 675 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 676 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 677 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 678 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 679 if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
pcercuei 0:03b5121a232e 680 (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
pcercuei 0:03b5121a232e 681 (facetType == XML_SCHEMA_FACET_MAXLENGTH) ||
pcercuei 0:03b5121a232e 682 (facetType == XML_SCHEMA_FACET_PATTERN) ||
pcercuei 0:03b5121a232e 683 (facetType == XML_SCHEMA_FACET_ENUMERATION) ||
pcercuei 0:03b5121a232e 684 (facetType == XML_SCHEMA_FACET_WHITESPACE))
pcercuei 0:03b5121a232e 685 return (1);
pcercuei 0:03b5121a232e 686 else
pcercuei 0:03b5121a232e 687 return (0);
pcercuei 0:03b5121a232e 688 case XML_SCHEMAS_DECIMAL:
pcercuei 0:03b5121a232e 689 if ((facetType == XML_SCHEMA_FACET_TOTALDIGITS) ||
pcercuei 0:03b5121a232e 690 (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) ||
pcercuei 0:03b5121a232e 691 (facetType == XML_SCHEMA_FACET_PATTERN) ||
pcercuei 0:03b5121a232e 692 (facetType == XML_SCHEMA_FACET_WHITESPACE) ||
pcercuei 0:03b5121a232e 693 (facetType == XML_SCHEMA_FACET_ENUMERATION) ||
pcercuei 0:03b5121a232e 694 (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) ||
pcercuei 0:03b5121a232e 695 (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) ||
pcercuei 0:03b5121a232e 696 (facetType == XML_SCHEMA_FACET_MININCLUSIVE) ||
pcercuei 0:03b5121a232e 697 (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE))
pcercuei 0:03b5121a232e 698 return (1);
pcercuei 0:03b5121a232e 699 else
pcercuei 0:03b5121a232e 700 return (0);
pcercuei 0:03b5121a232e 701 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 702 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 703 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 704 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 705 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 706 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 707 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 708 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 709 case XML_SCHEMAS_DURATION:
pcercuei 0:03b5121a232e 710 case XML_SCHEMAS_FLOAT:
pcercuei 0:03b5121a232e 711 case XML_SCHEMAS_DOUBLE:
pcercuei 0:03b5121a232e 712 if ((facetType == XML_SCHEMA_FACET_PATTERN) ||
pcercuei 0:03b5121a232e 713 (facetType == XML_SCHEMA_FACET_ENUMERATION) ||
pcercuei 0:03b5121a232e 714 (facetType == XML_SCHEMA_FACET_WHITESPACE) ||
pcercuei 0:03b5121a232e 715 (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) ||
pcercuei 0:03b5121a232e 716 (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) ||
pcercuei 0:03b5121a232e 717 (facetType == XML_SCHEMA_FACET_MININCLUSIVE) ||
pcercuei 0:03b5121a232e 718 (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE))
pcercuei 0:03b5121a232e 719 return (1);
pcercuei 0:03b5121a232e 720 else
pcercuei 0:03b5121a232e 721 return (0);
pcercuei 0:03b5121a232e 722 default:
pcercuei 0:03b5121a232e 723 break;
pcercuei 0:03b5121a232e 724 }
pcercuei 0:03b5121a232e 725 return (0);
pcercuei 0:03b5121a232e 726 }
pcercuei 0:03b5121a232e 727
pcercuei 0:03b5121a232e 728 /**
pcercuei 0:03b5121a232e 729 * xmlSchemaGetBuiltInType:
pcercuei 0:03b5121a232e 730 * @type: the type of the built in type
pcercuei 0:03b5121a232e 731 *
pcercuei 0:03b5121a232e 732 * Gives you the type struct for a built-in
pcercuei 0:03b5121a232e 733 * type by its type id.
pcercuei 0:03b5121a232e 734 *
pcercuei 0:03b5121a232e 735 * Returns the type if found, NULL otherwise.
pcercuei 0:03b5121a232e 736 */
pcercuei 0:03b5121a232e 737 xmlSchemaTypePtr
pcercuei 0:03b5121a232e 738 xmlSchemaGetBuiltInType(xmlSchemaValType type)
pcercuei 0:03b5121a232e 739 {
pcercuei 0:03b5121a232e 740 if (xmlSchemaTypesInitialized == 0)
pcercuei 0:03b5121a232e 741 xmlSchemaInitTypes();
pcercuei 0:03b5121a232e 742 switch (type) {
pcercuei 0:03b5121a232e 743
pcercuei 0:03b5121a232e 744 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 745 return (xmlSchemaTypeAnySimpleTypeDef);
pcercuei 0:03b5121a232e 746 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 747 return (xmlSchemaTypeStringDef);
pcercuei 0:03b5121a232e 748 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 749 return (xmlSchemaTypeNormStringDef);
pcercuei 0:03b5121a232e 750 case XML_SCHEMAS_DECIMAL:
pcercuei 0:03b5121a232e 751 return (xmlSchemaTypeDecimalDef);
pcercuei 0:03b5121a232e 752 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 753 return (xmlSchemaTypeTimeDef);
pcercuei 0:03b5121a232e 754 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 755 return (xmlSchemaTypeGDayDef);
pcercuei 0:03b5121a232e 756 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 757 return (xmlSchemaTypeGMonthDef);
pcercuei 0:03b5121a232e 758 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 759 return (xmlSchemaTypeGMonthDayDef);
pcercuei 0:03b5121a232e 760 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 761 return (xmlSchemaTypeGYearDef);
pcercuei 0:03b5121a232e 762 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 763 return (xmlSchemaTypeGYearMonthDef);
pcercuei 0:03b5121a232e 764 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 765 return (xmlSchemaTypeDateDef);
pcercuei 0:03b5121a232e 766 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 767 return (xmlSchemaTypeDatetimeDef);
pcercuei 0:03b5121a232e 768 case XML_SCHEMAS_DURATION:
pcercuei 0:03b5121a232e 769 return (xmlSchemaTypeDurationDef);
pcercuei 0:03b5121a232e 770 case XML_SCHEMAS_FLOAT:
pcercuei 0:03b5121a232e 771 return (xmlSchemaTypeFloatDef);
pcercuei 0:03b5121a232e 772 case XML_SCHEMAS_DOUBLE:
pcercuei 0:03b5121a232e 773 return (xmlSchemaTypeDoubleDef);
pcercuei 0:03b5121a232e 774 case XML_SCHEMAS_BOOLEAN:
pcercuei 0:03b5121a232e 775 return (xmlSchemaTypeBooleanDef);
pcercuei 0:03b5121a232e 776 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 777 return (xmlSchemaTypeTokenDef);
pcercuei 0:03b5121a232e 778 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 779 return (xmlSchemaTypeLanguageDef);
pcercuei 0:03b5121a232e 780 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 781 return (xmlSchemaTypeNmtokenDef);
pcercuei 0:03b5121a232e 782 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 783 return (xmlSchemaTypeNmtokensDef);
pcercuei 0:03b5121a232e 784 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 785 return (xmlSchemaTypeNameDef);
pcercuei 0:03b5121a232e 786 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 787 return (xmlSchemaTypeQNameDef);
pcercuei 0:03b5121a232e 788 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 789 return (xmlSchemaTypeNCNameDef);
pcercuei 0:03b5121a232e 790 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 791 return (xmlSchemaTypeIdDef);
pcercuei 0:03b5121a232e 792 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 793 return (xmlSchemaTypeIdrefDef);
pcercuei 0:03b5121a232e 794 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 795 return (xmlSchemaTypeIdrefsDef);
pcercuei 0:03b5121a232e 796 case XML_SCHEMAS_ENTITY:
pcercuei 0:03b5121a232e 797 return (xmlSchemaTypeEntityDef);
pcercuei 0:03b5121a232e 798 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 799 return (xmlSchemaTypeEntitiesDef);
pcercuei 0:03b5121a232e 800 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 801 return (xmlSchemaTypeNotationDef);
pcercuei 0:03b5121a232e 802 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 803 return (xmlSchemaTypeAnyURIDef);
pcercuei 0:03b5121a232e 804 case XML_SCHEMAS_INTEGER:
pcercuei 0:03b5121a232e 805 return (xmlSchemaTypeIntegerDef);
pcercuei 0:03b5121a232e 806 case XML_SCHEMAS_NPINTEGER:
pcercuei 0:03b5121a232e 807 return (xmlSchemaTypeNonPositiveIntegerDef);
pcercuei 0:03b5121a232e 808 case XML_SCHEMAS_NINTEGER:
pcercuei 0:03b5121a232e 809 return (xmlSchemaTypeNegativeIntegerDef);
pcercuei 0:03b5121a232e 810 case XML_SCHEMAS_NNINTEGER:
pcercuei 0:03b5121a232e 811 return (xmlSchemaTypeNonNegativeIntegerDef);
pcercuei 0:03b5121a232e 812 case XML_SCHEMAS_PINTEGER:
pcercuei 0:03b5121a232e 813 return (xmlSchemaTypePositiveIntegerDef);
pcercuei 0:03b5121a232e 814 case XML_SCHEMAS_INT:
pcercuei 0:03b5121a232e 815 return (xmlSchemaTypeIntDef);
pcercuei 0:03b5121a232e 816 case XML_SCHEMAS_UINT:
pcercuei 0:03b5121a232e 817 return (xmlSchemaTypeUnsignedIntDef);
pcercuei 0:03b5121a232e 818 case XML_SCHEMAS_LONG:
pcercuei 0:03b5121a232e 819 return (xmlSchemaTypeLongDef);
pcercuei 0:03b5121a232e 820 case XML_SCHEMAS_ULONG:
pcercuei 0:03b5121a232e 821 return (xmlSchemaTypeUnsignedLongDef);
pcercuei 0:03b5121a232e 822 case XML_SCHEMAS_SHORT:
pcercuei 0:03b5121a232e 823 return (xmlSchemaTypeShortDef);
pcercuei 0:03b5121a232e 824 case XML_SCHEMAS_USHORT:
pcercuei 0:03b5121a232e 825 return (xmlSchemaTypeUnsignedShortDef);
pcercuei 0:03b5121a232e 826 case XML_SCHEMAS_BYTE:
pcercuei 0:03b5121a232e 827 return (xmlSchemaTypeByteDef);
pcercuei 0:03b5121a232e 828 case XML_SCHEMAS_UBYTE:
pcercuei 0:03b5121a232e 829 return (xmlSchemaTypeUnsignedByteDef);
pcercuei 0:03b5121a232e 830 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 831 return (xmlSchemaTypeHexBinaryDef);
pcercuei 0:03b5121a232e 832 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 833 return (xmlSchemaTypeBase64BinaryDef);
pcercuei 0:03b5121a232e 834 case XML_SCHEMAS_ANYTYPE:
pcercuei 0:03b5121a232e 835 return (xmlSchemaTypeAnyTypeDef);
pcercuei 0:03b5121a232e 836 default:
pcercuei 0:03b5121a232e 837 return (NULL);
pcercuei 0:03b5121a232e 838 }
pcercuei 0:03b5121a232e 839 }
pcercuei 0:03b5121a232e 840
pcercuei 0:03b5121a232e 841 /**
pcercuei 0:03b5121a232e 842 * xmlSchemaValueAppend:
pcercuei 0:03b5121a232e 843 * @prev: the value
pcercuei 0:03b5121a232e 844 * @cur: the value to be appended
pcercuei 0:03b5121a232e 845 *
pcercuei 0:03b5121a232e 846 * Appends a next sibling to a list of computed values.
pcercuei 0:03b5121a232e 847 *
pcercuei 0:03b5121a232e 848 * Returns 0 if succeeded and -1 on API errors.
pcercuei 0:03b5121a232e 849 */
pcercuei 0:03b5121a232e 850 int
pcercuei 0:03b5121a232e 851 xmlSchemaValueAppend(xmlSchemaValPtr prev, xmlSchemaValPtr cur) {
pcercuei 0:03b5121a232e 852
pcercuei 0:03b5121a232e 853 if ((prev == NULL) || (cur == NULL))
pcercuei 0:03b5121a232e 854 return (-1);
pcercuei 0:03b5121a232e 855 prev->next = cur;
pcercuei 0:03b5121a232e 856 return (0);
pcercuei 0:03b5121a232e 857 }
pcercuei 0:03b5121a232e 858
pcercuei 0:03b5121a232e 859 /**
pcercuei 0:03b5121a232e 860 * xmlSchemaValueGetNext:
pcercuei 0:03b5121a232e 861 * @cur: the value
pcercuei 0:03b5121a232e 862 *
pcercuei 0:03b5121a232e 863 * Accessor for the next sibling of a list of computed values.
pcercuei 0:03b5121a232e 864 *
pcercuei 0:03b5121a232e 865 * Returns the next value or NULL if there was none, or on
pcercuei 0:03b5121a232e 866 * API errors.
pcercuei 0:03b5121a232e 867 */
pcercuei 0:03b5121a232e 868 xmlSchemaValPtr
pcercuei 0:03b5121a232e 869 xmlSchemaValueGetNext(xmlSchemaValPtr cur) {
pcercuei 0:03b5121a232e 870
pcercuei 0:03b5121a232e 871 if (cur == NULL)
pcercuei 0:03b5121a232e 872 return (NULL);
pcercuei 0:03b5121a232e 873 return (cur->next);
pcercuei 0:03b5121a232e 874 }
pcercuei 0:03b5121a232e 875
pcercuei 0:03b5121a232e 876 /**
pcercuei 0:03b5121a232e 877 * xmlSchemaValueGetAsString:
pcercuei 0:03b5121a232e 878 * @val: the value
pcercuei 0:03b5121a232e 879 *
pcercuei 0:03b5121a232e 880 * Accessor for the string value of a computed value.
pcercuei 0:03b5121a232e 881 *
pcercuei 0:03b5121a232e 882 * Returns the string value or NULL if there was none, or on
pcercuei 0:03b5121a232e 883 * API errors.
pcercuei 0:03b5121a232e 884 */
pcercuei 0:03b5121a232e 885 const xmlChar *
pcercuei 0:03b5121a232e 886 xmlSchemaValueGetAsString(xmlSchemaValPtr val)
pcercuei 0:03b5121a232e 887 {
pcercuei 0:03b5121a232e 888 if (val == NULL)
pcercuei 0:03b5121a232e 889 return (NULL);
pcercuei 0:03b5121a232e 890 switch (val->type) {
pcercuei 0:03b5121a232e 891 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 892 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 893 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 894 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 895 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 896 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 897 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 898 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 899 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 900 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 901 case XML_SCHEMAS_ENTITY:
pcercuei 0:03b5121a232e 902 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 903 return (BAD_CAST val->value.str);
pcercuei 0:03b5121a232e 904 default:
pcercuei 0:03b5121a232e 905 break;
pcercuei 0:03b5121a232e 906 }
pcercuei 0:03b5121a232e 907 return (NULL);
pcercuei 0:03b5121a232e 908 }
pcercuei 0:03b5121a232e 909
pcercuei 0:03b5121a232e 910 /**
pcercuei 0:03b5121a232e 911 * xmlSchemaValueGetAsBoolean:
pcercuei 0:03b5121a232e 912 * @val: the value
pcercuei 0:03b5121a232e 913 *
pcercuei 0:03b5121a232e 914 * Accessor for the boolean value of a computed value.
pcercuei 0:03b5121a232e 915 *
pcercuei 0:03b5121a232e 916 * Returns 1 if true and 0 if false, or in case of an error. Hmm.
pcercuei 0:03b5121a232e 917 */
pcercuei 0:03b5121a232e 918 int
pcercuei 0:03b5121a232e 919 xmlSchemaValueGetAsBoolean(xmlSchemaValPtr val)
pcercuei 0:03b5121a232e 920 {
pcercuei 0:03b5121a232e 921 if ((val == NULL) || (val->type != XML_SCHEMAS_BOOLEAN))
pcercuei 0:03b5121a232e 922 return (0);
pcercuei 0:03b5121a232e 923 return (val->value.b);
pcercuei 0:03b5121a232e 924 }
pcercuei 0:03b5121a232e 925
pcercuei 0:03b5121a232e 926 /**
pcercuei 0:03b5121a232e 927 * xmlSchemaNewStringValue:
pcercuei 0:03b5121a232e 928 * @type: the value type
pcercuei 0:03b5121a232e 929 * @value: the value
pcercuei 0:03b5121a232e 930 *
pcercuei 0:03b5121a232e 931 * Allocate a new simple type value. The type can be
pcercuei 0:03b5121a232e 932 * of XML_SCHEMAS_STRING.
pcercuei 0:03b5121a232e 933 * WARNING: This one is intended to be expanded for other
pcercuei 0:03b5121a232e 934 * string based types. We need this for anySimpleType as well.
pcercuei 0:03b5121a232e 935 * The given value is consumed and freed with the struct.
pcercuei 0:03b5121a232e 936 *
pcercuei 0:03b5121a232e 937 * Returns a pointer to the new value or NULL in case of error
pcercuei 0:03b5121a232e 938 */
pcercuei 0:03b5121a232e 939 xmlSchemaValPtr
pcercuei 0:03b5121a232e 940 xmlSchemaNewStringValue(xmlSchemaValType type,
pcercuei 0:03b5121a232e 941 const xmlChar *value)
pcercuei 0:03b5121a232e 942 {
pcercuei 0:03b5121a232e 943 xmlSchemaValPtr val;
pcercuei 0:03b5121a232e 944
pcercuei 0:03b5121a232e 945 if (type != XML_SCHEMAS_STRING)
pcercuei 0:03b5121a232e 946 return(NULL);
pcercuei 0:03b5121a232e 947 val = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
pcercuei 0:03b5121a232e 948 if (val == NULL) {
pcercuei 0:03b5121a232e 949 return(NULL);
pcercuei 0:03b5121a232e 950 }
pcercuei 0:03b5121a232e 951 memset(val, 0, sizeof(xmlSchemaVal));
pcercuei 0:03b5121a232e 952 val->type = type;
pcercuei 0:03b5121a232e 953 val->value.str = (xmlChar *) value;
pcercuei 0:03b5121a232e 954 return(val);
pcercuei 0:03b5121a232e 955 }
pcercuei 0:03b5121a232e 956
pcercuei 0:03b5121a232e 957 /**
pcercuei 0:03b5121a232e 958 * xmlSchemaNewNOTATIONValue:
pcercuei 0:03b5121a232e 959 * @name: the notation name
pcercuei 0:03b5121a232e 960 * @ns: the notation namespace name or NULL
pcercuei 0:03b5121a232e 961 *
pcercuei 0:03b5121a232e 962 * Allocate a new NOTATION value.
pcercuei 0:03b5121a232e 963 * The given values are consumed and freed with the struct.
pcercuei 0:03b5121a232e 964 *
pcercuei 0:03b5121a232e 965 * Returns a pointer to the new value or NULL in case of error
pcercuei 0:03b5121a232e 966 */
pcercuei 0:03b5121a232e 967 xmlSchemaValPtr
pcercuei 0:03b5121a232e 968 xmlSchemaNewNOTATIONValue(const xmlChar *name,
pcercuei 0:03b5121a232e 969 const xmlChar *ns)
pcercuei 0:03b5121a232e 970 {
pcercuei 0:03b5121a232e 971 xmlSchemaValPtr val;
pcercuei 0:03b5121a232e 972
pcercuei 0:03b5121a232e 973 val = xmlSchemaNewValue(XML_SCHEMAS_NOTATION);
pcercuei 0:03b5121a232e 974 if (val == NULL)
pcercuei 0:03b5121a232e 975 return (NULL);
pcercuei 0:03b5121a232e 976
pcercuei 0:03b5121a232e 977 val->value.qname.name = (xmlChar *)name;
pcercuei 0:03b5121a232e 978 if (ns != NULL)
pcercuei 0:03b5121a232e 979 val->value.qname.uri = (xmlChar *)ns;
pcercuei 0:03b5121a232e 980 return(val);
pcercuei 0:03b5121a232e 981 }
pcercuei 0:03b5121a232e 982
pcercuei 0:03b5121a232e 983 /**
pcercuei 0:03b5121a232e 984 * xmlSchemaNewQNameValue:
pcercuei 0:03b5121a232e 985 * @namespaceName: the namespace name
pcercuei 0:03b5121a232e 986 * @localName: the local name
pcercuei 0:03b5121a232e 987 *
pcercuei 0:03b5121a232e 988 * Allocate a new QName value.
pcercuei 0:03b5121a232e 989 * The given values are consumed and freed with the struct.
pcercuei 0:03b5121a232e 990 *
pcercuei 0:03b5121a232e 991 * Returns a pointer to the new value or NULL in case of an error.
pcercuei 0:03b5121a232e 992 */
pcercuei 0:03b5121a232e 993 xmlSchemaValPtr
pcercuei 0:03b5121a232e 994 xmlSchemaNewQNameValue(const xmlChar *namespaceName,
pcercuei 0:03b5121a232e 995 const xmlChar *localName)
pcercuei 0:03b5121a232e 996 {
pcercuei 0:03b5121a232e 997 xmlSchemaValPtr val;
pcercuei 0:03b5121a232e 998
pcercuei 0:03b5121a232e 999 val = xmlSchemaNewValue(XML_SCHEMAS_QNAME);
pcercuei 0:03b5121a232e 1000 if (val == NULL)
pcercuei 0:03b5121a232e 1001 return (NULL);
pcercuei 0:03b5121a232e 1002
pcercuei 0:03b5121a232e 1003 val->value.qname.name = (xmlChar *) localName;
pcercuei 0:03b5121a232e 1004 val->value.qname.uri = (xmlChar *) namespaceName;
pcercuei 0:03b5121a232e 1005 return(val);
pcercuei 0:03b5121a232e 1006 }
pcercuei 0:03b5121a232e 1007
pcercuei 0:03b5121a232e 1008 /**
pcercuei 0:03b5121a232e 1009 * xmlSchemaFreeValue:
pcercuei 0:03b5121a232e 1010 * @value: the value to free
pcercuei 0:03b5121a232e 1011 *
pcercuei 0:03b5121a232e 1012 * Cleanup the default XML Schemas type library
pcercuei 0:03b5121a232e 1013 */
pcercuei 0:03b5121a232e 1014 void
pcercuei 0:03b5121a232e 1015 xmlSchemaFreeValue(xmlSchemaValPtr value) {
pcercuei 0:03b5121a232e 1016 xmlSchemaValPtr prev;
pcercuei 0:03b5121a232e 1017
pcercuei 0:03b5121a232e 1018 while (value != NULL) {
pcercuei 0:03b5121a232e 1019 switch (value->type) {
pcercuei 0:03b5121a232e 1020 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 1021 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 1022 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 1023 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 1024 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 1025 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 1026 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 1027 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 1028 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 1029 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 1030 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 1031 case XML_SCHEMAS_ENTITY:
pcercuei 0:03b5121a232e 1032 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 1033 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 1034 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 1035 if (value->value.str != NULL)
pcercuei 0:03b5121a232e 1036 xmlFree(value->value.str);
pcercuei 0:03b5121a232e 1037 break;
pcercuei 0:03b5121a232e 1038 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 1039 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 1040 if (value->value.qname.uri != NULL)
pcercuei 0:03b5121a232e 1041 xmlFree(value->value.qname.uri);
pcercuei 0:03b5121a232e 1042 if (value->value.qname.name != NULL)
pcercuei 0:03b5121a232e 1043 xmlFree(value->value.qname.name);
pcercuei 0:03b5121a232e 1044 break;
pcercuei 0:03b5121a232e 1045 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 1046 if (value->value.hex.str != NULL)
pcercuei 0:03b5121a232e 1047 xmlFree(value->value.hex.str);
pcercuei 0:03b5121a232e 1048 break;
pcercuei 0:03b5121a232e 1049 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 1050 if (value->value.base64.str != NULL)
pcercuei 0:03b5121a232e 1051 xmlFree(value->value.base64.str);
pcercuei 0:03b5121a232e 1052 break;
pcercuei 0:03b5121a232e 1053 default:
pcercuei 0:03b5121a232e 1054 break;
pcercuei 0:03b5121a232e 1055 }
pcercuei 0:03b5121a232e 1056 prev = value;
pcercuei 0:03b5121a232e 1057 value = value->next;
pcercuei 0:03b5121a232e 1058 xmlFree(prev);
pcercuei 0:03b5121a232e 1059 }
pcercuei 0:03b5121a232e 1060 }
pcercuei 0:03b5121a232e 1061
pcercuei 0:03b5121a232e 1062 /**
pcercuei 0:03b5121a232e 1063 * xmlSchemaGetPredefinedType:
pcercuei 0:03b5121a232e 1064 * @name: the type name
pcercuei 0:03b5121a232e 1065 * @ns: the URI of the namespace usually "http://www.w3.org/2001/XMLSchema"
pcercuei 0:03b5121a232e 1066 *
pcercuei 0:03b5121a232e 1067 * Lookup a type in the default XML Schemas type library
pcercuei 0:03b5121a232e 1068 *
pcercuei 0:03b5121a232e 1069 * Returns the type if found, NULL otherwise
pcercuei 0:03b5121a232e 1070 */
pcercuei 0:03b5121a232e 1071 xmlSchemaTypePtr
pcercuei 0:03b5121a232e 1072 xmlSchemaGetPredefinedType(const xmlChar *name, const xmlChar *ns) {
pcercuei 0:03b5121a232e 1073 if (xmlSchemaTypesInitialized == 0)
pcercuei 0:03b5121a232e 1074 xmlSchemaInitTypes();
pcercuei 0:03b5121a232e 1075 if (name == NULL)
pcercuei 0:03b5121a232e 1076 return(NULL);
pcercuei 0:03b5121a232e 1077 return((xmlSchemaTypePtr) xmlHashLookup2(xmlSchemaTypesBank, name, ns));
pcercuei 0:03b5121a232e 1078 }
pcercuei 0:03b5121a232e 1079
pcercuei 0:03b5121a232e 1080 /**
pcercuei 0:03b5121a232e 1081 * xmlSchemaGetBuiltInListSimpleTypeItemType:
pcercuei 0:03b5121a232e 1082 * @type: the built-in simple type.
pcercuei 0:03b5121a232e 1083 *
pcercuei 0:03b5121a232e 1084 * Lookup function
pcercuei 0:03b5121a232e 1085 *
pcercuei 0:03b5121a232e 1086 * Returns the item type of @type as defined by the built-in datatype
pcercuei 0:03b5121a232e 1087 * hierarchy of XML Schema Part 2: Datatypes, or NULL in case of an error.
pcercuei 0:03b5121a232e 1088 */
pcercuei 0:03b5121a232e 1089 xmlSchemaTypePtr
pcercuei 0:03b5121a232e 1090 xmlSchemaGetBuiltInListSimpleTypeItemType(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 1091 {
pcercuei 0:03b5121a232e 1092 if ((type == NULL) || (type->type != XML_SCHEMA_TYPE_BASIC))
pcercuei 0:03b5121a232e 1093 return (NULL);
pcercuei 0:03b5121a232e 1094 switch (type->builtInType) {
pcercuei 0:03b5121a232e 1095 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 1096 return (xmlSchemaTypeNmtokenDef );
pcercuei 0:03b5121a232e 1097 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 1098 return (xmlSchemaTypeIdrefDef);
pcercuei 0:03b5121a232e 1099 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 1100 return (xmlSchemaTypeEntityDef);
pcercuei 0:03b5121a232e 1101 default:
pcercuei 0:03b5121a232e 1102 return (NULL);
pcercuei 0:03b5121a232e 1103 }
pcercuei 0:03b5121a232e 1104 }
pcercuei 0:03b5121a232e 1105
pcercuei 0:03b5121a232e 1106 /****************************************************************
pcercuei 0:03b5121a232e 1107 * *
pcercuei 0:03b5121a232e 1108 * Convenience macros and functions *
pcercuei 0:03b5121a232e 1109 * *
pcercuei 0:03b5121a232e 1110 ****************************************************************/
pcercuei 0:03b5121a232e 1111
pcercuei 0:03b5121a232e 1112 #define IS_TZO_CHAR(c) \
pcercuei 0:03b5121a232e 1113 ((c == 0) || (c == 'Z') || (c == '+') || (c == '-'))
pcercuei 0:03b5121a232e 1114
pcercuei 0:03b5121a232e 1115 #define VALID_YEAR(yr) (yr != 0)
pcercuei 0:03b5121a232e 1116 #define VALID_MONTH(mon) ((mon >= 1) && (mon <= 12))
pcercuei 0:03b5121a232e 1117 /* VALID_DAY should only be used when month is unknown */
pcercuei 0:03b5121a232e 1118 #define VALID_DAY(day) ((day >= 1) && (day <= 31))
pcercuei 0:03b5121a232e 1119 #define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
pcercuei 0:03b5121a232e 1120 #define VALID_MIN(min) ((min >= 0) && (min <= 59))
pcercuei 0:03b5121a232e 1121 #define VALID_SEC(sec) ((sec >= 0) && (sec < 60))
pcercuei 0:03b5121a232e 1122 #define VALID_TZO(tzo) ((tzo > -840) && (tzo < 840))
pcercuei 0:03b5121a232e 1123 #define IS_LEAP(y) \
pcercuei 0:03b5121a232e 1124 (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
pcercuei 0:03b5121a232e 1125
pcercuei 0:03b5121a232e 1126 static const unsigned int daysInMonth[12] =
pcercuei 0:03b5121a232e 1127 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
pcercuei 0:03b5121a232e 1128 static const unsigned int daysInMonthLeap[12] =
pcercuei 0:03b5121a232e 1129 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
pcercuei 0:03b5121a232e 1130
pcercuei 0:03b5121a232e 1131 #define MAX_DAYINMONTH(yr,mon) \
pcercuei 0:03b5121a232e 1132 (IS_LEAP(yr) ? daysInMonthLeap[mon - 1] : daysInMonth[mon - 1])
pcercuei 0:03b5121a232e 1133
pcercuei 0:03b5121a232e 1134 #define VALID_MDAY(dt) \
pcercuei 0:03b5121a232e 1135 (IS_LEAP(dt->year) ? \
pcercuei 0:03b5121a232e 1136 (dt->day <= daysInMonthLeap[dt->mon - 1]) : \
pcercuei 0:03b5121a232e 1137 (dt->day <= daysInMonth[dt->mon - 1]))
pcercuei 0:03b5121a232e 1138
pcercuei 0:03b5121a232e 1139 #define VALID_DATE(dt) \
pcercuei 0:03b5121a232e 1140 (VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
pcercuei 0:03b5121a232e 1141
pcercuei 0:03b5121a232e 1142 #define VALID_TIME(dt) \
pcercuei 0:03b5121a232e 1143 (VALID_HOUR(dt->hour) && VALID_MIN(dt->min) && \
pcercuei 0:03b5121a232e 1144 VALID_SEC(dt->sec) && VALID_TZO(dt->tzo))
pcercuei 0:03b5121a232e 1145
pcercuei 0:03b5121a232e 1146 #define VALID_DATETIME(dt) \
pcercuei 0:03b5121a232e 1147 (VALID_DATE(dt) && VALID_TIME(dt))
pcercuei 0:03b5121a232e 1148
pcercuei 0:03b5121a232e 1149 #define SECS_PER_MIN (60)
pcercuei 0:03b5121a232e 1150 #define SECS_PER_HOUR (60 * SECS_PER_MIN)
pcercuei 0:03b5121a232e 1151 #define SECS_PER_DAY (24 * SECS_PER_HOUR)
pcercuei 0:03b5121a232e 1152
pcercuei 0:03b5121a232e 1153 static const long dayInYearByMonth[12] =
pcercuei 0:03b5121a232e 1154 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
pcercuei 0:03b5121a232e 1155 static const long dayInLeapYearByMonth[12] =
pcercuei 0:03b5121a232e 1156 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
pcercuei 0:03b5121a232e 1157
pcercuei 0:03b5121a232e 1158 #define DAY_IN_YEAR(day, month, year) \
pcercuei 0:03b5121a232e 1159 ((IS_LEAP(year) ? \
pcercuei 0:03b5121a232e 1160 dayInLeapYearByMonth[month - 1] : \
pcercuei 0:03b5121a232e 1161 dayInYearByMonth[month - 1]) + day)
pcercuei 0:03b5121a232e 1162
pcercuei 0:03b5121a232e 1163 #ifdef DEBUG
pcercuei 0:03b5121a232e 1164 #define DEBUG_DATE(dt) \
pcercuei 0:03b5121a232e 1165 xmlGenericError(xmlGenericErrorContext, \
pcercuei 0:03b5121a232e 1166 "type=%o %04ld-%02u-%02uT%02u:%02u:%03f", \
pcercuei 0:03b5121a232e 1167 dt->type,dt->value.date.year,dt->value.date.mon, \
pcercuei 0:03b5121a232e 1168 dt->value.date.day,dt->value.date.hour,dt->value.date.min, \
pcercuei 0:03b5121a232e 1169 dt->value.date.sec); \
pcercuei 0:03b5121a232e 1170 if (dt->value.date.tz_flag) \
pcercuei 0:03b5121a232e 1171 if (dt->value.date.tzo != 0) \
pcercuei 0:03b5121a232e 1172 xmlGenericError(xmlGenericErrorContext, \
pcercuei 0:03b5121a232e 1173 "%+05d\n",dt->value.date.tzo); \
pcercuei 0:03b5121a232e 1174 else \
pcercuei 0:03b5121a232e 1175 xmlGenericError(xmlGenericErrorContext, "Z\n"); \
pcercuei 0:03b5121a232e 1176 else \
pcercuei 0:03b5121a232e 1177 xmlGenericError(xmlGenericErrorContext,"\n")
pcercuei 0:03b5121a232e 1178 #else
pcercuei 0:03b5121a232e 1179 #define DEBUG_DATE(dt)
pcercuei 0:03b5121a232e 1180 #endif
pcercuei 0:03b5121a232e 1181
pcercuei 0:03b5121a232e 1182 /**
pcercuei 0:03b5121a232e 1183 * _xmlSchemaParseGYear:
pcercuei 0:03b5121a232e 1184 * @dt: pointer to a date structure
pcercuei 0:03b5121a232e 1185 * @str: pointer to the string to analyze
pcercuei 0:03b5121a232e 1186 *
pcercuei 0:03b5121a232e 1187 * Parses a xs:gYear without time zone and fills in the appropriate
pcercuei 0:03b5121a232e 1188 * field of the @dt structure. @str is updated to point just after the
pcercuei 0:03b5121a232e 1189 * xs:gYear. It is supposed that @dt->year is big enough to contain
pcercuei 0:03b5121a232e 1190 * the year.
pcercuei 0:03b5121a232e 1191 *
pcercuei 0:03b5121a232e 1192 * Returns 0 or the error code
pcercuei 0:03b5121a232e 1193 */
pcercuei 0:03b5121a232e 1194 static int
pcercuei 0:03b5121a232e 1195 _xmlSchemaParseGYear (xmlSchemaValDatePtr dt, const xmlChar **str) {
pcercuei 0:03b5121a232e 1196 const xmlChar *cur = *str, *firstChar;
pcercuei 0:03b5121a232e 1197 int isneg = 0, digcnt = 0;
pcercuei 0:03b5121a232e 1198
pcercuei 0:03b5121a232e 1199 if (((*cur < '0') || (*cur > '9')) &&
pcercuei 0:03b5121a232e 1200 (*cur != '-') && (*cur != '+'))
pcercuei 0:03b5121a232e 1201 return -1;
pcercuei 0:03b5121a232e 1202
pcercuei 0:03b5121a232e 1203 if (*cur == '-') {
pcercuei 0:03b5121a232e 1204 isneg = 1;
pcercuei 0:03b5121a232e 1205 cur++;
pcercuei 0:03b5121a232e 1206 }
pcercuei 0:03b5121a232e 1207
pcercuei 0:03b5121a232e 1208 firstChar = cur;
pcercuei 0:03b5121a232e 1209
pcercuei 0:03b5121a232e 1210 while ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 1211 dt->year = dt->year * 10 + (*cur - '0');
pcercuei 0:03b5121a232e 1212 cur++;
pcercuei 0:03b5121a232e 1213 digcnt++;
pcercuei 0:03b5121a232e 1214 }
pcercuei 0:03b5121a232e 1215
pcercuei 0:03b5121a232e 1216 /* year must be at least 4 digits (CCYY); over 4
pcercuei 0:03b5121a232e 1217 * digits cannot have a leading zero. */
pcercuei 0:03b5121a232e 1218 if ((digcnt < 4) || ((digcnt > 4) && (*firstChar == '0')))
pcercuei 0:03b5121a232e 1219 return 1;
pcercuei 0:03b5121a232e 1220
pcercuei 0:03b5121a232e 1221 if (isneg)
pcercuei 0:03b5121a232e 1222 dt->year = - dt->year;
pcercuei 0:03b5121a232e 1223
pcercuei 0:03b5121a232e 1224 if (!VALID_YEAR(dt->year))
pcercuei 0:03b5121a232e 1225 return 2;
pcercuei 0:03b5121a232e 1226
pcercuei 0:03b5121a232e 1227 *str = cur;
pcercuei 0:03b5121a232e 1228 return 0;
pcercuei 0:03b5121a232e 1229 }
pcercuei 0:03b5121a232e 1230
pcercuei 0:03b5121a232e 1231 /**
pcercuei 0:03b5121a232e 1232 * PARSE_2_DIGITS:
pcercuei 0:03b5121a232e 1233 * @num: the integer to fill in
pcercuei 0:03b5121a232e 1234 * @cur: an #xmlChar *
pcercuei 0:03b5121a232e 1235 * @invalid: an integer
pcercuei 0:03b5121a232e 1236 *
pcercuei 0:03b5121a232e 1237 * Parses a 2-digits integer and updates @num with the value. @cur is
pcercuei 0:03b5121a232e 1238 * updated to point just after the integer.
pcercuei 0:03b5121a232e 1239 * In case of error, @invalid is set to %TRUE, values of @num and
pcercuei 0:03b5121a232e 1240 * @cur are undefined.
pcercuei 0:03b5121a232e 1241 */
pcercuei 0:03b5121a232e 1242 #define PARSE_2_DIGITS(num, cur, invalid) \
pcercuei 0:03b5121a232e 1243 if ((cur[0] < '0') || (cur[0] > '9') || \
pcercuei 0:03b5121a232e 1244 (cur[1] < '0') || (cur[1] > '9')) \
pcercuei 0:03b5121a232e 1245 invalid = 1; \
pcercuei 0:03b5121a232e 1246 else \
pcercuei 0:03b5121a232e 1247 num = (cur[0] - '0') * 10 + (cur[1] - '0'); \
pcercuei 0:03b5121a232e 1248 cur += 2;
pcercuei 0:03b5121a232e 1249
pcercuei 0:03b5121a232e 1250 /**
pcercuei 0:03b5121a232e 1251 * PARSE_FLOAT:
pcercuei 0:03b5121a232e 1252 * @num: the double to fill in
pcercuei 0:03b5121a232e 1253 * @cur: an #xmlChar *
pcercuei 0:03b5121a232e 1254 * @invalid: an integer
pcercuei 0:03b5121a232e 1255 *
pcercuei 0:03b5121a232e 1256 * Parses a float and updates @num with the value. @cur is
pcercuei 0:03b5121a232e 1257 * updated to point just after the float. The float must have a
pcercuei 0:03b5121a232e 1258 * 2-digits integer part and may or may not have a decimal part.
pcercuei 0:03b5121a232e 1259 * In case of error, @invalid is set to %TRUE, values of @num and
pcercuei 0:03b5121a232e 1260 * @cur are undefined.
pcercuei 0:03b5121a232e 1261 */
pcercuei 0:03b5121a232e 1262 #define PARSE_FLOAT(num, cur, invalid) \
pcercuei 0:03b5121a232e 1263 PARSE_2_DIGITS(num, cur, invalid); \
pcercuei 0:03b5121a232e 1264 if (!invalid && (*cur == '.')) { \
pcercuei 0:03b5121a232e 1265 double mult = 1; \
pcercuei 0:03b5121a232e 1266 cur++; \
pcercuei 0:03b5121a232e 1267 if ((*cur < '0') || (*cur > '9')) \
pcercuei 0:03b5121a232e 1268 invalid = 1; \
pcercuei 0:03b5121a232e 1269 while ((*cur >= '0') && (*cur <= '9')) { \
pcercuei 0:03b5121a232e 1270 mult /= 10; \
pcercuei 0:03b5121a232e 1271 num += (*cur - '0') * mult; \
pcercuei 0:03b5121a232e 1272 cur++; \
pcercuei 0:03b5121a232e 1273 } \
pcercuei 0:03b5121a232e 1274 }
pcercuei 0:03b5121a232e 1275
pcercuei 0:03b5121a232e 1276 /**
pcercuei 0:03b5121a232e 1277 * _xmlSchemaParseGMonth:
pcercuei 0:03b5121a232e 1278 * @dt: pointer to a date structure
pcercuei 0:03b5121a232e 1279 * @str: pointer to the string to analyze
pcercuei 0:03b5121a232e 1280 *
pcercuei 0:03b5121a232e 1281 * Parses a xs:gMonth without time zone and fills in the appropriate
pcercuei 0:03b5121a232e 1282 * field of the @dt structure. @str is updated to point just after the
pcercuei 0:03b5121a232e 1283 * xs:gMonth.
pcercuei 0:03b5121a232e 1284 *
pcercuei 0:03b5121a232e 1285 * Returns 0 or the error code
pcercuei 0:03b5121a232e 1286 */
pcercuei 0:03b5121a232e 1287 static int
pcercuei 0:03b5121a232e 1288 _xmlSchemaParseGMonth (xmlSchemaValDatePtr dt, const xmlChar **str) {
pcercuei 0:03b5121a232e 1289 const xmlChar *cur = *str;
pcercuei 0:03b5121a232e 1290 int ret = 0;
pcercuei 0:03b5121a232e 1291 unsigned int value = 0;
pcercuei 0:03b5121a232e 1292
pcercuei 0:03b5121a232e 1293 PARSE_2_DIGITS(value, cur, ret);
pcercuei 0:03b5121a232e 1294 if (ret != 0)
pcercuei 0:03b5121a232e 1295 return ret;
pcercuei 0:03b5121a232e 1296
pcercuei 0:03b5121a232e 1297 if (!VALID_MONTH(value))
pcercuei 0:03b5121a232e 1298 return 2;
pcercuei 0:03b5121a232e 1299
pcercuei 0:03b5121a232e 1300 dt->mon = value;
pcercuei 0:03b5121a232e 1301
pcercuei 0:03b5121a232e 1302 *str = cur;
pcercuei 0:03b5121a232e 1303 return 0;
pcercuei 0:03b5121a232e 1304 }
pcercuei 0:03b5121a232e 1305
pcercuei 0:03b5121a232e 1306 /**
pcercuei 0:03b5121a232e 1307 * _xmlSchemaParseGDay:
pcercuei 0:03b5121a232e 1308 * @dt: pointer to a date structure
pcercuei 0:03b5121a232e 1309 * @str: pointer to the string to analyze
pcercuei 0:03b5121a232e 1310 *
pcercuei 0:03b5121a232e 1311 * Parses a xs:gDay without time zone and fills in the appropriate
pcercuei 0:03b5121a232e 1312 * field of the @dt structure. @str is updated to point just after the
pcercuei 0:03b5121a232e 1313 * xs:gDay.
pcercuei 0:03b5121a232e 1314 *
pcercuei 0:03b5121a232e 1315 * Returns 0 or the error code
pcercuei 0:03b5121a232e 1316 */
pcercuei 0:03b5121a232e 1317 static int
pcercuei 0:03b5121a232e 1318 _xmlSchemaParseGDay (xmlSchemaValDatePtr dt, const xmlChar **str) {
pcercuei 0:03b5121a232e 1319 const xmlChar *cur = *str;
pcercuei 0:03b5121a232e 1320 int ret = 0;
pcercuei 0:03b5121a232e 1321 unsigned int value = 0;
pcercuei 0:03b5121a232e 1322
pcercuei 0:03b5121a232e 1323 PARSE_2_DIGITS(value, cur, ret);
pcercuei 0:03b5121a232e 1324 if (ret != 0)
pcercuei 0:03b5121a232e 1325 return ret;
pcercuei 0:03b5121a232e 1326
pcercuei 0:03b5121a232e 1327 if (!VALID_DAY(value))
pcercuei 0:03b5121a232e 1328 return 2;
pcercuei 0:03b5121a232e 1329
pcercuei 0:03b5121a232e 1330 dt->day = value;
pcercuei 0:03b5121a232e 1331 *str = cur;
pcercuei 0:03b5121a232e 1332 return 0;
pcercuei 0:03b5121a232e 1333 }
pcercuei 0:03b5121a232e 1334
pcercuei 0:03b5121a232e 1335 /**
pcercuei 0:03b5121a232e 1336 * _xmlSchemaParseTime:
pcercuei 0:03b5121a232e 1337 * @dt: pointer to a date structure
pcercuei 0:03b5121a232e 1338 * @str: pointer to the string to analyze
pcercuei 0:03b5121a232e 1339 *
pcercuei 0:03b5121a232e 1340 * Parses a xs:time without time zone and fills in the appropriate
pcercuei 0:03b5121a232e 1341 * fields of the @dt structure. @str is updated to point just after the
pcercuei 0:03b5121a232e 1342 * xs:time.
pcercuei 0:03b5121a232e 1343 * In case of error, values of @dt fields are undefined.
pcercuei 0:03b5121a232e 1344 *
pcercuei 0:03b5121a232e 1345 * Returns 0 or the error code
pcercuei 0:03b5121a232e 1346 */
pcercuei 0:03b5121a232e 1347 static int
pcercuei 0:03b5121a232e 1348 _xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) {
pcercuei 0:03b5121a232e 1349 const xmlChar *cur = *str;
pcercuei 0:03b5121a232e 1350 int ret = 0;
pcercuei 0:03b5121a232e 1351 int value = 0;
pcercuei 0:03b5121a232e 1352
pcercuei 0:03b5121a232e 1353 PARSE_2_DIGITS(value, cur, ret);
pcercuei 0:03b5121a232e 1354 if (ret != 0)
pcercuei 0:03b5121a232e 1355 return ret;
pcercuei 0:03b5121a232e 1356 if (*cur != ':')
pcercuei 0:03b5121a232e 1357 return 1;
pcercuei 0:03b5121a232e 1358 if (!VALID_HOUR(value))
pcercuei 0:03b5121a232e 1359 return 2;
pcercuei 0:03b5121a232e 1360 cur++;
pcercuei 0:03b5121a232e 1361
pcercuei 0:03b5121a232e 1362 /* the ':' insures this string is xs:time */
pcercuei 0:03b5121a232e 1363 dt->hour = value;
pcercuei 0:03b5121a232e 1364
pcercuei 0:03b5121a232e 1365 PARSE_2_DIGITS(value, cur, ret);
pcercuei 0:03b5121a232e 1366 if (ret != 0)
pcercuei 0:03b5121a232e 1367 return ret;
pcercuei 0:03b5121a232e 1368 if (!VALID_MIN(value))
pcercuei 0:03b5121a232e 1369 return 2;
pcercuei 0:03b5121a232e 1370 dt->min = value;
pcercuei 0:03b5121a232e 1371
pcercuei 0:03b5121a232e 1372 if (*cur != ':')
pcercuei 0:03b5121a232e 1373 return 1;
pcercuei 0:03b5121a232e 1374 cur++;
pcercuei 0:03b5121a232e 1375
pcercuei 0:03b5121a232e 1376 PARSE_FLOAT(dt->sec, cur, ret);
pcercuei 0:03b5121a232e 1377 if (ret != 0)
pcercuei 0:03b5121a232e 1378 return ret;
pcercuei 0:03b5121a232e 1379
pcercuei 0:03b5121a232e 1380 if ((!VALID_SEC(dt->sec)) || (!VALID_TZO(dt->tzo)))
pcercuei 0:03b5121a232e 1381 return 2;
pcercuei 0:03b5121a232e 1382
pcercuei 0:03b5121a232e 1383 *str = cur;
pcercuei 0:03b5121a232e 1384 return 0;
pcercuei 0:03b5121a232e 1385 }
pcercuei 0:03b5121a232e 1386
pcercuei 0:03b5121a232e 1387 /**
pcercuei 0:03b5121a232e 1388 * _xmlSchemaParseTimeZone:
pcercuei 0:03b5121a232e 1389 * @dt: pointer to a date structure
pcercuei 0:03b5121a232e 1390 * @str: pointer to the string to analyze
pcercuei 0:03b5121a232e 1391 *
pcercuei 0:03b5121a232e 1392 * Parses a time zone without time zone and fills in the appropriate
pcercuei 0:03b5121a232e 1393 * field of the @dt structure. @str is updated to point just after the
pcercuei 0:03b5121a232e 1394 * time zone.
pcercuei 0:03b5121a232e 1395 *
pcercuei 0:03b5121a232e 1396 * Returns 0 or the error code
pcercuei 0:03b5121a232e 1397 */
pcercuei 0:03b5121a232e 1398 static int
pcercuei 0:03b5121a232e 1399 _xmlSchemaParseTimeZone (xmlSchemaValDatePtr dt, const xmlChar **str) {
pcercuei 0:03b5121a232e 1400 const xmlChar *cur;
pcercuei 0:03b5121a232e 1401 int ret = 0;
pcercuei 0:03b5121a232e 1402
pcercuei 0:03b5121a232e 1403 if (str == NULL)
pcercuei 0:03b5121a232e 1404 return -1;
pcercuei 0:03b5121a232e 1405 cur = *str;
pcercuei 0:03b5121a232e 1406
pcercuei 0:03b5121a232e 1407 switch (*cur) {
pcercuei 0:03b5121a232e 1408 case 0:
pcercuei 0:03b5121a232e 1409 dt->tz_flag = 0;
pcercuei 0:03b5121a232e 1410 dt->tzo = 0;
pcercuei 0:03b5121a232e 1411 break;
pcercuei 0:03b5121a232e 1412
pcercuei 0:03b5121a232e 1413 case 'Z':
pcercuei 0:03b5121a232e 1414 dt->tz_flag = 1;
pcercuei 0:03b5121a232e 1415 dt->tzo = 0;
pcercuei 0:03b5121a232e 1416 cur++;
pcercuei 0:03b5121a232e 1417 break;
pcercuei 0:03b5121a232e 1418
pcercuei 0:03b5121a232e 1419 case '+':
pcercuei 0:03b5121a232e 1420 case '-': {
pcercuei 0:03b5121a232e 1421 int isneg = 0, tmp = 0;
pcercuei 0:03b5121a232e 1422 isneg = (*cur == '-');
pcercuei 0:03b5121a232e 1423
pcercuei 0:03b5121a232e 1424 cur++;
pcercuei 0:03b5121a232e 1425
pcercuei 0:03b5121a232e 1426 PARSE_2_DIGITS(tmp, cur, ret);
pcercuei 0:03b5121a232e 1427 if (ret != 0)
pcercuei 0:03b5121a232e 1428 return ret;
pcercuei 0:03b5121a232e 1429 if (!VALID_HOUR(tmp))
pcercuei 0:03b5121a232e 1430 return 2;
pcercuei 0:03b5121a232e 1431
pcercuei 0:03b5121a232e 1432 if (*cur != ':')
pcercuei 0:03b5121a232e 1433 return 1;
pcercuei 0:03b5121a232e 1434 cur++;
pcercuei 0:03b5121a232e 1435
pcercuei 0:03b5121a232e 1436 dt->tzo = tmp * 60;
pcercuei 0:03b5121a232e 1437
pcercuei 0:03b5121a232e 1438 PARSE_2_DIGITS(tmp, cur, ret);
pcercuei 0:03b5121a232e 1439 if (ret != 0)
pcercuei 0:03b5121a232e 1440 return ret;
pcercuei 0:03b5121a232e 1441 if (!VALID_MIN(tmp))
pcercuei 0:03b5121a232e 1442 return 2;
pcercuei 0:03b5121a232e 1443
pcercuei 0:03b5121a232e 1444 dt->tzo += tmp;
pcercuei 0:03b5121a232e 1445 if (isneg)
pcercuei 0:03b5121a232e 1446 dt->tzo = - dt->tzo;
pcercuei 0:03b5121a232e 1447
pcercuei 0:03b5121a232e 1448 if (!VALID_TZO(dt->tzo))
pcercuei 0:03b5121a232e 1449 return 2;
pcercuei 0:03b5121a232e 1450
pcercuei 0:03b5121a232e 1451 dt->tz_flag = 1;
pcercuei 0:03b5121a232e 1452 break;
pcercuei 0:03b5121a232e 1453 }
pcercuei 0:03b5121a232e 1454 default:
pcercuei 0:03b5121a232e 1455 return 1;
pcercuei 0:03b5121a232e 1456 }
pcercuei 0:03b5121a232e 1457
pcercuei 0:03b5121a232e 1458 *str = cur;
pcercuei 0:03b5121a232e 1459 return 0;
pcercuei 0:03b5121a232e 1460 }
pcercuei 0:03b5121a232e 1461
pcercuei 0:03b5121a232e 1462 /**
pcercuei 0:03b5121a232e 1463 * _xmlSchemaBase64Decode:
pcercuei 0:03b5121a232e 1464 * @ch: a character
pcercuei 0:03b5121a232e 1465 *
pcercuei 0:03b5121a232e 1466 * Converts a base64 encoded character to its base 64 value.
pcercuei 0:03b5121a232e 1467 *
pcercuei 0:03b5121a232e 1468 * Returns 0-63 (value), 64 (pad), or -1 (not recognized)
pcercuei 0:03b5121a232e 1469 */
pcercuei 0:03b5121a232e 1470 static int
pcercuei 0:03b5121a232e 1471 _xmlSchemaBase64Decode (const xmlChar ch) {
pcercuei 0:03b5121a232e 1472 if (('A' <= ch) && (ch <= 'Z')) return ch - 'A';
pcercuei 0:03b5121a232e 1473 if (('a' <= ch) && (ch <= 'z')) return ch - 'a' + 26;
pcercuei 0:03b5121a232e 1474 if (('0' <= ch) && (ch <= '9')) return ch - '0' + 52;
pcercuei 0:03b5121a232e 1475 if ('+' == ch) return 62;
pcercuei 0:03b5121a232e 1476 if ('/' == ch) return 63;
pcercuei 0:03b5121a232e 1477 if ('=' == ch) return 64;
pcercuei 0:03b5121a232e 1478 return -1;
pcercuei 0:03b5121a232e 1479 }
pcercuei 0:03b5121a232e 1480
pcercuei 0:03b5121a232e 1481 /****************************************************************
pcercuei 0:03b5121a232e 1482 * *
pcercuei 0:03b5121a232e 1483 * XML Schema Dates/Times Datatypes Handling *
pcercuei 0:03b5121a232e 1484 * *
pcercuei 0:03b5121a232e 1485 ****************************************************************/
pcercuei 0:03b5121a232e 1486
pcercuei 0:03b5121a232e 1487 /**
pcercuei 0:03b5121a232e 1488 * PARSE_DIGITS:
pcercuei 0:03b5121a232e 1489 * @num: the integer to fill in
pcercuei 0:03b5121a232e 1490 * @cur: an #xmlChar *
pcercuei 0:03b5121a232e 1491 * @num_type: an integer flag
pcercuei 0:03b5121a232e 1492 *
pcercuei 0:03b5121a232e 1493 * Parses a digits integer and updates @num with the value. @cur is
pcercuei 0:03b5121a232e 1494 * updated to point just after the integer.
pcercuei 0:03b5121a232e 1495 * In case of error, @num_type is set to -1, values of @num and
pcercuei 0:03b5121a232e 1496 * @cur are undefined.
pcercuei 0:03b5121a232e 1497 */
pcercuei 0:03b5121a232e 1498 #define PARSE_DIGITS(num, cur, num_type) \
pcercuei 0:03b5121a232e 1499 if ((*cur < '0') || (*cur > '9')) \
pcercuei 0:03b5121a232e 1500 num_type = -1; \
pcercuei 0:03b5121a232e 1501 else \
pcercuei 0:03b5121a232e 1502 while ((*cur >= '0') && (*cur <= '9')) { \
pcercuei 0:03b5121a232e 1503 num = num * 10 + (*cur - '0'); \
pcercuei 0:03b5121a232e 1504 cur++; \
pcercuei 0:03b5121a232e 1505 }
pcercuei 0:03b5121a232e 1506
pcercuei 0:03b5121a232e 1507 /**
pcercuei 0:03b5121a232e 1508 * PARSE_NUM:
pcercuei 0:03b5121a232e 1509 * @num: the double to fill in
pcercuei 0:03b5121a232e 1510 * @cur: an #xmlChar *
pcercuei 0:03b5121a232e 1511 * @num_type: an integer flag
pcercuei 0:03b5121a232e 1512 *
pcercuei 0:03b5121a232e 1513 * Parses a float or integer and updates @num with the value. @cur is
pcercuei 0:03b5121a232e 1514 * updated to point just after the number. If the number is a float,
pcercuei 0:03b5121a232e 1515 * then it must have an integer part and a decimal part; @num_type will
pcercuei 0:03b5121a232e 1516 * be set to 1. If there is no decimal part, @num_type is set to zero.
pcercuei 0:03b5121a232e 1517 * In case of error, @num_type is set to -1, values of @num and
pcercuei 0:03b5121a232e 1518 * @cur are undefined.
pcercuei 0:03b5121a232e 1519 */
pcercuei 0:03b5121a232e 1520 #define PARSE_NUM(num, cur, num_type) \
pcercuei 0:03b5121a232e 1521 num = 0; \
pcercuei 0:03b5121a232e 1522 PARSE_DIGITS(num, cur, num_type); \
pcercuei 0:03b5121a232e 1523 if (!num_type && (*cur == '.')) { \
pcercuei 0:03b5121a232e 1524 double mult = 1; \
pcercuei 0:03b5121a232e 1525 cur++; \
pcercuei 0:03b5121a232e 1526 if ((*cur < '0') || (*cur > '9')) \
pcercuei 0:03b5121a232e 1527 num_type = -1; \
pcercuei 0:03b5121a232e 1528 else \
pcercuei 0:03b5121a232e 1529 num_type = 1; \
pcercuei 0:03b5121a232e 1530 while ((*cur >= '0') && (*cur <= '9')) { \
pcercuei 0:03b5121a232e 1531 mult /= 10; \
pcercuei 0:03b5121a232e 1532 num += (*cur - '0') * mult; \
pcercuei 0:03b5121a232e 1533 cur++; \
pcercuei 0:03b5121a232e 1534 } \
pcercuei 0:03b5121a232e 1535 }
pcercuei 0:03b5121a232e 1536
pcercuei 0:03b5121a232e 1537 /**
pcercuei 0:03b5121a232e 1538 * xmlSchemaValidateDates:
pcercuei 0:03b5121a232e 1539 * @type: the expected type or XML_SCHEMAS_UNKNOWN
pcercuei 0:03b5121a232e 1540 * @dateTime: string to analyze
pcercuei 0:03b5121a232e 1541 * @val: the return computed value
pcercuei 0:03b5121a232e 1542 *
pcercuei 0:03b5121a232e 1543 * Check that @dateTime conforms to the lexical space of one of the date types.
pcercuei 0:03b5121a232e 1544 * if true a value is computed and returned in @val.
pcercuei 0:03b5121a232e 1545 *
pcercuei 0:03b5121a232e 1546 * Returns 0 if this validates, a positive error code number otherwise
pcercuei 0:03b5121a232e 1547 * and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 1548 */
pcercuei 0:03b5121a232e 1549 static int
pcercuei 0:03b5121a232e 1550 xmlSchemaValidateDates (xmlSchemaValType type,
pcercuei 0:03b5121a232e 1551 const xmlChar *dateTime, xmlSchemaValPtr *val,
pcercuei 0:03b5121a232e 1552 int collapse) {
pcercuei 0:03b5121a232e 1553 xmlSchemaValPtr dt;
pcercuei 0:03b5121a232e 1554 int ret;
pcercuei 0:03b5121a232e 1555 const xmlChar *cur = dateTime;
pcercuei 0:03b5121a232e 1556
pcercuei 0:03b5121a232e 1557 #define RETURN_TYPE_IF_VALID(t) \
pcercuei 0:03b5121a232e 1558 if (IS_TZO_CHAR(*cur)) { \
pcercuei 0:03b5121a232e 1559 ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur); \
pcercuei 0:03b5121a232e 1560 if (ret == 0) { \
pcercuei 0:03b5121a232e 1561 if (*cur != 0) \
pcercuei 0:03b5121a232e 1562 goto error; \
pcercuei 0:03b5121a232e 1563 dt->type = t; \
pcercuei 0:03b5121a232e 1564 goto done; \
pcercuei 0:03b5121a232e 1565 } \
pcercuei 0:03b5121a232e 1566 }
pcercuei 0:03b5121a232e 1567
pcercuei 0:03b5121a232e 1568 if (dateTime == NULL)
pcercuei 0:03b5121a232e 1569 return -1;
pcercuei 0:03b5121a232e 1570
pcercuei 0:03b5121a232e 1571 if (collapse)
pcercuei 0:03b5121a232e 1572 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 1573
pcercuei 0:03b5121a232e 1574 if ((*cur != '-') && (*cur < '0') && (*cur > '9'))
pcercuei 0:03b5121a232e 1575 return 1;
pcercuei 0:03b5121a232e 1576
pcercuei 0:03b5121a232e 1577 dt = xmlSchemaNewValue(XML_SCHEMAS_UNKNOWN);
pcercuei 0:03b5121a232e 1578 if (dt == NULL)
pcercuei 0:03b5121a232e 1579 return -1;
pcercuei 0:03b5121a232e 1580
pcercuei 0:03b5121a232e 1581 if ((cur[0] == '-') && (cur[1] == '-')) {
pcercuei 0:03b5121a232e 1582 /*
pcercuei 0:03b5121a232e 1583 * It's an incomplete date (xs:gMonthDay, xs:gMonth or
pcercuei 0:03b5121a232e 1584 * xs:gDay)
pcercuei 0:03b5121a232e 1585 */
pcercuei 0:03b5121a232e 1586 cur += 2;
pcercuei 0:03b5121a232e 1587
pcercuei 0:03b5121a232e 1588 /* is it an xs:gDay? */
pcercuei 0:03b5121a232e 1589 if (*cur == '-') {
pcercuei 0:03b5121a232e 1590 if (type == XML_SCHEMAS_GMONTH)
pcercuei 0:03b5121a232e 1591 goto error;
pcercuei 0:03b5121a232e 1592 ++cur;
pcercuei 0:03b5121a232e 1593 ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1594 if (ret != 0)
pcercuei 0:03b5121a232e 1595 goto error;
pcercuei 0:03b5121a232e 1596
pcercuei 0:03b5121a232e 1597 RETURN_TYPE_IF_VALID(XML_SCHEMAS_GDAY);
pcercuei 0:03b5121a232e 1598
pcercuei 0:03b5121a232e 1599 goto error;
pcercuei 0:03b5121a232e 1600 }
pcercuei 0:03b5121a232e 1601
pcercuei 0:03b5121a232e 1602 /*
pcercuei 0:03b5121a232e 1603 * it should be an xs:gMonthDay or xs:gMonth
pcercuei 0:03b5121a232e 1604 */
pcercuei 0:03b5121a232e 1605 ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1606 if (ret != 0)
pcercuei 0:03b5121a232e 1607 goto error;
pcercuei 0:03b5121a232e 1608
pcercuei 0:03b5121a232e 1609 /*
pcercuei 0:03b5121a232e 1610 * a '-' char could indicate this type is xs:gMonthDay or
pcercuei 0:03b5121a232e 1611 * a negative time zone offset. Check for xs:gMonthDay first.
pcercuei 0:03b5121a232e 1612 * Also the first three char's of a negative tzo (-MM:SS) can
pcercuei 0:03b5121a232e 1613 * appear to be a valid day; so even if the day portion
pcercuei 0:03b5121a232e 1614 * of the xs:gMonthDay verifies, we must insure it was not
pcercuei 0:03b5121a232e 1615 * a tzo.
pcercuei 0:03b5121a232e 1616 */
pcercuei 0:03b5121a232e 1617 if (*cur == '-') {
pcercuei 0:03b5121a232e 1618 const xmlChar *rewnd = cur;
pcercuei 0:03b5121a232e 1619 cur++;
pcercuei 0:03b5121a232e 1620
pcercuei 0:03b5121a232e 1621 ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1622 if ((ret == 0) && ((*cur == 0) || (*cur != ':'))) {
pcercuei 0:03b5121a232e 1623
pcercuei 0:03b5121a232e 1624 /*
pcercuei 0:03b5121a232e 1625 * we can use the VALID_MDAY macro to validate the month
pcercuei 0:03b5121a232e 1626 * and day because the leap year test will flag year zero
pcercuei 0:03b5121a232e 1627 * as a leap year (even though zero is an invalid year).
pcercuei 0:03b5121a232e 1628 * FUTURE TODO: Zero will become valid in XML Schema 1.1
pcercuei 0:03b5121a232e 1629 * probably.
pcercuei 0:03b5121a232e 1630 */
pcercuei 0:03b5121a232e 1631 if (VALID_MDAY((&(dt->value.date)))) {
pcercuei 0:03b5121a232e 1632
pcercuei 0:03b5121a232e 1633 RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTHDAY);
pcercuei 0:03b5121a232e 1634
pcercuei 0:03b5121a232e 1635 goto error;
pcercuei 0:03b5121a232e 1636 }
pcercuei 0:03b5121a232e 1637 }
pcercuei 0:03b5121a232e 1638
pcercuei 0:03b5121a232e 1639 /*
pcercuei 0:03b5121a232e 1640 * not xs:gMonthDay so rewind and check if just xs:gMonth
pcercuei 0:03b5121a232e 1641 * with an optional time zone.
pcercuei 0:03b5121a232e 1642 */
pcercuei 0:03b5121a232e 1643 cur = rewnd;
pcercuei 0:03b5121a232e 1644 }
pcercuei 0:03b5121a232e 1645
pcercuei 0:03b5121a232e 1646 RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTH);
pcercuei 0:03b5121a232e 1647
pcercuei 0:03b5121a232e 1648 goto error;
pcercuei 0:03b5121a232e 1649 }
pcercuei 0:03b5121a232e 1650
pcercuei 0:03b5121a232e 1651 /*
pcercuei 0:03b5121a232e 1652 * It's a right-truncated date or an xs:time.
pcercuei 0:03b5121a232e 1653 * Try to parse an xs:time then fallback on right-truncated dates.
pcercuei 0:03b5121a232e 1654 */
pcercuei 0:03b5121a232e 1655 if ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 1656 ret = _xmlSchemaParseTime(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1657 if (ret == 0) {
pcercuei 0:03b5121a232e 1658 /* it's an xs:time */
pcercuei 0:03b5121a232e 1659 RETURN_TYPE_IF_VALID(XML_SCHEMAS_TIME);
pcercuei 0:03b5121a232e 1660 }
pcercuei 0:03b5121a232e 1661 }
pcercuei 0:03b5121a232e 1662
pcercuei 0:03b5121a232e 1663 /* fallback on date parsing */
pcercuei 0:03b5121a232e 1664 cur = dateTime;
pcercuei 0:03b5121a232e 1665
pcercuei 0:03b5121a232e 1666 ret = _xmlSchemaParseGYear(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1667 if (ret != 0)
pcercuei 0:03b5121a232e 1668 goto error;
pcercuei 0:03b5121a232e 1669
pcercuei 0:03b5121a232e 1670 /* is it an xs:gYear? */
pcercuei 0:03b5121a232e 1671 RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEAR);
pcercuei 0:03b5121a232e 1672
pcercuei 0:03b5121a232e 1673 if (*cur != '-')
pcercuei 0:03b5121a232e 1674 goto error;
pcercuei 0:03b5121a232e 1675 cur++;
pcercuei 0:03b5121a232e 1676
pcercuei 0:03b5121a232e 1677 ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1678 if (ret != 0)
pcercuei 0:03b5121a232e 1679 goto error;
pcercuei 0:03b5121a232e 1680
pcercuei 0:03b5121a232e 1681 /* is it an xs:gYearMonth? */
pcercuei 0:03b5121a232e 1682 RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEARMONTH);
pcercuei 0:03b5121a232e 1683
pcercuei 0:03b5121a232e 1684 if (*cur != '-')
pcercuei 0:03b5121a232e 1685 goto error;
pcercuei 0:03b5121a232e 1686 cur++;
pcercuei 0:03b5121a232e 1687
pcercuei 0:03b5121a232e 1688 ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1689 if ((ret != 0) || !VALID_DATE((&(dt->value.date))))
pcercuei 0:03b5121a232e 1690 goto error;
pcercuei 0:03b5121a232e 1691
pcercuei 0:03b5121a232e 1692 /* is it an xs:date? */
pcercuei 0:03b5121a232e 1693 RETURN_TYPE_IF_VALID(XML_SCHEMAS_DATE);
pcercuei 0:03b5121a232e 1694
pcercuei 0:03b5121a232e 1695 if (*cur != 'T')
pcercuei 0:03b5121a232e 1696 goto error;
pcercuei 0:03b5121a232e 1697 cur++;
pcercuei 0:03b5121a232e 1698
pcercuei 0:03b5121a232e 1699 /* it should be an xs:dateTime */
pcercuei 0:03b5121a232e 1700 ret = _xmlSchemaParseTime(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1701 if (ret != 0)
pcercuei 0:03b5121a232e 1702 goto error;
pcercuei 0:03b5121a232e 1703
pcercuei 0:03b5121a232e 1704 ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur);
pcercuei 0:03b5121a232e 1705 if (collapse)
pcercuei 0:03b5121a232e 1706 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 1707 if ((ret != 0) || (*cur != 0) || (!(VALID_DATETIME((&(dt->value.date))))))
pcercuei 0:03b5121a232e 1708 goto error;
pcercuei 0:03b5121a232e 1709
pcercuei 0:03b5121a232e 1710
pcercuei 0:03b5121a232e 1711 dt->type = XML_SCHEMAS_DATETIME;
pcercuei 0:03b5121a232e 1712
pcercuei 0:03b5121a232e 1713 done:
pcercuei 0:03b5121a232e 1714 #if 1
pcercuei 0:03b5121a232e 1715 if ((type != XML_SCHEMAS_UNKNOWN) && (type != dt->type))
pcercuei 0:03b5121a232e 1716 goto error;
pcercuei 0:03b5121a232e 1717 #else
pcercuei 0:03b5121a232e 1718 /*
pcercuei 0:03b5121a232e 1719 * insure the parsed type is equal to or less significant (right
pcercuei 0:03b5121a232e 1720 * truncated) than the desired type.
pcercuei 0:03b5121a232e 1721 */
pcercuei 0:03b5121a232e 1722 if ((type != XML_SCHEMAS_UNKNOWN) && (type != dt->type)) {
pcercuei 0:03b5121a232e 1723
pcercuei 0:03b5121a232e 1724 /* time only matches time */
pcercuei 0:03b5121a232e 1725 if ((type == XML_SCHEMAS_TIME) && (dt->type == XML_SCHEMAS_TIME))
pcercuei 0:03b5121a232e 1726 goto error;
pcercuei 0:03b5121a232e 1727
pcercuei 0:03b5121a232e 1728 if ((type == XML_SCHEMAS_DATETIME) &&
pcercuei 0:03b5121a232e 1729 ((dt->type != XML_SCHEMAS_DATE) ||
pcercuei 0:03b5121a232e 1730 (dt->type != XML_SCHEMAS_GYEARMONTH) ||
pcercuei 0:03b5121a232e 1731 (dt->type != XML_SCHEMAS_GYEAR)))
pcercuei 0:03b5121a232e 1732 goto error;
pcercuei 0:03b5121a232e 1733
pcercuei 0:03b5121a232e 1734 if ((type == XML_SCHEMAS_DATE) &&
pcercuei 0:03b5121a232e 1735 ((dt->type != XML_SCHEMAS_GYEAR) ||
pcercuei 0:03b5121a232e 1736 (dt->type != XML_SCHEMAS_GYEARMONTH)))
pcercuei 0:03b5121a232e 1737 goto error;
pcercuei 0:03b5121a232e 1738
pcercuei 0:03b5121a232e 1739 if ((type == XML_SCHEMAS_GYEARMONTH) && (dt->type != XML_SCHEMAS_GYEAR))
pcercuei 0:03b5121a232e 1740 goto error;
pcercuei 0:03b5121a232e 1741
pcercuei 0:03b5121a232e 1742 if ((type == XML_SCHEMAS_GMONTHDAY) && (dt->type != XML_SCHEMAS_GMONTH))
pcercuei 0:03b5121a232e 1743 goto error;
pcercuei 0:03b5121a232e 1744 }
pcercuei 0:03b5121a232e 1745 #endif
pcercuei 0:03b5121a232e 1746
pcercuei 0:03b5121a232e 1747 if (val != NULL)
pcercuei 0:03b5121a232e 1748 *val = dt;
pcercuei 0:03b5121a232e 1749 else
pcercuei 0:03b5121a232e 1750 xmlSchemaFreeValue(dt);
pcercuei 0:03b5121a232e 1751
pcercuei 0:03b5121a232e 1752 return 0;
pcercuei 0:03b5121a232e 1753
pcercuei 0:03b5121a232e 1754 error:
pcercuei 0:03b5121a232e 1755 if (dt != NULL)
pcercuei 0:03b5121a232e 1756 xmlSchemaFreeValue(dt);
pcercuei 0:03b5121a232e 1757 return 1;
pcercuei 0:03b5121a232e 1758 }
pcercuei 0:03b5121a232e 1759
pcercuei 0:03b5121a232e 1760 /**
pcercuei 0:03b5121a232e 1761 * xmlSchemaValidateDuration:
pcercuei 0:03b5121a232e 1762 * @type: the predefined type
pcercuei 0:03b5121a232e 1763 * @duration: string to analyze
pcercuei 0:03b5121a232e 1764 * @val: the return computed value
pcercuei 0:03b5121a232e 1765 *
pcercuei 0:03b5121a232e 1766 * Check that @duration conforms to the lexical space of the duration type.
pcercuei 0:03b5121a232e 1767 * if true a value is computed and returned in @val.
pcercuei 0:03b5121a232e 1768 *
pcercuei 0:03b5121a232e 1769 * Returns 0 if this validates, a positive error code number otherwise
pcercuei 0:03b5121a232e 1770 * and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 1771 */
pcercuei 0:03b5121a232e 1772 static int
pcercuei 0:03b5121a232e 1773 xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 1774 const xmlChar *duration, xmlSchemaValPtr *val,
pcercuei 0:03b5121a232e 1775 int collapse) {
pcercuei 0:03b5121a232e 1776 const xmlChar *cur = duration;
pcercuei 0:03b5121a232e 1777 xmlSchemaValPtr dur;
pcercuei 0:03b5121a232e 1778 int isneg = 0;
pcercuei 0:03b5121a232e 1779 unsigned int seq = 0;
pcercuei 0:03b5121a232e 1780 double num;
pcercuei 0:03b5121a232e 1781 int num_type = 0; /* -1 = invalid, 0 = int, 1 = floating */
pcercuei 0:03b5121a232e 1782 const xmlChar desig[] = {'Y', 'M', 'D', 'H', 'M', 'S'};
pcercuei 0:03b5121a232e 1783 const double multi[] = { 0.0, 0.0, 86400.0, 3600.0, 60.0, 1.0, 0.0};
pcercuei 0:03b5121a232e 1784
pcercuei 0:03b5121a232e 1785 if (duration == NULL)
pcercuei 0:03b5121a232e 1786 return -1;
pcercuei 0:03b5121a232e 1787
pcercuei 0:03b5121a232e 1788 if (collapse)
pcercuei 0:03b5121a232e 1789 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 1790
pcercuei 0:03b5121a232e 1791 if (*cur == '-') {
pcercuei 0:03b5121a232e 1792 isneg = 1;
pcercuei 0:03b5121a232e 1793 cur++;
pcercuei 0:03b5121a232e 1794 }
pcercuei 0:03b5121a232e 1795
pcercuei 0:03b5121a232e 1796 /* duration must start with 'P' (after sign) */
pcercuei 0:03b5121a232e 1797 if (*cur++ != 'P')
pcercuei 0:03b5121a232e 1798 return 1;
pcercuei 0:03b5121a232e 1799
pcercuei 0:03b5121a232e 1800 if (*cur == 0)
pcercuei 0:03b5121a232e 1801 return 1;
pcercuei 0:03b5121a232e 1802
pcercuei 0:03b5121a232e 1803 dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
pcercuei 0:03b5121a232e 1804 if (dur == NULL)
pcercuei 0:03b5121a232e 1805 return -1;
pcercuei 0:03b5121a232e 1806
pcercuei 0:03b5121a232e 1807 while (*cur != 0) {
pcercuei 0:03b5121a232e 1808
pcercuei 0:03b5121a232e 1809 /* input string should be empty or invalid date/time item */
pcercuei 0:03b5121a232e 1810 if (seq >= sizeof(desig))
pcercuei 0:03b5121a232e 1811 goto error;
pcercuei 0:03b5121a232e 1812
pcercuei 0:03b5121a232e 1813 /* T designator must be present for time items */
pcercuei 0:03b5121a232e 1814 if (*cur == 'T') {
pcercuei 0:03b5121a232e 1815 if (seq <= 3) {
pcercuei 0:03b5121a232e 1816 seq = 3;
pcercuei 0:03b5121a232e 1817 cur++;
pcercuei 0:03b5121a232e 1818 } else
pcercuei 0:03b5121a232e 1819 return 1;
pcercuei 0:03b5121a232e 1820 } else if (seq == 3)
pcercuei 0:03b5121a232e 1821 goto error;
pcercuei 0:03b5121a232e 1822
pcercuei 0:03b5121a232e 1823 /* parse the number portion of the item */
pcercuei 0:03b5121a232e 1824 PARSE_NUM(num, cur, num_type);
pcercuei 0:03b5121a232e 1825
pcercuei 0:03b5121a232e 1826 if ((num_type == -1) || (*cur == 0))
pcercuei 0:03b5121a232e 1827 goto error;
pcercuei 0:03b5121a232e 1828
pcercuei 0:03b5121a232e 1829 /* update duration based on item type */
pcercuei 0:03b5121a232e 1830 while (seq < sizeof(desig)) {
pcercuei 0:03b5121a232e 1831 if (*cur == desig[seq]) {
pcercuei 0:03b5121a232e 1832
pcercuei 0:03b5121a232e 1833 /* verify numeric type; only seconds can be float */
pcercuei 0:03b5121a232e 1834 if ((num_type != 0) && (seq < (sizeof(desig)-1)))
pcercuei 0:03b5121a232e 1835 goto error;
pcercuei 0:03b5121a232e 1836
pcercuei 0:03b5121a232e 1837 switch (seq) {
pcercuei 0:03b5121a232e 1838 case 0:
pcercuei 0:03b5121a232e 1839 dur->value.dur.mon = (long)num * 12;
pcercuei 0:03b5121a232e 1840 break;
pcercuei 0:03b5121a232e 1841 case 1:
pcercuei 0:03b5121a232e 1842 dur->value.dur.mon += (long)num;
pcercuei 0:03b5121a232e 1843 break;
pcercuei 0:03b5121a232e 1844 default:
pcercuei 0:03b5121a232e 1845 /* convert to seconds using multiplier */
pcercuei 0:03b5121a232e 1846 dur->value.dur.sec += num * multi[seq];
pcercuei 0:03b5121a232e 1847 seq++;
pcercuei 0:03b5121a232e 1848 break;
pcercuei 0:03b5121a232e 1849 }
pcercuei 0:03b5121a232e 1850
pcercuei 0:03b5121a232e 1851 break; /* exit loop */
pcercuei 0:03b5121a232e 1852 }
pcercuei 0:03b5121a232e 1853 /* no date designators found? */
pcercuei 0:03b5121a232e 1854 if ((++seq == 3) || (seq == 6))
pcercuei 0:03b5121a232e 1855 goto error;
pcercuei 0:03b5121a232e 1856 }
pcercuei 0:03b5121a232e 1857 cur++;
pcercuei 0:03b5121a232e 1858 if (collapse)
pcercuei 0:03b5121a232e 1859 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 1860 }
pcercuei 0:03b5121a232e 1861
pcercuei 0:03b5121a232e 1862 if (isneg) {
pcercuei 0:03b5121a232e 1863 dur->value.dur.mon = -dur->value.dur.mon;
pcercuei 0:03b5121a232e 1864 dur->value.dur.day = -dur->value.dur.day;
pcercuei 0:03b5121a232e 1865 dur->value.dur.sec = -dur->value.dur.sec;
pcercuei 0:03b5121a232e 1866 }
pcercuei 0:03b5121a232e 1867
pcercuei 0:03b5121a232e 1868 if (val != NULL)
pcercuei 0:03b5121a232e 1869 *val = dur;
pcercuei 0:03b5121a232e 1870 else
pcercuei 0:03b5121a232e 1871 xmlSchemaFreeValue(dur);
pcercuei 0:03b5121a232e 1872
pcercuei 0:03b5121a232e 1873 return 0;
pcercuei 0:03b5121a232e 1874
pcercuei 0:03b5121a232e 1875 error:
pcercuei 0:03b5121a232e 1876 if (dur != NULL)
pcercuei 0:03b5121a232e 1877 xmlSchemaFreeValue(dur);
pcercuei 0:03b5121a232e 1878 return 1;
pcercuei 0:03b5121a232e 1879 }
pcercuei 0:03b5121a232e 1880
pcercuei 0:03b5121a232e 1881 /**
pcercuei 0:03b5121a232e 1882 * xmlSchemaStrip:
pcercuei 0:03b5121a232e 1883 * @value: a value
pcercuei 0:03b5121a232e 1884 *
pcercuei 0:03b5121a232e 1885 * Removes the leading and ending spaces of a string
pcercuei 0:03b5121a232e 1886 *
pcercuei 0:03b5121a232e 1887 * Returns the new string or NULL if no change was required.
pcercuei 0:03b5121a232e 1888 */
pcercuei 0:03b5121a232e 1889 static xmlChar *
pcercuei 0:03b5121a232e 1890 xmlSchemaStrip(const xmlChar *value) {
pcercuei 0:03b5121a232e 1891 const xmlChar *start = value, *end, *f;
pcercuei 0:03b5121a232e 1892
pcercuei 0:03b5121a232e 1893 if (value == NULL) return(NULL);
pcercuei 0:03b5121a232e 1894 while ((*start != 0) && (IS_BLANK_CH(*start))) start++;
pcercuei 0:03b5121a232e 1895 end = start;
pcercuei 0:03b5121a232e 1896 while (*end != 0) end++;
pcercuei 0:03b5121a232e 1897 f = end;
pcercuei 0:03b5121a232e 1898 end--;
pcercuei 0:03b5121a232e 1899 while ((end > start) && (IS_BLANK_CH(*end))) end--;
pcercuei 0:03b5121a232e 1900 end++;
pcercuei 0:03b5121a232e 1901 if ((start == value) && (f == end)) return(NULL);
pcercuei 0:03b5121a232e 1902 return(xmlStrndup(start, end - start));
pcercuei 0:03b5121a232e 1903 }
pcercuei 0:03b5121a232e 1904
pcercuei 0:03b5121a232e 1905 /**
pcercuei 0:03b5121a232e 1906 * xmlSchemaWhiteSpaceReplace:
pcercuei 0:03b5121a232e 1907 * @value: a value
pcercuei 0:03b5121a232e 1908 *
pcercuei 0:03b5121a232e 1909 * Replaces 0xd, 0x9 and 0xa with a space.
pcercuei 0:03b5121a232e 1910 *
pcercuei 0:03b5121a232e 1911 * Returns the new string or NULL if no change was required.
pcercuei 0:03b5121a232e 1912 */
pcercuei 0:03b5121a232e 1913 xmlChar *
pcercuei 0:03b5121a232e 1914 xmlSchemaWhiteSpaceReplace(const xmlChar *value) {
pcercuei 0:03b5121a232e 1915 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 1916 xmlChar *ret = NULL, *mcur;
pcercuei 0:03b5121a232e 1917
pcercuei 0:03b5121a232e 1918 if (value == NULL)
pcercuei 0:03b5121a232e 1919 return(NULL);
pcercuei 0:03b5121a232e 1920
pcercuei 0:03b5121a232e 1921 while ((*cur != 0) &&
pcercuei 0:03b5121a232e 1922 (((*cur) != 0xd) && ((*cur) != 0x9) && ((*cur) != 0xa))) {
pcercuei 0:03b5121a232e 1923 cur++;
pcercuei 0:03b5121a232e 1924 }
pcercuei 0:03b5121a232e 1925 if (*cur == 0)
pcercuei 0:03b5121a232e 1926 return (NULL);
pcercuei 0:03b5121a232e 1927 ret = xmlStrdup(value);
pcercuei 0:03b5121a232e 1928 /* TODO FIXME: I guess gcc will bark at this. */
pcercuei 0:03b5121a232e 1929 mcur = (xmlChar *) (ret + (cur - value));
pcercuei 0:03b5121a232e 1930 do {
pcercuei 0:03b5121a232e 1931 if ( ((*mcur) == 0xd) || ((*mcur) == 0x9) || ((*mcur) == 0xa) )
pcercuei 0:03b5121a232e 1932 *mcur = ' ';
pcercuei 0:03b5121a232e 1933 mcur++;
pcercuei 0:03b5121a232e 1934 } while (*mcur != 0);
pcercuei 0:03b5121a232e 1935 return(ret);
pcercuei 0:03b5121a232e 1936 }
pcercuei 0:03b5121a232e 1937
pcercuei 0:03b5121a232e 1938 /**
pcercuei 0:03b5121a232e 1939 * xmlSchemaCollapseString:
pcercuei 0:03b5121a232e 1940 * @value: a value
pcercuei 0:03b5121a232e 1941 *
pcercuei 0:03b5121a232e 1942 * Removes and normalize white spaces in the string
pcercuei 0:03b5121a232e 1943 *
pcercuei 0:03b5121a232e 1944 * Returns the new string or NULL if no change was required.
pcercuei 0:03b5121a232e 1945 */
pcercuei 0:03b5121a232e 1946 xmlChar *
pcercuei 0:03b5121a232e 1947 xmlSchemaCollapseString(const xmlChar *value) {
pcercuei 0:03b5121a232e 1948 const xmlChar *start = value, *end, *f;
pcercuei 0:03b5121a232e 1949 xmlChar *g;
pcercuei 0:03b5121a232e 1950 int col = 0;
pcercuei 0:03b5121a232e 1951
pcercuei 0:03b5121a232e 1952 if (value == NULL) return(NULL);
pcercuei 0:03b5121a232e 1953 while ((*start != 0) && (IS_BLANK_CH(*start))) start++;
pcercuei 0:03b5121a232e 1954 end = start;
pcercuei 0:03b5121a232e 1955 while (*end != 0) {
pcercuei 0:03b5121a232e 1956 if ((*end == ' ') && (IS_BLANK_CH(end[1]))) {
pcercuei 0:03b5121a232e 1957 col = end - start;
pcercuei 0:03b5121a232e 1958 break;
pcercuei 0:03b5121a232e 1959 } else if ((*end == 0xa) || (*end == 0x9) || (*end == 0xd)) {
pcercuei 0:03b5121a232e 1960 col = end - start;
pcercuei 0:03b5121a232e 1961 break;
pcercuei 0:03b5121a232e 1962 }
pcercuei 0:03b5121a232e 1963 end++;
pcercuei 0:03b5121a232e 1964 }
pcercuei 0:03b5121a232e 1965 if (col == 0) {
pcercuei 0:03b5121a232e 1966 f = end;
pcercuei 0:03b5121a232e 1967 end--;
pcercuei 0:03b5121a232e 1968 while ((end > start) && (IS_BLANK_CH(*end))) end--;
pcercuei 0:03b5121a232e 1969 end++;
pcercuei 0:03b5121a232e 1970 if ((start == value) && (f == end)) return(NULL);
pcercuei 0:03b5121a232e 1971 return(xmlStrndup(start, end - start));
pcercuei 0:03b5121a232e 1972 }
pcercuei 0:03b5121a232e 1973 start = xmlStrdup(start);
pcercuei 0:03b5121a232e 1974 if (start == NULL) return(NULL);
pcercuei 0:03b5121a232e 1975 g = (xmlChar *) (start + col);
pcercuei 0:03b5121a232e 1976 end = g;
pcercuei 0:03b5121a232e 1977 while (*end != 0) {
pcercuei 0:03b5121a232e 1978 if (IS_BLANK_CH(*end)) {
pcercuei 0:03b5121a232e 1979 end++;
pcercuei 0:03b5121a232e 1980 while (IS_BLANK_CH(*end)) end++;
pcercuei 0:03b5121a232e 1981 if (*end != 0)
pcercuei 0:03b5121a232e 1982 *g++ = ' ';
pcercuei 0:03b5121a232e 1983 } else
pcercuei 0:03b5121a232e 1984 *g++ = *end++;
pcercuei 0:03b5121a232e 1985 }
pcercuei 0:03b5121a232e 1986 *g = 0;
pcercuei 0:03b5121a232e 1987 return((xmlChar *) start);
pcercuei 0:03b5121a232e 1988 }
pcercuei 0:03b5121a232e 1989
pcercuei 0:03b5121a232e 1990 /**
pcercuei 0:03b5121a232e 1991 * xmlSchemaValAtomicListNode:
pcercuei 0:03b5121a232e 1992 * @type: the predefined atomic type for a token in the list
pcercuei 0:03b5121a232e 1993 * @value: the list value to check
pcercuei 0:03b5121a232e 1994 * @ret: the return computed value
pcercuei 0:03b5121a232e 1995 * @node: the node containing the value
pcercuei 0:03b5121a232e 1996 *
pcercuei 0:03b5121a232e 1997 * Check that a value conforms to the lexical space of the predefined
pcercuei 0:03b5121a232e 1998 * list type. if true a value is computed and returned in @ret.
pcercuei 0:03b5121a232e 1999 *
pcercuei 0:03b5121a232e 2000 * Returns the number of items if this validates, a negative error code
pcercuei 0:03b5121a232e 2001 * number otherwise
pcercuei 0:03b5121a232e 2002 */
pcercuei 0:03b5121a232e 2003 static int
pcercuei 0:03b5121a232e 2004 xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value,
pcercuei 0:03b5121a232e 2005 xmlSchemaValPtr *ret, xmlNodePtr node) {
pcercuei 0:03b5121a232e 2006 xmlChar *val, *cur, *endval;
pcercuei 0:03b5121a232e 2007 int nb_values = 0;
pcercuei 0:03b5121a232e 2008 int tmp = 0;
pcercuei 0:03b5121a232e 2009
pcercuei 0:03b5121a232e 2010 if (value == NULL) {
pcercuei 0:03b5121a232e 2011 return(-1);
pcercuei 0:03b5121a232e 2012 }
pcercuei 0:03b5121a232e 2013 val = xmlStrdup(value);
pcercuei 0:03b5121a232e 2014 if (val == NULL) {
pcercuei 0:03b5121a232e 2015 return(-1);
pcercuei 0:03b5121a232e 2016 }
pcercuei 0:03b5121a232e 2017 if (ret != NULL) {
pcercuei 0:03b5121a232e 2018 *ret = NULL;
pcercuei 0:03b5121a232e 2019 }
pcercuei 0:03b5121a232e 2020 cur = val;
pcercuei 0:03b5121a232e 2021 /*
pcercuei 0:03b5121a232e 2022 * Split the list
pcercuei 0:03b5121a232e 2023 */
pcercuei 0:03b5121a232e 2024 while (IS_BLANK_CH(*cur)) *cur++ = 0;
pcercuei 0:03b5121a232e 2025 while (*cur != 0) {
pcercuei 0:03b5121a232e 2026 if (IS_BLANK_CH(*cur)) {
pcercuei 0:03b5121a232e 2027 *cur = 0;
pcercuei 0:03b5121a232e 2028 cur++;
pcercuei 0:03b5121a232e 2029 while (IS_BLANK_CH(*cur)) *cur++ = 0;
pcercuei 0:03b5121a232e 2030 } else {
pcercuei 0:03b5121a232e 2031 nb_values++;
pcercuei 0:03b5121a232e 2032 cur++;
pcercuei 0:03b5121a232e 2033 while ((*cur != 0) && (!IS_BLANK_CH(*cur))) cur++;
pcercuei 0:03b5121a232e 2034 }
pcercuei 0:03b5121a232e 2035 }
pcercuei 0:03b5121a232e 2036 if (nb_values == 0) {
pcercuei 0:03b5121a232e 2037 xmlFree(val);
pcercuei 0:03b5121a232e 2038 return(nb_values);
pcercuei 0:03b5121a232e 2039 }
pcercuei 0:03b5121a232e 2040 endval = cur;
pcercuei 0:03b5121a232e 2041 cur = val;
pcercuei 0:03b5121a232e 2042 while ((*cur == 0) && (cur != endval)) cur++;
pcercuei 0:03b5121a232e 2043 while (cur != endval) {
pcercuei 0:03b5121a232e 2044 tmp = xmlSchemaValPredefTypeNode(type, cur, NULL, node);
pcercuei 0:03b5121a232e 2045 if (tmp != 0)
pcercuei 0:03b5121a232e 2046 break;
pcercuei 0:03b5121a232e 2047 while (*cur != 0) cur++;
pcercuei 0:03b5121a232e 2048 while ((*cur == 0) && (cur != endval)) cur++;
pcercuei 0:03b5121a232e 2049 }
pcercuei 0:03b5121a232e 2050 /* TODO what return value ? c.f. bug #158628
pcercuei 0:03b5121a232e 2051 if (ret != NULL) {
pcercuei 0:03b5121a232e 2052 TODO
pcercuei 0:03b5121a232e 2053 } */
pcercuei 0:03b5121a232e 2054 xmlFree(val);
pcercuei 0:03b5121a232e 2055 if (tmp == 0)
pcercuei 0:03b5121a232e 2056 return(nb_values);
pcercuei 0:03b5121a232e 2057 return(-1);
pcercuei 0:03b5121a232e 2058 }
pcercuei 0:03b5121a232e 2059
pcercuei 0:03b5121a232e 2060 /**
pcercuei 0:03b5121a232e 2061 * xmlSchemaParseUInt:
pcercuei 0:03b5121a232e 2062 * @str: pointer to the string R/W
pcercuei 0:03b5121a232e 2063 * @llo: pointer to the low result
pcercuei 0:03b5121a232e 2064 * @lmi: pointer to the mid result
pcercuei 0:03b5121a232e 2065 * @lhi: pointer to the high result
pcercuei 0:03b5121a232e 2066 *
pcercuei 0:03b5121a232e 2067 * Parse an unsigned long into 3 fields.
pcercuei 0:03b5121a232e 2068 *
pcercuei 0:03b5121a232e 2069 * Returns the number of significant digits in the number or
pcercuei 0:03b5121a232e 2070 * -1 if overflow of the capacity and -2 if it's not a number.
pcercuei 0:03b5121a232e 2071 */
pcercuei 0:03b5121a232e 2072 static int
pcercuei 0:03b5121a232e 2073 xmlSchemaParseUInt(const xmlChar **str, unsigned long *llo,
pcercuei 0:03b5121a232e 2074 unsigned long *lmi, unsigned long *lhi) {
pcercuei 0:03b5121a232e 2075 unsigned long lo = 0, mi = 0, hi = 0;
pcercuei 0:03b5121a232e 2076 const xmlChar *tmp, *cur = *str;
pcercuei 0:03b5121a232e 2077 int ret = 0, i = 0;
pcercuei 0:03b5121a232e 2078
pcercuei 0:03b5121a232e 2079 if (!((*cur >= '0') && (*cur <= '9')))
pcercuei 0:03b5121a232e 2080 return(-2);
pcercuei 0:03b5121a232e 2081
pcercuei 0:03b5121a232e 2082 while (*cur == '0') { /* ignore leading zeroes */
pcercuei 0:03b5121a232e 2083 cur++;
pcercuei 0:03b5121a232e 2084 }
pcercuei 0:03b5121a232e 2085 tmp = cur;
pcercuei 0:03b5121a232e 2086 while ((*tmp != 0) && (*tmp >= '0') && (*tmp <= '9')) {
pcercuei 0:03b5121a232e 2087 i++;tmp++;ret++;
pcercuei 0:03b5121a232e 2088 }
pcercuei 0:03b5121a232e 2089 if (i > 24) {
pcercuei 0:03b5121a232e 2090 *str = tmp;
pcercuei 0:03b5121a232e 2091 return(-1);
pcercuei 0:03b5121a232e 2092 }
pcercuei 0:03b5121a232e 2093 while (i > 16) {
pcercuei 0:03b5121a232e 2094 hi = hi * 10 + (*cur++ - '0');
pcercuei 0:03b5121a232e 2095 i--;
pcercuei 0:03b5121a232e 2096 }
pcercuei 0:03b5121a232e 2097 while (i > 8) {
pcercuei 0:03b5121a232e 2098 mi = mi * 10 + (*cur++ - '0');
pcercuei 0:03b5121a232e 2099 i--;
pcercuei 0:03b5121a232e 2100 }
pcercuei 0:03b5121a232e 2101 while (i > 0) {
pcercuei 0:03b5121a232e 2102 lo = lo * 10 + (*cur++ - '0');
pcercuei 0:03b5121a232e 2103 i--;
pcercuei 0:03b5121a232e 2104 }
pcercuei 0:03b5121a232e 2105
pcercuei 0:03b5121a232e 2106 *str = cur;
pcercuei 0:03b5121a232e 2107 *llo = lo;
pcercuei 0:03b5121a232e 2108 *lmi = mi;
pcercuei 0:03b5121a232e 2109 *lhi = hi;
pcercuei 0:03b5121a232e 2110 return(ret);
pcercuei 0:03b5121a232e 2111 }
pcercuei 0:03b5121a232e 2112
pcercuei 0:03b5121a232e 2113 /**
pcercuei 0:03b5121a232e 2114 * xmlSchemaValAtomicType:
pcercuei 0:03b5121a232e 2115 * @type: the predefined type
pcercuei 0:03b5121a232e 2116 * @value: the value to check
pcercuei 0:03b5121a232e 2117 * @val: the return computed value
pcercuei 0:03b5121a232e 2118 * @node: the node containing the value
pcercuei 0:03b5121a232e 2119 * flags: flags to control the vlidation
pcercuei 0:03b5121a232e 2120 *
pcercuei 0:03b5121a232e 2121 * Check that a value conforms to the lexical space of the atomic type.
pcercuei 0:03b5121a232e 2122 * if true a value is computed and returned in @val.
pcercuei 0:03b5121a232e 2123 * This checks the value space for list types as well (IDREFS, NMTOKENS).
pcercuei 0:03b5121a232e 2124 *
pcercuei 0:03b5121a232e 2125 * Returns 0 if this validates, a positive error code number otherwise
pcercuei 0:03b5121a232e 2126 * and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 2127 */
pcercuei 0:03b5121a232e 2128 static int
pcercuei 0:03b5121a232e 2129 xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
pcercuei 0:03b5121a232e 2130 xmlSchemaValPtr * val, xmlNodePtr node, int flags,
pcercuei 0:03b5121a232e 2131 xmlSchemaWhitespaceValueType ws,
pcercuei 0:03b5121a232e 2132 int normOnTheFly, int applyNorm, int createStringValue)
pcercuei 0:03b5121a232e 2133 {
pcercuei 0:03b5121a232e 2134 xmlSchemaValPtr v;
pcercuei 0:03b5121a232e 2135 xmlChar *norm = NULL;
pcercuei 0:03b5121a232e 2136 int ret = 0;
pcercuei 0:03b5121a232e 2137
pcercuei 0:03b5121a232e 2138 if (xmlSchemaTypesInitialized == 0)
pcercuei 0:03b5121a232e 2139 xmlSchemaInitTypes();
pcercuei 0:03b5121a232e 2140 if (type == NULL)
pcercuei 0:03b5121a232e 2141 return (-1);
pcercuei 0:03b5121a232e 2142
pcercuei 0:03b5121a232e 2143 /*
pcercuei 0:03b5121a232e 2144 * validating a non existant text node is similar to validating
pcercuei 0:03b5121a232e 2145 * an empty one.
pcercuei 0:03b5121a232e 2146 */
pcercuei 0:03b5121a232e 2147 if (value == NULL)
pcercuei 0:03b5121a232e 2148 value = BAD_CAST "";
pcercuei 0:03b5121a232e 2149
pcercuei 0:03b5121a232e 2150 if (val != NULL)
pcercuei 0:03b5121a232e 2151 *val = NULL;
pcercuei 0:03b5121a232e 2152 if ((flags == 0) && (value != NULL)) {
pcercuei 0:03b5121a232e 2153
pcercuei 0:03b5121a232e 2154 if ((type->builtInType != XML_SCHEMAS_STRING) &&
pcercuei 0:03b5121a232e 2155 (type->builtInType != XML_SCHEMAS_ANYTYPE) &&
pcercuei 0:03b5121a232e 2156 (type->builtInType != XML_SCHEMAS_ANYSIMPLETYPE)) {
pcercuei 0:03b5121a232e 2157 if (type->builtInType == XML_SCHEMAS_NORMSTRING)
pcercuei 0:03b5121a232e 2158 norm = xmlSchemaWhiteSpaceReplace(value);
pcercuei 0:03b5121a232e 2159 else
pcercuei 0:03b5121a232e 2160 norm = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 2161 if (norm != NULL)
pcercuei 0:03b5121a232e 2162 value = norm;
pcercuei 0:03b5121a232e 2163 }
pcercuei 0:03b5121a232e 2164 }
pcercuei 0:03b5121a232e 2165
pcercuei 0:03b5121a232e 2166 switch (type->builtInType) {
pcercuei 0:03b5121a232e 2167 case XML_SCHEMAS_UNKNOWN:
pcercuei 0:03b5121a232e 2168 goto error;
pcercuei 0:03b5121a232e 2169 case XML_SCHEMAS_ANYTYPE:
pcercuei 0:03b5121a232e 2170 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 2171 if ((createStringValue) && (val != NULL)) {
pcercuei 0:03b5121a232e 2172 v = xmlSchemaNewValue(XML_SCHEMAS_ANYSIMPLETYPE);
pcercuei 0:03b5121a232e 2173 if (v != NULL) {
pcercuei 0:03b5121a232e 2174 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2175 *val = v;
pcercuei 0:03b5121a232e 2176 } else {
pcercuei 0:03b5121a232e 2177 goto error;
pcercuei 0:03b5121a232e 2178 }
pcercuei 0:03b5121a232e 2179 }
pcercuei 0:03b5121a232e 2180 goto return0;
pcercuei 0:03b5121a232e 2181 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 2182 if (! normOnTheFly) {
pcercuei 0:03b5121a232e 2183 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 2184
pcercuei 0:03b5121a232e 2185 if (ws == XML_SCHEMA_WHITESPACE_REPLACE) {
pcercuei 0:03b5121a232e 2186 while (*cur != 0) {
pcercuei 0:03b5121a232e 2187 if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
pcercuei 0:03b5121a232e 2188 goto return1;
pcercuei 0:03b5121a232e 2189 } else {
pcercuei 0:03b5121a232e 2190 cur++;
pcercuei 0:03b5121a232e 2191 }
pcercuei 0:03b5121a232e 2192 }
pcercuei 0:03b5121a232e 2193 } else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
pcercuei 0:03b5121a232e 2194 while (*cur != 0) {
pcercuei 0:03b5121a232e 2195 if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
pcercuei 0:03b5121a232e 2196 goto return1;
pcercuei 0:03b5121a232e 2197 } else if IS_WSP_SPACE_CH(*cur) {
pcercuei 0:03b5121a232e 2198 cur++;
pcercuei 0:03b5121a232e 2199 if IS_WSP_SPACE_CH(*cur)
pcercuei 0:03b5121a232e 2200 goto return1;
pcercuei 0:03b5121a232e 2201 } else {
pcercuei 0:03b5121a232e 2202 cur++;
pcercuei 0:03b5121a232e 2203 }
pcercuei 0:03b5121a232e 2204 }
pcercuei 0:03b5121a232e 2205 }
pcercuei 0:03b5121a232e 2206 }
pcercuei 0:03b5121a232e 2207 if (createStringValue && (val != NULL)) {
pcercuei 0:03b5121a232e 2208 if (applyNorm) {
pcercuei 0:03b5121a232e 2209 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 2210 norm = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 2211 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 2212 norm = xmlSchemaWhiteSpaceReplace(value);
pcercuei 0:03b5121a232e 2213 if (norm != NULL)
pcercuei 0:03b5121a232e 2214 value = norm;
pcercuei 0:03b5121a232e 2215 }
pcercuei 0:03b5121a232e 2216 v = xmlSchemaNewValue(XML_SCHEMAS_STRING);
pcercuei 0:03b5121a232e 2217 if (v != NULL) {
pcercuei 0:03b5121a232e 2218 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2219 *val = v;
pcercuei 0:03b5121a232e 2220 } else {
pcercuei 0:03b5121a232e 2221 goto error;
pcercuei 0:03b5121a232e 2222 }
pcercuei 0:03b5121a232e 2223 }
pcercuei 0:03b5121a232e 2224 goto return0;
pcercuei 0:03b5121a232e 2225 case XML_SCHEMAS_NORMSTRING:{
pcercuei 0:03b5121a232e 2226 if (normOnTheFly) {
pcercuei 0:03b5121a232e 2227 if (applyNorm) {
pcercuei 0:03b5121a232e 2228 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 2229 norm = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 2230 else
pcercuei 0:03b5121a232e 2231 norm = xmlSchemaWhiteSpaceReplace(value);
pcercuei 0:03b5121a232e 2232 if (norm != NULL)
pcercuei 0:03b5121a232e 2233 value = norm;
pcercuei 0:03b5121a232e 2234 }
pcercuei 0:03b5121a232e 2235 } else {
pcercuei 0:03b5121a232e 2236 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 2237 while (*cur != 0) {
pcercuei 0:03b5121a232e 2238 if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
pcercuei 0:03b5121a232e 2239 goto return1;
pcercuei 0:03b5121a232e 2240 } else {
pcercuei 0:03b5121a232e 2241 cur++;
pcercuei 0:03b5121a232e 2242 }
pcercuei 0:03b5121a232e 2243 }
pcercuei 0:03b5121a232e 2244 }
pcercuei 0:03b5121a232e 2245 if (val != NULL) {
pcercuei 0:03b5121a232e 2246 v = xmlSchemaNewValue(XML_SCHEMAS_NORMSTRING);
pcercuei 0:03b5121a232e 2247 if (v != NULL) {
pcercuei 0:03b5121a232e 2248 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2249 *val = v;
pcercuei 0:03b5121a232e 2250 } else {
pcercuei 0:03b5121a232e 2251 goto error;
pcercuei 0:03b5121a232e 2252 }
pcercuei 0:03b5121a232e 2253 }
pcercuei 0:03b5121a232e 2254 goto return0;
pcercuei 0:03b5121a232e 2255 }
pcercuei 0:03b5121a232e 2256 case XML_SCHEMAS_DECIMAL:{
pcercuei 0:03b5121a232e 2257 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 2258 unsigned int len, neg, integ, hasLeadingZeroes;
pcercuei 0:03b5121a232e 2259 xmlChar cval[25];
pcercuei 0:03b5121a232e 2260 xmlChar *cptr = cval;
pcercuei 0:03b5121a232e 2261
pcercuei 0:03b5121a232e 2262 if ((cur == NULL) || (*cur == 0))
pcercuei 0:03b5121a232e 2263 goto return1;
pcercuei 0:03b5121a232e 2264
pcercuei 0:03b5121a232e 2265 /*
pcercuei 0:03b5121a232e 2266 * xs:decimal has a whitespace-facet value of 'collapse'.
pcercuei 0:03b5121a232e 2267 */
pcercuei 0:03b5121a232e 2268 if (normOnTheFly)
pcercuei 0:03b5121a232e 2269 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2270
pcercuei 0:03b5121a232e 2271 /*
pcercuei 0:03b5121a232e 2272 * First we handle an optional sign.
pcercuei 0:03b5121a232e 2273 */
pcercuei 0:03b5121a232e 2274 neg = 0;
pcercuei 0:03b5121a232e 2275 if (*cur == '-') {
pcercuei 0:03b5121a232e 2276 neg = 1;
pcercuei 0:03b5121a232e 2277 cur++;
pcercuei 0:03b5121a232e 2278 } else if (*cur == '+')
pcercuei 0:03b5121a232e 2279 cur++;
pcercuei 0:03b5121a232e 2280 /*
pcercuei 0:03b5121a232e 2281 * Disallow: "", "-", "- "
pcercuei 0:03b5121a232e 2282 */
pcercuei 0:03b5121a232e 2283 if (*cur == 0)
pcercuei 0:03b5121a232e 2284 goto return1;
pcercuei 0:03b5121a232e 2285 /*
pcercuei 0:03b5121a232e 2286 * Next we "pre-parse" the number, in preparation for calling
pcercuei 0:03b5121a232e 2287 * the common routine xmlSchemaParseUInt. We get rid of any
pcercuei 0:03b5121a232e 2288 * leading zeroes (because we have reserved only 25 chars),
pcercuei 0:03b5121a232e 2289 * and note the position of a decimal point.
pcercuei 0:03b5121a232e 2290 */
pcercuei 0:03b5121a232e 2291 len = 0;
pcercuei 0:03b5121a232e 2292 integ = ~0u;
pcercuei 0:03b5121a232e 2293 hasLeadingZeroes = 0;
pcercuei 0:03b5121a232e 2294 /*
pcercuei 0:03b5121a232e 2295 * Skip leading zeroes.
pcercuei 0:03b5121a232e 2296 */
pcercuei 0:03b5121a232e 2297 while (*cur == '0') {
pcercuei 0:03b5121a232e 2298 cur++;
pcercuei 0:03b5121a232e 2299 hasLeadingZeroes = 1;
pcercuei 0:03b5121a232e 2300 }
pcercuei 0:03b5121a232e 2301 if (*cur != 0) {
pcercuei 0:03b5121a232e 2302 do {
pcercuei 0:03b5121a232e 2303 if ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 2304 *cptr++ = *cur++;
pcercuei 0:03b5121a232e 2305 len++;
pcercuei 0:03b5121a232e 2306 } else if (*cur == '.') {
pcercuei 0:03b5121a232e 2307 cur++;
pcercuei 0:03b5121a232e 2308 integ = len;
pcercuei 0:03b5121a232e 2309 do {
pcercuei 0:03b5121a232e 2310 if ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 2311 *cptr++ = *cur++;
pcercuei 0:03b5121a232e 2312 len++;
pcercuei 0:03b5121a232e 2313 } else
pcercuei 0:03b5121a232e 2314 break;
pcercuei 0:03b5121a232e 2315 } while (len < 24);
pcercuei 0:03b5121a232e 2316 /*
pcercuei 0:03b5121a232e 2317 * Disallow "." but allow "00."
pcercuei 0:03b5121a232e 2318 */
pcercuei 0:03b5121a232e 2319 if ((len == 0) && (!hasLeadingZeroes))
pcercuei 0:03b5121a232e 2320 goto return1;
pcercuei 0:03b5121a232e 2321 break;
pcercuei 0:03b5121a232e 2322 } else
pcercuei 0:03b5121a232e 2323 break;
pcercuei 0:03b5121a232e 2324 } while (len < 24);
pcercuei 0:03b5121a232e 2325 }
pcercuei 0:03b5121a232e 2326 if (normOnTheFly)
pcercuei 0:03b5121a232e 2327 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2328 if (*cur != 0)
pcercuei 0:03b5121a232e 2329 goto return1; /* error if any extraneous chars */
pcercuei 0:03b5121a232e 2330 if (val != NULL) {
pcercuei 0:03b5121a232e 2331 v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
pcercuei 0:03b5121a232e 2332 if (v != NULL) {
pcercuei 0:03b5121a232e 2333 /*
pcercuei 0:03b5121a232e 2334 * Now evaluate the significant digits of the number
pcercuei 0:03b5121a232e 2335 */
pcercuei 0:03b5121a232e 2336 if (len != 0) {
pcercuei 0:03b5121a232e 2337
pcercuei 0:03b5121a232e 2338 if (integ != ~0u) {
pcercuei 0:03b5121a232e 2339 /*
pcercuei 0:03b5121a232e 2340 * Get rid of trailing zeroes in the
pcercuei 0:03b5121a232e 2341 * fractional part.
pcercuei 0:03b5121a232e 2342 */
pcercuei 0:03b5121a232e 2343 while ((len != integ) && (*(cptr-1) == '0')) {
pcercuei 0:03b5121a232e 2344 cptr--;
pcercuei 0:03b5121a232e 2345 len--;
pcercuei 0:03b5121a232e 2346 }
pcercuei 0:03b5121a232e 2347 }
pcercuei 0:03b5121a232e 2348 /*
pcercuei 0:03b5121a232e 2349 * Terminate the (preparsed) string.
pcercuei 0:03b5121a232e 2350 */
pcercuei 0:03b5121a232e 2351 if (len != 0) {
pcercuei 0:03b5121a232e 2352 *cptr = 0;
pcercuei 0:03b5121a232e 2353 cptr = cval;
pcercuei 0:03b5121a232e 2354
pcercuei 0:03b5121a232e 2355 xmlSchemaParseUInt((const xmlChar **)&cptr,
pcercuei 0:03b5121a232e 2356 &v->value.decimal.lo,
pcercuei 0:03b5121a232e 2357 &v->value.decimal.mi,
pcercuei 0:03b5121a232e 2358 &v->value.decimal.hi);
pcercuei 0:03b5121a232e 2359 }
pcercuei 0:03b5121a232e 2360 }
pcercuei 0:03b5121a232e 2361 /*
pcercuei 0:03b5121a232e 2362 * Set the total digits to 1 if a zero value.
pcercuei 0:03b5121a232e 2363 */
pcercuei 0:03b5121a232e 2364 v->value.decimal.sign = neg;
pcercuei 0:03b5121a232e 2365 if (len == 0) {
pcercuei 0:03b5121a232e 2366 /* Speedup for zero values. */
pcercuei 0:03b5121a232e 2367 v->value.decimal.total = 1;
pcercuei 0:03b5121a232e 2368 } else {
pcercuei 0:03b5121a232e 2369 v->value.decimal.total = len;
pcercuei 0:03b5121a232e 2370 if (integ == ~0u)
pcercuei 0:03b5121a232e 2371 v->value.decimal.frac = 0;
pcercuei 0:03b5121a232e 2372 else
pcercuei 0:03b5121a232e 2373 v->value.decimal.frac = len - integ;
pcercuei 0:03b5121a232e 2374 }
pcercuei 0:03b5121a232e 2375 *val = v;
pcercuei 0:03b5121a232e 2376 }
pcercuei 0:03b5121a232e 2377 }
pcercuei 0:03b5121a232e 2378 goto return0;
pcercuei 0:03b5121a232e 2379 }
pcercuei 0:03b5121a232e 2380 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 2381 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 2382 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 2383 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 2384 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 2385 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 2386 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 2387 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 2388 ret = xmlSchemaValidateDates(type->builtInType, value, val,
pcercuei 0:03b5121a232e 2389 normOnTheFly);
pcercuei 0:03b5121a232e 2390 break;
pcercuei 0:03b5121a232e 2391 case XML_SCHEMAS_DURATION:
pcercuei 0:03b5121a232e 2392 ret = xmlSchemaValidateDuration(type, value, val,
pcercuei 0:03b5121a232e 2393 normOnTheFly);
pcercuei 0:03b5121a232e 2394 break;
pcercuei 0:03b5121a232e 2395 case XML_SCHEMAS_FLOAT:
pcercuei 0:03b5121a232e 2396 case XML_SCHEMAS_DOUBLE: {
pcercuei 0:03b5121a232e 2397 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 2398 int neg = 0;
pcercuei 0:03b5121a232e 2399 int digits_before = 0;
pcercuei 0:03b5121a232e 2400 int digits_after = 0;
pcercuei 0:03b5121a232e 2401
pcercuei 0:03b5121a232e 2402 if (normOnTheFly)
pcercuei 0:03b5121a232e 2403 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2404
pcercuei 0:03b5121a232e 2405 if ((cur[0] == 'N') && (cur[1] == 'a') && (cur[2] == 'N')) {
pcercuei 0:03b5121a232e 2406 cur += 3;
pcercuei 0:03b5121a232e 2407 if (*cur != 0)
pcercuei 0:03b5121a232e 2408 goto return1;
pcercuei 0:03b5121a232e 2409 if (val != NULL) {
pcercuei 0:03b5121a232e 2410 if (type == xmlSchemaTypeFloatDef) {
pcercuei 0:03b5121a232e 2411 v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
pcercuei 0:03b5121a232e 2412 if (v != NULL) {
pcercuei 0:03b5121a232e 2413 v->value.f = (float) xmlXPathNAN;
pcercuei 0:03b5121a232e 2414 } else {
pcercuei 0:03b5121a232e 2415 xmlSchemaFreeValue(v);
pcercuei 0:03b5121a232e 2416 goto error;
pcercuei 0:03b5121a232e 2417 }
pcercuei 0:03b5121a232e 2418 } else {
pcercuei 0:03b5121a232e 2419 v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
pcercuei 0:03b5121a232e 2420 if (v != NULL) {
pcercuei 0:03b5121a232e 2421 v->value.d = xmlXPathNAN;
pcercuei 0:03b5121a232e 2422 } else {
pcercuei 0:03b5121a232e 2423 xmlSchemaFreeValue(v);
pcercuei 0:03b5121a232e 2424 goto error;
pcercuei 0:03b5121a232e 2425 }
pcercuei 0:03b5121a232e 2426 }
pcercuei 0:03b5121a232e 2427 *val = v;
pcercuei 0:03b5121a232e 2428 }
pcercuei 0:03b5121a232e 2429 goto return0;
pcercuei 0:03b5121a232e 2430 }
pcercuei 0:03b5121a232e 2431 if (*cur == '-') {
pcercuei 0:03b5121a232e 2432 neg = 1;
pcercuei 0:03b5121a232e 2433 cur++;
pcercuei 0:03b5121a232e 2434 }
pcercuei 0:03b5121a232e 2435 if ((cur[0] == 'I') && (cur[1] == 'N') && (cur[2] == 'F')) {
pcercuei 0:03b5121a232e 2436 cur += 3;
pcercuei 0:03b5121a232e 2437 if (*cur != 0)
pcercuei 0:03b5121a232e 2438 goto return1;
pcercuei 0:03b5121a232e 2439 if (val != NULL) {
pcercuei 0:03b5121a232e 2440 if (type == xmlSchemaTypeFloatDef) {
pcercuei 0:03b5121a232e 2441 v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
pcercuei 0:03b5121a232e 2442 if (v != NULL) {
pcercuei 0:03b5121a232e 2443 if (neg)
pcercuei 0:03b5121a232e 2444 v->value.f = (float) xmlXPathNINF;
pcercuei 0:03b5121a232e 2445 else
pcercuei 0:03b5121a232e 2446 v->value.f = (float) xmlXPathPINF;
pcercuei 0:03b5121a232e 2447 } else {
pcercuei 0:03b5121a232e 2448 xmlSchemaFreeValue(v);
pcercuei 0:03b5121a232e 2449 goto error;
pcercuei 0:03b5121a232e 2450 }
pcercuei 0:03b5121a232e 2451 } else {
pcercuei 0:03b5121a232e 2452 v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
pcercuei 0:03b5121a232e 2453 if (v != NULL) {
pcercuei 0:03b5121a232e 2454 if (neg)
pcercuei 0:03b5121a232e 2455 v->value.d = xmlXPathNINF;
pcercuei 0:03b5121a232e 2456 else
pcercuei 0:03b5121a232e 2457 v->value.d = xmlXPathPINF;
pcercuei 0:03b5121a232e 2458 } else {
pcercuei 0:03b5121a232e 2459 xmlSchemaFreeValue(v);
pcercuei 0:03b5121a232e 2460 goto error;
pcercuei 0:03b5121a232e 2461 }
pcercuei 0:03b5121a232e 2462 }
pcercuei 0:03b5121a232e 2463 *val = v;
pcercuei 0:03b5121a232e 2464 }
pcercuei 0:03b5121a232e 2465 goto return0;
pcercuei 0:03b5121a232e 2466 }
pcercuei 0:03b5121a232e 2467 if ((neg == 0) && (*cur == '+'))
pcercuei 0:03b5121a232e 2468 cur++;
pcercuei 0:03b5121a232e 2469 if ((cur[0] == 0) || (cur[0] == '+') || (cur[0] == '-'))
pcercuei 0:03b5121a232e 2470 goto return1;
pcercuei 0:03b5121a232e 2471 while ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 2472 cur++;
pcercuei 0:03b5121a232e 2473 digits_before++;
pcercuei 0:03b5121a232e 2474 }
pcercuei 0:03b5121a232e 2475 if (*cur == '.') {
pcercuei 0:03b5121a232e 2476 cur++;
pcercuei 0:03b5121a232e 2477 while ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 2478 cur++;
pcercuei 0:03b5121a232e 2479 digits_after++;
pcercuei 0:03b5121a232e 2480 }
pcercuei 0:03b5121a232e 2481 }
pcercuei 0:03b5121a232e 2482 if ((digits_before == 0) && (digits_after == 0))
pcercuei 0:03b5121a232e 2483 goto return1;
pcercuei 0:03b5121a232e 2484 if ((*cur == 'e') || (*cur == 'E')) {
pcercuei 0:03b5121a232e 2485 cur++;
pcercuei 0:03b5121a232e 2486 if ((*cur == '-') || (*cur == '+'))
pcercuei 0:03b5121a232e 2487 cur++;
pcercuei 0:03b5121a232e 2488 while ((*cur >= '0') && (*cur <= '9'))
pcercuei 0:03b5121a232e 2489 cur++;
pcercuei 0:03b5121a232e 2490 }
pcercuei 0:03b5121a232e 2491 if (normOnTheFly)
pcercuei 0:03b5121a232e 2492 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2493
pcercuei 0:03b5121a232e 2494 if (*cur != 0)
pcercuei 0:03b5121a232e 2495 goto return1;
pcercuei 0:03b5121a232e 2496 if (val != NULL) {
pcercuei 0:03b5121a232e 2497 if (type == xmlSchemaTypeFloatDef) {
pcercuei 0:03b5121a232e 2498 v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
pcercuei 0:03b5121a232e 2499 if (v != NULL) {
pcercuei 0:03b5121a232e 2500 /*
pcercuei 0:03b5121a232e 2501 * TODO: sscanf seems not to give the correct
pcercuei 0:03b5121a232e 2502 * value for extremely high/low values.
pcercuei 0:03b5121a232e 2503 * E.g. "1E-149" results in zero.
pcercuei 0:03b5121a232e 2504 */
pcercuei 0:03b5121a232e 2505 if (sscanf((const char *) value, "%f",
pcercuei 0:03b5121a232e 2506 &(v->value.f)) == 1) {
pcercuei 0:03b5121a232e 2507 *val = v;
pcercuei 0:03b5121a232e 2508 } else {
pcercuei 0:03b5121a232e 2509 xmlSchemaFreeValue(v);
pcercuei 0:03b5121a232e 2510 goto return1;
pcercuei 0:03b5121a232e 2511 }
pcercuei 0:03b5121a232e 2512 } else {
pcercuei 0:03b5121a232e 2513 goto error;
pcercuei 0:03b5121a232e 2514 }
pcercuei 0:03b5121a232e 2515 } else {
pcercuei 0:03b5121a232e 2516 v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
pcercuei 0:03b5121a232e 2517 if (v != NULL) {
pcercuei 0:03b5121a232e 2518 /*
pcercuei 0:03b5121a232e 2519 * TODO: sscanf seems not to give the correct
pcercuei 0:03b5121a232e 2520 * value for extremely high/low values.
pcercuei 0:03b5121a232e 2521 */
pcercuei 0:03b5121a232e 2522 if (sscanf((const char *) value, "%lf",
pcercuei 0:03b5121a232e 2523 &(v->value.d)) == 1) {
pcercuei 0:03b5121a232e 2524 *val = v;
pcercuei 0:03b5121a232e 2525 } else {
pcercuei 0:03b5121a232e 2526 xmlSchemaFreeValue(v);
pcercuei 0:03b5121a232e 2527 goto return1;
pcercuei 0:03b5121a232e 2528 }
pcercuei 0:03b5121a232e 2529 } else {
pcercuei 0:03b5121a232e 2530 goto error;
pcercuei 0:03b5121a232e 2531 }
pcercuei 0:03b5121a232e 2532 }
pcercuei 0:03b5121a232e 2533 }
pcercuei 0:03b5121a232e 2534 goto return0;
pcercuei 0:03b5121a232e 2535 }
pcercuei 0:03b5121a232e 2536 case XML_SCHEMAS_BOOLEAN:{
pcercuei 0:03b5121a232e 2537 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 2538
pcercuei 0:03b5121a232e 2539 if (normOnTheFly) {
pcercuei 0:03b5121a232e 2540 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2541 if (*cur == '0') {
pcercuei 0:03b5121a232e 2542 ret = 0;
pcercuei 0:03b5121a232e 2543 cur++;
pcercuei 0:03b5121a232e 2544 } else if (*cur == '1') {
pcercuei 0:03b5121a232e 2545 ret = 1;
pcercuei 0:03b5121a232e 2546 cur++;
pcercuei 0:03b5121a232e 2547 } else if (*cur == 't') {
pcercuei 0:03b5121a232e 2548 cur++;
pcercuei 0:03b5121a232e 2549 if ((*cur++ == 'r') && (*cur++ == 'u') &&
pcercuei 0:03b5121a232e 2550 (*cur++ == 'e')) {
pcercuei 0:03b5121a232e 2551 ret = 1;
pcercuei 0:03b5121a232e 2552 } else
pcercuei 0:03b5121a232e 2553 goto return1;
pcercuei 0:03b5121a232e 2554 } else if (*cur == 'f') {
pcercuei 0:03b5121a232e 2555 cur++;
pcercuei 0:03b5121a232e 2556 if ((*cur++ == 'a') && (*cur++ == 'l') &&
pcercuei 0:03b5121a232e 2557 (*cur++ == 's') && (*cur++ == 'e')) {
pcercuei 0:03b5121a232e 2558 ret = 0;
pcercuei 0:03b5121a232e 2559 } else
pcercuei 0:03b5121a232e 2560 goto return1;
pcercuei 0:03b5121a232e 2561 } else
pcercuei 0:03b5121a232e 2562 goto return1;
pcercuei 0:03b5121a232e 2563 if (*cur != 0) {
pcercuei 0:03b5121a232e 2564 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2565 if (*cur != 0)
pcercuei 0:03b5121a232e 2566 goto return1;
pcercuei 0:03b5121a232e 2567 }
pcercuei 0:03b5121a232e 2568 } else {
pcercuei 0:03b5121a232e 2569 if ((cur[0] == '0') && (cur[1] == 0))
pcercuei 0:03b5121a232e 2570 ret = 0;
pcercuei 0:03b5121a232e 2571 else if ((cur[0] == '1') && (cur[1] == 0))
pcercuei 0:03b5121a232e 2572 ret = 1;
pcercuei 0:03b5121a232e 2573 else if ((cur[0] == 't') && (cur[1] == 'r')
pcercuei 0:03b5121a232e 2574 && (cur[2] == 'u') && (cur[3] == 'e')
pcercuei 0:03b5121a232e 2575 && (cur[4] == 0))
pcercuei 0:03b5121a232e 2576 ret = 1;
pcercuei 0:03b5121a232e 2577 else if ((cur[0] == 'f') && (cur[1] == 'a')
pcercuei 0:03b5121a232e 2578 && (cur[2] == 'l') && (cur[3] == 's')
pcercuei 0:03b5121a232e 2579 && (cur[4] == 'e') && (cur[5] == 0))
pcercuei 0:03b5121a232e 2580 ret = 0;
pcercuei 0:03b5121a232e 2581 else
pcercuei 0:03b5121a232e 2582 goto return1;
pcercuei 0:03b5121a232e 2583 }
pcercuei 0:03b5121a232e 2584 if (val != NULL) {
pcercuei 0:03b5121a232e 2585 v = xmlSchemaNewValue(XML_SCHEMAS_BOOLEAN);
pcercuei 0:03b5121a232e 2586 if (v != NULL) {
pcercuei 0:03b5121a232e 2587 v->value.b = ret;
pcercuei 0:03b5121a232e 2588 *val = v;
pcercuei 0:03b5121a232e 2589 } else {
pcercuei 0:03b5121a232e 2590 goto error;
pcercuei 0:03b5121a232e 2591 }
pcercuei 0:03b5121a232e 2592 }
pcercuei 0:03b5121a232e 2593 goto return0;
pcercuei 0:03b5121a232e 2594 }
pcercuei 0:03b5121a232e 2595 case XML_SCHEMAS_TOKEN:{
pcercuei 0:03b5121a232e 2596 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 2597
pcercuei 0:03b5121a232e 2598 if (! normOnTheFly) {
pcercuei 0:03b5121a232e 2599 while (*cur != 0) {
pcercuei 0:03b5121a232e 2600 if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
pcercuei 0:03b5121a232e 2601 goto return1;
pcercuei 0:03b5121a232e 2602 } else if (*cur == ' ') {
pcercuei 0:03b5121a232e 2603 cur++;
pcercuei 0:03b5121a232e 2604 if (*cur == 0)
pcercuei 0:03b5121a232e 2605 goto return1;
pcercuei 0:03b5121a232e 2606 if (*cur == ' ')
pcercuei 0:03b5121a232e 2607 goto return1;
pcercuei 0:03b5121a232e 2608 } else {
pcercuei 0:03b5121a232e 2609 cur++;
pcercuei 0:03b5121a232e 2610 }
pcercuei 0:03b5121a232e 2611 }
pcercuei 0:03b5121a232e 2612 }
pcercuei 0:03b5121a232e 2613 if (val != NULL) {
pcercuei 0:03b5121a232e 2614 v = xmlSchemaNewValue(XML_SCHEMAS_TOKEN);
pcercuei 0:03b5121a232e 2615 if (v != NULL) {
pcercuei 0:03b5121a232e 2616 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2617 *val = v;
pcercuei 0:03b5121a232e 2618 } else {
pcercuei 0:03b5121a232e 2619 goto error;
pcercuei 0:03b5121a232e 2620 }
pcercuei 0:03b5121a232e 2621 }
pcercuei 0:03b5121a232e 2622 goto return0;
pcercuei 0:03b5121a232e 2623 }
pcercuei 0:03b5121a232e 2624 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 2625 if (normOnTheFly) {
pcercuei 0:03b5121a232e 2626 norm = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 2627 if (norm != NULL)
pcercuei 0:03b5121a232e 2628 value = norm;
pcercuei 0:03b5121a232e 2629 }
pcercuei 0:03b5121a232e 2630 if (xmlCheckLanguageID(value) == 1) {
pcercuei 0:03b5121a232e 2631 if (val != NULL) {
pcercuei 0:03b5121a232e 2632 v = xmlSchemaNewValue(XML_SCHEMAS_LANGUAGE);
pcercuei 0:03b5121a232e 2633 if (v != NULL) {
pcercuei 0:03b5121a232e 2634 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2635 *val = v;
pcercuei 0:03b5121a232e 2636 } else {
pcercuei 0:03b5121a232e 2637 goto error;
pcercuei 0:03b5121a232e 2638 }
pcercuei 0:03b5121a232e 2639 }
pcercuei 0:03b5121a232e 2640 goto return0;
pcercuei 0:03b5121a232e 2641 }
pcercuei 0:03b5121a232e 2642 goto return1;
pcercuei 0:03b5121a232e 2643 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 2644 if (xmlValidateNMToken(value, 1) == 0) {
pcercuei 0:03b5121a232e 2645 if (val != NULL) {
pcercuei 0:03b5121a232e 2646 v = xmlSchemaNewValue(XML_SCHEMAS_NMTOKEN);
pcercuei 0:03b5121a232e 2647 if (v != NULL) {
pcercuei 0:03b5121a232e 2648 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2649 *val = v;
pcercuei 0:03b5121a232e 2650 } else {
pcercuei 0:03b5121a232e 2651 goto error;
pcercuei 0:03b5121a232e 2652 }
pcercuei 0:03b5121a232e 2653 }
pcercuei 0:03b5121a232e 2654 goto return0;
pcercuei 0:03b5121a232e 2655 }
pcercuei 0:03b5121a232e 2656 goto return1;
pcercuei 0:03b5121a232e 2657 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 2658 ret = xmlSchemaValAtomicListNode(xmlSchemaTypeNmtokenDef,
pcercuei 0:03b5121a232e 2659 value, val, node);
pcercuei 0:03b5121a232e 2660 if (ret > 0)
pcercuei 0:03b5121a232e 2661 ret = 0;
pcercuei 0:03b5121a232e 2662 else
pcercuei 0:03b5121a232e 2663 ret = 1;
pcercuei 0:03b5121a232e 2664 goto done;
pcercuei 0:03b5121a232e 2665 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 2666 ret = xmlValidateName(value, 1);
pcercuei 0:03b5121a232e 2667 if ((ret == 0) && (val != NULL) && (value != NULL)) {
pcercuei 0:03b5121a232e 2668 v = xmlSchemaNewValue(XML_SCHEMAS_NAME);
pcercuei 0:03b5121a232e 2669 if (v != NULL) {
pcercuei 0:03b5121a232e 2670 const xmlChar *start = value, *end;
pcercuei 0:03b5121a232e 2671 while (IS_BLANK_CH(*start)) start++;
pcercuei 0:03b5121a232e 2672 end = start;
pcercuei 0:03b5121a232e 2673 while ((*end != 0) && (!IS_BLANK_CH(*end))) end++;
pcercuei 0:03b5121a232e 2674 v->value.str = xmlStrndup(start, end - start);
pcercuei 0:03b5121a232e 2675 *val = v;
pcercuei 0:03b5121a232e 2676 } else {
pcercuei 0:03b5121a232e 2677 goto error;
pcercuei 0:03b5121a232e 2678 }
pcercuei 0:03b5121a232e 2679 }
pcercuei 0:03b5121a232e 2680 goto done;
pcercuei 0:03b5121a232e 2681 case XML_SCHEMAS_QNAME:{
pcercuei 0:03b5121a232e 2682 const xmlChar *uri = NULL;
pcercuei 0:03b5121a232e 2683 xmlChar *local = NULL;
pcercuei 0:03b5121a232e 2684
pcercuei 0:03b5121a232e 2685 ret = xmlValidateQName(value, 1);
pcercuei 0:03b5121a232e 2686 if (ret != 0)
pcercuei 0:03b5121a232e 2687 goto done;
pcercuei 0:03b5121a232e 2688 if (node != NULL) {
pcercuei 0:03b5121a232e 2689 xmlChar *prefix;
pcercuei 0:03b5121a232e 2690 xmlNsPtr ns;
pcercuei 0:03b5121a232e 2691
pcercuei 0:03b5121a232e 2692 local = xmlSplitQName2(value, &prefix);
pcercuei 0:03b5121a232e 2693 ns = xmlSearchNs(node->doc, node, prefix);
pcercuei 0:03b5121a232e 2694 if ((ns == NULL) && (prefix != NULL)) {
pcercuei 0:03b5121a232e 2695 xmlFree(prefix);
pcercuei 0:03b5121a232e 2696 if (local != NULL)
pcercuei 0:03b5121a232e 2697 xmlFree(local);
pcercuei 0:03b5121a232e 2698 goto return1;
pcercuei 0:03b5121a232e 2699 }
pcercuei 0:03b5121a232e 2700 if (ns != NULL)
pcercuei 0:03b5121a232e 2701 uri = ns->href;
pcercuei 0:03b5121a232e 2702 if (prefix != NULL)
pcercuei 0:03b5121a232e 2703 xmlFree(prefix);
pcercuei 0:03b5121a232e 2704 }
pcercuei 0:03b5121a232e 2705 if (val != NULL) {
pcercuei 0:03b5121a232e 2706 v = xmlSchemaNewValue(XML_SCHEMAS_QNAME);
pcercuei 0:03b5121a232e 2707 if (v == NULL) {
pcercuei 0:03b5121a232e 2708 if (local != NULL)
pcercuei 0:03b5121a232e 2709 xmlFree(local);
pcercuei 0:03b5121a232e 2710 goto error;
pcercuei 0:03b5121a232e 2711 }
pcercuei 0:03b5121a232e 2712 if (local != NULL)
pcercuei 0:03b5121a232e 2713 v->value.qname.name = local;
pcercuei 0:03b5121a232e 2714 else
pcercuei 0:03b5121a232e 2715 v->value.qname.name = xmlStrdup(value);
pcercuei 0:03b5121a232e 2716 if (uri != NULL)
pcercuei 0:03b5121a232e 2717 v->value.qname.uri = xmlStrdup(uri);
pcercuei 0:03b5121a232e 2718 *val = v;
pcercuei 0:03b5121a232e 2719 } else
pcercuei 0:03b5121a232e 2720 if (local != NULL)
pcercuei 0:03b5121a232e 2721 xmlFree(local);
pcercuei 0:03b5121a232e 2722 goto done;
pcercuei 0:03b5121a232e 2723 }
pcercuei 0:03b5121a232e 2724 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 2725 ret = xmlValidateNCName(value, 1);
pcercuei 0:03b5121a232e 2726 if ((ret == 0) && (val != NULL)) {
pcercuei 0:03b5121a232e 2727 v = xmlSchemaNewValue(XML_SCHEMAS_NCNAME);
pcercuei 0:03b5121a232e 2728 if (v != NULL) {
pcercuei 0:03b5121a232e 2729 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2730 *val = v;
pcercuei 0:03b5121a232e 2731 } else {
pcercuei 0:03b5121a232e 2732 goto error;
pcercuei 0:03b5121a232e 2733 }
pcercuei 0:03b5121a232e 2734 }
pcercuei 0:03b5121a232e 2735 goto done;
pcercuei 0:03b5121a232e 2736 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 2737 ret = xmlValidateNCName(value, 1);
pcercuei 0:03b5121a232e 2738 if ((ret == 0) && (val != NULL)) {
pcercuei 0:03b5121a232e 2739 v = xmlSchemaNewValue(XML_SCHEMAS_ID);
pcercuei 0:03b5121a232e 2740 if (v != NULL) {
pcercuei 0:03b5121a232e 2741 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2742 *val = v;
pcercuei 0:03b5121a232e 2743 } else {
pcercuei 0:03b5121a232e 2744 goto error;
pcercuei 0:03b5121a232e 2745 }
pcercuei 0:03b5121a232e 2746 }
pcercuei 0:03b5121a232e 2747 if ((ret == 0) && (node != NULL) &&
pcercuei 0:03b5121a232e 2748 (node->type == XML_ATTRIBUTE_NODE)) {
pcercuei 0:03b5121a232e 2749 xmlAttrPtr attr = (xmlAttrPtr) node;
pcercuei 0:03b5121a232e 2750
pcercuei 0:03b5121a232e 2751 /*
pcercuei 0:03b5121a232e 2752 * NOTE: the IDness might have already be declared in the DTD
pcercuei 0:03b5121a232e 2753 */
pcercuei 0:03b5121a232e 2754 if (attr->atype != XML_ATTRIBUTE_ID) {
pcercuei 0:03b5121a232e 2755 xmlIDPtr res;
pcercuei 0:03b5121a232e 2756 xmlChar *strip;
pcercuei 0:03b5121a232e 2757
pcercuei 0:03b5121a232e 2758 strip = xmlSchemaStrip(value);
pcercuei 0:03b5121a232e 2759 if (strip != NULL) {
pcercuei 0:03b5121a232e 2760 res = xmlAddID(NULL, node->doc, strip, attr);
pcercuei 0:03b5121a232e 2761 xmlFree(strip);
pcercuei 0:03b5121a232e 2762 } else
pcercuei 0:03b5121a232e 2763 res = xmlAddID(NULL, node->doc, value, attr);
pcercuei 0:03b5121a232e 2764 if (res == NULL) {
pcercuei 0:03b5121a232e 2765 ret = 2;
pcercuei 0:03b5121a232e 2766 } else {
pcercuei 0:03b5121a232e 2767 attr->atype = XML_ATTRIBUTE_ID;
pcercuei 0:03b5121a232e 2768 }
pcercuei 0:03b5121a232e 2769 }
pcercuei 0:03b5121a232e 2770 }
pcercuei 0:03b5121a232e 2771 goto done;
pcercuei 0:03b5121a232e 2772 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 2773 ret = xmlValidateNCName(value, 1);
pcercuei 0:03b5121a232e 2774 if ((ret == 0) && (val != NULL)) {
pcercuei 0:03b5121a232e 2775 v = xmlSchemaNewValue(XML_SCHEMAS_IDREF);
pcercuei 0:03b5121a232e 2776 if (v == NULL)
pcercuei 0:03b5121a232e 2777 goto error;
pcercuei 0:03b5121a232e 2778 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2779 *val = v;
pcercuei 0:03b5121a232e 2780 }
pcercuei 0:03b5121a232e 2781 if ((ret == 0) && (node != NULL) &&
pcercuei 0:03b5121a232e 2782 (node->type == XML_ATTRIBUTE_NODE)) {
pcercuei 0:03b5121a232e 2783 xmlAttrPtr attr = (xmlAttrPtr) node;
pcercuei 0:03b5121a232e 2784 xmlChar *strip;
pcercuei 0:03b5121a232e 2785
pcercuei 0:03b5121a232e 2786 strip = xmlSchemaStrip(value);
pcercuei 0:03b5121a232e 2787 if (strip != NULL) {
pcercuei 0:03b5121a232e 2788 xmlAddRef(NULL, node->doc, strip, attr);
pcercuei 0:03b5121a232e 2789 xmlFree(strip);
pcercuei 0:03b5121a232e 2790 } else
pcercuei 0:03b5121a232e 2791 xmlAddRef(NULL, node->doc, value, attr);
pcercuei 0:03b5121a232e 2792 attr->atype = XML_ATTRIBUTE_IDREF;
pcercuei 0:03b5121a232e 2793 }
pcercuei 0:03b5121a232e 2794 goto done;
pcercuei 0:03b5121a232e 2795 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 2796 ret = xmlSchemaValAtomicListNode(xmlSchemaTypeIdrefDef,
pcercuei 0:03b5121a232e 2797 value, val, node);
pcercuei 0:03b5121a232e 2798 if (ret < 0)
pcercuei 0:03b5121a232e 2799 ret = 2;
pcercuei 0:03b5121a232e 2800 else
pcercuei 0:03b5121a232e 2801 ret = 0;
pcercuei 0:03b5121a232e 2802 if ((ret == 0) && (node != NULL) &&
pcercuei 0:03b5121a232e 2803 (node->type == XML_ATTRIBUTE_NODE)) {
pcercuei 0:03b5121a232e 2804 xmlAttrPtr attr = (xmlAttrPtr) node;
pcercuei 0:03b5121a232e 2805
pcercuei 0:03b5121a232e 2806 attr->atype = XML_ATTRIBUTE_IDREFS;
pcercuei 0:03b5121a232e 2807 }
pcercuei 0:03b5121a232e 2808 goto done;
pcercuei 0:03b5121a232e 2809 case XML_SCHEMAS_ENTITY:{
pcercuei 0:03b5121a232e 2810 xmlChar *strip;
pcercuei 0:03b5121a232e 2811
pcercuei 0:03b5121a232e 2812 ret = xmlValidateNCName(value, 1);
pcercuei 0:03b5121a232e 2813 if ((node == NULL) || (node->doc == NULL))
pcercuei 0:03b5121a232e 2814 ret = 3;
pcercuei 0:03b5121a232e 2815 if (ret == 0) {
pcercuei 0:03b5121a232e 2816 xmlEntityPtr ent;
pcercuei 0:03b5121a232e 2817
pcercuei 0:03b5121a232e 2818 strip = xmlSchemaStrip(value);
pcercuei 0:03b5121a232e 2819 if (strip != NULL) {
pcercuei 0:03b5121a232e 2820 ent = xmlGetDocEntity(node->doc, strip);
pcercuei 0:03b5121a232e 2821 xmlFree(strip);
pcercuei 0:03b5121a232e 2822 } else {
pcercuei 0:03b5121a232e 2823 ent = xmlGetDocEntity(node->doc, value);
pcercuei 0:03b5121a232e 2824 }
pcercuei 0:03b5121a232e 2825 if ((ent == NULL) ||
pcercuei 0:03b5121a232e 2826 (ent->etype !=
pcercuei 0:03b5121a232e 2827 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY))
pcercuei 0:03b5121a232e 2828 ret = 4;
pcercuei 0:03b5121a232e 2829 }
pcercuei 0:03b5121a232e 2830 if ((ret == 0) && (val != NULL)) {
pcercuei 0:03b5121a232e 2831 TODO;
pcercuei 0:03b5121a232e 2832 }
pcercuei 0:03b5121a232e 2833 if ((ret == 0) && (node != NULL) &&
pcercuei 0:03b5121a232e 2834 (node->type == XML_ATTRIBUTE_NODE)) {
pcercuei 0:03b5121a232e 2835 xmlAttrPtr attr = (xmlAttrPtr) node;
pcercuei 0:03b5121a232e 2836
pcercuei 0:03b5121a232e 2837 attr->atype = XML_ATTRIBUTE_ENTITY;
pcercuei 0:03b5121a232e 2838 }
pcercuei 0:03b5121a232e 2839 goto done;
pcercuei 0:03b5121a232e 2840 }
pcercuei 0:03b5121a232e 2841 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 2842 if ((node == NULL) || (node->doc == NULL))
pcercuei 0:03b5121a232e 2843 goto return3;
pcercuei 0:03b5121a232e 2844 ret = xmlSchemaValAtomicListNode(xmlSchemaTypeEntityDef,
pcercuei 0:03b5121a232e 2845 value, val, node);
pcercuei 0:03b5121a232e 2846 if (ret <= 0)
pcercuei 0:03b5121a232e 2847 ret = 1;
pcercuei 0:03b5121a232e 2848 else
pcercuei 0:03b5121a232e 2849 ret = 0;
pcercuei 0:03b5121a232e 2850 if ((ret == 0) && (node != NULL) &&
pcercuei 0:03b5121a232e 2851 (node->type == XML_ATTRIBUTE_NODE)) {
pcercuei 0:03b5121a232e 2852 xmlAttrPtr attr = (xmlAttrPtr) node;
pcercuei 0:03b5121a232e 2853
pcercuei 0:03b5121a232e 2854 attr->atype = XML_ATTRIBUTE_ENTITIES;
pcercuei 0:03b5121a232e 2855 }
pcercuei 0:03b5121a232e 2856 goto done;
pcercuei 0:03b5121a232e 2857 case XML_SCHEMAS_NOTATION:{
pcercuei 0:03b5121a232e 2858 xmlChar *uri = NULL;
pcercuei 0:03b5121a232e 2859 xmlChar *local = NULL;
pcercuei 0:03b5121a232e 2860
pcercuei 0:03b5121a232e 2861 ret = xmlValidateQName(value, 1);
pcercuei 0:03b5121a232e 2862 if ((ret == 0) && (node != NULL)) {
pcercuei 0:03b5121a232e 2863 xmlChar *prefix;
pcercuei 0:03b5121a232e 2864
pcercuei 0:03b5121a232e 2865 local = xmlSplitQName2(value, &prefix);
pcercuei 0:03b5121a232e 2866 if (prefix != NULL) {
pcercuei 0:03b5121a232e 2867 xmlNsPtr ns;
pcercuei 0:03b5121a232e 2868
pcercuei 0:03b5121a232e 2869 ns = xmlSearchNs(node->doc, node, prefix);
pcercuei 0:03b5121a232e 2870 if (ns == NULL)
pcercuei 0:03b5121a232e 2871 ret = 1;
pcercuei 0:03b5121a232e 2872 else if (val != NULL)
pcercuei 0:03b5121a232e 2873 uri = xmlStrdup(ns->href);
pcercuei 0:03b5121a232e 2874 }
pcercuei 0:03b5121a232e 2875 if ((local != NULL) && ((val == NULL) || (ret != 0)))
pcercuei 0:03b5121a232e 2876 xmlFree(local);
pcercuei 0:03b5121a232e 2877 if (prefix != NULL)
pcercuei 0:03b5121a232e 2878 xmlFree(prefix);
pcercuei 0:03b5121a232e 2879 }
pcercuei 0:03b5121a232e 2880 if ((node == NULL) || (node->doc == NULL))
pcercuei 0:03b5121a232e 2881 ret = 3;
pcercuei 0:03b5121a232e 2882 if (ret == 0) {
pcercuei 0:03b5121a232e 2883 ret = xmlValidateNotationUse(NULL, node->doc, value);
pcercuei 0:03b5121a232e 2884 if (ret == 1)
pcercuei 0:03b5121a232e 2885 ret = 0;
pcercuei 0:03b5121a232e 2886 else
pcercuei 0:03b5121a232e 2887 ret = 1;
pcercuei 0:03b5121a232e 2888 }
pcercuei 0:03b5121a232e 2889 if ((ret == 0) && (val != NULL)) {
pcercuei 0:03b5121a232e 2890 v = xmlSchemaNewValue(XML_SCHEMAS_NOTATION);
pcercuei 0:03b5121a232e 2891 if (v != NULL) {
pcercuei 0:03b5121a232e 2892 if (local != NULL)
pcercuei 0:03b5121a232e 2893 v->value.qname.name = local;
pcercuei 0:03b5121a232e 2894 else
pcercuei 0:03b5121a232e 2895 v->value.qname.name = xmlStrdup(value);
pcercuei 0:03b5121a232e 2896 if (uri != NULL)
pcercuei 0:03b5121a232e 2897 v->value.qname.uri = uri;
pcercuei 0:03b5121a232e 2898
pcercuei 0:03b5121a232e 2899 *val = v;
pcercuei 0:03b5121a232e 2900 } else {
pcercuei 0:03b5121a232e 2901 if (local != NULL)
pcercuei 0:03b5121a232e 2902 xmlFree(local);
pcercuei 0:03b5121a232e 2903 if (uri != NULL)
pcercuei 0:03b5121a232e 2904 xmlFree(uri);
pcercuei 0:03b5121a232e 2905 goto error;
pcercuei 0:03b5121a232e 2906 }
pcercuei 0:03b5121a232e 2907 }
pcercuei 0:03b5121a232e 2908 goto done;
pcercuei 0:03b5121a232e 2909 }
pcercuei 0:03b5121a232e 2910 case XML_SCHEMAS_ANYURI:{
pcercuei 0:03b5121a232e 2911 if (*value != 0) {
pcercuei 0:03b5121a232e 2912 xmlURIPtr uri;
pcercuei 0:03b5121a232e 2913 xmlChar *tmpval, *cur;
pcercuei 0:03b5121a232e 2914 if (normOnTheFly) {
pcercuei 0:03b5121a232e 2915 norm = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 2916 if (norm != NULL)
pcercuei 0:03b5121a232e 2917 value = norm;
pcercuei 0:03b5121a232e 2918 }
pcercuei 0:03b5121a232e 2919 tmpval = xmlStrdup(value);
pcercuei 0:03b5121a232e 2920 for (cur = tmpval; *cur; ++cur) {
pcercuei 0:03b5121a232e 2921 if (*cur < 32 || *cur >= 127 || *cur == ' ' ||
pcercuei 0:03b5121a232e 2922 *cur == '<' || *cur == '>' || *cur == '"' ||
pcercuei 0:03b5121a232e 2923 *cur == '{' || *cur == '}' || *cur == '|' ||
pcercuei 0:03b5121a232e 2924 *cur == '\\' || *cur == '^' || *cur == '`' ||
pcercuei 0:03b5121a232e 2925 *cur == '\'')
pcercuei 0:03b5121a232e 2926 *cur = '_';
pcercuei 0:03b5121a232e 2927 }
pcercuei 0:03b5121a232e 2928 uri = xmlParseURI((const char *) tmpval);
pcercuei 0:03b5121a232e 2929 xmlFree(tmpval);
pcercuei 0:03b5121a232e 2930 if (uri == NULL)
pcercuei 0:03b5121a232e 2931 goto return1;
pcercuei 0:03b5121a232e 2932 xmlFreeURI(uri);
pcercuei 0:03b5121a232e 2933 }
pcercuei 0:03b5121a232e 2934
pcercuei 0:03b5121a232e 2935 if (val != NULL) {
pcercuei 0:03b5121a232e 2936 v = xmlSchemaNewValue(XML_SCHEMAS_ANYURI);
pcercuei 0:03b5121a232e 2937 if (v == NULL)
pcercuei 0:03b5121a232e 2938 goto error;
pcercuei 0:03b5121a232e 2939 v->value.str = xmlStrdup(value);
pcercuei 0:03b5121a232e 2940 *val = v;
pcercuei 0:03b5121a232e 2941 }
pcercuei 0:03b5121a232e 2942 goto return0;
pcercuei 0:03b5121a232e 2943 }
pcercuei 0:03b5121a232e 2944 case XML_SCHEMAS_HEXBINARY:{
pcercuei 0:03b5121a232e 2945 const xmlChar *cur = value, *start;
pcercuei 0:03b5121a232e 2946 xmlChar *base;
pcercuei 0:03b5121a232e 2947 int total, i = 0;
pcercuei 0:03b5121a232e 2948
pcercuei 0:03b5121a232e 2949 if (cur == NULL)
pcercuei 0:03b5121a232e 2950 goto return1;
pcercuei 0:03b5121a232e 2951
pcercuei 0:03b5121a232e 2952 if (normOnTheFly)
pcercuei 0:03b5121a232e 2953 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2954
pcercuei 0:03b5121a232e 2955 start = cur;
pcercuei 0:03b5121a232e 2956 while (((*cur >= '0') && (*cur <= '9')) ||
pcercuei 0:03b5121a232e 2957 ((*cur >= 'A') && (*cur <= 'F')) ||
pcercuei 0:03b5121a232e 2958 ((*cur >= 'a') && (*cur <= 'f'))) {
pcercuei 0:03b5121a232e 2959 i++;
pcercuei 0:03b5121a232e 2960 cur++;
pcercuei 0:03b5121a232e 2961 }
pcercuei 0:03b5121a232e 2962 if (normOnTheFly)
pcercuei 0:03b5121a232e 2963 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 2964
pcercuei 0:03b5121a232e 2965 if (*cur != 0)
pcercuei 0:03b5121a232e 2966 goto return1;
pcercuei 0:03b5121a232e 2967 if ((i % 2) != 0)
pcercuei 0:03b5121a232e 2968 goto return1;
pcercuei 0:03b5121a232e 2969
pcercuei 0:03b5121a232e 2970 if (val != NULL) {
pcercuei 0:03b5121a232e 2971
pcercuei 0:03b5121a232e 2972 v = xmlSchemaNewValue(XML_SCHEMAS_HEXBINARY);
pcercuei 0:03b5121a232e 2973 if (v == NULL)
pcercuei 0:03b5121a232e 2974 goto error;
pcercuei 0:03b5121a232e 2975 /*
pcercuei 0:03b5121a232e 2976 * Copy only the normalized piece.
pcercuei 0:03b5121a232e 2977 * CRITICAL TODO: Check this.
pcercuei 0:03b5121a232e 2978 */
pcercuei 0:03b5121a232e 2979 cur = xmlStrndup(start, i);
pcercuei 0:03b5121a232e 2980 if (cur == NULL) {
pcercuei 0:03b5121a232e 2981 xmlSchemaTypeErrMemory(node, "allocating hexbin data");
pcercuei 0:03b5121a232e 2982 xmlFree(v);
pcercuei 0:03b5121a232e 2983 goto return1;
pcercuei 0:03b5121a232e 2984 }
pcercuei 0:03b5121a232e 2985
pcercuei 0:03b5121a232e 2986 total = i / 2; /* number of octets */
pcercuei 0:03b5121a232e 2987
pcercuei 0:03b5121a232e 2988 base = (xmlChar *) cur;
pcercuei 0:03b5121a232e 2989 while (i-- > 0) {
pcercuei 0:03b5121a232e 2990 if (*base >= 'a')
pcercuei 0:03b5121a232e 2991 *base = *base - ('a' - 'A');
pcercuei 0:03b5121a232e 2992 base++;
pcercuei 0:03b5121a232e 2993 }
pcercuei 0:03b5121a232e 2994
pcercuei 0:03b5121a232e 2995 v->value.hex.str = (xmlChar *) cur;
pcercuei 0:03b5121a232e 2996 v->value.hex.total = total;
pcercuei 0:03b5121a232e 2997 *val = v;
pcercuei 0:03b5121a232e 2998 }
pcercuei 0:03b5121a232e 2999 goto return0;
pcercuei 0:03b5121a232e 3000 }
pcercuei 0:03b5121a232e 3001 case XML_SCHEMAS_BASE64BINARY:{
pcercuei 0:03b5121a232e 3002 /* ISSUE:
pcercuei 0:03b5121a232e 3003 *
pcercuei 0:03b5121a232e 3004 * Ignore all stray characters? (yes, currently)
pcercuei 0:03b5121a232e 3005 * Worry about long lines? (no, currently)
pcercuei 0:03b5121a232e 3006 *
pcercuei 0:03b5121a232e 3007 * rfc2045.txt:
pcercuei 0:03b5121a232e 3008 *
pcercuei 0:03b5121a232e 3009 * "The encoded output stream must be represented in lines of
pcercuei 0:03b5121a232e 3010 * no more than 76 characters each. All line breaks or other
pcercuei 0:03b5121a232e 3011 * characters not found in Table 1 must be ignored by decoding
pcercuei 0:03b5121a232e 3012 * software. In base64 data, characters other than those in
pcercuei 0:03b5121a232e 3013 * Table 1, line breaks, and other white space probably
pcercuei 0:03b5121a232e 3014 * indicate a transmission error, about which a warning
pcercuei 0:03b5121a232e 3015 * message or even a message rejection might be appropriate
pcercuei 0:03b5121a232e 3016 * under some circumstances." */
pcercuei 0:03b5121a232e 3017 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 3018 xmlChar *base;
pcercuei 0:03b5121a232e 3019 int total, i = 0, pad = 0;
pcercuei 0:03b5121a232e 3020
pcercuei 0:03b5121a232e 3021 if (cur == NULL)
pcercuei 0:03b5121a232e 3022 goto return1;
pcercuei 0:03b5121a232e 3023
pcercuei 0:03b5121a232e 3024 for (; *cur; ++cur) {
pcercuei 0:03b5121a232e 3025 int decc;
pcercuei 0:03b5121a232e 3026
pcercuei 0:03b5121a232e 3027 decc = _xmlSchemaBase64Decode(*cur);
pcercuei 0:03b5121a232e 3028 if (decc < 0) ;
pcercuei 0:03b5121a232e 3029 else if (decc < 64)
pcercuei 0:03b5121a232e 3030 i++;
pcercuei 0:03b5121a232e 3031 else
pcercuei 0:03b5121a232e 3032 break;
pcercuei 0:03b5121a232e 3033 }
pcercuei 0:03b5121a232e 3034 for (; *cur; ++cur) {
pcercuei 0:03b5121a232e 3035 int decc;
pcercuei 0:03b5121a232e 3036
pcercuei 0:03b5121a232e 3037 decc = _xmlSchemaBase64Decode(*cur);
pcercuei 0:03b5121a232e 3038 if (decc < 0) ;
pcercuei 0:03b5121a232e 3039 else if (decc < 64)
pcercuei 0:03b5121a232e 3040 goto return1;
pcercuei 0:03b5121a232e 3041 if (decc == 64)
pcercuei 0:03b5121a232e 3042 pad++;
pcercuei 0:03b5121a232e 3043 }
pcercuei 0:03b5121a232e 3044
pcercuei 0:03b5121a232e 3045 /* rfc2045.txt: "Special processing is performed if fewer than
pcercuei 0:03b5121a232e 3046 * 24 bits are available at the end of the data being encoded.
pcercuei 0:03b5121a232e 3047 * A full encoding quantum is always completed at the end of a
pcercuei 0:03b5121a232e 3048 * body. When fewer than 24 input bits are available in an
pcercuei 0:03b5121a232e 3049 * input group, zero bits are added (on the right) to form an
pcercuei 0:03b5121a232e 3050 * integral number of 6-bit groups. Padding at the end of the
pcercuei 0:03b5121a232e 3051 * data is performed using the "=" character. Since all
pcercuei 0:03b5121a232e 3052 * base64 input is an integral number of octets, only the
pcercuei 0:03b5121a232e 3053 * following cases can arise: (1) the final quantum of
pcercuei 0:03b5121a232e 3054 * encoding input is an integral multiple of 24 bits; here,
pcercuei 0:03b5121a232e 3055 * the final unit of encoded output will be an integral
pcercuei 0:03b5121a232e 3056 * multiple ofindent: Standard input:701: Warning:old style
pcercuei 0:03b5121a232e 3057 * assignment ambiguity in "=*". Assuming "= *" 4 characters
pcercuei 0:03b5121a232e 3058 * with no "=" padding, (2) the final
pcercuei 0:03b5121a232e 3059 * quantum of encoding input is exactly 8 bits; here, the
pcercuei 0:03b5121a232e 3060 * final unit of encoded output will be two characters
pcercuei 0:03b5121a232e 3061 * followed by two "=" padding characters, or (3) the final
pcercuei 0:03b5121a232e 3062 * quantum of encoding input is exactly 16 bits; here, the
pcercuei 0:03b5121a232e 3063 * final unit of encoded output will be three characters
pcercuei 0:03b5121a232e 3064 * followed by one "=" padding character." */
pcercuei 0:03b5121a232e 3065
pcercuei 0:03b5121a232e 3066 total = 3 * (i / 4);
pcercuei 0:03b5121a232e 3067 if (pad == 0) {
pcercuei 0:03b5121a232e 3068 if (i % 4 != 0)
pcercuei 0:03b5121a232e 3069 goto return1;
pcercuei 0:03b5121a232e 3070 } else if (pad == 1) {
pcercuei 0:03b5121a232e 3071 int decc;
pcercuei 0:03b5121a232e 3072
pcercuei 0:03b5121a232e 3073 if (i % 4 != 3)
pcercuei 0:03b5121a232e 3074 goto return1;
pcercuei 0:03b5121a232e 3075 for (decc = _xmlSchemaBase64Decode(*cur);
pcercuei 0:03b5121a232e 3076 (decc < 0) || (decc > 63);
pcercuei 0:03b5121a232e 3077 decc = _xmlSchemaBase64Decode(*cur))
pcercuei 0:03b5121a232e 3078 --cur;
pcercuei 0:03b5121a232e 3079 /* 16bits in 24bits means 2 pad bits: nnnnnn nnmmmm mmmm00*/
pcercuei 0:03b5121a232e 3080 /* 00111100 -> 0x3c */
pcercuei 0:03b5121a232e 3081 if (decc & ~0x3c)
pcercuei 0:03b5121a232e 3082 goto return1;
pcercuei 0:03b5121a232e 3083 total += 2;
pcercuei 0:03b5121a232e 3084 } else if (pad == 2) {
pcercuei 0:03b5121a232e 3085 int decc;
pcercuei 0:03b5121a232e 3086
pcercuei 0:03b5121a232e 3087 if (i % 4 != 2)
pcercuei 0:03b5121a232e 3088 goto return1;
pcercuei 0:03b5121a232e 3089 for (decc = _xmlSchemaBase64Decode(*cur);
pcercuei 0:03b5121a232e 3090 (decc < 0) || (decc > 63);
pcercuei 0:03b5121a232e 3091 decc = _xmlSchemaBase64Decode(*cur))
pcercuei 0:03b5121a232e 3092 --cur;
pcercuei 0:03b5121a232e 3093 /* 8bits in 12bits means 4 pad bits: nnnnnn nn0000 */
pcercuei 0:03b5121a232e 3094 /* 00110000 -> 0x30 */
pcercuei 0:03b5121a232e 3095 if (decc & ~0x30)
pcercuei 0:03b5121a232e 3096 goto return1;
pcercuei 0:03b5121a232e 3097 total += 1;
pcercuei 0:03b5121a232e 3098 } else
pcercuei 0:03b5121a232e 3099 goto return1;
pcercuei 0:03b5121a232e 3100
pcercuei 0:03b5121a232e 3101 if (val != NULL) {
pcercuei 0:03b5121a232e 3102 v = xmlSchemaNewValue(XML_SCHEMAS_BASE64BINARY);
pcercuei 0:03b5121a232e 3103 if (v == NULL)
pcercuei 0:03b5121a232e 3104 goto error;
pcercuei 0:03b5121a232e 3105 base =
pcercuei 0:03b5121a232e 3106 (xmlChar *) xmlMallocAtomic((i + pad + 1) *
pcercuei 0:03b5121a232e 3107 sizeof(xmlChar));
pcercuei 0:03b5121a232e 3108 if (base == NULL) {
pcercuei 0:03b5121a232e 3109 xmlSchemaTypeErrMemory(node, "allocating base64 data");
pcercuei 0:03b5121a232e 3110 xmlFree(v);
pcercuei 0:03b5121a232e 3111 goto return1;
pcercuei 0:03b5121a232e 3112 }
pcercuei 0:03b5121a232e 3113 v->value.base64.str = base;
pcercuei 0:03b5121a232e 3114 for (cur = value; *cur; ++cur)
pcercuei 0:03b5121a232e 3115 if (_xmlSchemaBase64Decode(*cur) >= 0) {
pcercuei 0:03b5121a232e 3116 *base = *cur;
pcercuei 0:03b5121a232e 3117 ++base;
pcercuei 0:03b5121a232e 3118 }
pcercuei 0:03b5121a232e 3119 *base = 0;
pcercuei 0:03b5121a232e 3120 v->value.base64.total = total;
pcercuei 0:03b5121a232e 3121 *val = v;
pcercuei 0:03b5121a232e 3122 }
pcercuei 0:03b5121a232e 3123 goto return0;
pcercuei 0:03b5121a232e 3124 }
pcercuei 0:03b5121a232e 3125 case XML_SCHEMAS_INTEGER:
pcercuei 0:03b5121a232e 3126 case XML_SCHEMAS_PINTEGER:
pcercuei 0:03b5121a232e 3127 case XML_SCHEMAS_NPINTEGER:
pcercuei 0:03b5121a232e 3128 case XML_SCHEMAS_NINTEGER:
pcercuei 0:03b5121a232e 3129 case XML_SCHEMAS_NNINTEGER:{
pcercuei 0:03b5121a232e 3130 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 3131 unsigned long lo, mi, hi;
pcercuei 0:03b5121a232e 3132 int sign = 0;
pcercuei 0:03b5121a232e 3133
pcercuei 0:03b5121a232e 3134 if (cur == NULL)
pcercuei 0:03b5121a232e 3135 goto return1;
pcercuei 0:03b5121a232e 3136 if (normOnTheFly)
pcercuei 0:03b5121a232e 3137 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 3138 if (*cur == '-') {
pcercuei 0:03b5121a232e 3139 sign = 1;
pcercuei 0:03b5121a232e 3140 cur++;
pcercuei 0:03b5121a232e 3141 } else if (*cur == '+')
pcercuei 0:03b5121a232e 3142 cur++;
pcercuei 0:03b5121a232e 3143 ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
pcercuei 0:03b5121a232e 3144 if (ret < 0)
pcercuei 0:03b5121a232e 3145 goto return1;
pcercuei 0:03b5121a232e 3146 if (normOnTheFly)
pcercuei 0:03b5121a232e 3147 while IS_WSP_BLANK_CH(*cur) cur++;
pcercuei 0:03b5121a232e 3148 if (*cur != 0)
pcercuei 0:03b5121a232e 3149 goto return1;
pcercuei 0:03b5121a232e 3150 if (type->builtInType == XML_SCHEMAS_NPINTEGER) {
pcercuei 0:03b5121a232e 3151 if ((sign == 0) &&
pcercuei 0:03b5121a232e 3152 ((hi != 0) || (mi != 0) || (lo != 0)))
pcercuei 0:03b5121a232e 3153 goto return1;
pcercuei 0:03b5121a232e 3154 } else if (type->builtInType == XML_SCHEMAS_PINTEGER) {
pcercuei 0:03b5121a232e 3155 if (sign == 1)
pcercuei 0:03b5121a232e 3156 goto return1;
pcercuei 0:03b5121a232e 3157 if ((hi == 0) && (mi == 0) && (lo == 0))
pcercuei 0:03b5121a232e 3158 goto return1;
pcercuei 0:03b5121a232e 3159 } else if (type->builtInType == XML_SCHEMAS_NINTEGER) {
pcercuei 0:03b5121a232e 3160 if (sign == 0)
pcercuei 0:03b5121a232e 3161 goto return1;
pcercuei 0:03b5121a232e 3162 if ((hi == 0) && (mi == 0) && (lo == 0))
pcercuei 0:03b5121a232e 3163 goto return1;
pcercuei 0:03b5121a232e 3164 } else if (type->builtInType == XML_SCHEMAS_NNINTEGER) {
pcercuei 0:03b5121a232e 3165 if ((sign == 1) &&
pcercuei 0:03b5121a232e 3166 ((hi != 0) || (mi != 0) || (lo != 0)))
pcercuei 0:03b5121a232e 3167 goto return1;
pcercuei 0:03b5121a232e 3168 }
pcercuei 0:03b5121a232e 3169 if (val != NULL) {
pcercuei 0:03b5121a232e 3170 v = xmlSchemaNewValue(type->builtInType);
pcercuei 0:03b5121a232e 3171 if (v != NULL) {
pcercuei 0:03b5121a232e 3172 if (ret == 0)
pcercuei 0:03b5121a232e 3173 ret++;
pcercuei 0:03b5121a232e 3174 v->value.decimal.lo = lo;
pcercuei 0:03b5121a232e 3175 v->value.decimal.mi = mi;
pcercuei 0:03b5121a232e 3176 v->value.decimal.hi = hi;
pcercuei 0:03b5121a232e 3177 v->value.decimal.sign = sign;
pcercuei 0:03b5121a232e 3178 v->value.decimal.frac = 0;
pcercuei 0:03b5121a232e 3179 v->value.decimal.total = ret;
pcercuei 0:03b5121a232e 3180 *val = v;
pcercuei 0:03b5121a232e 3181 }
pcercuei 0:03b5121a232e 3182 }
pcercuei 0:03b5121a232e 3183 goto return0;
pcercuei 0:03b5121a232e 3184 }
pcercuei 0:03b5121a232e 3185 case XML_SCHEMAS_LONG:
pcercuei 0:03b5121a232e 3186 case XML_SCHEMAS_BYTE:
pcercuei 0:03b5121a232e 3187 case XML_SCHEMAS_SHORT:
pcercuei 0:03b5121a232e 3188 case XML_SCHEMAS_INT:{
pcercuei 0:03b5121a232e 3189 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 3190 unsigned long lo, mi, hi;
pcercuei 0:03b5121a232e 3191 int sign = 0;
pcercuei 0:03b5121a232e 3192
pcercuei 0:03b5121a232e 3193 if (cur == NULL)
pcercuei 0:03b5121a232e 3194 goto return1;
pcercuei 0:03b5121a232e 3195 if (*cur == '-') {
pcercuei 0:03b5121a232e 3196 sign = 1;
pcercuei 0:03b5121a232e 3197 cur++;
pcercuei 0:03b5121a232e 3198 } else if (*cur == '+')
pcercuei 0:03b5121a232e 3199 cur++;
pcercuei 0:03b5121a232e 3200 ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
pcercuei 0:03b5121a232e 3201 if (ret < 0)
pcercuei 0:03b5121a232e 3202 goto return1;
pcercuei 0:03b5121a232e 3203 if (*cur != 0)
pcercuei 0:03b5121a232e 3204 goto return1;
pcercuei 0:03b5121a232e 3205 if (type->builtInType == XML_SCHEMAS_LONG) {
pcercuei 0:03b5121a232e 3206 if (hi >= 922) {
pcercuei 0:03b5121a232e 3207 if (hi > 922)
pcercuei 0:03b5121a232e 3208 goto return1;
pcercuei 0:03b5121a232e 3209 if (mi >= 33720368) {
pcercuei 0:03b5121a232e 3210 if (mi > 33720368)
pcercuei 0:03b5121a232e 3211 goto return1;
pcercuei 0:03b5121a232e 3212 if ((sign == 0) && (lo > 54775807))
pcercuei 0:03b5121a232e 3213 goto return1;
pcercuei 0:03b5121a232e 3214 if ((sign == 1) && (lo > 54775808))
pcercuei 0:03b5121a232e 3215 goto return1;
pcercuei 0:03b5121a232e 3216 }
pcercuei 0:03b5121a232e 3217 }
pcercuei 0:03b5121a232e 3218 } else if (type->builtInType == XML_SCHEMAS_INT) {
pcercuei 0:03b5121a232e 3219 if (hi != 0)
pcercuei 0:03b5121a232e 3220 goto return1;
pcercuei 0:03b5121a232e 3221 if (mi >= 21) {
pcercuei 0:03b5121a232e 3222 if (mi > 21)
pcercuei 0:03b5121a232e 3223 goto return1;
pcercuei 0:03b5121a232e 3224 if ((sign == 0) && (lo > 47483647))
pcercuei 0:03b5121a232e 3225 goto return1;
pcercuei 0:03b5121a232e 3226 if ((sign == 1) && (lo > 47483648))
pcercuei 0:03b5121a232e 3227 goto return1;
pcercuei 0:03b5121a232e 3228 }
pcercuei 0:03b5121a232e 3229 } else if (type->builtInType == XML_SCHEMAS_SHORT) {
pcercuei 0:03b5121a232e 3230 if ((mi != 0) || (hi != 0))
pcercuei 0:03b5121a232e 3231 goto return1;
pcercuei 0:03b5121a232e 3232 if ((sign == 1) && (lo > 32768))
pcercuei 0:03b5121a232e 3233 goto return1;
pcercuei 0:03b5121a232e 3234 if ((sign == 0) && (lo > 32767))
pcercuei 0:03b5121a232e 3235 goto return1;
pcercuei 0:03b5121a232e 3236 } else if (type->builtInType == XML_SCHEMAS_BYTE) {
pcercuei 0:03b5121a232e 3237 if ((mi != 0) || (hi != 0))
pcercuei 0:03b5121a232e 3238 goto return1;
pcercuei 0:03b5121a232e 3239 if ((sign == 1) && (lo > 128))
pcercuei 0:03b5121a232e 3240 goto return1;
pcercuei 0:03b5121a232e 3241 if ((sign == 0) && (lo > 127))
pcercuei 0:03b5121a232e 3242 goto return1;
pcercuei 0:03b5121a232e 3243 }
pcercuei 0:03b5121a232e 3244 if (val != NULL) {
pcercuei 0:03b5121a232e 3245 v = xmlSchemaNewValue(type->builtInType);
pcercuei 0:03b5121a232e 3246 if (v != NULL) {
pcercuei 0:03b5121a232e 3247 v->value.decimal.lo = lo;
pcercuei 0:03b5121a232e 3248 v->value.decimal.mi = mi;
pcercuei 0:03b5121a232e 3249 v->value.decimal.hi = hi;
pcercuei 0:03b5121a232e 3250 v->value.decimal.sign = sign;
pcercuei 0:03b5121a232e 3251 v->value.decimal.frac = 0;
pcercuei 0:03b5121a232e 3252 v->value.decimal.total = ret;
pcercuei 0:03b5121a232e 3253 *val = v;
pcercuei 0:03b5121a232e 3254 }
pcercuei 0:03b5121a232e 3255 }
pcercuei 0:03b5121a232e 3256 goto return0;
pcercuei 0:03b5121a232e 3257 }
pcercuei 0:03b5121a232e 3258 case XML_SCHEMAS_UINT:
pcercuei 0:03b5121a232e 3259 case XML_SCHEMAS_ULONG:
pcercuei 0:03b5121a232e 3260 case XML_SCHEMAS_USHORT:
pcercuei 0:03b5121a232e 3261 case XML_SCHEMAS_UBYTE:{
pcercuei 0:03b5121a232e 3262 const xmlChar *cur = value;
pcercuei 0:03b5121a232e 3263 unsigned long lo, mi, hi;
pcercuei 0:03b5121a232e 3264
pcercuei 0:03b5121a232e 3265 if (cur == NULL)
pcercuei 0:03b5121a232e 3266 goto return1;
pcercuei 0:03b5121a232e 3267 ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
pcercuei 0:03b5121a232e 3268 if (ret < 0)
pcercuei 0:03b5121a232e 3269 goto return1;
pcercuei 0:03b5121a232e 3270 if (*cur != 0)
pcercuei 0:03b5121a232e 3271 goto return1;
pcercuei 0:03b5121a232e 3272 if (type->builtInType == XML_SCHEMAS_ULONG) {
pcercuei 0:03b5121a232e 3273 if (hi >= 1844) {
pcercuei 0:03b5121a232e 3274 if (hi > 1844)
pcercuei 0:03b5121a232e 3275 goto return1;
pcercuei 0:03b5121a232e 3276 if (mi >= 67440737) {
pcercuei 0:03b5121a232e 3277 if (mi > 67440737)
pcercuei 0:03b5121a232e 3278 goto return1;
pcercuei 0:03b5121a232e 3279 if (lo > 9551615)
pcercuei 0:03b5121a232e 3280 goto return1;
pcercuei 0:03b5121a232e 3281 }
pcercuei 0:03b5121a232e 3282 }
pcercuei 0:03b5121a232e 3283 } else if (type->builtInType == XML_SCHEMAS_UINT) {
pcercuei 0:03b5121a232e 3284 if (hi != 0)
pcercuei 0:03b5121a232e 3285 goto return1;
pcercuei 0:03b5121a232e 3286 if (mi >= 42) {
pcercuei 0:03b5121a232e 3287 if (mi > 42)
pcercuei 0:03b5121a232e 3288 goto return1;
pcercuei 0:03b5121a232e 3289 if (lo > 94967295)
pcercuei 0:03b5121a232e 3290 goto return1;
pcercuei 0:03b5121a232e 3291 }
pcercuei 0:03b5121a232e 3292 } else if (type->builtInType == XML_SCHEMAS_USHORT) {
pcercuei 0:03b5121a232e 3293 if ((mi != 0) || (hi != 0))
pcercuei 0:03b5121a232e 3294 goto return1;
pcercuei 0:03b5121a232e 3295 if (lo > 65535)
pcercuei 0:03b5121a232e 3296 goto return1;
pcercuei 0:03b5121a232e 3297 } else if (type->builtInType == XML_SCHEMAS_UBYTE) {
pcercuei 0:03b5121a232e 3298 if ((mi != 0) || (hi != 0))
pcercuei 0:03b5121a232e 3299 goto return1;
pcercuei 0:03b5121a232e 3300 if (lo > 255)
pcercuei 0:03b5121a232e 3301 goto return1;
pcercuei 0:03b5121a232e 3302 }
pcercuei 0:03b5121a232e 3303 if (val != NULL) {
pcercuei 0:03b5121a232e 3304 v = xmlSchemaNewValue(type->builtInType);
pcercuei 0:03b5121a232e 3305 if (v != NULL) {
pcercuei 0:03b5121a232e 3306 v->value.decimal.lo = lo;
pcercuei 0:03b5121a232e 3307 v->value.decimal.mi = mi;
pcercuei 0:03b5121a232e 3308 v->value.decimal.hi = hi;
pcercuei 0:03b5121a232e 3309 v->value.decimal.sign = 0;
pcercuei 0:03b5121a232e 3310 v->value.decimal.frac = 0;
pcercuei 0:03b5121a232e 3311 v->value.decimal.total = ret;
pcercuei 0:03b5121a232e 3312 *val = v;
pcercuei 0:03b5121a232e 3313 }
pcercuei 0:03b5121a232e 3314 }
pcercuei 0:03b5121a232e 3315 goto return0;
pcercuei 0:03b5121a232e 3316 }
pcercuei 0:03b5121a232e 3317 }
pcercuei 0:03b5121a232e 3318
pcercuei 0:03b5121a232e 3319 done:
pcercuei 0:03b5121a232e 3320 if (norm != NULL)
pcercuei 0:03b5121a232e 3321 xmlFree(norm);
pcercuei 0:03b5121a232e 3322 return (ret);
pcercuei 0:03b5121a232e 3323 return3:
pcercuei 0:03b5121a232e 3324 if (norm != NULL)
pcercuei 0:03b5121a232e 3325 xmlFree(norm);
pcercuei 0:03b5121a232e 3326 return (3);
pcercuei 0:03b5121a232e 3327 return1:
pcercuei 0:03b5121a232e 3328 if (norm != NULL)
pcercuei 0:03b5121a232e 3329 xmlFree(norm);
pcercuei 0:03b5121a232e 3330 return (1);
pcercuei 0:03b5121a232e 3331 return0:
pcercuei 0:03b5121a232e 3332 if (norm != NULL)
pcercuei 0:03b5121a232e 3333 xmlFree(norm);
pcercuei 0:03b5121a232e 3334 return (0);
pcercuei 0:03b5121a232e 3335 error:
pcercuei 0:03b5121a232e 3336 if (norm != NULL)
pcercuei 0:03b5121a232e 3337 xmlFree(norm);
pcercuei 0:03b5121a232e 3338 return (-1);
pcercuei 0:03b5121a232e 3339 }
pcercuei 0:03b5121a232e 3340
pcercuei 0:03b5121a232e 3341 /**
pcercuei 0:03b5121a232e 3342 * xmlSchemaValPredefTypeNode:
pcercuei 0:03b5121a232e 3343 * @type: the predefined type
pcercuei 0:03b5121a232e 3344 * @value: the value to check
pcercuei 0:03b5121a232e 3345 * @val: the return computed value
pcercuei 0:03b5121a232e 3346 * @node: the node containing the value
pcercuei 0:03b5121a232e 3347 *
pcercuei 0:03b5121a232e 3348 * Check that a value conforms to the lexical space of the predefined type.
pcercuei 0:03b5121a232e 3349 * if true a value is computed and returned in @val.
pcercuei 0:03b5121a232e 3350 *
pcercuei 0:03b5121a232e 3351 * Returns 0 if this validates, a positive error code number otherwise
pcercuei 0:03b5121a232e 3352 * and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 3353 */
pcercuei 0:03b5121a232e 3354 int
pcercuei 0:03b5121a232e 3355 xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value,
pcercuei 0:03b5121a232e 3356 xmlSchemaValPtr *val, xmlNodePtr node) {
pcercuei 0:03b5121a232e 3357 return(xmlSchemaValAtomicType(type, value, val, node, 0,
pcercuei 0:03b5121a232e 3358 XML_SCHEMA_WHITESPACE_UNKNOWN, 1, 1, 0));
pcercuei 0:03b5121a232e 3359 }
pcercuei 0:03b5121a232e 3360
pcercuei 0:03b5121a232e 3361 /**
pcercuei 0:03b5121a232e 3362 * xmlSchemaValPredefTypeNodeNoNorm:
pcercuei 0:03b5121a232e 3363 * @type: the predefined type
pcercuei 0:03b5121a232e 3364 * @value: the value to check
pcercuei 0:03b5121a232e 3365 * @val: the return computed value
pcercuei 0:03b5121a232e 3366 * @node: the node containing the value
pcercuei 0:03b5121a232e 3367 *
pcercuei 0:03b5121a232e 3368 * Check that a value conforms to the lexical space of the predefined type.
pcercuei 0:03b5121a232e 3369 * if true a value is computed and returned in @val.
pcercuei 0:03b5121a232e 3370 * This one does apply any normalization to the value.
pcercuei 0:03b5121a232e 3371 *
pcercuei 0:03b5121a232e 3372 * Returns 0 if this validates, a positive error code number otherwise
pcercuei 0:03b5121a232e 3373 * and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 3374 */
pcercuei 0:03b5121a232e 3375 int
pcercuei 0:03b5121a232e 3376 xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaTypePtr type, const xmlChar *value,
pcercuei 0:03b5121a232e 3377 xmlSchemaValPtr *val, xmlNodePtr node) {
pcercuei 0:03b5121a232e 3378 return(xmlSchemaValAtomicType(type, value, val, node, 1,
pcercuei 0:03b5121a232e 3379 XML_SCHEMA_WHITESPACE_UNKNOWN, 1, 0, 1));
pcercuei 0:03b5121a232e 3380 }
pcercuei 0:03b5121a232e 3381
pcercuei 0:03b5121a232e 3382 /**
pcercuei 0:03b5121a232e 3383 * xmlSchemaValidatePredefinedType:
pcercuei 0:03b5121a232e 3384 * @type: the predefined type
pcercuei 0:03b5121a232e 3385 * @value: the value to check
pcercuei 0:03b5121a232e 3386 * @val: the return computed value
pcercuei 0:03b5121a232e 3387 *
pcercuei 0:03b5121a232e 3388 * Check that a value conforms to the lexical space of the predefined type.
pcercuei 0:03b5121a232e 3389 * if true a value is computed and returned in @val.
pcercuei 0:03b5121a232e 3390 *
pcercuei 0:03b5121a232e 3391 * Returns 0 if this validates, a positive error code number otherwise
pcercuei 0:03b5121a232e 3392 * and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 3393 */
pcercuei 0:03b5121a232e 3394 int
pcercuei 0:03b5121a232e 3395 xmlSchemaValidatePredefinedType(xmlSchemaTypePtr type, const xmlChar *value,
pcercuei 0:03b5121a232e 3396 xmlSchemaValPtr *val) {
pcercuei 0:03b5121a232e 3397 return(xmlSchemaValPredefTypeNode(type, value, val, NULL));
pcercuei 0:03b5121a232e 3398 }
pcercuei 0:03b5121a232e 3399
pcercuei 0:03b5121a232e 3400 /**
pcercuei 0:03b5121a232e 3401 * xmlSchemaCompareDecimals:
pcercuei 0:03b5121a232e 3402 * @x: a first decimal value
pcercuei 0:03b5121a232e 3403 * @y: a second decimal value
pcercuei 0:03b5121a232e 3404 *
pcercuei 0:03b5121a232e 3405 * Compare 2 decimals
pcercuei 0:03b5121a232e 3406 *
pcercuei 0:03b5121a232e 3407 * Returns -1 if x < y, 0 if x == y, 1 if x > y and -2 in case of error
pcercuei 0:03b5121a232e 3408 */
pcercuei 0:03b5121a232e 3409 static int
pcercuei 0:03b5121a232e 3410 xmlSchemaCompareDecimals(xmlSchemaValPtr x, xmlSchemaValPtr y)
pcercuei 0:03b5121a232e 3411 {
pcercuei 0:03b5121a232e 3412 xmlSchemaValPtr swp;
pcercuei 0:03b5121a232e 3413 int order = 1, integx, integy, dlen;
pcercuei 0:03b5121a232e 3414 unsigned long hi, mi, lo;
pcercuei 0:03b5121a232e 3415
pcercuei 0:03b5121a232e 3416 /*
pcercuei 0:03b5121a232e 3417 * First test: If x is -ve and not zero
pcercuei 0:03b5121a232e 3418 */
pcercuei 0:03b5121a232e 3419 if ((x->value.decimal.sign) &&
pcercuei 0:03b5121a232e 3420 ((x->value.decimal.lo != 0) ||
pcercuei 0:03b5121a232e 3421 (x->value.decimal.mi != 0) ||
pcercuei 0:03b5121a232e 3422 (x->value.decimal.hi != 0))) {
pcercuei 0:03b5121a232e 3423 /*
pcercuei 0:03b5121a232e 3424 * Then if y is -ve and not zero reverse the compare
pcercuei 0:03b5121a232e 3425 */
pcercuei 0:03b5121a232e 3426 if ((y->value.decimal.sign) &&
pcercuei 0:03b5121a232e 3427 ((y->value.decimal.lo != 0) ||
pcercuei 0:03b5121a232e 3428 (y->value.decimal.mi != 0) ||
pcercuei 0:03b5121a232e 3429 (y->value.decimal.hi != 0)))
pcercuei 0:03b5121a232e 3430 order = -1;
pcercuei 0:03b5121a232e 3431 /*
pcercuei 0:03b5121a232e 3432 * Otherwise (y >= 0) we have the answer
pcercuei 0:03b5121a232e 3433 */
pcercuei 0:03b5121a232e 3434 else
pcercuei 0:03b5121a232e 3435 return (-1);
pcercuei 0:03b5121a232e 3436 /*
pcercuei 0:03b5121a232e 3437 * If x is not -ve and y is -ve we have the answer
pcercuei 0:03b5121a232e 3438 */
pcercuei 0:03b5121a232e 3439 } else if ((y->value.decimal.sign) &&
pcercuei 0:03b5121a232e 3440 ((y->value.decimal.lo != 0) ||
pcercuei 0:03b5121a232e 3441 (y->value.decimal.mi != 0) ||
pcercuei 0:03b5121a232e 3442 (y->value.decimal.hi != 0))) {
pcercuei 0:03b5121a232e 3443 return (1);
pcercuei 0:03b5121a232e 3444 }
pcercuei 0:03b5121a232e 3445 /*
pcercuei 0:03b5121a232e 3446 * If it's not simply determined by a difference in sign,
pcercuei 0:03b5121a232e 3447 * then we need to compare the actual values of the two nums.
pcercuei 0:03b5121a232e 3448 * To do this, we start by looking at the integral parts.
pcercuei 0:03b5121a232e 3449 * If the number of integral digits differ, then we have our
pcercuei 0:03b5121a232e 3450 * answer.
pcercuei 0:03b5121a232e 3451 */
pcercuei 0:03b5121a232e 3452 integx = x->value.decimal.total - x->value.decimal.frac;
pcercuei 0:03b5121a232e 3453 integy = y->value.decimal.total - y->value.decimal.frac;
pcercuei 0:03b5121a232e 3454 /*
pcercuei 0:03b5121a232e 3455 * NOTE: We changed the "total" for values like "0.1"
pcercuei 0:03b5121a232e 3456 * (or "-0.1" or ".1") to be 1, which was 2 previously.
pcercuei 0:03b5121a232e 3457 * Therefore the special case, when such values are
pcercuei 0:03b5121a232e 3458 * compared with 0, needs to be handled separately;
pcercuei 0:03b5121a232e 3459 * otherwise a zero would be recognized incorrectly as
pcercuei 0:03b5121a232e 3460 * greater than those values. This has the nice side effect
pcercuei 0:03b5121a232e 3461 * that we gain an overall optimized comparison with zeroes.
pcercuei 0:03b5121a232e 3462 * Note that a "0" has a "total" of 1 already.
pcercuei 0:03b5121a232e 3463 */
pcercuei 0:03b5121a232e 3464 if (integx == 1) {
pcercuei 0:03b5121a232e 3465 if (x->value.decimal.lo == 0) {
pcercuei 0:03b5121a232e 3466 if (integy != 1)
pcercuei 0:03b5121a232e 3467 return -order;
pcercuei 0:03b5121a232e 3468 else if (y->value.decimal.lo != 0)
pcercuei 0:03b5121a232e 3469 return -order;
pcercuei 0:03b5121a232e 3470 else
pcercuei 0:03b5121a232e 3471 return(0);
pcercuei 0:03b5121a232e 3472 }
pcercuei 0:03b5121a232e 3473 }
pcercuei 0:03b5121a232e 3474 if (integy == 1) {
pcercuei 0:03b5121a232e 3475 if (y->value.decimal.lo == 0) {
pcercuei 0:03b5121a232e 3476 if (integx != 1)
pcercuei 0:03b5121a232e 3477 return order;
pcercuei 0:03b5121a232e 3478 else if (x->value.decimal.lo != 0)
pcercuei 0:03b5121a232e 3479 return order;
pcercuei 0:03b5121a232e 3480 else
pcercuei 0:03b5121a232e 3481 return(0);
pcercuei 0:03b5121a232e 3482 }
pcercuei 0:03b5121a232e 3483 }
pcercuei 0:03b5121a232e 3484
pcercuei 0:03b5121a232e 3485 if (integx > integy)
pcercuei 0:03b5121a232e 3486 return order;
pcercuei 0:03b5121a232e 3487 else if (integy > integx)
pcercuei 0:03b5121a232e 3488 return -order;
pcercuei 0:03b5121a232e 3489
pcercuei 0:03b5121a232e 3490 /*
pcercuei 0:03b5121a232e 3491 * If the number of integral digits is the same for both numbers,
pcercuei 0:03b5121a232e 3492 * then things get a little more complicated. We need to "normalize"
pcercuei 0:03b5121a232e 3493 * the numbers in order to properly compare them. To do this, we
pcercuei 0:03b5121a232e 3494 * look at the total length of each number (length => number of
pcercuei 0:03b5121a232e 3495 * significant digits), and divide the "shorter" by 10 (decreasing
pcercuei 0:03b5121a232e 3496 * the length) until they are of equal length.
pcercuei 0:03b5121a232e 3497 */
pcercuei 0:03b5121a232e 3498 dlen = x->value.decimal.total - y->value.decimal.total;
pcercuei 0:03b5121a232e 3499 if (dlen < 0) { /* y has more digits than x */
pcercuei 0:03b5121a232e 3500 swp = x;
pcercuei 0:03b5121a232e 3501 hi = y->value.decimal.hi;
pcercuei 0:03b5121a232e 3502 mi = y->value.decimal.mi;
pcercuei 0:03b5121a232e 3503 lo = y->value.decimal.lo;
pcercuei 0:03b5121a232e 3504 dlen = -dlen;
pcercuei 0:03b5121a232e 3505 order = -order;
pcercuei 0:03b5121a232e 3506 } else { /* x has more digits than y */
pcercuei 0:03b5121a232e 3507 swp = y;
pcercuei 0:03b5121a232e 3508 hi = x->value.decimal.hi;
pcercuei 0:03b5121a232e 3509 mi = x->value.decimal.mi;
pcercuei 0:03b5121a232e 3510 lo = x->value.decimal.lo;
pcercuei 0:03b5121a232e 3511 }
pcercuei 0:03b5121a232e 3512 while (dlen > 8) { /* in effect, right shift by 10**8 */
pcercuei 0:03b5121a232e 3513 lo = mi;
pcercuei 0:03b5121a232e 3514 mi = hi;
pcercuei 0:03b5121a232e 3515 hi = 0;
pcercuei 0:03b5121a232e 3516 dlen -= 8;
pcercuei 0:03b5121a232e 3517 }
pcercuei 0:03b5121a232e 3518 while (dlen > 0) {
pcercuei 0:03b5121a232e 3519 unsigned long rem1, rem2;
pcercuei 0:03b5121a232e 3520 rem1 = (hi % 10) * 100000000L;
pcercuei 0:03b5121a232e 3521 hi = hi / 10;
pcercuei 0:03b5121a232e 3522 rem2 = (mi % 10) * 100000000L;
pcercuei 0:03b5121a232e 3523 mi = (mi + rem1) / 10;
pcercuei 0:03b5121a232e 3524 lo = (lo + rem2) / 10;
pcercuei 0:03b5121a232e 3525 dlen--;
pcercuei 0:03b5121a232e 3526 }
pcercuei 0:03b5121a232e 3527 if (hi > swp->value.decimal.hi) {
pcercuei 0:03b5121a232e 3528 return order;
pcercuei 0:03b5121a232e 3529 } else if (hi == swp->value.decimal.hi) {
pcercuei 0:03b5121a232e 3530 if (mi > swp->value.decimal.mi) {
pcercuei 0:03b5121a232e 3531 return order;
pcercuei 0:03b5121a232e 3532 } else if (mi == swp->value.decimal.mi) {
pcercuei 0:03b5121a232e 3533 if (lo > swp->value.decimal.lo) {
pcercuei 0:03b5121a232e 3534 return order;
pcercuei 0:03b5121a232e 3535 } else if (lo == swp->value.decimal.lo) {
pcercuei 0:03b5121a232e 3536 if (x->value.decimal.total == y->value.decimal.total) {
pcercuei 0:03b5121a232e 3537 return 0;
pcercuei 0:03b5121a232e 3538 } else {
pcercuei 0:03b5121a232e 3539 return order;
pcercuei 0:03b5121a232e 3540 }
pcercuei 0:03b5121a232e 3541 }
pcercuei 0:03b5121a232e 3542 }
pcercuei 0:03b5121a232e 3543 }
pcercuei 0:03b5121a232e 3544 return -order;
pcercuei 0:03b5121a232e 3545 }
pcercuei 0:03b5121a232e 3546
pcercuei 0:03b5121a232e 3547 /**
pcercuei 0:03b5121a232e 3548 * xmlSchemaCompareDurations:
pcercuei 0:03b5121a232e 3549 * @x: a first duration value
pcercuei 0:03b5121a232e 3550 * @y: a second duration value
pcercuei 0:03b5121a232e 3551 *
pcercuei 0:03b5121a232e 3552 * Compare 2 durations
pcercuei 0:03b5121a232e 3553 *
pcercuei 0:03b5121a232e 3554 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
pcercuei 0:03b5121a232e 3555 * case of error
pcercuei 0:03b5121a232e 3556 */
pcercuei 0:03b5121a232e 3557 static int
pcercuei 0:03b5121a232e 3558 xmlSchemaCompareDurations(xmlSchemaValPtr x, xmlSchemaValPtr y)
pcercuei 0:03b5121a232e 3559 {
pcercuei 0:03b5121a232e 3560 long carry, mon, day;
pcercuei 0:03b5121a232e 3561 double sec;
pcercuei 0:03b5121a232e 3562 int invert = 1;
pcercuei 0:03b5121a232e 3563 long xmon, xday, myear, minday, maxday;
pcercuei 0:03b5121a232e 3564 static const long dayRange [2][12] = {
pcercuei 0:03b5121a232e 3565 { 0, 28, 59, 89, 120, 150, 181, 212, 242, 273, 303, 334, },
pcercuei 0:03b5121a232e 3566 { 0, 31, 62, 92, 123, 153, 184, 215, 245, 276, 306, 337} };
pcercuei 0:03b5121a232e 3567
pcercuei 0:03b5121a232e 3568 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 3569 return -2;
pcercuei 0:03b5121a232e 3570
pcercuei 0:03b5121a232e 3571 /* months */
pcercuei 0:03b5121a232e 3572 mon = x->value.dur.mon - y->value.dur.mon;
pcercuei 0:03b5121a232e 3573
pcercuei 0:03b5121a232e 3574 /* seconds */
pcercuei 0:03b5121a232e 3575 sec = x->value.dur.sec - y->value.dur.sec;
pcercuei 0:03b5121a232e 3576 carry = (long)(sec / SECS_PER_DAY);
pcercuei 0:03b5121a232e 3577 sec -= ((double)carry) * SECS_PER_DAY;
pcercuei 0:03b5121a232e 3578
pcercuei 0:03b5121a232e 3579 /* days */
pcercuei 0:03b5121a232e 3580 day = x->value.dur.day - y->value.dur.day + carry;
pcercuei 0:03b5121a232e 3581
pcercuei 0:03b5121a232e 3582 /* easy test */
pcercuei 0:03b5121a232e 3583 if (mon == 0) {
pcercuei 0:03b5121a232e 3584 if (day == 0)
pcercuei 0:03b5121a232e 3585 if (sec == 0.0)
pcercuei 0:03b5121a232e 3586 return 0;
pcercuei 0:03b5121a232e 3587 else if (sec < 0.0)
pcercuei 0:03b5121a232e 3588 return -1;
pcercuei 0:03b5121a232e 3589 else
pcercuei 0:03b5121a232e 3590 return 1;
pcercuei 0:03b5121a232e 3591 else if (day < 0)
pcercuei 0:03b5121a232e 3592 return -1;
pcercuei 0:03b5121a232e 3593 else
pcercuei 0:03b5121a232e 3594 return 1;
pcercuei 0:03b5121a232e 3595 }
pcercuei 0:03b5121a232e 3596
pcercuei 0:03b5121a232e 3597 if (mon > 0) {
pcercuei 0:03b5121a232e 3598 if ((day >= 0) && (sec >= 0.0))
pcercuei 0:03b5121a232e 3599 return 1;
pcercuei 0:03b5121a232e 3600 else {
pcercuei 0:03b5121a232e 3601 xmon = mon;
pcercuei 0:03b5121a232e 3602 xday = -day;
pcercuei 0:03b5121a232e 3603 }
pcercuei 0:03b5121a232e 3604 } else if ((day <= 0) && (sec <= 0.0)) {
pcercuei 0:03b5121a232e 3605 return -1;
pcercuei 0:03b5121a232e 3606 } else {
pcercuei 0:03b5121a232e 3607 invert = -1;
pcercuei 0:03b5121a232e 3608 xmon = -mon;
pcercuei 0:03b5121a232e 3609 xday = day;
pcercuei 0:03b5121a232e 3610 }
pcercuei 0:03b5121a232e 3611
pcercuei 0:03b5121a232e 3612 myear = xmon / 12;
pcercuei 0:03b5121a232e 3613 if (myear == 0) {
pcercuei 0:03b5121a232e 3614 minday = 0;
pcercuei 0:03b5121a232e 3615 maxday = 0;
pcercuei 0:03b5121a232e 3616 } else {
pcercuei 0:03b5121a232e 3617 maxday = 366 * ((myear + 3) / 4) +
pcercuei 0:03b5121a232e 3618 365 * ((myear - 1) % 4);
pcercuei 0:03b5121a232e 3619 minday = maxday - 1;
pcercuei 0:03b5121a232e 3620 }
pcercuei 0:03b5121a232e 3621
pcercuei 0:03b5121a232e 3622 xmon = xmon % 12;
pcercuei 0:03b5121a232e 3623 minday += dayRange[0][xmon];
pcercuei 0:03b5121a232e 3624 maxday += dayRange[1][xmon];
pcercuei 0:03b5121a232e 3625
pcercuei 0:03b5121a232e 3626 if ((maxday == minday) && (maxday == xday))
pcercuei 0:03b5121a232e 3627 return(0); /* can this really happen ? */
pcercuei 0:03b5121a232e 3628 if (maxday < xday)
pcercuei 0:03b5121a232e 3629 return(-invert);
pcercuei 0:03b5121a232e 3630 if (minday > xday)
pcercuei 0:03b5121a232e 3631 return(invert);
pcercuei 0:03b5121a232e 3632
pcercuei 0:03b5121a232e 3633 /* indeterminate */
pcercuei 0:03b5121a232e 3634 return 2;
pcercuei 0:03b5121a232e 3635 }
pcercuei 0:03b5121a232e 3636
pcercuei 0:03b5121a232e 3637 /*
pcercuei 0:03b5121a232e 3638 * macros for adding date/times and durations
pcercuei 0:03b5121a232e 3639 */
pcercuei 0:03b5121a232e 3640 #define FQUOTIENT(a,b) (floor(((double)a/(double)b)))
pcercuei 0:03b5121a232e 3641 #define MODULO(a,b) (a - FQUOTIENT(a,b) * b)
pcercuei 0:03b5121a232e 3642 #define FQUOTIENT_RANGE(a,low,high) (FQUOTIENT((a-low),(high-low)))
pcercuei 0:03b5121a232e 3643 #define MODULO_RANGE(a,low,high) ((MODULO((a-low),(high-low)))+low)
pcercuei 0:03b5121a232e 3644
pcercuei 0:03b5121a232e 3645 /**
pcercuei 0:03b5121a232e 3646 * xmlSchemaDupVal:
pcercuei 0:03b5121a232e 3647 * @v: the #xmlSchemaValPtr value to duplicate
pcercuei 0:03b5121a232e 3648 *
pcercuei 0:03b5121a232e 3649 * Makes a copy of @v. The calling program is responsible for freeing
pcercuei 0:03b5121a232e 3650 * the returned value.
pcercuei 0:03b5121a232e 3651 *
pcercuei 0:03b5121a232e 3652 * returns a pointer to a duplicated #xmlSchemaValPtr or NULL if error.
pcercuei 0:03b5121a232e 3653 */
pcercuei 0:03b5121a232e 3654 static xmlSchemaValPtr
pcercuei 0:03b5121a232e 3655 xmlSchemaDupVal (xmlSchemaValPtr v)
pcercuei 0:03b5121a232e 3656 {
pcercuei 0:03b5121a232e 3657 xmlSchemaValPtr ret = xmlSchemaNewValue(v->type);
pcercuei 0:03b5121a232e 3658 if (ret == NULL)
pcercuei 0:03b5121a232e 3659 return NULL;
pcercuei 0:03b5121a232e 3660
pcercuei 0:03b5121a232e 3661 memcpy(ret, v, sizeof(xmlSchemaVal));
pcercuei 0:03b5121a232e 3662 ret->next = NULL;
pcercuei 0:03b5121a232e 3663 return ret;
pcercuei 0:03b5121a232e 3664 }
pcercuei 0:03b5121a232e 3665
pcercuei 0:03b5121a232e 3666 /**
pcercuei 0:03b5121a232e 3667 * xmlSchemaCopyValue:
pcercuei 0:03b5121a232e 3668 * @val: the precomputed value to be copied
pcercuei 0:03b5121a232e 3669 *
pcercuei 0:03b5121a232e 3670 * Copies the precomputed value. This duplicates any string within.
pcercuei 0:03b5121a232e 3671 *
pcercuei 0:03b5121a232e 3672 * Returns the copy or NULL if a copy for a data-type is not implemented.
pcercuei 0:03b5121a232e 3673 */
pcercuei 0:03b5121a232e 3674 xmlSchemaValPtr
pcercuei 0:03b5121a232e 3675 xmlSchemaCopyValue(xmlSchemaValPtr val)
pcercuei 0:03b5121a232e 3676 {
pcercuei 0:03b5121a232e 3677 xmlSchemaValPtr ret = NULL, prev = NULL, cur;
pcercuei 0:03b5121a232e 3678
pcercuei 0:03b5121a232e 3679 /*
pcercuei 0:03b5121a232e 3680 * Copy the string values.
pcercuei 0:03b5121a232e 3681 */
pcercuei 0:03b5121a232e 3682 while (val != NULL) {
pcercuei 0:03b5121a232e 3683 switch (val->type) {
pcercuei 0:03b5121a232e 3684 case XML_SCHEMAS_ANYTYPE:
pcercuei 0:03b5121a232e 3685 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 3686 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 3687 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 3688 xmlSchemaFreeValue(ret);
pcercuei 0:03b5121a232e 3689 return (NULL);
pcercuei 0:03b5121a232e 3690 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 3691 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 3692 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 3693 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 3694 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 3695 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 3696 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 3697 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 3698 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 3699 case XML_SCHEMAS_ENTITY:
pcercuei 0:03b5121a232e 3700 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 3701 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 3702 cur = xmlSchemaDupVal(val);
pcercuei 0:03b5121a232e 3703 if (val->value.str != NULL)
pcercuei 0:03b5121a232e 3704 cur->value.str = xmlStrdup(BAD_CAST val->value.str);
pcercuei 0:03b5121a232e 3705 break;
pcercuei 0:03b5121a232e 3706 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 3707 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 3708 cur = xmlSchemaDupVal(val);
pcercuei 0:03b5121a232e 3709 if (val->value.qname.name != NULL)
pcercuei 0:03b5121a232e 3710 cur->value.qname.name =
pcercuei 0:03b5121a232e 3711 xmlStrdup(BAD_CAST val->value.qname.name);
pcercuei 0:03b5121a232e 3712 if (val->value.qname.uri != NULL)
pcercuei 0:03b5121a232e 3713 cur->value.qname.uri =
pcercuei 0:03b5121a232e 3714 xmlStrdup(BAD_CAST val->value.qname.uri);
pcercuei 0:03b5121a232e 3715 break;
pcercuei 0:03b5121a232e 3716 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 3717 cur = xmlSchemaDupVal(val);
pcercuei 0:03b5121a232e 3718 if (val->value.hex.str != NULL)
pcercuei 0:03b5121a232e 3719 cur->value.hex.str = xmlStrdup(BAD_CAST val->value.hex.str);
pcercuei 0:03b5121a232e 3720 break;
pcercuei 0:03b5121a232e 3721 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 3722 cur = xmlSchemaDupVal(val);
pcercuei 0:03b5121a232e 3723 if (val->value.base64.str != NULL)
pcercuei 0:03b5121a232e 3724 cur->value.base64.str =
pcercuei 0:03b5121a232e 3725 xmlStrdup(BAD_CAST val->value.base64.str);
pcercuei 0:03b5121a232e 3726 break;
pcercuei 0:03b5121a232e 3727 default:
pcercuei 0:03b5121a232e 3728 cur = xmlSchemaDupVal(val);
pcercuei 0:03b5121a232e 3729 break;
pcercuei 0:03b5121a232e 3730 }
pcercuei 0:03b5121a232e 3731 if (ret == NULL)
pcercuei 0:03b5121a232e 3732 ret = cur;
pcercuei 0:03b5121a232e 3733 else
pcercuei 0:03b5121a232e 3734 prev->next = cur;
pcercuei 0:03b5121a232e 3735 prev = cur;
pcercuei 0:03b5121a232e 3736 val = val->next;
pcercuei 0:03b5121a232e 3737 }
pcercuei 0:03b5121a232e 3738 return (ret);
pcercuei 0:03b5121a232e 3739 }
pcercuei 0:03b5121a232e 3740
pcercuei 0:03b5121a232e 3741 /**
pcercuei 0:03b5121a232e 3742 * _xmlSchemaDateAdd:
pcercuei 0:03b5121a232e 3743 * @dt: an #xmlSchemaValPtr
pcercuei 0:03b5121a232e 3744 * @dur: an #xmlSchemaValPtr of type #XS_DURATION
pcercuei 0:03b5121a232e 3745 *
pcercuei 0:03b5121a232e 3746 * Compute a new date/time from @dt and @dur. This function assumes @dt
pcercuei 0:03b5121a232e 3747 * is either #XML_SCHEMAS_DATETIME, #XML_SCHEMAS_DATE, #XML_SCHEMAS_GYEARMONTH,
pcercuei 0:03b5121a232e 3748 * or #XML_SCHEMAS_GYEAR. The returned #xmlSchemaVal is the same type as
pcercuei 0:03b5121a232e 3749 * @dt. The calling program is responsible for freeing the returned value.
pcercuei 0:03b5121a232e 3750 *
pcercuei 0:03b5121a232e 3751 * Returns a pointer to a new #xmlSchemaVal or NULL if error.
pcercuei 0:03b5121a232e 3752 */
pcercuei 0:03b5121a232e 3753 static xmlSchemaValPtr
pcercuei 0:03b5121a232e 3754 _xmlSchemaDateAdd (xmlSchemaValPtr dt, xmlSchemaValPtr dur)
pcercuei 0:03b5121a232e 3755 {
pcercuei 0:03b5121a232e 3756 xmlSchemaValPtr ret, tmp;
pcercuei 0:03b5121a232e 3757 long carry, tempdays, temp;
pcercuei 0:03b5121a232e 3758 xmlSchemaValDatePtr r, d;
pcercuei 0:03b5121a232e 3759 xmlSchemaValDurationPtr u;
pcercuei 0:03b5121a232e 3760
pcercuei 0:03b5121a232e 3761 if ((dt == NULL) || (dur == NULL))
pcercuei 0:03b5121a232e 3762 return NULL;
pcercuei 0:03b5121a232e 3763
pcercuei 0:03b5121a232e 3764 ret = xmlSchemaNewValue(dt->type);
pcercuei 0:03b5121a232e 3765 if (ret == NULL)
pcercuei 0:03b5121a232e 3766 return NULL;
pcercuei 0:03b5121a232e 3767
pcercuei 0:03b5121a232e 3768 /* make a copy so we don't alter the original value */
pcercuei 0:03b5121a232e 3769 tmp = xmlSchemaDupVal(dt);
pcercuei 0:03b5121a232e 3770 if (tmp == NULL) {
pcercuei 0:03b5121a232e 3771 xmlSchemaFreeValue(ret);
pcercuei 0:03b5121a232e 3772 return NULL;
pcercuei 0:03b5121a232e 3773 }
pcercuei 0:03b5121a232e 3774
pcercuei 0:03b5121a232e 3775 r = &(ret->value.date);
pcercuei 0:03b5121a232e 3776 d = &(tmp->value.date);
pcercuei 0:03b5121a232e 3777 u = &(dur->value.dur);
pcercuei 0:03b5121a232e 3778
pcercuei 0:03b5121a232e 3779 /* normalization */
pcercuei 0:03b5121a232e 3780 if (d->mon == 0)
pcercuei 0:03b5121a232e 3781 d->mon = 1;
pcercuei 0:03b5121a232e 3782
pcercuei 0:03b5121a232e 3783 /* normalize for time zone offset */
pcercuei 0:03b5121a232e 3784 u->sec -= (d->tzo * 60);
pcercuei 0:03b5121a232e 3785 d->tzo = 0;
pcercuei 0:03b5121a232e 3786
pcercuei 0:03b5121a232e 3787 /* normalization */
pcercuei 0:03b5121a232e 3788 if (d->day == 0)
pcercuei 0:03b5121a232e 3789 d->day = 1;
pcercuei 0:03b5121a232e 3790
pcercuei 0:03b5121a232e 3791 /* month */
pcercuei 0:03b5121a232e 3792 carry = d->mon + u->mon;
pcercuei 0:03b5121a232e 3793 r->mon = (unsigned int) MODULO_RANGE(carry, 1, 13);
pcercuei 0:03b5121a232e 3794 carry = (long) FQUOTIENT_RANGE(carry, 1, 13);
pcercuei 0:03b5121a232e 3795
pcercuei 0:03b5121a232e 3796 /* year (may be modified later) */
pcercuei 0:03b5121a232e 3797 r->year = d->year + carry;
pcercuei 0:03b5121a232e 3798 if (r->year == 0) {
pcercuei 0:03b5121a232e 3799 if (d->year > 0)
pcercuei 0:03b5121a232e 3800 r->year--;
pcercuei 0:03b5121a232e 3801 else
pcercuei 0:03b5121a232e 3802 r->year++;
pcercuei 0:03b5121a232e 3803 }
pcercuei 0:03b5121a232e 3804
pcercuei 0:03b5121a232e 3805 /* time zone */
pcercuei 0:03b5121a232e 3806 r->tzo = d->tzo;
pcercuei 0:03b5121a232e 3807 r->tz_flag = d->tz_flag;
pcercuei 0:03b5121a232e 3808
pcercuei 0:03b5121a232e 3809 /* seconds */
pcercuei 0:03b5121a232e 3810 r->sec = d->sec + u->sec;
pcercuei 0:03b5121a232e 3811 carry = (long) FQUOTIENT((long)r->sec, 60);
pcercuei 0:03b5121a232e 3812 if (r->sec != 0.0) {
pcercuei 0:03b5121a232e 3813 r->sec = MODULO(r->sec, 60.0);
pcercuei 0:03b5121a232e 3814 }
pcercuei 0:03b5121a232e 3815
pcercuei 0:03b5121a232e 3816 /* minute */
pcercuei 0:03b5121a232e 3817 carry += d->min;
pcercuei 0:03b5121a232e 3818 r->min = (unsigned int) MODULO(carry, 60);
pcercuei 0:03b5121a232e 3819 carry = (long) FQUOTIENT(carry, 60);
pcercuei 0:03b5121a232e 3820
pcercuei 0:03b5121a232e 3821 /* hours */
pcercuei 0:03b5121a232e 3822 carry += d->hour;
pcercuei 0:03b5121a232e 3823 r->hour = (unsigned int) MODULO(carry, 24);
pcercuei 0:03b5121a232e 3824 carry = (long)FQUOTIENT(carry, 24);
pcercuei 0:03b5121a232e 3825
pcercuei 0:03b5121a232e 3826 /*
pcercuei 0:03b5121a232e 3827 * days
pcercuei 0:03b5121a232e 3828 * Note we use tempdays because the temporary values may need more
pcercuei 0:03b5121a232e 3829 * than 5 bits
pcercuei 0:03b5121a232e 3830 */
pcercuei 0:03b5121a232e 3831 if ((VALID_YEAR(r->year)) && (VALID_MONTH(r->mon)) &&
pcercuei 0:03b5121a232e 3832 (d->day > MAX_DAYINMONTH(r->year, r->mon)))
pcercuei 0:03b5121a232e 3833 tempdays = MAX_DAYINMONTH(r->year, r->mon);
pcercuei 0:03b5121a232e 3834 else if (d->day < 1)
pcercuei 0:03b5121a232e 3835 tempdays = 1;
pcercuei 0:03b5121a232e 3836 else
pcercuei 0:03b5121a232e 3837 tempdays = d->day;
pcercuei 0:03b5121a232e 3838
pcercuei 0:03b5121a232e 3839 tempdays += u->day + carry;
pcercuei 0:03b5121a232e 3840
pcercuei 0:03b5121a232e 3841 while (1) {
pcercuei 0:03b5121a232e 3842 if (tempdays < 1) {
pcercuei 0:03b5121a232e 3843 long tmon = (long) MODULO_RANGE((int)r->mon-1, 1, 13);
pcercuei 0:03b5121a232e 3844 long tyr = r->year + (long)FQUOTIENT_RANGE((int)r->mon-1, 1, 13);
pcercuei 0:03b5121a232e 3845 if (tyr == 0)
pcercuei 0:03b5121a232e 3846 tyr--;
pcercuei 0:03b5121a232e 3847 /*
pcercuei 0:03b5121a232e 3848 * Coverity detected an overrun in daysInMonth
pcercuei 0:03b5121a232e 3849 * of size 12 at position 12 with index variable "((r)->mon - 1)"
pcercuei 0:03b5121a232e 3850 */
pcercuei 0:03b5121a232e 3851 if (tmon < 1)
pcercuei 0:03b5121a232e 3852 tmon = 1;
pcercuei 0:03b5121a232e 3853 if (tmon > 12)
pcercuei 0:03b5121a232e 3854 tmon = 12;
pcercuei 0:03b5121a232e 3855 tempdays += MAX_DAYINMONTH(tyr, tmon);
pcercuei 0:03b5121a232e 3856 carry = -1;
pcercuei 0:03b5121a232e 3857 } else if (VALID_YEAR(r->year) && VALID_MONTH(r->mon) &&
pcercuei 0:03b5121a232e 3858 tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
pcercuei 0:03b5121a232e 3859 tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
pcercuei 0:03b5121a232e 3860 carry = 1;
pcercuei 0:03b5121a232e 3861 } else
pcercuei 0:03b5121a232e 3862 break;
pcercuei 0:03b5121a232e 3863
pcercuei 0:03b5121a232e 3864 temp = r->mon + carry;
pcercuei 0:03b5121a232e 3865 r->mon = (unsigned int) MODULO_RANGE(temp, 1, 13);
pcercuei 0:03b5121a232e 3866 r->year = r->year + (unsigned int) FQUOTIENT_RANGE(temp, 1, 13);
pcercuei 0:03b5121a232e 3867 if (r->year == 0) {
pcercuei 0:03b5121a232e 3868 if (temp < 1)
pcercuei 0:03b5121a232e 3869 r->year--;
pcercuei 0:03b5121a232e 3870 else
pcercuei 0:03b5121a232e 3871 r->year++;
pcercuei 0:03b5121a232e 3872 }
pcercuei 0:03b5121a232e 3873 }
pcercuei 0:03b5121a232e 3874
pcercuei 0:03b5121a232e 3875 r->day = tempdays;
pcercuei 0:03b5121a232e 3876
pcercuei 0:03b5121a232e 3877 /*
pcercuei 0:03b5121a232e 3878 * adjust the date/time type to the date values
pcercuei 0:03b5121a232e 3879 */
pcercuei 0:03b5121a232e 3880 if (ret->type != XML_SCHEMAS_DATETIME) {
pcercuei 0:03b5121a232e 3881 if ((r->hour) || (r->min) || (r->sec))
pcercuei 0:03b5121a232e 3882 ret->type = XML_SCHEMAS_DATETIME;
pcercuei 0:03b5121a232e 3883 else if (ret->type != XML_SCHEMAS_DATE) {
pcercuei 0:03b5121a232e 3884 if ((r->mon != 1) && (r->day != 1))
pcercuei 0:03b5121a232e 3885 ret->type = XML_SCHEMAS_DATE;
pcercuei 0:03b5121a232e 3886 else if ((ret->type != XML_SCHEMAS_GYEARMONTH) && (r->mon != 1))
pcercuei 0:03b5121a232e 3887 ret->type = XML_SCHEMAS_GYEARMONTH;
pcercuei 0:03b5121a232e 3888 }
pcercuei 0:03b5121a232e 3889 }
pcercuei 0:03b5121a232e 3890
pcercuei 0:03b5121a232e 3891 xmlSchemaFreeValue(tmp);
pcercuei 0:03b5121a232e 3892
pcercuei 0:03b5121a232e 3893 return ret;
pcercuei 0:03b5121a232e 3894 }
pcercuei 0:03b5121a232e 3895
pcercuei 0:03b5121a232e 3896 /**
pcercuei 0:03b5121a232e 3897 * xmlSchemaDateNormalize:
pcercuei 0:03b5121a232e 3898 * @dt: an #xmlSchemaValPtr of a date/time type value.
pcercuei 0:03b5121a232e 3899 * @offset: number of seconds to adjust @dt by.
pcercuei 0:03b5121a232e 3900 *
pcercuei 0:03b5121a232e 3901 * Normalize @dt to GMT time. The @offset parameter is subtracted from
pcercuei 0:03b5121a232e 3902 * the return value is a time-zone offset is present on @dt.
pcercuei 0:03b5121a232e 3903 *
pcercuei 0:03b5121a232e 3904 * Returns a normalized copy of @dt or NULL if error.
pcercuei 0:03b5121a232e 3905 */
pcercuei 0:03b5121a232e 3906 static xmlSchemaValPtr
pcercuei 0:03b5121a232e 3907 xmlSchemaDateNormalize (xmlSchemaValPtr dt, double offset)
pcercuei 0:03b5121a232e 3908 {
pcercuei 0:03b5121a232e 3909 xmlSchemaValPtr dur, ret;
pcercuei 0:03b5121a232e 3910
pcercuei 0:03b5121a232e 3911 if (dt == NULL)
pcercuei 0:03b5121a232e 3912 return NULL;
pcercuei 0:03b5121a232e 3913
pcercuei 0:03b5121a232e 3914 if (((dt->type != XML_SCHEMAS_TIME) &&
pcercuei 0:03b5121a232e 3915 (dt->type != XML_SCHEMAS_DATETIME) &&
pcercuei 0:03b5121a232e 3916 (dt->type != XML_SCHEMAS_DATE)) || (dt->value.date.tzo == 0))
pcercuei 0:03b5121a232e 3917 return xmlSchemaDupVal(dt);
pcercuei 0:03b5121a232e 3918
pcercuei 0:03b5121a232e 3919 dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
pcercuei 0:03b5121a232e 3920 if (dur == NULL)
pcercuei 0:03b5121a232e 3921 return NULL;
pcercuei 0:03b5121a232e 3922
pcercuei 0:03b5121a232e 3923 dur->value.date.sec -= offset;
pcercuei 0:03b5121a232e 3924
pcercuei 0:03b5121a232e 3925 ret = _xmlSchemaDateAdd(dt, dur);
pcercuei 0:03b5121a232e 3926 if (ret == NULL)
pcercuei 0:03b5121a232e 3927 return NULL;
pcercuei 0:03b5121a232e 3928
pcercuei 0:03b5121a232e 3929 xmlSchemaFreeValue(dur);
pcercuei 0:03b5121a232e 3930
pcercuei 0:03b5121a232e 3931 /* ret->value.date.tzo = 0; */
pcercuei 0:03b5121a232e 3932 return ret;
pcercuei 0:03b5121a232e 3933 }
pcercuei 0:03b5121a232e 3934
pcercuei 0:03b5121a232e 3935 /**
pcercuei 0:03b5121a232e 3936 * _xmlSchemaDateCastYMToDays:
pcercuei 0:03b5121a232e 3937 * @dt: an #xmlSchemaValPtr
pcercuei 0:03b5121a232e 3938 *
pcercuei 0:03b5121a232e 3939 * Convert mon and year of @dt to total number of days. Take the
pcercuei 0:03b5121a232e 3940 * number of years since (or before) 1 AD and add the number of leap
pcercuei 0:03b5121a232e 3941 * years. This is a function because negative
pcercuei 0:03b5121a232e 3942 * years must be handled a little differently and there is no zero year.
pcercuei 0:03b5121a232e 3943 *
pcercuei 0:03b5121a232e 3944 * Returns number of days.
pcercuei 0:03b5121a232e 3945 */
pcercuei 0:03b5121a232e 3946 static long
pcercuei 0:03b5121a232e 3947 _xmlSchemaDateCastYMToDays (const xmlSchemaValPtr dt)
pcercuei 0:03b5121a232e 3948 {
pcercuei 0:03b5121a232e 3949 long ret;
pcercuei 0:03b5121a232e 3950 int mon;
pcercuei 0:03b5121a232e 3951
pcercuei 0:03b5121a232e 3952 mon = dt->value.date.mon;
pcercuei 0:03b5121a232e 3953 if (mon <= 0) mon = 1; /* normalization */
pcercuei 0:03b5121a232e 3954
pcercuei 0:03b5121a232e 3955 if (dt->value.date.year <= 0)
pcercuei 0:03b5121a232e 3956 ret = (dt->value.date.year * 365) +
pcercuei 0:03b5121a232e 3957 (((dt->value.date.year+1)/4)-((dt->value.date.year+1)/100)+
pcercuei 0:03b5121a232e 3958 ((dt->value.date.year+1)/400)) +
pcercuei 0:03b5121a232e 3959 DAY_IN_YEAR(0, mon, dt->value.date.year);
pcercuei 0:03b5121a232e 3960 else
pcercuei 0:03b5121a232e 3961 ret = ((dt->value.date.year-1) * 365) +
pcercuei 0:03b5121a232e 3962 (((dt->value.date.year-1)/4)-((dt->value.date.year-1)/100)+
pcercuei 0:03b5121a232e 3963 ((dt->value.date.year-1)/400)) +
pcercuei 0:03b5121a232e 3964 DAY_IN_YEAR(0, mon, dt->value.date.year);
pcercuei 0:03b5121a232e 3965
pcercuei 0:03b5121a232e 3966 return ret;
pcercuei 0:03b5121a232e 3967 }
pcercuei 0:03b5121a232e 3968
pcercuei 0:03b5121a232e 3969 /**
pcercuei 0:03b5121a232e 3970 * TIME_TO_NUMBER:
pcercuei 0:03b5121a232e 3971 * @dt: an #xmlSchemaValPtr
pcercuei 0:03b5121a232e 3972 *
pcercuei 0:03b5121a232e 3973 * Calculates the number of seconds in the time portion of @dt.
pcercuei 0:03b5121a232e 3974 *
pcercuei 0:03b5121a232e 3975 * Returns seconds.
pcercuei 0:03b5121a232e 3976 */
pcercuei 0:03b5121a232e 3977 #define TIME_TO_NUMBER(dt) \
pcercuei 0:03b5121a232e 3978 ((double)((dt->value.date.hour * SECS_PER_HOUR) + \
pcercuei 0:03b5121a232e 3979 (dt->value.date.min * SECS_PER_MIN) + \
pcercuei 0:03b5121a232e 3980 (dt->value.date.tzo * SECS_PER_MIN)) + \
pcercuei 0:03b5121a232e 3981 dt->value.date.sec)
pcercuei 0:03b5121a232e 3982
pcercuei 0:03b5121a232e 3983 /**
pcercuei 0:03b5121a232e 3984 * xmlSchemaCompareDates:
pcercuei 0:03b5121a232e 3985 * @x: a first date/time value
pcercuei 0:03b5121a232e 3986 * @y: a second date/time value
pcercuei 0:03b5121a232e 3987 *
pcercuei 0:03b5121a232e 3988 * Compare 2 date/times
pcercuei 0:03b5121a232e 3989 *
pcercuei 0:03b5121a232e 3990 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
pcercuei 0:03b5121a232e 3991 * case of error
pcercuei 0:03b5121a232e 3992 */
pcercuei 0:03b5121a232e 3993 static int
pcercuei 0:03b5121a232e 3994 xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
pcercuei 0:03b5121a232e 3995 {
pcercuei 0:03b5121a232e 3996 unsigned char xmask, ymask, xor_mask, and_mask;
pcercuei 0:03b5121a232e 3997 xmlSchemaValPtr p1, p2, q1, q2;
pcercuei 0:03b5121a232e 3998 long p1d, p2d, q1d, q2d;
pcercuei 0:03b5121a232e 3999
pcercuei 0:03b5121a232e 4000 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4001 return -2;
pcercuei 0:03b5121a232e 4002
pcercuei 0:03b5121a232e 4003 if (x->value.date.tz_flag) {
pcercuei 0:03b5121a232e 4004
pcercuei 0:03b5121a232e 4005 if (!y->value.date.tz_flag) {
pcercuei 0:03b5121a232e 4006 p1 = xmlSchemaDateNormalize(x, 0);
pcercuei 0:03b5121a232e 4007 p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
pcercuei 0:03b5121a232e 4008 /* normalize y + 14:00 */
pcercuei 0:03b5121a232e 4009 q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR));
pcercuei 0:03b5121a232e 4010
pcercuei 0:03b5121a232e 4011 q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
pcercuei 0:03b5121a232e 4012 if (p1d < q1d) {
pcercuei 0:03b5121a232e 4013 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4014 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4015 return -1;
pcercuei 0:03b5121a232e 4016 } else if (p1d == q1d) {
pcercuei 0:03b5121a232e 4017 double sec;
pcercuei 0:03b5121a232e 4018
pcercuei 0:03b5121a232e 4019 sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
pcercuei 0:03b5121a232e 4020 if (sec < 0.0) {
pcercuei 0:03b5121a232e 4021 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4022 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4023 return -1;
pcercuei 0:03b5121a232e 4024 } else {
pcercuei 0:03b5121a232e 4025 int ret = 0;
pcercuei 0:03b5121a232e 4026 /* normalize y - 14:00 */
pcercuei 0:03b5121a232e 4027 q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR));
pcercuei 0:03b5121a232e 4028 q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day;
pcercuei 0:03b5121a232e 4029 if (p1d > q2d)
pcercuei 0:03b5121a232e 4030 ret = 1;
pcercuei 0:03b5121a232e 4031 else if (p1d == q2d) {
pcercuei 0:03b5121a232e 4032 sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q2);
pcercuei 0:03b5121a232e 4033 if (sec > 0.0)
pcercuei 0:03b5121a232e 4034 ret = 1;
pcercuei 0:03b5121a232e 4035 else
pcercuei 0:03b5121a232e 4036 ret = 2; /* indeterminate */
pcercuei 0:03b5121a232e 4037 }
pcercuei 0:03b5121a232e 4038 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4039 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4040 xmlSchemaFreeValue(q2);
pcercuei 0:03b5121a232e 4041 if (ret != 0)
pcercuei 0:03b5121a232e 4042 return(ret);
pcercuei 0:03b5121a232e 4043 }
pcercuei 0:03b5121a232e 4044 } else {
pcercuei 0:03b5121a232e 4045 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4046 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4047 }
pcercuei 0:03b5121a232e 4048 }
pcercuei 0:03b5121a232e 4049 } else if (y->value.date.tz_flag) {
pcercuei 0:03b5121a232e 4050 q1 = xmlSchemaDateNormalize(y, 0);
pcercuei 0:03b5121a232e 4051 q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
pcercuei 0:03b5121a232e 4052
pcercuei 0:03b5121a232e 4053 /* normalize x - 14:00 */
pcercuei 0:03b5121a232e 4054 p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR));
pcercuei 0:03b5121a232e 4055 p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
pcercuei 0:03b5121a232e 4056
pcercuei 0:03b5121a232e 4057 if (p1d < q1d) {
pcercuei 0:03b5121a232e 4058 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4059 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4060 return -1;
pcercuei 0:03b5121a232e 4061 } else if (p1d == q1d) {
pcercuei 0:03b5121a232e 4062 double sec;
pcercuei 0:03b5121a232e 4063
pcercuei 0:03b5121a232e 4064 sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
pcercuei 0:03b5121a232e 4065 if (sec < 0.0) {
pcercuei 0:03b5121a232e 4066 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4067 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4068 return -1;
pcercuei 0:03b5121a232e 4069 } else {
pcercuei 0:03b5121a232e 4070 int ret = 0;
pcercuei 0:03b5121a232e 4071 /* normalize x + 14:00 */
pcercuei 0:03b5121a232e 4072 p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR));
pcercuei 0:03b5121a232e 4073 p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day;
pcercuei 0:03b5121a232e 4074
pcercuei 0:03b5121a232e 4075 if (p2d > q1d) {
pcercuei 0:03b5121a232e 4076 ret = 1;
pcercuei 0:03b5121a232e 4077 } else if (p2d == q1d) {
pcercuei 0:03b5121a232e 4078 sec = TIME_TO_NUMBER(p2) - TIME_TO_NUMBER(q1);
pcercuei 0:03b5121a232e 4079 if (sec > 0.0)
pcercuei 0:03b5121a232e 4080 ret = 1;
pcercuei 0:03b5121a232e 4081 else
pcercuei 0:03b5121a232e 4082 ret = 2; /* indeterminate */
pcercuei 0:03b5121a232e 4083 }
pcercuei 0:03b5121a232e 4084 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4085 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4086 xmlSchemaFreeValue(p2);
pcercuei 0:03b5121a232e 4087 if (ret != 0)
pcercuei 0:03b5121a232e 4088 return(ret);
pcercuei 0:03b5121a232e 4089 }
pcercuei 0:03b5121a232e 4090 } else {
pcercuei 0:03b5121a232e 4091 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4092 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4093 }
pcercuei 0:03b5121a232e 4094 }
pcercuei 0:03b5121a232e 4095
pcercuei 0:03b5121a232e 4096 /*
pcercuei 0:03b5121a232e 4097 * if the same type then calculate the difference
pcercuei 0:03b5121a232e 4098 */
pcercuei 0:03b5121a232e 4099 if (x->type == y->type) {
pcercuei 0:03b5121a232e 4100 int ret = 0;
pcercuei 0:03b5121a232e 4101 q1 = xmlSchemaDateNormalize(y, 0);
pcercuei 0:03b5121a232e 4102 q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
pcercuei 0:03b5121a232e 4103
pcercuei 0:03b5121a232e 4104 p1 = xmlSchemaDateNormalize(x, 0);
pcercuei 0:03b5121a232e 4105 p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
pcercuei 0:03b5121a232e 4106
pcercuei 0:03b5121a232e 4107 if (p1d < q1d) {
pcercuei 0:03b5121a232e 4108 ret = -1;
pcercuei 0:03b5121a232e 4109 } else if (p1d > q1d) {
pcercuei 0:03b5121a232e 4110 ret = 1;
pcercuei 0:03b5121a232e 4111 } else {
pcercuei 0:03b5121a232e 4112 double sec;
pcercuei 0:03b5121a232e 4113
pcercuei 0:03b5121a232e 4114 sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
pcercuei 0:03b5121a232e 4115 if (sec < 0.0)
pcercuei 0:03b5121a232e 4116 ret = -1;
pcercuei 0:03b5121a232e 4117 else if (sec > 0.0)
pcercuei 0:03b5121a232e 4118 ret = 1;
pcercuei 0:03b5121a232e 4119
pcercuei 0:03b5121a232e 4120 }
pcercuei 0:03b5121a232e 4121 xmlSchemaFreeValue(p1);
pcercuei 0:03b5121a232e 4122 xmlSchemaFreeValue(q1);
pcercuei 0:03b5121a232e 4123 return(ret);
pcercuei 0:03b5121a232e 4124 }
pcercuei 0:03b5121a232e 4125
pcercuei 0:03b5121a232e 4126 switch (x->type) {
pcercuei 0:03b5121a232e 4127 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 4128 xmask = 0xf;
pcercuei 0:03b5121a232e 4129 break;
pcercuei 0:03b5121a232e 4130 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 4131 xmask = 0x7;
pcercuei 0:03b5121a232e 4132 break;
pcercuei 0:03b5121a232e 4133 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 4134 xmask = 0x1;
pcercuei 0:03b5121a232e 4135 break;
pcercuei 0:03b5121a232e 4136 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 4137 xmask = 0x2;
pcercuei 0:03b5121a232e 4138 break;
pcercuei 0:03b5121a232e 4139 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 4140 xmask = 0x3;
pcercuei 0:03b5121a232e 4141 break;
pcercuei 0:03b5121a232e 4142 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 4143 xmask = 0x3;
pcercuei 0:03b5121a232e 4144 break;
pcercuei 0:03b5121a232e 4145 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 4146 xmask = 0x6;
pcercuei 0:03b5121a232e 4147 break;
pcercuei 0:03b5121a232e 4148 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 4149 xmask = 0x8;
pcercuei 0:03b5121a232e 4150 break;
pcercuei 0:03b5121a232e 4151 default:
pcercuei 0:03b5121a232e 4152 xmask = 0;
pcercuei 0:03b5121a232e 4153 break;
pcercuei 0:03b5121a232e 4154 }
pcercuei 0:03b5121a232e 4155
pcercuei 0:03b5121a232e 4156 switch (y->type) {
pcercuei 0:03b5121a232e 4157 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 4158 ymask = 0xf;
pcercuei 0:03b5121a232e 4159 break;
pcercuei 0:03b5121a232e 4160 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 4161 ymask = 0x7;
pcercuei 0:03b5121a232e 4162 break;
pcercuei 0:03b5121a232e 4163 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 4164 ymask = 0x1;
pcercuei 0:03b5121a232e 4165 break;
pcercuei 0:03b5121a232e 4166 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 4167 ymask = 0x2;
pcercuei 0:03b5121a232e 4168 break;
pcercuei 0:03b5121a232e 4169 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 4170 ymask = 0x3;
pcercuei 0:03b5121a232e 4171 break;
pcercuei 0:03b5121a232e 4172 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 4173 ymask = 0x3;
pcercuei 0:03b5121a232e 4174 break;
pcercuei 0:03b5121a232e 4175 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 4176 ymask = 0x6;
pcercuei 0:03b5121a232e 4177 break;
pcercuei 0:03b5121a232e 4178 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 4179 ymask = 0x8;
pcercuei 0:03b5121a232e 4180 break;
pcercuei 0:03b5121a232e 4181 default:
pcercuei 0:03b5121a232e 4182 ymask = 0;
pcercuei 0:03b5121a232e 4183 break;
pcercuei 0:03b5121a232e 4184 }
pcercuei 0:03b5121a232e 4185
pcercuei 0:03b5121a232e 4186 xor_mask = xmask ^ ymask; /* mark type differences */
pcercuei 0:03b5121a232e 4187 and_mask = xmask & ymask; /* mark field specification */
pcercuei 0:03b5121a232e 4188
pcercuei 0:03b5121a232e 4189 /* year */
pcercuei 0:03b5121a232e 4190 if (xor_mask & 1)
pcercuei 0:03b5121a232e 4191 return 2; /* indeterminate */
pcercuei 0:03b5121a232e 4192 else if (and_mask & 1) {
pcercuei 0:03b5121a232e 4193 if (x->value.date.year < y->value.date.year)
pcercuei 0:03b5121a232e 4194 return -1;
pcercuei 0:03b5121a232e 4195 else if (x->value.date.year > y->value.date.year)
pcercuei 0:03b5121a232e 4196 return 1;
pcercuei 0:03b5121a232e 4197 }
pcercuei 0:03b5121a232e 4198
pcercuei 0:03b5121a232e 4199 /* month */
pcercuei 0:03b5121a232e 4200 if (xor_mask & 2)
pcercuei 0:03b5121a232e 4201 return 2; /* indeterminate */
pcercuei 0:03b5121a232e 4202 else if (and_mask & 2) {
pcercuei 0:03b5121a232e 4203 if (x->value.date.mon < y->value.date.mon)
pcercuei 0:03b5121a232e 4204 return -1;
pcercuei 0:03b5121a232e 4205 else if (x->value.date.mon > y->value.date.mon)
pcercuei 0:03b5121a232e 4206 return 1;
pcercuei 0:03b5121a232e 4207 }
pcercuei 0:03b5121a232e 4208
pcercuei 0:03b5121a232e 4209 /* day */
pcercuei 0:03b5121a232e 4210 if (xor_mask & 4)
pcercuei 0:03b5121a232e 4211 return 2; /* indeterminate */
pcercuei 0:03b5121a232e 4212 else if (and_mask & 4) {
pcercuei 0:03b5121a232e 4213 if (x->value.date.day < y->value.date.day)
pcercuei 0:03b5121a232e 4214 return -1;
pcercuei 0:03b5121a232e 4215 else if (x->value.date.day > y->value.date.day)
pcercuei 0:03b5121a232e 4216 return 1;
pcercuei 0:03b5121a232e 4217 }
pcercuei 0:03b5121a232e 4218
pcercuei 0:03b5121a232e 4219 /* time */
pcercuei 0:03b5121a232e 4220 if (xor_mask & 8)
pcercuei 0:03b5121a232e 4221 return 2; /* indeterminate */
pcercuei 0:03b5121a232e 4222 else if (and_mask & 8) {
pcercuei 0:03b5121a232e 4223 if (x->value.date.hour < y->value.date.hour)
pcercuei 0:03b5121a232e 4224 return -1;
pcercuei 0:03b5121a232e 4225 else if (x->value.date.hour > y->value.date.hour)
pcercuei 0:03b5121a232e 4226 return 1;
pcercuei 0:03b5121a232e 4227 else if (x->value.date.min < y->value.date.min)
pcercuei 0:03b5121a232e 4228 return -1;
pcercuei 0:03b5121a232e 4229 else if (x->value.date.min > y->value.date.min)
pcercuei 0:03b5121a232e 4230 return 1;
pcercuei 0:03b5121a232e 4231 else if (x->value.date.sec < y->value.date.sec)
pcercuei 0:03b5121a232e 4232 return -1;
pcercuei 0:03b5121a232e 4233 else if (x->value.date.sec > y->value.date.sec)
pcercuei 0:03b5121a232e 4234 return 1;
pcercuei 0:03b5121a232e 4235 }
pcercuei 0:03b5121a232e 4236
pcercuei 0:03b5121a232e 4237 return 0;
pcercuei 0:03b5121a232e 4238 }
pcercuei 0:03b5121a232e 4239
pcercuei 0:03b5121a232e 4240 /**
pcercuei 0:03b5121a232e 4241 * xmlSchemaComparePreserveReplaceStrings:
pcercuei 0:03b5121a232e 4242 * @x: a first string value
pcercuei 0:03b5121a232e 4243 * @y: a second string value
pcercuei 0:03b5121a232e 4244 * @invert: inverts the result if x < y or x > y.
pcercuei 0:03b5121a232e 4245 *
pcercuei 0:03b5121a232e 4246 * Compare 2 string for their normalized values.
pcercuei 0:03b5121a232e 4247 * @x is a string with whitespace of "preserve", @y is
pcercuei 0:03b5121a232e 4248 * a string with a whitespace of "replace". I.e. @x could
pcercuei 0:03b5121a232e 4249 * be an "xsd:string" and @y an "xsd:normalizedString".
pcercuei 0:03b5121a232e 4250 *
pcercuei 0:03b5121a232e 4251 * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
pcercuei 0:03b5121a232e 4252 * case of error
pcercuei 0:03b5121a232e 4253 */
pcercuei 0:03b5121a232e 4254 static int
pcercuei 0:03b5121a232e 4255 xmlSchemaComparePreserveReplaceStrings(const xmlChar *x,
pcercuei 0:03b5121a232e 4256 const xmlChar *y,
pcercuei 0:03b5121a232e 4257 int invert)
pcercuei 0:03b5121a232e 4258 {
pcercuei 0:03b5121a232e 4259 int tmp;
pcercuei 0:03b5121a232e 4260
pcercuei 0:03b5121a232e 4261 while ((*x != 0) && (*y != 0)) {
pcercuei 0:03b5121a232e 4262 if (IS_WSP_REPLACE_CH(*y)) {
pcercuei 0:03b5121a232e 4263 if (! IS_WSP_SPACE_CH(*x)) {
pcercuei 0:03b5121a232e 4264 if ((*x - 0x20) < 0) {
pcercuei 0:03b5121a232e 4265 if (invert)
pcercuei 0:03b5121a232e 4266 return(1);
pcercuei 0:03b5121a232e 4267 else
pcercuei 0:03b5121a232e 4268 return(-1);
pcercuei 0:03b5121a232e 4269 } else {
pcercuei 0:03b5121a232e 4270 if (invert)
pcercuei 0:03b5121a232e 4271 return(-1);
pcercuei 0:03b5121a232e 4272 else
pcercuei 0:03b5121a232e 4273 return(1);
pcercuei 0:03b5121a232e 4274 }
pcercuei 0:03b5121a232e 4275 }
pcercuei 0:03b5121a232e 4276 } else {
pcercuei 0:03b5121a232e 4277 tmp = *x - *y;
pcercuei 0:03b5121a232e 4278 if (tmp < 0) {
pcercuei 0:03b5121a232e 4279 if (invert)
pcercuei 0:03b5121a232e 4280 return(1);
pcercuei 0:03b5121a232e 4281 else
pcercuei 0:03b5121a232e 4282 return(-1);
pcercuei 0:03b5121a232e 4283 }
pcercuei 0:03b5121a232e 4284 if (tmp > 0) {
pcercuei 0:03b5121a232e 4285 if (invert)
pcercuei 0:03b5121a232e 4286 return(-1);
pcercuei 0:03b5121a232e 4287 else
pcercuei 0:03b5121a232e 4288 return(1);
pcercuei 0:03b5121a232e 4289 }
pcercuei 0:03b5121a232e 4290 }
pcercuei 0:03b5121a232e 4291 x++;
pcercuei 0:03b5121a232e 4292 y++;
pcercuei 0:03b5121a232e 4293 }
pcercuei 0:03b5121a232e 4294 if (*x != 0) {
pcercuei 0:03b5121a232e 4295 if (invert)
pcercuei 0:03b5121a232e 4296 return(-1);
pcercuei 0:03b5121a232e 4297 else
pcercuei 0:03b5121a232e 4298 return(1);
pcercuei 0:03b5121a232e 4299 }
pcercuei 0:03b5121a232e 4300 if (*y != 0) {
pcercuei 0:03b5121a232e 4301 if (invert)
pcercuei 0:03b5121a232e 4302 return(1);
pcercuei 0:03b5121a232e 4303 else
pcercuei 0:03b5121a232e 4304 return(-1);
pcercuei 0:03b5121a232e 4305 }
pcercuei 0:03b5121a232e 4306 return(0);
pcercuei 0:03b5121a232e 4307 }
pcercuei 0:03b5121a232e 4308
pcercuei 0:03b5121a232e 4309 /**
pcercuei 0:03b5121a232e 4310 * xmlSchemaComparePreserveCollapseStrings:
pcercuei 0:03b5121a232e 4311 * @x: a first string value
pcercuei 0:03b5121a232e 4312 * @y: a second string value
pcercuei 0:03b5121a232e 4313 *
pcercuei 0:03b5121a232e 4314 * Compare 2 string for their normalized values.
pcercuei 0:03b5121a232e 4315 * @x is a string with whitespace of "preserve", @y is
pcercuei 0:03b5121a232e 4316 * a string with a whitespace of "collapse". I.e. @x could
pcercuei 0:03b5121a232e 4317 * be an "xsd:string" and @y an "xsd:normalizedString".
pcercuei 0:03b5121a232e 4318 *
pcercuei 0:03b5121a232e 4319 * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
pcercuei 0:03b5121a232e 4320 * case of error
pcercuei 0:03b5121a232e 4321 */
pcercuei 0:03b5121a232e 4322 static int
pcercuei 0:03b5121a232e 4323 xmlSchemaComparePreserveCollapseStrings(const xmlChar *x,
pcercuei 0:03b5121a232e 4324 const xmlChar *y,
pcercuei 0:03b5121a232e 4325 int invert)
pcercuei 0:03b5121a232e 4326 {
pcercuei 0:03b5121a232e 4327 int tmp;
pcercuei 0:03b5121a232e 4328
pcercuei 0:03b5121a232e 4329 /*
pcercuei 0:03b5121a232e 4330 * Skip leading blank chars of the collapsed string.
pcercuei 0:03b5121a232e 4331 */
pcercuei 0:03b5121a232e 4332 while IS_WSP_BLANK_CH(*y)
pcercuei 0:03b5121a232e 4333 y++;
pcercuei 0:03b5121a232e 4334
pcercuei 0:03b5121a232e 4335 while ((*x != 0) && (*y != 0)) {
pcercuei 0:03b5121a232e 4336 if IS_WSP_BLANK_CH(*y) {
pcercuei 0:03b5121a232e 4337 if (! IS_WSP_SPACE_CH(*x)) {
pcercuei 0:03b5121a232e 4338 /*
pcercuei 0:03b5121a232e 4339 * The yv character would have been replaced to 0x20.
pcercuei 0:03b5121a232e 4340 */
pcercuei 0:03b5121a232e 4341 if ((*x - 0x20) < 0) {
pcercuei 0:03b5121a232e 4342 if (invert)
pcercuei 0:03b5121a232e 4343 return(1);
pcercuei 0:03b5121a232e 4344 else
pcercuei 0:03b5121a232e 4345 return(-1);
pcercuei 0:03b5121a232e 4346 } else {
pcercuei 0:03b5121a232e 4347 if (invert)
pcercuei 0:03b5121a232e 4348 return(-1);
pcercuei 0:03b5121a232e 4349 else
pcercuei 0:03b5121a232e 4350 return(1);
pcercuei 0:03b5121a232e 4351 }
pcercuei 0:03b5121a232e 4352 }
pcercuei 0:03b5121a232e 4353 x++;
pcercuei 0:03b5121a232e 4354 y++;
pcercuei 0:03b5121a232e 4355 /*
pcercuei 0:03b5121a232e 4356 * Skip contiguous blank chars of the collapsed string.
pcercuei 0:03b5121a232e 4357 */
pcercuei 0:03b5121a232e 4358 while IS_WSP_BLANK_CH(*y)
pcercuei 0:03b5121a232e 4359 y++;
pcercuei 0:03b5121a232e 4360 } else {
pcercuei 0:03b5121a232e 4361 tmp = *x++ - *y++;
pcercuei 0:03b5121a232e 4362 if (tmp < 0) {
pcercuei 0:03b5121a232e 4363 if (invert)
pcercuei 0:03b5121a232e 4364 return(1);
pcercuei 0:03b5121a232e 4365 else
pcercuei 0:03b5121a232e 4366 return(-1);
pcercuei 0:03b5121a232e 4367 }
pcercuei 0:03b5121a232e 4368 if (tmp > 0) {
pcercuei 0:03b5121a232e 4369 if (invert)
pcercuei 0:03b5121a232e 4370 return(-1);
pcercuei 0:03b5121a232e 4371 else
pcercuei 0:03b5121a232e 4372 return(1);
pcercuei 0:03b5121a232e 4373 }
pcercuei 0:03b5121a232e 4374 }
pcercuei 0:03b5121a232e 4375 }
pcercuei 0:03b5121a232e 4376 if (*x != 0) {
pcercuei 0:03b5121a232e 4377 if (invert)
pcercuei 0:03b5121a232e 4378 return(-1);
pcercuei 0:03b5121a232e 4379 else
pcercuei 0:03b5121a232e 4380 return(1);
pcercuei 0:03b5121a232e 4381 }
pcercuei 0:03b5121a232e 4382 if (*y != 0) {
pcercuei 0:03b5121a232e 4383 /*
pcercuei 0:03b5121a232e 4384 * Skip trailing blank chars of the collapsed string.
pcercuei 0:03b5121a232e 4385 */
pcercuei 0:03b5121a232e 4386 while IS_WSP_BLANK_CH(*y)
pcercuei 0:03b5121a232e 4387 y++;
pcercuei 0:03b5121a232e 4388 if (*y != 0) {
pcercuei 0:03b5121a232e 4389 if (invert)
pcercuei 0:03b5121a232e 4390 return(1);
pcercuei 0:03b5121a232e 4391 else
pcercuei 0:03b5121a232e 4392 return(-1);
pcercuei 0:03b5121a232e 4393 }
pcercuei 0:03b5121a232e 4394 }
pcercuei 0:03b5121a232e 4395 return(0);
pcercuei 0:03b5121a232e 4396 }
pcercuei 0:03b5121a232e 4397
pcercuei 0:03b5121a232e 4398 /**
pcercuei 0:03b5121a232e 4399 * xmlSchemaComparePreserveCollapseStrings:
pcercuei 0:03b5121a232e 4400 * @x: a first string value
pcercuei 0:03b5121a232e 4401 * @y: a second string value
pcercuei 0:03b5121a232e 4402 *
pcercuei 0:03b5121a232e 4403 * Compare 2 string for their normalized values.
pcercuei 0:03b5121a232e 4404 * @x is a string with whitespace of "preserve", @y is
pcercuei 0:03b5121a232e 4405 * a string with a whitespace of "collapse". I.e. @x could
pcercuei 0:03b5121a232e 4406 * be an "xsd:string" and @y an "xsd:normalizedString".
pcercuei 0:03b5121a232e 4407 *
pcercuei 0:03b5121a232e 4408 * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
pcercuei 0:03b5121a232e 4409 * case of error
pcercuei 0:03b5121a232e 4410 */
pcercuei 0:03b5121a232e 4411 static int
pcercuei 0:03b5121a232e 4412 xmlSchemaCompareReplaceCollapseStrings(const xmlChar *x,
pcercuei 0:03b5121a232e 4413 const xmlChar *y,
pcercuei 0:03b5121a232e 4414 int invert)
pcercuei 0:03b5121a232e 4415 {
pcercuei 0:03b5121a232e 4416 int tmp;
pcercuei 0:03b5121a232e 4417
pcercuei 0:03b5121a232e 4418 /*
pcercuei 0:03b5121a232e 4419 * Skip leading blank chars of the collapsed string.
pcercuei 0:03b5121a232e 4420 */
pcercuei 0:03b5121a232e 4421 while IS_WSP_BLANK_CH(*y)
pcercuei 0:03b5121a232e 4422 y++;
pcercuei 0:03b5121a232e 4423
pcercuei 0:03b5121a232e 4424 while ((*x != 0) && (*y != 0)) {
pcercuei 0:03b5121a232e 4425 if IS_WSP_BLANK_CH(*y) {
pcercuei 0:03b5121a232e 4426 if (! IS_WSP_BLANK_CH(*x)) {
pcercuei 0:03b5121a232e 4427 /*
pcercuei 0:03b5121a232e 4428 * The yv character would have been replaced to 0x20.
pcercuei 0:03b5121a232e 4429 */
pcercuei 0:03b5121a232e 4430 if ((*x - 0x20) < 0) {
pcercuei 0:03b5121a232e 4431 if (invert)
pcercuei 0:03b5121a232e 4432 return(1);
pcercuei 0:03b5121a232e 4433 else
pcercuei 0:03b5121a232e 4434 return(-1);
pcercuei 0:03b5121a232e 4435 } else {
pcercuei 0:03b5121a232e 4436 if (invert)
pcercuei 0:03b5121a232e 4437 return(-1);
pcercuei 0:03b5121a232e 4438 else
pcercuei 0:03b5121a232e 4439 return(1);
pcercuei 0:03b5121a232e 4440 }
pcercuei 0:03b5121a232e 4441 }
pcercuei 0:03b5121a232e 4442 x++;
pcercuei 0:03b5121a232e 4443 y++;
pcercuei 0:03b5121a232e 4444 /*
pcercuei 0:03b5121a232e 4445 * Skip contiguous blank chars of the collapsed string.
pcercuei 0:03b5121a232e 4446 */
pcercuei 0:03b5121a232e 4447 while IS_WSP_BLANK_CH(*y)
pcercuei 0:03b5121a232e 4448 y++;
pcercuei 0:03b5121a232e 4449 } else {
pcercuei 0:03b5121a232e 4450 if IS_WSP_BLANK_CH(*x) {
pcercuei 0:03b5121a232e 4451 /*
pcercuei 0:03b5121a232e 4452 * The xv character would have been replaced to 0x20.
pcercuei 0:03b5121a232e 4453 */
pcercuei 0:03b5121a232e 4454 if ((0x20 - *y) < 0) {
pcercuei 0:03b5121a232e 4455 if (invert)
pcercuei 0:03b5121a232e 4456 return(1);
pcercuei 0:03b5121a232e 4457 else
pcercuei 0:03b5121a232e 4458 return(-1);
pcercuei 0:03b5121a232e 4459 } else {
pcercuei 0:03b5121a232e 4460 if (invert)
pcercuei 0:03b5121a232e 4461 return(-1);
pcercuei 0:03b5121a232e 4462 else
pcercuei 0:03b5121a232e 4463 return(1);
pcercuei 0:03b5121a232e 4464 }
pcercuei 0:03b5121a232e 4465 }
pcercuei 0:03b5121a232e 4466 tmp = *x++ - *y++;
pcercuei 0:03b5121a232e 4467 if (tmp < 0)
pcercuei 0:03b5121a232e 4468 return(-1);
pcercuei 0:03b5121a232e 4469 if (tmp > 0)
pcercuei 0:03b5121a232e 4470 return(1);
pcercuei 0:03b5121a232e 4471 }
pcercuei 0:03b5121a232e 4472 }
pcercuei 0:03b5121a232e 4473 if (*x != 0) {
pcercuei 0:03b5121a232e 4474 if (invert)
pcercuei 0:03b5121a232e 4475 return(-1);
pcercuei 0:03b5121a232e 4476 else
pcercuei 0:03b5121a232e 4477 return(1);
pcercuei 0:03b5121a232e 4478 }
pcercuei 0:03b5121a232e 4479 if (*y != 0) {
pcercuei 0:03b5121a232e 4480 /*
pcercuei 0:03b5121a232e 4481 * Skip trailing blank chars of the collapsed string.
pcercuei 0:03b5121a232e 4482 */
pcercuei 0:03b5121a232e 4483 while IS_WSP_BLANK_CH(*y)
pcercuei 0:03b5121a232e 4484 y++;
pcercuei 0:03b5121a232e 4485 if (*y != 0) {
pcercuei 0:03b5121a232e 4486 if (invert)
pcercuei 0:03b5121a232e 4487 return(1);
pcercuei 0:03b5121a232e 4488 else
pcercuei 0:03b5121a232e 4489 return(-1);
pcercuei 0:03b5121a232e 4490 }
pcercuei 0:03b5121a232e 4491 }
pcercuei 0:03b5121a232e 4492 return(0);
pcercuei 0:03b5121a232e 4493 }
pcercuei 0:03b5121a232e 4494
pcercuei 0:03b5121a232e 4495
pcercuei 0:03b5121a232e 4496 /**
pcercuei 0:03b5121a232e 4497 * xmlSchemaCompareReplacedStrings:
pcercuei 0:03b5121a232e 4498 * @x: a first string value
pcercuei 0:03b5121a232e 4499 * @y: a second string value
pcercuei 0:03b5121a232e 4500 *
pcercuei 0:03b5121a232e 4501 * Compare 2 string for their normalized values.
pcercuei 0:03b5121a232e 4502 *
pcercuei 0:03b5121a232e 4503 * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
pcercuei 0:03b5121a232e 4504 * case of error
pcercuei 0:03b5121a232e 4505 */
pcercuei 0:03b5121a232e 4506 static int
pcercuei 0:03b5121a232e 4507 xmlSchemaCompareReplacedStrings(const xmlChar *x,
pcercuei 0:03b5121a232e 4508 const xmlChar *y)
pcercuei 0:03b5121a232e 4509 {
pcercuei 0:03b5121a232e 4510 int tmp;
pcercuei 0:03b5121a232e 4511
pcercuei 0:03b5121a232e 4512 while ((*x != 0) && (*y != 0)) {
pcercuei 0:03b5121a232e 4513 if IS_WSP_BLANK_CH(*y) {
pcercuei 0:03b5121a232e 4514 if (! IS_WSP_BLANK_CH(*x)) {
pcercuei 0:03b5121a232e 4515 if ((*x - 0x20) < 0)
pcercuei 0:03b5121a232e 4516 return(-1);
pcercuei 0:03b5121a232e 4517 else
pcercuei 0:03b5121a232e 4518 return(1);
pcercuei 0:03b5121a232e 4519 }
pcercuei 0:03b5121a232e 4520 } else {
pcercuei 0:03b5121a232e 4521 if IS_WSP_BLANK_CH(*x) {
pcercuei 0:03b5121a232e 4522 if ((0x20 - *y) < 0)
pcercuei 0:03b5121a232e 4523 return(-1);
pcercuei 0:03b5121a232e 4524 else
pcercuei 0:03b5121a232e 4525 return(1);
pcercuei 0:03b5121a232e 4526 }
pcercuei 0:03b5121a232e 4527 tmp = *x - *y;
pcercuei 0:03b5121a232e 4528 if (tmp < 0)
pcercuei 0:03b5121a232e 4529 return(-1);
pcercuei 0:03b5121a232e 4530 if (tmp > 0)
pcercuei 0:03b5121a232e 4531 return(1);
pcercuei 0:03b5121a232e 4532 }
pcercuei 0:03b5121a232e 4533 x++;
pcercuei 0:03b5121a232e 4534 y++;
pcercuei 0:03b5121a232e 4535 }
pcercuei 0:03b5121a232e 4536 if (*x != 0)
pcercuei 0:03b5121a232e 4537 return(1);
pcercuei 0:03b5121a232e 4538 if (*y != 0)
pcercuei 0:03b5121a232e 4539 return(-1);
pcercuei 0:03b5121a232e 4540 return(0);
pcercuei 0:03b5121a232e 4541 }
pcercuei 0:03b5121a232e 4542
pcercuei 0:03b5121a232e 4543 /**
pcercuei 0:03b5121a232e 4544 * xmlSchemaCompareNormStrings:
pcercuei 0:03b5121a232e 4545 * @x: a first string value
pcercuei 0:03b5121a232e 4546 * @y: a second string value
pcercuei 0:03b5121a232e 4547 *
pcercuei 0:03b5121a232e 4548 * Compare 2 string for their normalized values.
pcercuei 0:03b5121a232e 4549 *
pcercuei 0:03b5121a232e 4550 * Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
pcercuei 0:03b5121a232e 4551 * case of error
pcercuei 0:03b5121a232e 4552 */
pcercuei 0:03b5121a232e 4553 static int
pcercuei 0:03b5121a232e 4554 xmlSchemaCompareNormStrings(const xmlChar *x,
pcercuei 0:03b5121a232e 4555 const xmlChar *y) {
pcercuei 0:03b5121a232e 4556 int tmp;
pcercuei 0:03b5121a232e 4557
pcercuei 0:03b5121a232e 4558 while (IS_BLANK_CH(*x)) x++;
pcercuei 0:03b5121a232e 4559 while (IS_BLANK_CH(*y)) y++;
pcercuei 0:03b5121a232e 4560 while ((*x != 0) && (*y != 0)) {
pcercuei 0:03b5121a232e 4561 if (IS_BLANK_CH(*x)) {
pcercuei 0:03b5121a232e 4562 if (!IS_BLANK_CH(*y)) {
pcercuei 0:03b5121a232e 4563 tmp = *x - *y;
pcercuei 0:03b5121a232e 4564 return(tmp);
pcercuei 0:03b5121a232e 4565 }
pcercuei 0:03b5121a232e 4566 while (IS_BLANK_CH(*x)) x++;
pcercuei 0:03b5121a232e 4567 while (IS_BLANK_CH(*y)) y++;
pcercuei 0:03b5121a232e 4568 } else {
pcercuei 0:03b5121a232e 4569 tmp = *x++ - *y++;
pcercuei 0:03b5121a232e 4570 if (tmp < 0)
pcercuei 0:03b5121a232e 4571 return(-1);
pcercuei 0:03b5121a232e 4572 if (tmp > 0)
pcercuei 0:03b5121a232e 4573 return(1);
pcercuei 0:03b5121a232e 4574 }
pcercuei 0:03b5121a232e 4575 }
pcercuei 0:03b5121a232e 4576 if (*x != 0) {
pcercuei 0:03b5121a232e 4577 while (IS_BLANK_CH(*x)) x++;
pcercuei 0:03b5121a232e 4578 if (*x != 0)
pcercuei 0:03b5121a232e 4579 return(1);
pcercuei 0:03b5121a232e 4580 }
pcercuei 0:03b5121a232e 4581 if (*y != 0) {
pcercuei 0:03b5121a232e 4582 while (IS_BLANK_CH(*y)) y++;
pcercuei 0:03b5121a232e 4583 if (*y != 0)
pcercuei 0:03b5121a232e 4584 return(-1);
pcercuei 0:03b5121a232e 4585 }
pcercuei 0:03b5121a232e 4586 return(0);
pcercuei 0:03b5121a232e 4587 }
pcercuei 0:03b5121a232e 4588
pcercuei 0:03b5121a232e 4589 /**
pcercuei 0:03b5121a232e 4590 * xmlSchemaCompareFloats:
pcercuei 0:03b5121a232e 4591 * @x: a first float or double value
pcercuei 0:03b5121a232e 4592 * @y: a second float or double value
pcercuei 0:03b5121a232e 4593 *
pcercuei 0:03b5121a232e 4594 * Compare 2 values
pcercuei 0:03b5121a232e 4595 *
pcercuei 0:03b5121a232e 4596 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
pcercuei 0:03b5121a232e 4597 * case of error
pcercuei 0:03b5121a232e 4598 */
pcercuei 0:03b5121a232e 4599 static int
pcercuei 0:03b5121a232e 4600 xmlSchemaCompareFloats(xmlSchemaValPtr x, xmlSchemaValPtr y) {
pcercuei 0:03b5121a232e 4601 double d1, d2;
pcercuei 0:03b5121a232e 4602
pcercuei 0:03b5121a232e 4603 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4604 return(-2);
pcercuei 0:03b5121a232e 4605
pcercuei 0:03b5121a232e 4606 /*
pcercuei 0:03b5121a232e 4607 * Cast everything to doubles.
pcercuei 0:03b5121a232e 4608 */
pcercuei 0:03b5121a232e 4609 if (x->type == XML_SCHEMAS_DOUBLE)
pcercuei 0:03b5121a232e 4610 d1 = x->value.d;
pcercuei 0:03b5121a232e 4611 else if (x->type == XML_SCHEMAS_FLOAT)
pcercuei 0:03b5121a232e 4612 d1 = x->value.f;
pcercuei 0:03b5121a232e 4613 else
pcercuei 0:03b5121a232e 4614 return(-2);
pcercuei 0:03b5121a232e 4615
pcercuei 0:03b5121a232e 4616 if (y->type == XML_SCHEMAS_DOUBLE)
pcercuei 0:03b5121a232e 4617 d2 = y->value.d;
pcercuei 0:03b5121a232e 4618 else if (y->type == XML_SCHEMAS_FLOAT)
pcercuei 0:03b5121a232e 4619 d2 = y->value.f;
pcercuei 0:03b5121a232e 4620 else
pcercuei 0:03b5121a232e 4621 return(-2);
pcercuei 0:03b5121a232e 4622
pcercuei 0:03b5121a232e 4623 /*
pcercuei 0:03b5121a232e 4624 * Check for special cases.
pcercuei 0:03b5121a232e 4625 */
pcercuei 0:03b5121a232e 4626 if (xmlXPathIsNaN(d1)) {
pcercuei 0:03b5121a232e 4627 if (xmlXPathIsNaN(d2))
pcercuei 0:03b5121a232e 4628 return(0);
pcercuei 0:03b5121a232e 4629 return(1);
pcercuei 0:03b5121a232e 4630 }
pcercuei 0:03b5121a232e 4631 if (xmlXPathIsNaN(d2))
pcercuei 0:03b5121a232e 4632 return(-1);
pcercuei 0:03b5121a232e 4633 if (d1 == xmlXPathPINF) {
pcercuei 0:03b5121a232e 4634 if (d2 == xmlXPathPINF)
pcercuei 0:03b5121a232e 4635 return(0);
pcercuei 0:03b5121a232e 4636 return(1);
pcercuei 0:03b5121a232e 4637 }
pcercuei 0:03b5121a232e 4638 if (d2 == xmlXPathPINF)
pcercuei 0:03b5121a232e 4639 return(-1);
pcercuei 0:03b5121a232e 4640 if (d1 == xmlXPathNINF) {
pcercuei 0:03b5121a232e 4641 if (d2 == xmlXPathNINF)
pcercuei 0:03b5121a232e 4642 return(0);
pcercuei 0:03b5121a232e 4643 return(-1);
pcercuei 0:03b5121a232e 4644 }
pcercuei 0:03b5121a232e 4645 if (d2 == xmlXPathNINF)
pcercuei 0:03b5121a232e 4646 return(1);
pcercuei 0:03b5121a232e 4647
pcercuei 0:03b5121a232e 4648 /*
pcercuei 0:03b5121a232e 4649 * basic tests, the last one we should have equality, but
pcercuei 0:03b5121a232e 4650 * portability is more important than speed and handling
pcercuei 0:03b5121a232e 4651 * NaN or Inf in a portable way is always a challenge, so ...
pcercuei 0:03b5121a232e 4652 */
pcercuei 0:03b5121a232e 4653 if (d1 < d2)
pcercuei 0:03b5121a232e 4654 return(-1);
pcercuei 0:03b5121a232e 4655 if (d1 > d2)
pcercuei 0:03b5121a232e 4656 return(1);
pcercuei 0:03b5121a232e 4657 if (d1 == d2)
pcercuei 0:03b5121a232e 4658 return(0);
pcercuei 0:03b5121a232e 4659 return(2);
pcercuei 0:03b5121a232e 4660 }
pcercuei 0:03b5121a232e 4661
pcercuei 0:03b5121a232e 4662 /**
pcercuei 0:03b5121a232e 4663 * xmlSchemaCompareValues:
pcercuei 0:03b5121a232e 4664 * @x: a first value
pcercuei 0:03b5121a232e 4665 * @xvalue: the first value as a string (optional)
pcercuei 0:03b5121a232e 4666 * @xwtsp: the whitespace type
pcercuei 0:03b5121a232e 4667 * @y: a second value
pcercuei 0:03b5121a232e 4668 * @xvalue: the second value as a string (optional)
pcercuei 0:03b5121a232e 4669 * @ywtsp: the whitespace type
pcercuei 0:03b5121a232e 4670 *
pcercuei 0:03b5121a232e 4671 * Compare 2 values
pcercuei 0:03b5121a232e 4672 *
pcercuei 0:03b5121a232e 4673 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, 3 if not
pcercuei 0:03b5121a232e 4674 * comparable and -2 in case of error
pcercuei 0:03b5121a232e 4675 */
pcercuei 0:03b5121a232e 4676 static int
pcercuei 0:03b5121a232e 4677 xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
pcercuei 0:03b5121a232e 4678 xmlSchemaValPtr x,
pcercuei 0:03b5121a232e 4679 const xmlChar *xvalue,
pcercuei 0:03b5121a232e 4680 xmlSchemaWhitespaceValueType xws,
pcercuei 0:03b5121a232e 4681 xmlSchemaValType ytype,
pcercuei 0:03b5121a232e 4682 xmlSchemaValPtr y,
pcercuei 0:03b5121a232e 4683 const xmlChar *yvalue,
pcercuei 0:03b5121a232e 4684 xmlSchemaWhitespaceValueType yws)
pcercuei 0:03b5121a232e 4685 {
pcercuei 0:03b5121a232e 4686 switch (xtype) {
pcercuei 0:03b5121a232e 4687 case XML_SCHEMAS_UNKNOWN:
pcercuei 0:03b5121a232e 4688 case XML_SCHEMAS_ANYTYPE:
pcercuei 0:03b5121a232e 4689 return(-2);
pcercuei 0:03b5121a232e 4690 case XML_SCHEMAS_INTEGER:
pcercuei 0:03b5121a232e 4691 case XML_SCHEMAS_NPINTEGER:
pcercuei 0:03b5121a232e 4692 case XML_SCHEMAS_NINTEGER:
pcercuei 0:03b5121a232e 4693 case XML_SCHEMAS_NNINTEGER:
pcercuei 0:03b5121a232e 4694 case XML_SCHEMAS_PINTEGER:
pcercuei 0:03b5121a232e 4695 case XML_SCHEMAS_INT:
pcercuei 0:03b5121a232e 4696 case XML_SCHEMAS_UINT:
pcercuei 0:03b5121a232e 4697 case XML_SCHEMAS_LONG:
pcercuei 0:03b5121a232e 4698 case XML_SCHEMAS_ULONG:
pcercuei 0:03b5121a232e 4699 case XML_SCHEMAS_SHORT:
pcercuei 0:03b5121a232e 4700 case XML_SCHEMAS_USHORT:
pcercuei 0:03b5121a232e 4701 case XML_SCHEMAS_BYTE:
pcercuei 0:03b5121a232e 4702 case XML_SCHEMAS_UBYTE:
pcercuei 0:03b5121a232e 4703 case XML_SCHEMAS_DECIMAL:
pcercuei 0:03b5121a232e 4704 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4705 return(-2);
pcercuei 0:03b5121a232e 4706 if (ytype == xtype)
pcercuei 0:03b5121a232e 4707 return(xmlSchemaCompareDecimals(x, y));
pcercuei 0:03b5121a232e 4708 if ((ytype == XML_SCHEMAS_DECIMAL) ||
pcercuei 0:03b5121a232e 4709 (ytype == XML_SCHEMAS_INTEGER) ||
pcercuei 0:03b5121a232e 4710 (ytype == XML_SCHEMAS_NPINTEGER) ||
pcercuei 0:03b5121a232e 4711 (ytype == XML_SCHEMAS_NINTEGER) ||
pcercuei 0:03b5121a232e 4712 (ytype == XML_SCHEMAS_NNINTEGER) ||
pcercuei 0:03b5121a232e 4713 (ytype == XML_SCHEMAS_PINTEGER) ||
pcercuei 0:03b5121a232e 4714 (ytype == XML_SCHEMAS_INT) ||
pcercuei 0:03b5121a232e 4715 (ytype == XML_SCHEMAS_UINT) ||
pcercuei 0:03b5121a232e 4716 (ytype == XML_SCHEMAS_LONG) ||
pcercuei 0:03b5121a232e 4717 (ytype == XML_SCHEMAS_ULONG) ||
pcercuei 0:03b5121a232e 4718 (ytype == XML_SCHEMAS_SHORT) ||
pcercuei 0:03b5121a232e 4719 (ytype == XML_SCHEMAS_USHORT) ||
pcercuei 0:03b5121a232e 4720 (ytype == XML_SCHEMAS_BYTE) ||
pcercuei 0:03b5121a232e 4721 (ytype == XML_SCHEMAS_UBYTE))
pcercuei 0:03b5121a232e 4722 return(xmlSchemaCompareDecimals(x, y));
pcercuei 0:03b5121a232e 4723 return(-2);
pcercuei 0:03b5121a232e 4724 case XML_SCHEMAS_DURATION:
pcercuei 0:03b5121a232e 4725 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4726 return(-2);
pcercuei 0:03b5121a232e 4727 if (ytype == XML_SCHEMAS_DURATION)
pcercuei 0:03b5121a232e 4728 return(xmlSchemaCompareDurations(x, y));
pcercuei 0:03b5121a232e 4729 return(-2);
pcercuei 0:03b5121a232e 4730 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 4731 case XML_SCHEMAS_GDAY:
pcercuei 0:03b5121a232e 4732 case XML_SCHEMAS_GMONTH:
pcercuei 0:03b5121a232e 4733 case XML_SCHEMAS_GMONTHDAY:
pcercuei 0:03b5121a232e 4734 case XML_SCHEMAS_GYEAR:
pcercuei 0:03b5121a232e 4735 case XML_SCHEMAS_GYEARMONTH:
pcercuei 0:03b5121a232e 4736 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 4737 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 4738 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4739 return(-2);
pcercuei 0:03b5121a232e 4740 if ((ytype == XML_SCHEMAS_DATETIME) ||
pcercuei 0:03b5121a232e 4741 (ytype == XML_SCHEMAS_TIME) ||
pcercuei 0:03b5121a232e 4742 (ytype == XML_SCHEMAS_GDAY) ||
pcercuei 0:03b5121a232e 4743 (ytype == XML_SCHEMAS_GMONTH) ||
pcercuei 0:03b5121a232e 4744 (ytype == XML_SCHEMAS_GMONTHDAY) ||
pcercuei 0:03b5121a232e 4745 (ytype == XML_SCHEMAS_GYEAR) ||
pcercuei 0:03b5121a232e 4746 (ytype == XML_SCHEMAS_DATE) ||
pcercuei 0:03b5121a232e 4747 (ytype == XML_SCHEMAS_GYEARMONTH))
pcercuei 0:03b5121a232e 4748 return (xmlSchemaCompareDates(x, y));
pcercuei 0:03b5121a232e 4749 return (-2);
pcercuei 0:03b5121a232e 4750 /*
pcercuei 0:03b5121a232e 4751 * Note that we will support comparison of string types against
pcercuei 0:03b5121a232e 4752 * anySimpleType as well.
pcercuei 0:03b5121a232e 4753 */
pcercuei 0:03b5121a232e 4754 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 4755 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 4756 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 4757 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 4758 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 4759 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 4760 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 4761 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 4762 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 4763 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 4764 case XML_SCHEMAS_ENTITY:
pcercuei 0:03b5121a232e 4765 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 4766 {
pcercuei 0:03b5121a232e 4767 const xmlChar *xv, *yv;
pcercuei 0:03b5121a232e 4768
pcercuei 0:03b5121a232e 4769 if (x == NULL)
pcercuei 0:03b5121a232e 4770 xv = xvalue;
pcercuei 0:03b5121a232e 4771 else
pcercuei 0:03b5121a232e 4772 xv = x->value.str;
pcercuei 0:03b5121a232e 4773 if (y == NULL)
pcercuei 0:03b5121a232e 4774 yv = yvalue;
pcercuei 0:03b5121a232e 4775 else
pcercuei 0:03b5121a232e 4776 yv = y->value.str;
pcercuei 0:03b5121a232e 4777 /*
pcercuei 0:03b5121a232e 4778 * TODO: Compare those against QName.
pcercuei 0:03b5121a232e 4779 */
pcercuei 0:03b5121a232e 4780 if (ytype == XML_SCHEMAS_QNAME) {
pcercuei 0:03b5121a232e 4781 TODO
pcercuei 0:03b5121a232e 4782 if (y == NULL)
pcercuei 0:03b5121a232e 4783 return(-2);
pcercuei 0:03b5121a232e 4784 return (-2);
pcercuei 0:03b5121a232e 4785 }
pcercuei 0:03b5121a232e 4786 if ((ytype == XML_SCHEMAS_ANYSIMPLETYPE) ||
pcercuei 0:03b5121a232e 4787 (ytype == XML_SCHEMAS_STRING) ||
pcercuei 0:03b5121a232e 4788 (ytype == XML_SCHEMAS_NORMSTRING) ||
pcercuei 0:03b5121a232e 4789 (ytype == XML_SCHEMAS_TOKEN) ||
pcercuei 0:03b5121a232e 4790 (ytype == XML_SCHEMAS_LANGUAGE) ||
pcercuei 0:03b5121a232e 4791 (ytype == XML_SCHEMAS_NMTOKEN) ||
pcercuei 0:03b5121a232e 4792 (ytype == XML_SCHEMAS_NAME) ||
pcercuei 0:03b5121a232e 4793 (ytype == XML_SCHEMAS_NCNAME) ||
pcercuei 0:03b5121a232e 4794 (ytype == XML_SCHEMAS_ID) ||
pcercuei 0:03b5121a232e 4795 (ytype == XML_SCHEMAS_IDREF) ||
pcercuei 0:03b5121a232e 4796 (ytype == XML_SCHEMAS_ENTITY) ||
pcercuei 0:03b5121a232e 4797 (ytype == XML_SCHEMAS_ANYURI)) {
pcercuei 0:03b5121a232e 4798
pcercuei 0:03b5121a232e 4799 if (xws == XML_SCHEMA_WHITESPACE_PRESERVE) {
pcercuei 0:03b5121a232e 4800
pcercuei 0:03b5121a232e 4801 if (yws == XML_SCHEMA_WHITESPACE_PRESERVE) {
pcercuei 0:03b5121a232e 4802 /* TODO: What about x < y or x > y. */
pcercuei 0:03b5121a232e 4803 if (xmlStrEqual(xv, yv))
pcercuei 0:03b5121a232e 4804 return (0);
pcercuei 0:03b5121a232e 4805 else
pcercuei 0:03b5121a232e 4806 return (2);
pcercuei 0:03b5121a232e 4807 } else if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 4808 return (xmlSchemaComparePreserveReplaceStrings(xv, yv, 0));
pcercuei 0:03b5121a232e 4809 else if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 4810 return (xmlSchemaComparePreserveCollapseStrings(xv, yv, 0));
pcercuei 0:03b5121a232e 4811
pcercuei 0:03b5121a232e 4812 } else if (xws == XML_SCHEMA_WHITESPACE_REPLACE) {
pcercuei 0:03b5121a232e 4813
pcercuei 0:03b5121a232e 4814 if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
pcercuei 0:03b5121a232e 4815 return (xmlSchemaComparePreserveReplaceStrings(yv, xv, 1));
pcercuei 0:03b5121a232e 4816 if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 4817 return (xmlSchemaCompareReplacedStrings(xv, yv));
pcercuei 0:03b5121a232e 4818 if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 4819 return (xmlSchemaCompareReplaceCollapseStrings(xv, yv, 0));
pcercuei 0:03b5121a232e 4820
pcercuei 0:03b5121a232e 4821 } else if (xws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
pcercuei 0:03b5121a232e 4822
pcercuei 0:03b5121a232e 4823 if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
pcercuei 0:03b5121a232e 4824 return (xmlSchemaComparePreserveCollapseStrings(yv, xv, 1));
pcercuei 0:03b5121a232e 4825 if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 4826 return (xmlSchemaCompareReplaceCollapseStrings(yv, xv, 1));
pcercuei 0:03b5121a232e 4827 if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 4828 return (xmlSchemaCompareNormStrings(xv, yv));
pcercuei 0:03b5121a232e 4829 } else
pcercuei 0:03b5121a232e 4830 return (-2);
pcercuei 0:03b5121a232e 4831
pcercuei 0:03b5121a232e 4832 }
pcercuei 0:03b5121a232e 4833 return (-2);
pcercuei 0:03b5121a232e 4834 }
pcercuei 0:03b5121a232e 4835 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 4836 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 4837 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4838 return(-2);
pcercuei 0:03b5121a232e 4839 if ((ytype == XML_SCHEMAS_QNAME) ||
pcercuei 0:03b5121a232e 4840 (ytype == XML_SCHEMAS_NOTATION)) {
pcercuei 0:03b5121a232e 4841 if ((xmlStrEqual(x->value.qname.name, y->value.qname.name)) &&
pcercuei 0:03b5121a232e 4842 (xmlStrEqual(x->value.qname.uri, y->value.qname.uri)))
pcercuei 0:03b5121a232e 4843 return(0);
pcercuei 0:03b5121a232e 4844 return(2);
pcercuei 0:03b5121a232e 4845 }
pcercuei 0:03b5121a232e 4846 return (-2);
pcercuei 0:03b5121a232e 4847 case XML_SCHEMAS_FLOAT:
pcercuei 0:03b5121a232e 4848 case XML_SCHEMAS_DOUBLE:
pcercuei 0:03b5121a232e 4849 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4850 return(-2);
pcercuei 0:03b5121a232e 4851 if ((ytype == XML_SCHEMAS_FLOAT) ||
pcercuei 0:03b5121a232e 4852 (ytype == XML_SCHEMAS_DOUBLE))
pcercuei 0:03b5121a232e 4853 return (xmlSchemaCompareFloats(x, y));
pcercuei 0:03b5121a232e 4854 return (-2);
pcercuei 0:03b5121a232e 4855 case XML_SCHEMAS_BOOLEAN:
pcercuei 0:03b5121a232e 4856 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4857 return(-2);
pcercuei 0:03b5121a232e 4858 if (ytype == XML_SCHEMAS_BOOLEAN) {
pcercuei 0:03b5121a232e 4859 if (x->value.b == y->value.b)
pcercuei 0:03b5121a232e 4860 return(0);
pcercuei 0:03b5121a232e 4861 if (x->value.b == 0)
pcercuei 0:03b5121a232e 4862 return(-1);
pcercuei 0:03b5121a232e 4863 return(1);
pcercuei 0:03b5121a232e 4864 }
pcercuei 0:03b5121a232e 4865 return (-2);
pcercuei 0:03b5121a232e 4866 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 4867 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4868 return(-2);
pcercuei 0:03b5121a232e 4869 if (ytype == XML_SCHEMAS_HEXBINARY) {
pcercuei 0:03b5121a232e 4870 if (x->value.hex.total == y->value.hex.total) {
pcercuei 0:03b5121a232e 4871 int ret = xmlStrcmp(x->value.hex.str, y->value.hex.str);
pcercuei 0:03b5121a232e 4872 if (ret > 0)
pcercuei 0:03b5121a232e 4873 return(1);
pcercuei 0:03b5121a232e 4874 else if (ret == 0)
pcercuei 0:03b5121a232e 4875 return(0);
pcercuei 0:03b5121a232e 4876 }
pcercuei 0:03b5121a232e 4877 else if (x->value.hex.total > y->value.hex.total)
pcercuei 0:03b5121a232e 4878 return(1);
pcercuei 0:03b5121a232e 4879
pcercuei 0:03b5121a232e 4880 return(-1);
pcercuei 0:03b5121a232e 4881 }
pcercuei 0:03b5121a232e 4882 return (-2);
pcercuei 0:03b5121a232e 4883 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 4884 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4885 return(-2);
pcercuei 0:03b5121a232e 4886 if (ytype == XML_SCHEMAS_BASE64BINARY) {
pcercuei 0:03b5121a232e 4887 if (x->value.base64.total == y->value.base64.total) {
pcercuei 0:03b5121a232e 4888 int ret = xmlStrcmp(x->value.base64.str,
pcercuei 0:03b5121a232e 4889 y->value.base64.str);
pcercuei 0:03b5121a232e 4890 if (ret > 0)
pcercuei 0:03b5121a232e 4891 return(1);
pcercuei 0:03b5121a232e 4892 else if (ret == 0)
pcercuei 0:03b5121a232e 4893 return(0);
pcercuei 0:03b5121a232e 4894 else
pcercuei 0:03b5121a232e 4895 return(-1);
pcercuei 0:03b5121a232e 4896 }
pcercuei 0:03b5121a232e 4897 else if (x->value.base64.total > y->value.base64.total)
pcercuei 0:03b5121a232e 4898 return(1);
pcercuei 0:03b5121a232e 4899 else
pcercuei 0:03b5121a232e 4900 return(-1);
pcercuei 0:03b5121a232e 4901 }
pcercuei 0:03b5121a232e 4902 return (-2);
pcercuei 0:03b5121a232e 4903 case XML_SCHEMAS_IDREFS:
pcercuei 0:03b5121a232e 4904 case XML_SCHEMAS_ENTITIES:
pcercuei 0:03b5121a232e 4905 case XML_SCHEMAS_NMTOKENS:
pcercuei 0:03b5121a232e 4906 TODO
pcercuei 0:03b5121a232e 4907 break;
pcercuei 0:03b5121a232e 4908 }
pcercuei 0:03b5121a232e 4909 return -2;
pcercuei 0:03b5121a232e 4910 }
pcercuei 0:03b5121a232e 4911
pcercuei 0:03b5121a232e 4912 /**
pcercuei 0:03b5121a232e 4913 * xmlSchemaCompareValues:
pcercuei 0:03b5121a232e 4914 * @x: a first value
pcercuei 0:03b5121a232e 4915 * @y: a second value
pcercuei 0:03b5121a232e 4916 *
pcercuei 0:03b5121a232e 4917 * Compare 2 values
pcercuei 0:03b5121a232e 4918 *
pcercuei 0:03b5121a232e 4919 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
pcercuei 0:03b5121a232e 4920 * case of error
pcercuei 0:03b5121a232e 4921 */
pcercuei 0:03b5121a232e 4922 int
pcercuei 0:03b5121a232e 4923 xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
pcercuei 0:03b5121a232e 4924 xmlSchemaWhitespaceValueType xws, yws;
pcercuei 0:03b5121a232e 4925
pcercuei 0:03b5121a232e 4926 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4927 return(-2);
pcercuei 0:03b5121a232e 4928 if (x->type == XML_SCHEMAS_STRING)
pcercuei 0:03b5121a232e 4929 xws = XML_SCHEMA_WHITESPACE_PRESERVE;
pcercuei 0:03b5121a232e 4930 else if (x->type == XML_SCHEMAS_NORMSTRING)
pcercuei 0:03b5121a232e 4931 xws = XML_SCHEMA_WHITESPACE_REPLACE;
pcercuei 0:03b5121a232e 4932 else
pcercuei 0:03b5121a232e 4933 xws = XML_SCHEMA_WHITESPACE_COLLAPSE;
pcercuei 0:03b5121a232e 4934
pcercuei 0:03b5121a232e 4935 if (y->type == XML_SCHEMAS_STRING)
pcercuei 0:03b5121a232e 4936 yws = XML_SCHEMA_WHITESPACE_PRESERVE;
pcercuei 0:03b5121a232e 4937 else if (y->type == XML_SCHEMAS_NORMSTRING)
pcercuei 0:03b5121a232e 4938 yws = XML_SCHEMA_WHITESPACE_REPLACE;
pcercuei 0:03b5121a232e 4939 else
pcercuei 0:03b5121a232e 4940 yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
pcercuei 0:03b5121a232e 4941
pcercuei 0:03b5121a232e 4942 return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
pcercuei 0:03b5121a232e 4943 y, NULL, yws));
pcercuei 0:03b5121a232e 4944 }
pcercuei 0:03b5121a232e 4945
pcercuei 0:03b5121a232e 4946 /**
pcercuei 0:03b5121a232e 4947 * xmlSchemaCompareValuesWhtsp:
pcercuei 0:03b5121a232e 4948 * @x: a first value
pcercuei 0:03b5121a232e 4949 * @xws: the whitespace value of x
pcercuei 0:03b5121a232e 4950 * @y: a second value
pcercuei 0:03b5121a232e 4951 * @yws: the whitespace value of y
pcercuei 0:03b5121a232e 4952 *
pcercuei 0:03b5121a232e 4953 * Compare 2 values
pcercuei 0:03b5121a232e 4954 *
pcercuei 0:03b5121a232e 4955 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
pcercuei 0:03b5121a232e 4956 * case of error
pcercuei 0:03b5121a232e 4957 */
pcercuei 0:03b5121a232e 4958 int
pcercuei 0:03b5121a232e 4959 xmlSchemaCompareValuesWhtsp(xmlSchemaValPtr x,
pcercuei 0:03b5121a232e 4960 xmlSchemaWhitespaceValueType xws,
pcercuei 0:03b5121a232e 4961 xmlSchemaValPtr y,
pcercuei 0:03b5121a232e 4962 xmlSchemaWhitespaceValueType yws)
pcercuei 0:03b5121a232e 4963 {
pcercuei 0:03b5121a232e 4964 if ((x == NULL) || (y == NULL))
pcercuei 0:03b5121a232e 4965 return(-2);
pcercuei 0:03b5121a232e 4966 return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
pcercuei 0:03b5121a232e 4967 y, NULL, yws));
pcercuei 0:03b5121a232e 4968 }
pcercuei 0:03b5121a232e 4969
pcercuei 0:03b5121a232e 4970 /**
pcercuei 0:03b5121a232e 4971 * xmlSchemaCompareValuesWhtspExt:
pcercuei 0:03b5121a232e 4972 * @x: a first value
pcercuei 0:03b5121a232e 4973 * @xws: the whitespace value of x
pcercuei 0:03b5121a232e 4974 * @y: a second value
pcercuei 0:03b5121a232e 4975 * @yws: the whitespace value of y
pcercuei 0:03b5121a232e 4976 *
pcercuei 0:03b5121a232e 4977 * Compare 2 values
pcercuei 0:03b5121a232e 4978 *
pcercuei 0:03b5121a232e 4979 * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
pcercuei 0:03b5121a232e 4980 * case of error
pcercuei 0:03b5121a232e 4981 */
pcercuei 0:03b5121a232e 4982 static int
pcercuei 0:03b5121a232e 4983 xmlSchemaCompareValuesWhtspExt(xmlSchemaValType xtype,
pcercuei 0:03b5121a232e 4984 xmlSchemaValPtr x,
pcercuei 0:03b5121a232e 4985 const xmlChar *xvalue,
pcercuei 0:03b5121a232e 4986 xmlSchemaWhitespaceValueType xws,
pcercuei 0:03b5121a232e 4987 xmlSchemaValType ytype,
pcercuei 0:03b5121a232e 4988 xmlSchemaValPtr y,
pcercuei 0:03b5121a232e 4989 const xmlChar *yvalue,
pcercuei 0:03b5121a232e 4990 xmlSchemaWhitespaceValueType yws)
pcercuei 0:03b5121a232e 4991 {
pcercuei 0:03b5121a232e 4992 return(xmlSchemaCompareValuesInternal(xtype, x, xvalue, xws, ytype, y,
pcercuei 0:03b5121a232e 4993 yvalue, yws));
pcercuei 0:03b5121a232e 4994 }
pcercuei 0:03b5121a232e 4995
pcercuei 0:03b5121a232e 4996 /**
pcercuei 0:03b5121a232e 4997 * xmlSchemaNormLen:
pcercuei 0:03b5121a232e 4998 * @value: a string
pcercuei 0:03b5121a232e 4999 *
pcercuei 0:03b5121a232e 5000 * Computes the UTF8 length of the normalized value of the string
pcercuei 0:03b5121a232e 5001 *
pcercuei 0:03b5121a232e 5002 * Returns the length or -1 in case of error.
pcercuei 0:03b5121a232e 5003 */
pcercuei 0:03b5121a232e 5004 static int
pcercuei 0:03b5121a232e 5005 xmlSchemaNormLen(const xmlChar *value) {
pcercuei 0:03b5121a232e 5006 const xmlChar *utf;
pcercuei 0:03b5121a232e 5007 int ret = 0;
pcercuei 0:03b5121a232e 5008
pcercuei 0:03b5121a232e 5009 if (value == NULL)
pcercuei 0:03b5121a232e 5010 return(-1);
pcercuei 0:03b5121a232e 5011 utf = value;
pcercuei 0:03b5121a232e 5012 while (IS_BLANK_CH(*utf)) utf++;
pcercuei 0:03b5121a232e 5013 while (*utf != 0) {
pcercuei 0:03b5121a232e 5014 if (utf[0] & 0x80) {
pcercuei 0:03b5121a232e 5015 if ((utf[1] & 0xc0) != 0x80)
pcercuei 0:03b5121a232e 5016 return(-1);
pcercuei 0:03b5121a232e 5017 if ((utf[0] & 0xe0) == 0xe0) {
pcercuei 0:03b5121a232e 5018 if ((utf[2] & 0xc0) != 0x80)
pcercuei 0:03b5121a232e 5019 return(-1);
pcercuei 0:03b5121a232e 5020 if ((utf[0] & 0xf0) == 0xf0) {
pcercuei 0:03b5121a232e 5021 if ((utf[0] & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
pcercuei 0:03b5121a232e 5022 return(-1);
pcercuei 0:03b5121a232e 5023 utf += 4;
pcercuei 0:03b5121a232e 5024 } else {
pcercuei 0:03b5121a232e 5025 utf += 3;
pcercuei 0:03b5121a232e 5026 }
pcercuei 0:03b5121a232e 5027 } else {
pcercuei 0:03b5121a232e 5028 utf += 2;
pcercuei 0:03b5121a232e 5029 }
pcercuei 0:03b5121a232e 5030 } else if (IS_BLANK_CH(*utf)) {
pcercuei 0:03b5121a232e 5031 while (IS_BLANK_CH(*utf)) utf++;
pcercuei 0:03b5121a232e 5032 if (*utf == 0)
pcercuei 0:03b5121a232e 5033 break;
pcercuei 0:03b5121a232e 5034 } else {
pcercuei 0:03b5121a232e 5035 utf++;
pcercuei 0:03b5121a232e 5036 }
pcercuei 0:03b5121a232e 5037 ret++;
pcercuei 0:03b5121a232e 5038 }
pcercuei 0:03b5121a232e 5039 return(ret);
pcercuei 0:03b5121a232e 5040 }
pcercuei 0:03b5121a232e 5041
pcercuei 0:03b5121a232e 5042 /**
pcercuei 0:03b5121a232e 5043 * xmlSchemaGetFacetValueAsULong:
pcercuei 0:03b5121a232e 5044 * @facet: an schemas type facet
pcercuei 0:03b5121a232e 5045 *
pcercuei 0:03b5121a232e 5046 * Extract the value of a facet
pcercuei 0:03b5121a232e 5047 *
pcercuei 0:03b5121a232e 5048 * Returns the value as a long
pcercuei 0:03b5121a232e 5049 */
pcercuei 0:03b5121a232e 5050 unsigned long
pcercuei 0:03b5121a232e 5051 xmlSchemaGetFacetValueAsULong(xmlSchemaFacetPtr facet)
pcercuei 0:03b5121a232e 5052 {
pcercuei 0:03b5121a232e 5053 /*
pcercuei 0:03b5121a232e 5054 * TODO: Check if this is a decimal.
pcercuei 0:03b5121a232e 5055 */
pcercuei 0:03b5121a232e 5056 if (facet == NULL)
pcercuei 0:03b5121a232e 5057 return 0;
pcercuei 0:03b5121a232e 5058 return ((unsigned long) facet->val->value.decimal.lo);
pcercuei 0:03b5121a232e 5059 }
pcercuei 0:03b5121a232e 5060
pcercuei 0:03b5121a232e 5061 /**
pcercuei 0:03b5121a232e 5062 * xmlSchemaValidateListSimpleTypeFacet:
pcercuei 0:03b5121a232e 5063 * @facet: the facet to check
pcercuei 0:03b5121a232e 5064 * @value: the lexical repr of the value to validate
pcercuei 0:03b5121a232e 5065 * @actualLen: the number of list items
pcercuei 0:03b5121a232e 5066 * @expectedLen: the resulting expected number of list items
pcercuei 0:03b5121a232e 5067 *
pcercuei 0:03b5121a232e 5068 * Checks the value of a list simple type against a facet.
pcercuei 0:03b5121a232e 5069 *
pcercuei 0:03b5121a232e 5070 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 5071 * number otherwise and -1 in case of an internal error.
pcercuei 0:03b5121a232e 5072 */
pcercuei 0:03b5121a232e 5073 int
pcercuei 0:03b5121a232e 5074 xmlSchemaValidateListSimpleTypeFacet(xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5075 const xmlChar *value,
pcercuei 0:03b5121a232e 5076 unsigned long actualLen,
pcercuei 0:03b5121a232e 5077 unsigned long *expectedLen)
pcercuei 0:03b5121a232e 5078 {
pcercuei 0:03b5121a232e 5079 if (facet == NULL)
pcercuei 0:03b5121a232e 5080 return(-1);
pcercuei 0:03b5121a232e 5081 /*
pcercuei 0:03b5121a232e 5082 * TODO: Check if this will work with large numbers.
pcercuei 0:03b5121a232e 5083 * (compare value.decimal.mi and value.decimal.hi as well?).
pcercuei 0:03b5121a232e 5084 */
pcercuei 0:03b5121a232e 5085 if (facet->type == XML_SCHEMA_FACET_LENGTH) {
pcercuei 0:03b5121a232e 5086 if (actualLen != facet->val->value.decimal.lo) {
pcercuei 0:03b5121a232e 5087 if (expectedLen != NULL)
pcercuei 0:03b5121a232e 5088 *expectedLen = facet->val->value.decimal.lo;
pcercuei 0:03b5121a232e 5089 return (XML_SCHEMAV_CVC_LENGTH_VALID);
pcercuei 0:03b5121a232e 5090 }
pcercuei 0:03b5121a232e 5091 } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
pcercuei 0:03b5121a232e 5092 if (actualLen < facet->val->value.decimal.lo) {
pcercuei 0:03b5121a232e 5093 if (expectedLen != NULL)
pcercuei 0:03b5121a232e 5094 *expectedLen = facet->val->value.decimal.lo;
pcercuei 0:03b5121a232e 5095 return (XML_SCHEMAV_CVC_MINLENGTH_VALID);
pcercuei 0:03b5121a232e 5096 }
pcercuei 0:03b5121a232e 5097 } else if (facet->type == XML_SCHEMA_FACET_MAXLENGTH) {
pcercuei 0:03b5121a232e 5098 if (actualLen > facet->val->value.decimal.lo) {
pcercuei 0:03b5121a232e 5099 if (expectedLen != NULL)
pcercuei 0:03b5121a232e 5100 *expectedLen = facet->val->value.decimal.lo;
pcercuei 0:03b5121a232e 5101 return (XML_SCHEMAV_CVC_MAXLENGTH_VALID);
pcercuei 0:03b5121a232e 5102 }
pcercuei 0:03b5121a232e 5103 } else
pcercuei 0:03b5121a232e 5104 /*
pcercuei 0:03b5121a232e 5105 * NOTE: That we can pass NULL as xmlSchemaValPtr to
pcercuei 0:03b5121a232e 5106 * xmlSchemaValidateFacet, since the remaining facet types
pcercuei 0:03b5121a232e 5107 * are: XML_SCHEMA_FACET_PATTERN, XML_SCHEMA_FACET_ENUMERATION.
pcercuei 0:03b5121a232e 5108 */
pcercuei 0:03b5121a232e 5109 return(xmlSchemaValidateFacet(NULL, facet, value, NULL));
pcercuei 0:03b5121a232e 5110 return (0);
pcercuei 0:03b5121a232e 5111 }
pcercuei 0:03b5121a232e 5112
pcercuei 0:03b5121a232e 5113 /**
pcercuei 0:03b5121a232e 5114 * xmlSchemaValidateLengthFacet:
pcercuei 0:03b5121a232e 5115 * @type: the built-in type
pcercuei 0:03b5121a232e 5116 * @facet: the facet to check
pcercuei 0:03b5121a232e 5117 * @value: the lexical repr. of the value to be validated
pcercuei 0:03b5121a232e 5118 * @val: the precomputed value
pcercuei 0:03b5121a232e 5119 * @ws: the whitespace type of the value
pcercuei 0:03b5121a232e 5120 * @length: the actual length of the value
pcercuei 0:03b5121a232e 5121 *
pcercuei 0:03b5121a232e 5122 * Checka a value against a "length", "minLength" and "maxLength"
pcercuei 0:03b5121a232e 5123 * facet; sets @length to the computed length of @value.
pcercuei 0:03b5121a232e 5124 *
pcercuei 0:03b5121a232e 5125 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 5126 * otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 5127 */
pcercuei 0:03b5121a232e 5128 static int
pcercuei 0:03b5121a232e 5129 xmlSchemaValidateLengthFacetInternal(xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5130 xmlSchemaValType valType,
pcercuei 0:03b5121a232e 5131 const xmlChar *value,
pcercuei 0:03b5121a232e 5132 xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 5133 unsigned long *length,
pcercuei 0:03b5121a232e 5134 xmlSchemaWhitespaceValueType ws)
pcercuei 0:03b5121a232e 5135 {
pcercuei 0:03b5121a232e 5136 unsigned int len = 0;
pcercuei 0:03b5121a232e 5137
pcercuei 0:03b5121a232e 5138 if ((length == NULL) || (facet == NULL))
pcercuei 0:03b5121a232e 5139 return (-1);
pcercuei 0:03b5121a232e 5140 *length = 0;
pcercuei 0:03b5121a232e 5141 if ((facet->type != XML_SCHEMA_FACET_LENGTH) &&
pcercuei 0:03b5121a232e 5142 (facet->type != XML_SCHEMA_FACET_MAXLENGTH) &&
pcercuei 0:03b5121a232e 5143 (facet->type != XML_SCHEMA_FACET_MINLENGTH))
pcercuei 0:03b5121a232e 5144 return (-1);
pcercuei 0:03b5121a232e 5145
pcercuei 0:03b5121a232e 5146 /*
pcercuei 0:03b5121a232e 5147 * TODO: length, maxLength and minLength must be of type
pcercuei 0:03b5121a232e 5148 * nonNegativeInteger only. Check if decimal is used somehow.
pcercuei 0:03b5121a232e 5149 */
pcercuei 0:03b5121a232e 5150 if ((facet->val == NULL) ||
pcercuei 0:03b5121a232e 5151 ((facet->val->type != XML_SCHEMAS_DECIMAL) &&
pcercuei 0:03b5121a232e 5152 (facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
pcercuei 0:03b5121a232e 5153 (facet->val->value.decimal.frac != 0)) {
pcercuei 0:03b5121a232e 5154 return(-1);
pcercuei 0:03b5121a232e 5155 }
pcercuei 0:03b5121a232e 5156 if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
pcercuei 0:03b5121a232e 5157 len = val->value.hex.total;
pcercuei 0:03b5121a232e 5158 else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
pcercuei 0:03b5121a232e 5159 len = val->value.base64.total;
pcercuei 0:03b5121a232e 5160 else {
pcercuei 0:03b5121a232e 5161 switch (valType) {
pcercuei 0:03b5121a232e 5162 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 5163 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 5164 if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
pcercuei 0:03b5121a232e 5165 /*
pcercuei 0:03b5121a232e 5166 * This is to ensure API compatibility with the old
pcercuei 0:03b5121a232e 5167 * xmlSchemaValidateLengthFacet(). Anyway, this was and
pcercuei 0:03b5121a232e 5168 * is not the correct handling.
pcercuei 0:03b5121a232e 5169 * TODO: Get rid of this case somehow.
pcercuei 0:03b5121a232e 5170 */
pcercuei 0:03b5121a232e 5171 if (valType == XML_SCHEMAS_STRING)
pcercuei 0:03b5121a232e 5172 len = xmlUTF8Strlen(value);
pcercuei 0:03b5121a232e 5173 else
pcercuei 0:03b5121a232e 5174 len = xmlSchemaNormLen(value);
pcercuei 0:03b5121a232e 5175 } else if (value != NULL) {
pcercuei 0:03b5121a232e 5176 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 5177 len = xmlSchemaNormLen(value);
pcercuei 0:03b5121a232e 5178 else
pcercuei 0:03b5121a232e 5179 /*
pcercuei 0:03b5121a232e 5180 * Should be OK for "preserve" as well.
pcercuei 0:03b5121a232e 5181 */
pcercuei 0:03b5121a232e 5182 len = xmlUTF8Strlen(value);
pcercuei 0:03b5121a232e 5183 }
pcercuei 0:03b5121a232e 5184 break;
pcercuei 0:03b5121a232e 5185 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 5186 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 5187 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 5188 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 5189 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 5190 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 5191 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 5192 /*
pcercuei 0:03b5121a232e 5193 * FIXME: What exactly to do with anyURI?
pcercuei 0:03b5121a232e 5194 */
pcercuei 0:03b5121a232e 5195 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 5196 if (value != NULL)
pcercuei 0:03b5121a232e 5197 len = xmlSchemaNormLen(value);
pcercuei 0:03b5121a232e 5198 break;
pcercuei 0:03b5121a232e 5199 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 5200 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 5201 /*
pcercuei 0:03b5121a232e 5202 * For QName and NOTATION, those facets are
pcercuei 0:03b5121a232e 5203 * deprecated and should be ignored.
pcercuei 0:03b5121a232e 5204 */
pcercuei 0:03b5121a232e 5205 return (0);
pcercuei 0:03b5121a232e 5206 default:
pcercuei 0:03b5121a232e 5207 TODO
pcercuei 0:03b5121a232e 5208 }
pcercuei 0:03b5121a232e 5209 }
pcercuei 0:03b5121a232e 5210 *length = (unsigned long) len;
pcercuei 0:03b5121a232e 5211 /*
pcercuei 0:03b5121a232e 5212 * TODO: Return the whole expected value, i.e. "lo", "mi" and "hi".
pcercuei 0:03b5121a232e 5213 */
pcercuei 0:03b5121a232e 5214 if (facet->type == XML_SCHEMA_FACET_LENGTH) {
pcercuei 0:03b5121a232e 5215 if (len != facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5216 return(XML_SCHEMAV_CVC_LENGTH_VALID);
pcercuei 0:03b5121a232e 5217 } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
pcercuei 0:03b5121a232e 5218 if (len < facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5219 return(XML_SCHEMAV_CVC_MINLENGTH_VALID);
pcercuei 0:03b5121a232e 5220 } else {
pcercuei 0:03b5121a232e 5221 if (len > facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5222 return(XML_SCHEMAV_CVC_MAXLENGTH_VALID);
pcercuei 0:03b5121a232e 5223 }
pcercuei 0:03b5121a232e 5224
pcercuei 0:03b5121a232e 5225 return (0);
pcercuei 0:03b5121a232e 5226 }
pcercuei 0:03b5121a232e 5227
pcercuei 0:03b5121a232e 5228 /**
pcercuei 0:03b5121a232e 5229 * xmlSchemaValidateLengthFacet:
pcercuei 0:03b5121a232e 5230 * @type: the built-in type
pcercuei 0:03b5121a232e 5231 * @facet: the facet to check
pcercuei 0:03b5121a232e 5232 * @value: the lexical repr. of the value to be validated
pcercuei 0:03b5121a232e 5233 * @val: the precomputed value
pcercuei 0:03b5121a232e 5234 * @length: the actual length of the value
pcercuei 0:03b5121a232e 5235 *
pcercuei 0:03b5121a232e 5236 * Checka a value against a "length", "minLength" and "maxLength"
pcercuei 0:03b5121a232e 5237 * facet; sets @length to the computed length of @value.
pcercuei 0:03b5121a232e 5238 *
pcercuei 0:03b5121a232e 5239 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 5240 * otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 5241 */
pcercuei 0:03b5121a232e 5242 int
pcercuei 0:03b5121a232e 5243 xmlSchemaValidateLengthFacet(xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 5244 xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5245 const xmlChar *value,
pcercuei 0:03b5121a232e 5246 xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 5247 unsigned long *length)
pcercuei 0:03b5121a232e 5248 {
pcercuei 0:03b5121a232e 5249 if (type == NULL)
pcercuei 0:03b5121a232e 5250 return(-1);
pcercuei 0:03b5121a232e 5251 return (xmlSchemaValidateLengthFacetInternal(facet,
pcercuei 0:03b5121a232e 5252 type->builtInType, value, val, length,
pcercuei 0:03b5121a232e 5253 XML_SCHEMA_WHITESPACE_UNKNOWN));
pcercuei 0:03b5121a232e 5254 }
pcercuei 0:03b5121a232e 5255
pcercuei 0:03b5121a232e 5256 /**
pcercuei 0:03b5121a232e 5257 * xmlSchemaValidateLengthFacetWhtsp:
pcercuei 0:03b5121a232e 5258 * @facet: the facet to check
pcercuei 0:03b5121a232e 5259 * @valType: the built-in type
pcercuei 0:03b5121a232e 5260 * @value: the lexical repr. of the value to be validated
pcercuei 0:03b5121a232e 5261 * @val: the precomputed value
pcercuei 0:03b5121a232e 5262 * @ws: the whitespace type of the value
pcercuei 0:03b5121a232e 5263 * @length: the actual length of the value
pcercuei 0:03b5121a232e 5264 *
pcercuei 0:03b5121a232e 5265 * Checka a value against a "length", "minLength" and "maxLength"
pcercuei 0:03b5121a232e 5266 * facet; sets @length to the computed length of @value.
pcercuei 0:03b5121a232e 5267 *
pcercuei 0:03b5121a232e 5268 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 5269 * otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 5270 */
pcercuei 0:03b5121a232e 5271 int
pcercuei 0:03b5121a232e 5272 xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5273 xmlSchemaValType valType,
pcercuei 0:03b5121a232e 5274 const xmlChar *value,
pcercuei 0:03b5121a232e 5275 xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 5276 unsigned long *length,
pcercuei 0:03b5121a232e 5277 xmlSchemaWhitespaceValueType ws)
pcercuei 0:03b5121a232e 5278 {
pcercuei 0:03b5121a232e 5279 return (xmlSchemaValidateLengthFacetInternal(facet, valType, value, val,
pcercuei 0:03b5121a232e 5280 length, ws));
pcercuei 0:03b5121a232e 5281 }
pcercuei 0:03b5121a232e 5282
pcercuei 0:03b5121a232e 5283 /**
pcercuei 0:03b5121a232e 5284 * xmlSchemaValidateFacetInternal:
pcercuei 0:03b5121a232e 5285 * @facet: the facet to check
pcercuei 0:03b5121a232e 5286 * @fws: the whitespace type of the facet's value
pcercuei 0:03b5121a232e 5287 * @valType: the built-in type of the value
pcercuei 0:03b5121a232e 5288 * @value: the lexical repr of the value to validate
pcercuei 0:03b5121a232e 5289 * @val: the precomputed value
pcercuei 0:03b5121a232e 5290 * @ws: the whitespace type of the value
pcercuei 0:03b5121a232e 5291 *
pcercuei 0:03b5121a232e 5292 * Check a value against a facet condition
pcercuei 0:03b5121a232e 5293 *
pcercuei 0:03b5121a232e 5294 * Returns 0 if the element is schemas valid, a positive error code
pcercuei 0:03b5121a232e 5295 * number otherwise and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 5296 */
pcercuei 0:03b5121a232e 5297 static int
pcercuei 0:03b5121a232e 5298 xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5299 xmlSchemaWhitespaceValueType fws,
pcercuei 0:03b5121a232e 5300 xmlSchemaValType valType,
pcercuei 0:03b5121a232e 5301 const xmlChar *value,
pcercuei 0:03b5121a232e 5302 xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 5303 xmlSchemaWhitespaceValueType ws)
pcercuei 0:03b5121a232e 5304 {
pcercuei 0:03b5121a232e 5305 int ret;
pcercuei 0:03b5121a232e 5306
pcercuei 0:03b5121a232e 5307 if (facet == NULL)
pcercuei 0:03b5121a232e 5308 return(-1);
pcercuei 0:03b5121a232e 5309
pcercuei 0:03b5121a232e 5310 switch (facet->type) {
pcercuei 0:03b5121a232e 5311 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 5312 /*
pcercuei 0:03b5121a232e 5313 * NOTE that for patterns, the @value needs to be the normalized
pcercuei 0:03b5121a232e 5314 * value, *not* the lexical initial value or the canonical value.
pcercuei 0:03b5121a232e 5315 */
pcercuei 0:03b5121a232e 5316 if (value == NULL)
pcercuei 0:03b5121a232e 5317 return(-1);
pcercuei 0:03b5121a232e 5318 ret = xmlRegexpExec(facet->regexp, value);
pcercuei 0:03b5121a232e 5319 if (ret == 1)
pcercuei 0:03b5121a232e 5320 return(0);
pcercuei 0:03b5121a232e 5321 if (ret == 0)
pcercuei 0:03b5121a232e 5322 return(XML_SCHEMAV_CVC_PATTERN_VALID);
pcercuei 0:03b5121a232e 5323 return(ret);
pcercuei 0:03b5121a232e 5324 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 5325 ret = xmlSchemaCompareValues(val, facet->val);
pcercuei 0:03b5121a232e 5326 if (ret == -2)
pcercuei 0:03b5121a232e 5327 return(-1);
pcercuei 0:03b5121a232e 5328 if (ret == -1)
pcercuei 0:03b5121a232e 5329 return(0);
pcercuei 0:03b5121a232e 5330 return(XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID);
pcercuei 0:03b5121a232e 5331 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 5332 ret = xmlSchemaCompareValues(val, facet->val);
pcercuei 0:03b5121a232e 5333 if (ret == -2)
pcercuei 0:03b5121a232e 5334 return(-1);
pcercuei 0:03b5121a232e 5335 if ((ret == -1) || (ret == 0))
pcercuei 0:03b5121a232e 5336 return(0);
pcercuei 0:03b5121a232e 5337 return(XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID);
pcercuei 0:03b5121a232e 5338 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 5339 ret = xmlSchemaCompareValues(val, facet->val);
pcercuei 0:03b5121a232e 5340 if (ret == -2)
pcercuei 0:03b5121a232e 5341 return(-1);
pcercuei 0:03b5121a232e 5342 if (ret == 1)
pcercuei 0:03b5121a232e 5343 return(0);
pcercuei 0:03b5121a232e 5344 return(XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID);
pcercuei 0:03b5121a232e 5345 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 5346 ret = xmlSchemaCompareValues(val, facet->val);
pcercuei 0:03b5121a232e 5347 if (ret == -2)
pcercuei 0:03b5121a232e 5348 return(-1);
pcercuei 0:03b5121a232e 5349 if ((ret == 1) || (ret == 0))
pcercuei 0:03b5121a232e 5350 return(0);
pcercuei 0:03b5121a232e 5351 return(XML_SCHEMAV_CVC_MININCLUSIVE_VALID);
pcercuei 0:03b5121a232e 5352 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 5353 /* TODO whitespaces */
pcercuei 0:03b5121a232e 5354 /*
pcercuei 0:03b5121a232e 5355 * NOTE: Whitespace should be handled to normalize
pcercuei 0:03b5121a232e 5356 * the value to be validated against a the facets;
pcercuei 0:03b5121a232e 5357 * not to normalize the value in-between.
pcercuei 0:03b5121a232e 5358 */
pcercuei 0:03b5121a232e 5359 return(0);
pcercuei 0:03b5121a232e 5360 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 5361 if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
pcercuei 0:03b5121a232e 5362 /*
pcercuei 0:03b5121a232e 5363 * This is to ensure API compatibility with the old
pcercuei 0:03b5121a232e 5364 * xmlSchemaValidateFacet().
pcercuei 0:03b5121a232e 5365 * TODO: Get rid of this case.
pcercuei 0:03b5121a232e 5366 */
pcercuei 0:03b5121a232e 5367 if ((facet->value != NULL) &&
pcercuei 0:03b5121a232e 5368 (xmlStrEqual(facet->value, value)))
pcercuei 0:03b5121a232e 5369 return(0);
pcercuei 0:03b5121a232e 5370 } else {
pcercuei 0:03b5121a232e 5371 ret = xmlSchemaCompareValuesWhtspExt(facet->val->type,
pcercuei 0:03b5121a232e 5372 facet->val, facet->value, fws, valType, val,
pcercuei 0:03b5121a232e 5373 value, ws);
pcercuei 0:03b5121a232e 5374 if (ret == -2)
pcercuei 0:03b5121a232e 5375 return(-1);
pcercuei 0:03b5121a232e 5376 if (ret == 0)
pcercuei 0:03b5121a232e 5377 return(0);
pcercuei 0:03b5121a232e 5378 }
pcercuei 0:03b5121a232e 5379 return(XML_SCHEMAV_CVC_ENUMERATION_VALID);
pcercuei 0:03b5121a232e 5380 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 5381 /*
pcercuei 0:03b5121a232e 5382 * SPEC (1.3) "if {primitive type definition} is QName or NOTATION,
pcercuei 0:03b5121a232e 5383 * then any {value} is facet-valid."
pcercuei 0:03b5121a232e 5384 */
pcercuei 0:03b5121a232e 5385 if ((valType == XML_SCHEMAS_QNAME) ||
pcercuei 0:03b5121a232e 5386 (valType == XML_SCHEMAS_NOTATION))
pcercuei 0:03b5121a232e 5387 return (0);
pcercuei 0:03b5121a232e 5388 /* No break on purpose. */
pcercuei 0:03b5121a232e 5389 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 5390 case XML_SCHEMA_FACET_MINLENGTH: {
pcercuei 0:03b5121a232e 5391 unsigned int len = 0;
pcercuei 0:03b5121a232e 5392
pcercuei 0:03b5121a232e 5393 if ((valType == XML_SCHEMAS_QNAME) ||
pcercuei 0:03b5121a232e 5394 (valType == XML_SCHEMAS_NOTATION))
pcercuei 0:03b5121a232e 5395 return (0);
pcercuei 0:03b5121a232e 5396 /*
pcercuei 0:03b5121a232e 5397 * TODO: length, maxLength and minLength must be of type
pcercuei 0:03b5121a232e 5398 * nonNegativeInteger only. Check if decimal is used somehow.
pcercuei 0:03b5121a232e 5399 */
pcercuei 0:03b5121a232e 5400 if ((facet->val == NULL) ||
pcercuei 0:03b5121a232e 5401 ((facet->val->type != XML_SCHEMAS_DECIMAL) &&
pcercuei 0:03b5121a232e 5402 (facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
pcercuei 0:03b5121a232e 5403 (facet->val->value.decimal.frac != 0)) {
pcercuei 0:03b5121a232e 5404 return(-1);
pcercuei 0:03b5121a232e 5405 }
pcercuei 0:03b5121a232e 5406 if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
pcercuei 0:03b5121a232e 5407 len = val->value.hex.total;
pcercuei 0:03b5121a232e 5408 else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
pcercuei 0:03b5121a232e 5409 len = val->value.base64.total;
pcercuei 0:03b5121a232e 5410 else {
pcercuei 0:03b5121a232e 5411 switch (valType) {
pcercuei 0:03b5121a232e 5412 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 5413 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 5414 if (ws == XML_SCHEMA_WHITESPACE_UNKNOWN) {
pcercuei 0:03b5121a232e 5415 /*
pcercuei 0:03b5121a232e 5416 * This is to ensure API compatibility with the old
pcercuei 0:03b5121a232e 5417 * xmlSchemaValidateFacet(). Anyway, this was and
pcercuei 0:03b5121a232e 5418 * is not the correct handling.
pcercuei 0:03b5121a232e 5419 * TODO: Get rid of this case somehow.
pcercuei 0:03b5121a232e 5420 */
pcercuei 0:03b5121a232e 5421 if (valType == XML_SCHEMAS_STRING)
pcercuei 0:03b5121a232e 5422 len = xmlUTF8Strlen(value);
pcercuei 0:03b5121a232e 5423 else
pcercuei 0:03b5121a232e 5424 len = xmlSchemaNormLen(value);
pcercuei 0:03b5121a232e 5425 } else if (value != NULL) {
pcercuei 0:03b5121a232e 5426 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 5427 len = xmlSchemaNormLen(value);
pcercuei 0:03b5121a232e 5428 else
pcercuei 0:03b5121a232e 5429 /*
pcercuei 0:03b5121a232e 5430 * Should be OK for "preserve" as well.
pcercuei 0:03b5121a232e 5431 */
pcercuei 0:03b5121a232e 5432 len = xmlUTF8Strlen(value);
pcercuei 0:03b5121a232e 5433 }
pcercuei 0:03b5121a232e 5434 break;
pcercuei 0:03b5121a232e 5435 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 5436 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 5437 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 5438 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 5439 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 5440 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 5441 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 5442 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 5443 if (value != NULL)
pcercuei 0:03b5121a232e 5444 len = xmlSchemaNormLen(value);
pcercuei 0:03b5121a232e 5445 break;
pcercuei 0:03b5121a232e 5446 default:
pcercuei 0:03b5121a232e 5447 TODO
pcercuei 0:03b5121a232e 5448 }
pcercuei 0:03b5121a232e 5449 }
pcercuei 0:03b5121a232e 5450 if (facet->type == XML_SCHEMA_FACET_LENGTH) {
pcercuei 0:03b5121a232e 5451 if (len != facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5452 return(XML_SCHEMAV_CVC_LENGTH_VALID);
pcercuei 0:03b5121a232e 5453 } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) {
pcercuei 0:03b5121a232e 5454 if (len < facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5455 return(XML_SCHEMAV_CVC_MINLENGTH_VALID);
pcercuei 0:03b5121a232e 5456 } else {
pcercuei 0:03b5121a232e 5457 if (len > facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5458 return(XML_SCHEMAV_CVC_MAXLENGTH_VALID);
pcercuei 0:03b5121a232e 5459 }
pcercuei 0:03b5121a232e 5460 break;
pcercuei 0:03b5121a232e 5461 }
pcercuei 0:03b5121a232e 5462 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 5463 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 5464
pcercuei 0:03b5121a232e 5465 if ((facet->val == NULL) ||
pcercuei 0:03b5121a232e 5466 ((facet->val->type != XML_SCHEMAS_PINTEGER) &&
pcercuei 0:03b5121a232e 5467 (facet->val->type != XML_SCHEMAS_NNINTEGER)) ||
pcercuei 0:03b5121a232e 5468 (facet->val->value.decimal.frac != 0)) {
pcercuei 0:03b5121a232e 5469 return(-1);
pcercuei 0:03b5121a232e 5470 }
pcercuei 0:03b5121a232e 5471 if ((val == NULL) ||
pcercuei 0:03b5121a232e 5472 ((val->type != XML_SCHEMAS_DECIMAL) &&
pcercuei 0:03b5121a232e 5473 (val->type != XML_SCHEMAS_INTEGER) &&
pcercuei 0:03b5121a232e 5474 (val->type != XML_SCHEMAS_NPINTEGER) &&
pcercuei 0:03b5121a232e 5475 (val->type != XML_SCHEMAS_NINTEGER) &&
pcercuei 0:03b5121a232e 5476 (val->type != XML_SCHEMAS_NNINTEGER) &&
pcercuei 0:03b5121a232e 5477 (val->type != XML_SCHEMAS_PINTEGER) &&
pcercuei 0:03b5121a232e 5478 (val->type != XML_SCHEMAS_INT) &&
pcercuei 0:03b5121a232e 5479 (val->type != XML_SCHEMAS_UINT) &&
pcercuei 0:03b5121a232e 5480 (val->type != XML_SCHEMAS_LONG) &&
pcercuei 0:03b5121a232e 5481 (val->type != XML_SCHEMAS_ULONG) &&
pcercuei 0:03b5121a232e 5482 (val->type != XML_SCHEMAS_SHORT) &&
pcercuei 0:03b5121a232e 5483 (val->type != XML_SCHEMAS_USHORT) &&
pcercuei 0:03b5121a232e 5484 (val->type != XML_SCHEMAS_BYTE) &&
pcercuei 0:03b5121a232e 5485 (val->type != XML_SCHEMAS_UBYTE))) {
pcercuei 0:03b5121a232e 5486 return(-1);
pcercuei 0:03b5121a232e 5487 }
pcercuei 0:03b5121a232e 5488 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
pcercuei 0:03b5121a232e 5489 if (val->value.decimal.total > facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5490 return(XML_SCHEMAV_CVC_TOTALDIGITS_VALID);
pcercuei 0:03b5121a232e 5491
pcercuei 0:03b5121a232e 5492 } else if (facet->type == XML_SCHEMA_FACET_FRACTIONDIGITS) {
pcercuei 0:03b5121a232e 5493 if (val->value.decimal.frac > facet->val->value.decimal.lo)
pcercuei 0:03b5121a232e 5494 return(XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID);
pcercuei 0:03b5121a232e 5495 }
pcercuei 0:03b5121a232e 5496 break;
pcercuei 0:03b5121a232e 5497 default:
pcercuei 0:03b5121a232e 5498 TODO
pcercuei 0:03b5121a232e 5499 }
pcercuei 0:03b5121a232e 5500 return(0);
pcercuei 0:03b5121a232e 5501
pcercuei 0:03b5121a232e 5502 }
pcercuei 0:03b5121a232e 5503
pcercuei 0:03b5121a232e 5504 /**
pcercuei 0:03b5121a232e 5505 * xmlSchemaValidateFacet:
pcercuei 0:03b5121a232e 5506 * @base: the base type
pcercuei 0:03b5121a232e 5507 * @facet: the facet to check
pcercuei 0:03b5121a232e 5508 * @value: the lexical repr of the value to validate
pcercuei 0:03b5121a232e 5509 * @val: the precomputed value
pcercuei 0:03b5121a232e 5510 *
pcercuei 0:03b5121a232e 5511 * Check a value against a facet condition
pcercuei 0:03b5121a232e 5512 *
pcercuei 0:03b5121a232e 5513 * Returns 0 if the element is schemas valid, a positive error code
pcercuei 0:03b5121a232e 5514 * number otherwise and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 5515 */
pcercuei 0:03b5121a232e 5516 int
pcercuei 0:03b5121a232e 5517 xmlSchemaValidateFacet(xmlSchemaTypePtr base,
pcercuei 0:03b5121a232e 5518 xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5519 const xmlChar *value,
pcercuei 0:03b5121a232e 5520 xmlSchemaValPtr val)
pcercuei 0:03b5121a232e 5521 {
pcercuei 0:03b5121a232e 5522 /*
pcercuei 0:03b5121a232e 5523 * This tries to ensure API compatibility regarding the old
pcercuei 0:03b5121a232e 5524 * xmlSchemaValidateFacet() and the new xmlSchemaValidateFacetInternal() and
pcercuei 0:03b5121a232e 5525 * xmlSchemaValidateFacetWhtsp().
pcercuei 0:03b5121a232e 5526 */
pcercuei 0:03b5121a232e 5527 if (val != NULL)
pcercuei 0:03b5121a232e 5528 return(xmlSchemaValidateFacetInternal(facet,
pcercuei 0:03b5121a232e 5529 XML_SCHEMA_WHITESPACE_UNKNOWN, val->type, value, val,
pcercuei 0:03b5121a232e 5530 XML_SCHEMA_WHITESPACE_UNKNOWN));
pcercuei 0:03b5121a232e 5531 else if (base != NULL)
pcercuei 0:03b5121a232e 5532 return(xmlSchemaValidateFacetInternal(facet,
pcercuei 0:03b5121a232e 5533 XML_SCHEMA_WHITESPACE_UNKNOWN, base->builtInType, value, val,
pcercuei 0:03b5121a232e 5534 XML_SCHEMA_WHITESPACE_UNKNOWN));
pcercuei 0:03b5121a232e 5535 return(-1);
pcercuei 0:03b5121a232e 5536 }
pcercuei 0:03b5121a232e 5537
pcercuei 0:03b5121a232e 5538 /**
pcercuei 0:03b5121a232e 5539 * xmlSchemaValidateFacetWhtsp:
pcercuei 0:03b5121a232e 5540 * @facet: the facet to check
pcercuei 0:03b5121a232e 5541 * @fws: the whitespace type of the facet's value
pcercuei 0:03b5121a232e 5542 * @valType: the built-in type of the value
pcercuei 0:03b5121a232e 5543 * @value: the lexical (or normalized for pattern) repr of the value to validate
pcercuei 0:03b5121a232e 5544 * @val: the precomputed value
pcercuei 0:03b5121a232e 5545 * @ws: the whitespace type of the value
pcercuei 0:03b5121a232e 5546 *
pcercuei 0:03b5121a232e 5547 * Check a value against a facet condition. This takes value normalization
pcercuei 0:03b5121a232e 5548 * according to the specified whitespace types into account.
pcercuei 0:03b5121a232e 5549 * Note that @value needs to be the *normalized* value if the facet
pcercuei 0:03b5121a232e 5550 * is of type "pattern".
pcercuei 0:03b5121a232e 5551 *
pcercuei 0:03b5121a232e 5552 * Returns 0 if the element is schemas valid, a positive error code
pcercuei 0:03b5121a232e 5553 * number otherwise and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 5554 */
pcercuei 0:03b5121a232e 5555 int
pcercuei 0:03b5121a232e 5556 xmlSchemaValidateFacetWhtsp(xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 5557 xmlSchemaWhitespaceValueType fws,
pcercuei 0:03b5121a232e 5558 xmlSchemaValType valType,
pcercuei 0:03b5121a232e 5559 const xmlChar *value,
pcercuei 0:03b5121a232e 5560 xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 5561 xmlSchemaWhitespaceValueType ws)
pcercuei 0:03b5121a232e 5562 {
pcercuei 0:03b5121a232e 5563 return(xmlSchemaValidateFacetInternal(facet, fws, valType,
pcercuei 0:03b5121a232e 5564 value, val, ws));
pcercuei 0:03b5121a232e 5565 }
pcercuei 0:03b5121a232e 5566
pcercuei 0:03b5121a232e 5567 #if 0
pcercuei 0:03b5121a232e 5568 #ifndef DBL_DIG
pcercuei 0:03b5121a232e 5569 #define DBL_DIG 16
pcercuei 0:03b5121a232e 5570 #endif
pcercuei 0:03b5121a232e 5571 #ifndef DBL_EPSILON
pcercuei 0:03b5121a232e 5572 #define DBL_EPSILON 1E-9
pcercuei 0:03b5121a232e 5573 #endif
pcercuei 0:03b5121a232e 5574
pcercuei 0:03b5121a232e 5575 #define INTEGER_DIGITS DBL_DIG
pcercuei 0:03b5121a232e 5576 #define FRACTION_DIGITS (DBL_DIG + 1)
pcercuei 0:03b5121a232e 5577 #define EXPONENT_DIGITS (3 + 2)
pcercuei 0:03b5121a232e 5578
pcercuei 0:03b5121a232e 5579 /**
pcercuei 0:03b5121a232e 5580 * xmlXPathFormatNumber:
pcercuei 0:03b5121a232e 5581 * @number: number to format
pcercuei 0:03b5121a232e 5582 * @buffer: output buffer
pcercuei 0:03b5121a232e 5583 * @buffersize: size of output buffer
pcercuei 0:03b5121a232e 5584 *
pcercuei 0:03b5121a232e 5585 * Convert the number into a string representation.
pcercuei 0:03b5121a232e 5586 */
pcercuei 0:03b5121a232e 5587 static void
pcercuei 0:03b5121a232e 5588 xmlSchemaFormatFloat(double number, char buffer[], int buffersize)
pcercuei 0:03b5121a232e 5589 {
pcercuei 0:03b5121a232e 5590 switch (xmlXPathIsInf(number)) {
pcercuei 0:03b5121a232e 5591 case 1:
pcercuei 0:03b5121a232e 5592 if (buffersize > (int)sizeof("INF"))
pcercuei 0:03b5121a232e 5593 snprintf(buffer, buffersize, "INF");
pcercuei 0:03b5121a232e 5594 break;
pcercuei 0:03b5121a232e 5595 case -1:
pcercuei 0:03b5121a232e 5596 if (buffersize > (int)sizeof("-INF"))
pcercuei 0:03b5121a232e 5597 snprintf(buffer, buffersize, "-INF");
pcercuei 0:03b5121a232e 5598 break;
pcercuei 0:03b5121a232e 5599 default:
pcercuei 0:03b5121a232e 5600 if (xmlXPathIsNaN(number)) {
pcercuei 0:03b5121a232e 5601 if (buffersize > (int)sizeof("NaN"))
pcercuei 0:03b5121a232e 5602 snprintf(buffer, buffersize, "NaN");
pcercuei 0:03b5121a232e 5603 } else if (number == 0) {
pcercuei 0:03b5121a232e 5604 snprintf(buffer, buffersize, "0.0E0");
pcercuei 0:03b5121a232e 5605 } else {
pcercuei 0:03b5121a232e 5606 /* 3 is sign, decimal point, and terminating zero */
pcercuei 0:03b5121a232e 5607 char work[DBL_DIG + EXPONENT_DIGITS + 3];
pcercuei 0:03b5121a232e 5608 int integer_place, fraction_place;
pcercuei 0:03b5121a232e 5609 char *ptr;
pcercuei 0:03b5121a232e 5610 char *after_fraction;
pcercuei 0:03b5121a232e 5611 double absolute_value;
pcercuei 0:03b5121a232e 5612 int size;
pcercuei 0:03b5121a232e 5613
pcercuei 0:03b5121a232e 5614 absolute_value = fabs(number);
pcercuei 0:03b5121a232e 5615
pcercuei 0:03b5121a232e 5616 /*
pcercuei 0:03b5121a232e 5617 * Result is in work, and after_fraction points
pcercuei 0:03b5121a232e 5618 * just past the fractional part.
pcercuei 0:03b5121a232e 5619 * Use scientific notation
pcercuei 0:03b5121a232e 5620 */
pcercuei 0:03b5121a232e 5621 integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
pcercuei 0:03b5121a232e 5622 fraction_place = DBL_DIG - 1;
pcercuei 0:03b5121a232e 5623 snprintf(work, sizeof(work),"%*.*e",
pcercuei 0:03b5121a232e 5624 integer_place, fraction_place, number);
pcercuei 0:03b5121a232e 5625 after_fraction = strchr(work + DBL_DIG, 'e');
pcercuei 0:03b5121a232e 5626 /* Remove fractional trailing zeroes */
pcercuei 0:03b5121a232e 5627 ptr = after_fraction;
pcercuei 0:03b5121a232e 5628 while (*(--ptr) == '0')
pcercuei 0:03b5121a232e 5629 ;
pcercuei 0:03b5121a232e 5630 if (*ptr != '.')
pcercuei 0:03b5121a232e 5631 ptr++;
pcercuei 0:03b5121a232e 5632 while ((*ptr++ = *after_fraction++) != 0);
pcercuei 0:03b5121a232e 5633
pcercuei 0:03b5121a232e 5634 /* Finally copy result back to caller */
pcercuei 0:03b5121a232e 5635 size = strlen(work) + 1;
pcercuei 0:03b5121a232e 5636 if (size > buffersize) {
pcercuei 0:03b5121a232e 5637 work[buffersize - 1] = 0;
pcercuei 0:03b5121a232e 5638 size = buffersize;
pcercuei 0:03b5121a232e 5639 }
pcercuei 0:03b5121a232e 5640 memmove(buffer, work, size);
pcercuei 0:03b5121a232e 5641 }
pcercuei 0:03b5121a232e 5642 break;
pcercuei 0:03b5121a232e 5643 }
pcercuei 0:03b5121a232e 5644 }
pcercuei 0:03b5121a232e 5645 #endif
pcercuei 0:03b5121a232e 5646
pcercuei 0:03b5121a232e 5647 /**
pcercuei 0:03b5121a232e 5648 * xmlSchemaGetCanonValue:
pcercuei 0:03b5121a232e 5649 * @val: the precomputed value
pcercuei 0:03b5121a232e 5650 * @retValue: the returned value
pcercuei 0:03b5121a232e 5651 *
pcercuei 0:03b5121a232e 5652 * Get the canonical lexical representation of the value.
pcercuei 0:03b5121a232e 5653 * The caller has to FREE the returned retValue.
pcercuei 0:03b5121a232e 5654 *
pcercuei 0:03b5121a232e 5655 * WARNING: Some value types are not supported yet, resulting
pcercuei 0:03b5121a232e 5656 * in a @retValue of "???".
pcercuei 0:03b5121a232e 5657 *
pcercuei 0:03b5121a232e 5658 * TODO: XML Schema 1.0 does not define canonical representations
pcercuei 0:03b5121a232e 5659 * for: duration, gYearMonth, gYear, gMonthDay, gMonth, gDay,
pcercuei 0:03b5121a232e 5660 * anyURI, QName, NOTATION. This will be fixed in XML Schema 1.1.
pcercuei 0:03b5121a232e 5661 *
pcercuei 0:03b5121a232e 5662 *
pcercuei 0:03b5121a232e 5663 * Returns 0 if the value could be built, 1 if the value type is
pcercuei 0:03b5121a232e 5664 * not supported yet and -1 in case of API errors.
pcercuei 0:03b5121a232e 5665 */
pcercuei 0:03b5121a232e 5666 int
pcercuei 0:03b5121a232e 5667 xmlSchemaGetCanonValue(xmlSchemaValPtr val, const xmlChar **retValue)
pcercuei 0:03b5121a232e 5668 {
pcercuei 0:03b5121a232e 5669 if ((retValue == NULL) || (val == NULL))
pcercuei 0:03b5121a232e 5670 return (-1);
pcercuei 0:03b5121a232e 5671 *retValue = NULL;
pcercuei 0:03b5121a232e 5672 switch (val->type) {
pcercuei 0:03b5121a232e 5673 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 5674 if (val->value.str == NULL)
pcercuei 0:03b5121a232e 5675 *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 5676 else
pcercuei 0:03b5121a232e 5677 *retValue =
pcercuei 0:03b5121a232e 5678 BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
pcercuei 0:03b5121a232e 5679 break;
pcercuei 0:03b5121a232e 5680 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 5681 if (val->value.str == NULL)
pcercuei 0:03b5121a232e 5682 *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 5683 else {
pcercuei 0:03b5121a232e 5684 *retValue = xmlSchemaWhiteSpaceReplace(
pcercuei 0:03b5121a232e 5685 (const xmlChar *) val->value.str);
pcercuei 0:03b5121a232e 5686 if ((*retValue) == NULL)
pcercuei 0:03b5121a232e 5687 *retValue = BAD_CAST xmlStrdup(
pcercuei 0:03b5121a232e 5688 (const xmlChar *) val->value.str);
pcercuei 0:03b5121a232e 5689 }
pcercuei 0:03b5121a232e 5690 break;
pcercuei 0:03b5121a232e 5691 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 5692 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 5693 case XML_SCHEMAS_NMTOKEN:
pcercuei 0:03b5121a232e 5694 case XML_SCHEMAS_NAME:
pcercuei 0:03b5121a232e 5695 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 5696 case XML_SCHEMAS_ID:
pcercuei 0:03b5121a232e 5697 case XML_SCHEMAS_IDREF:
pcercuei 0:03b5121a232e 5698 case XML_SCHEMAS_ENTITY:
pcercuei 0:03b5121a232e 5699 case XML_SCHEMAS_NOTATION: /* Unclear */
pcercuei 0:03b5121a232e 5700 case XML_SCHEMAS_ANYURI: /* Unclear */
pcercuei 0:03b5121a232e 5701 if (val->value.str == NULL)
pcercuei 0:03b5121a232e 5702 return (-1);
pcercuei 0:03b5121a232e 5703 *retValue =
pcercuei 0:03b5121a232e 5704 BAD_CAST xmlSchemaCollapseString(BAD_CAST val->value.str);
pcercuei 0:03b5121a232e 5705 if (*retValue == NULL)
pcercuei 0:03b5121a232e 5706 *retValue =
pcercuei 0:03b5121a232e 5707 BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
pcercuei 0:03b5121a232e 5708 break;
pcercuei 0:03b5121a232e 5709 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 5710 /* TODO: Unclear in XML Schema 1.0. */
pcercuei 0:03b5121a232e 5711 if (val->value.qname.uri == NULL) {
pcercuei 0:03b5121a232e 5712 *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.qname.name);
pcercuei 0:03b5121a232e 5713 return (0);
pcercuei 0:03b5121a232e 5714 } else {
pcercuei 0:03b5121a232e 5715 *retValue = BAD_CAST xmlStrdup(BAD_CAST "{");
pcercuei 0:03b5121a232e 5716 *retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
pcercuei 0:03b5121a232e 5717 BAD_CAST val->value.qname.uri);
pcercuei 0:03b5121a232e 5718 *retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
pcercuei 0:03b5121a232e 5719 BAD_CAST "}");
pcercuei 0:03b5121a232e 5720 *retValue = BAD_CAST xmlStrcat((xmlChar *) (*retValue),
pcercuei 0:03b5121a232e 5721 BAD_CAST val->value.qname.uri);
pcercuei 0:03b5121a232e 5722 }
pcercuei 0:03b5121a232e 5723 break;
pcercuei 0:03b5121a232e 5724 case XML_SCHEMAS_DECIMAL:
pcercuei 0:03b5121a232e 5725 /*
pcercuei 0:03b5121a232e 5726 * TODO: Lookout for a more simple implementation.
pcercuei 0:03b5121a232e 5727 */
pcercuei 0:03b5121a232e 5728 if ((val->value.decimal.total == 1) &&
pcercuei 0:03b5121a232e 5729 (val->value.decimal.lo == 0)) {
pcercuei 0:03b5121a232e 5730 *retValue = xmlStrdup(BAD_CAST "0.0");
pcercuei 0:03b5121a232e 5731 } else {
pcercuei 0:03b5121a232e 5732 xmlSchemaValDecimal dec = val->value.decimal;
pcercuei 0:03b5121a232e 5733 int bufsize;
pcercuei 0:03b5121a232e 5734 char *buf = NULL, *offs;
pcercuei 0:03b5121a232e 5735
pcercuei 0:03b5121a232e 5736 /* Add room for the decimal point as well. */
pcercuei 0:03b5121a232e 5737 bufsize = dec.total + 2;
pcercuei 0:03b5121a232e 5738 if (dec.sign)
pcercuei 0:03b5121a232e 5739 bufsize++;
pcercuei 0:03b5121a232e 5740 /* Add room for leading/trailing zero. */
pcercuei 0:03b5121a232e 5741 if ((dec.frac == 0) || (dec.frac == dec.total))
pcercuei 0:03b5121a232e 5742 bufsize++;
pcercuei 0:03b5121a232e 5743 buf = xmlMalloc(bufsize);
pcercuei 0:03b5121a232e 5744 if (buf == NULL)
pcercuei 0:03b5121a232e 5745 return(-1);
pcercuei 0:03b5121a232e 5746 offs = buf;
pcercuei 0:03b5121a232e 5747 if (dec.sign)
pcercuei 0:03b5121a232e 5748 *offs++ = '-';
pcercuei 0:03b5121a232e 5749 if (dec.frac == dec.total) {
pcercuei 0:03b5121a232e 5750 *offs++ = '0';
pcercuei 0:03b5121a232e 5751 *offs++ = '.';
pcercuei 0:03b5121a232e 5752 }
pcercuei 0:03b5121a232e 5753 if (dec.hi != 0)
pcercuei 0:03b5121a232e 5754 snprintf(offs, bufsize - (offs - buf),
pcercuei 0:03b5121a232e 5755 "%lu%lu%lu", dec.hi, dec.mi, dec.lo);
pcercuei 0:03b5121a232e 5756 else if (dec.mi != 0)
pcercuei 0:03b5121a232e 5757 snprintf(offs, bufsize - (offs - buf),
pcercuei 0:03b5121a232e 5758 "%lu%lu", dec.mi, dec.lo);
pcercuei 0:03b5121a232e 5759 else
pcercuei 0:03b5121a232e 5760 snprintf(offs, bufsize - (offs - buf),
pcercuei 0:03b5121a232e 5761 "%lu", dec.lo);
pcercuei 0:03b5121a232e 5762
pcercuei 0:03b5121a232e 5763 if (dec.frac != 0) {
pcercuei 0:03b5121a232e 5764 if (dec.frac != dec.total) {
pcercuei 0:03b5121a232e 5765 int diff = dec.total - dec.frac;
pcercuei 0:03b5121a232e 5766 /*
pcercuei 0:03b5121a232e 5767 * Insert the decimal point.
pcercuei 0:03b5121a232e 5768 */
pcercuei 0:03b5121a232e 5769 memmove(offs + diff + 1, offs + diff, dec.frac +1);
pcercuei 0:03b5121a232e 5770 offs[diff] = '.';
pcercuei 0:03b5121a232e 5771 } else {
pcercuei 0:03b5121a232e 5772 unsigned int i = 0;
pcercuei 0:03b5121a232e 5773 /*
pcercuei 0:03b5121a232e 5774 * Insert missing zeroes behind the decimal point.
pcercuei 0:03b5121a232e 5775 */
pcercuei 0:03b5121a232e 5776 while (*(offs + i) != 0)
pcercuei 0:03b5121a232e 5777 i++;
pcercuei 0:03b5121a232e 5778 if (i < dec.total) {
pcercuei 0:03b5121a232e 5779 memmove(offs + (dec.total - i), offs, i +1);
pcercuei 0:03b5121a232e 5780 memset(offs, '0', dec.total - i);
pcercuei 0:03b5121a232e 5781 }
pcercuei 0:03b5121a232e 5782 }
pcercuei 0:03b5121a232e 5783 } else {
pcercuei 0:03b5121a232e 5784 /*
pcercuei 0:03b5121a232e 5785 * Append decimal point and zero.
pcercuei 0:03b5121a232e 5786 */
pcercuei 0:03b5121a232e 5787 offs = buf + bufsize - 1;
pcercuei 0:03b5121a232e 5788 *offs-- = 0;
pcercuei 0:03b5121a232e 5789 *offs-- = '0';
pcercuei 0:03b5121a232e 5790 *offs-- = '.';
pcercuei 0:03b5121a232e 5791 }
pcercuei 0:03b5121a232e 5792 *retValue = BAD_CAST buf;
pcercuei 0:03b5121a232e 5793 }
pcercuei 0:03b5121a232e 5794 break;
pcercuei 0:03b5121a232e 5795 case XML_SCHEMAS_INTEGER:
pcercuei 0:03b5121a232e 5796 case XML_SCHEMAS_PINTEGER:
pcercuei 0:03b5121a232e 5797 case XML_SCHEMAS_NPINTEGER:
pcercuei 0:03b5121a232e 5798 case XML_SCHEMAS_NINTEGER:
pcercuei 0:03b5121a232e 5799 case XML_SCHEMAS_NNINTEGER:
pcercuei 0:03b5121a232e 5800 case XML_SCHEMAS_LONG:
pcercuei 0:03b5121a232e 5801 case XML_SCHEMAS_BYTE:
pcercuei 0:03b5121a232e 5802 case XML_SCHEMAS_SHORT:
pcercuei 0:03b5121a232e 5803 case XML_SCHEMAS_INT:
pcercuei 0:03b5121a232e 5804 case XML_SCHEMAS_UINT:
pcercuei 0:03b5121a232e 5805 case XML_SCHEMAS_ULONG:
pcercuei 0:03b5121a232e 5806 case XML_SCHEMAS_USHORT:
pcercuei 0:03b5121a232e 5807 case XML_SCHEMAS_UBYTE:
pcercuei 0:03b5121a232e 5808 if ((val->value.decimal.total == 1) &&
pcercuei 0:03b5121a232e 5809 (val->value.decimal.lo == 0))
pcercuei 0:03b5121a232e 5810 *retValue = xmlStrdup(BAD_CAST "0");
pcercuei 0:03b5121a232e 5811 else {
pcercuei 0:03b5121a232e 5812 xmlSchemaValDecimal dec = val->value.decimal;
pcercuei 0:03b5121a232e 5813 int bufsize = dec.total + 1;
pcercuei 0:03b5121a232e 5814
pcercuei 0:03b5121a232e 5815 /* Add room for the decimal point as well. */
pcercuei 0:03b5121a232e 5816 if (dec.sign)
pcercuei 0:03b5121a232e 5817 bufsize++;
pcercuei 0:03b5121a232e 5818 *retValue = xmlMalloc(bufsize);
pcercuei 0:03b5121a232e 5819 if (*retValue == NULL)
pcercuei 0:03b5121a232e 5820 return(-1);
pcercuei 0:03b5121a232e 5821 if (dec.hi != 0) {
pcercuei 0:03b5121a232e 5822 if (dec.sign)
pcercuei 0:03b5121a232e 5823 snprintf((char *) *retValue, bufsize,
pcercuei 0:03b5121a232e 5824 "-%lu%lu%lu", dec.hi, dec.mi, dec.lo);
pcercuei 0:03b5121a232e 5825 else
pcercuei 0:03b5121a232e 5826 snprintf((char *) *retValue, bufsize,
pcercuei 0:03b5121a232e 5827 "%lu%lu%lu", dec.hi, dec.mi, dec.lo);
pcercuei 0:03b5121a232e 5828 } else if (dec.mi != 0) {
pcercuei 0:03b5121a232e 5829 if (dec.sign)
pcercuei 0:03b5121a232e 5830 snprintf((char *) *retValue, bufsize,
pcercuei 0:03b5121a232e 5831 "-%lu%lu", dec.mi, dec.lo);
pcercuei 0:03b5121a232e 5832 else
pcercuei 0:03b5121a232e 5833 snprintf((char *) *retValue, bufsize,
pcercuei 0:03b5121a232e 5834 "%lu%lu", dec.mi, dec.lo);
pcercuei 0:03b5121a232e 5835 } else {
pcercuei 0:03b5121a232e 5836 if (dec.sign)
pcercuei 0:03b5121a232e 5837 snprintf((char *) *retValue, bufsize, "-%lu", dec.lo);
pcercuei 0:03b5121a232e 5838 else
pcercuei 0:03b5121a232e 5839 snprintf((char *) *retValue, bufsize, "%lu", dec.lo);
pcercuei 0:03b5121a232e 5840 }
pcercuei 0:03b5121a232e 5841 }
pcercuei 0:03b5121a232e 5842 break;
pcercuei 0:03b5121a232e 5843 case XML_SCHEMAS_BOOLEAN:
pcercuei 0:03b5121a232e 5844 if (val->value.b)
pcercuei 0:03b5121a232e 5845 *retValue = BAD_CAST xmlStrdup(BAD_CAST "true");
pcercuei 0:03b5121a232e 5846 else
pcercuei 0:03b5121a232e 5847 *retValue = BAD_CAST xmlStrdup(BAD_CAST "false");
pcercuei 0:03b5121a232e 5848 break;
pcercuei 0:03b5121a232e 5849 case XML_SCHEMAS_DURATION: {
pcercuei 0:03b5121a232e 5850 char buf[100];
pcercuei 0:03b5121a232e 5851 unsigned long year;
pcercuei 0:03b5121a232e 5852 unsigned long mon, day, hour = 0, min = 0;
pcercuei 0:03b5121a232e 5853 double sec = 0, left;
pcercuei 0:03b5121a232e 5854
pcercuei 0:03b5121a232e 5855 /* TODO: Unclear in XML Schema 1.0 */
pcercuei 0:03b5121a232e 5856 /*
pcercuei 0:03b5121a232e 5857 * TODO: This results in a normalized output of the value
pcercuei 0:03b5121a232e 5858 * - which is NOT conformant to the spec -
pcercuei 0:03b5121a232e 5859 * since the exact values of each property are not
pcercuei 0:03b5121a232e 5860 * recoverable. Think about extending the structure to
pcercuei 0:03b5121a232e 5861 * provide a field for every property.
pcercuei 0:03b5121a232e 5862 */
pcercuei 0:03b5121a232e 5863 year = (unsigned long) FQUOTIENT(labs(val->value.dur.mon), 12);
pcercuei 0:03b5121a232e 5864 mon = labs(val->value.dur.mon) - 12 * year;
pcercuei 0:03b5121a232e 5865
pcercuei 0:03b5121a232e 5866 day = (unsigned long) FQUOTIENT(fabs(val->value.dur.sec), 86400);
pcercuei 0:03b5121a232e 5867 left = fabs(val->value.dur.sec) - day * 86400;
pcercuei 0:03b5121a232e 5868 if (left > 0) {
pcercuei 0:03b5121a232e 5869 hour = (unsigned long) FQUOTIENT(left, 3600);
pcercuei 0:03b5121a232e 5870 left = left - (hour * 3600);
pcercuei 0:03b5121a232e 5871 if (left > 0) {
pcercuei 0:03b5121a232e 5872 min = (unsigned long) FQUOTIENT(left, 60);
pcercuei 0:03b5121a232e 5873 sec = left - (min * 60);
pcercuei 0:03b5121a232e 5874 }
pcercuei 0:03b5121a232e 5875 }
pcercuei 0:03b5121a232e 5876 if ((val->value.dur.mon < 0) || (val->value.dur.sec < 0))
pcercuei 0:03b5121a232e 5877 snprintf(buf, 100, "P%luY%luM%luDT%luH%luM%.14gS",
pcercuei 0:03b5121a232e 5878 year, mon, day, hour, min, sec);
pcercuei 0:03b5121a232e 5879 else
pcercuei 0:03b5121a232e 5880 snprintf(buf, 100, "-P%luY%luM%luDT%luH%luM%.14gS",
pcercuei 0:03b5121a232e 5881 year, mon, day, hour, min, sec);
pcercuei 0:03b5121a232e 5882 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 5883 }
pcercuei 0:03b5121a232e 5884 break;
pcercuei 0:03b5121a232e 5885 case XML_SCHEMAS_GYEAR: {
pcercuei 0:03b5121a232e 5886 char buf[30];
pcercuei 0:03b5121a232e 5887 /* TODO: Unclear in XML Schema 1.0 */
pcercuei 0:03b5121a232e 5888 /* TODO: What to do with the timezone? */
pcercuei 0:03b5121a232e 5889 snprintf(buf, 30, "%04ld", val->value.date.year);
pcercuei 0:03b5121a232e 5890 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 5891 }
pcercuei 0:03b5121a232e 5892 break;
pcercuei 0:03b5121a232e 5893 case XML_SCHEMAS_GMONTH: {
pcercuei 0:03b5121a232e 5894 /* TODO: Unclear in XML Schema 1.0 */
pcercuei 0:03b5121a232e 5895 /* TODO: What to do with the timezone? */
pcercuei 0:03b5121a232e 5896 *retValue = xmlMalloc(6);
pcercuei 0:03b5121a232e 5897 if (*retValue == NULL)
pcercuei 0:03b5121a232e 5898 return(-1);
pcercuei 0:03b5121a232e 5899 snprintf((char *) *retValue, 6, "--%02u",
pcercuei 0:03b5121a232e 5900 val->value.date.mon);
pcercuei 0:03b5121a232e 5901 }
pcercuei 0:03b5121a232e 5902 break;
pcercuei 0:03b5121a232e 5903 case XML_SCHEMAS_GDAY: {
pcercuei 0:03b5121a232e 5904 /* TODO: Unclear in XML Schema 1.0 */
pcercuei 0:03b5121a232e 5905 /* TODO: What to do with the timezone? */
pcercuei 0:03b5121a232e 5906 *retValue = xmlMalloc(6);
pcercuei 0:03b5121a232e 5907 if (*retValue == NULL)
pcercuei 0:03b5121a232e 5908 return(-1);
pcercuei 0:03b5121a232e 5909 snprintf((char *) *retValue, 6, "---%02u",
pcercuei 0:03b5121a232e 5910 val->value.date.day);
pcercuei 0:03b5121a232e 5911 }
pcercuei 0:03b5121a232e 5912 break;
pcercuei 0:03b5121a232e 5913 case XML_SCHEMAS_GMONTHDAY: {
pcercuei 0:03b5121a232e 5914 /* TODO: Unclear in XML Schema 1.0 */
pcercuei 0:03b5121a232e 5915 /* TODO: What to do with the timezone? */
pcercuei 0:03b5121a232e 5916 *retValue = xmlMalloc(8);
pcercuei 0:03b5121a232e 5917 if (*retValue == NULL)
pcercuei 0:03b5121a232e 5918 return(-1);
pcercuei 0:03b5121a232e 5919 snprintf((char *) *retValue, 8, "--%02u-%02u",
pcercuei 0:03b5121a232e 5920 val->value.date.mon, val->value.date.day);
pcercuei 0:03b5121a232e 5921 }
pcercuei 0:03b5121a232e 5922 break;
pcercuei 0:03b5121a232e 5923 case XML_SCHEMAS_GYEARMONTH: {
pcercuei 0:03b5121a232e 5924 char buf[35];
pcercuei 0:03b5121a232e 5925 /* TODO: Unclear in XML Schema 1.0 */
pcercuei 0:03b5121a232e 5926 /* TODO: What to do with the timezone? */
pcercuei 0:03b5121a232e 5927 if (val->value.date.year < 0)
pcercuei 0:03b5121a232e 5928 snprintf(buf, 35, "-%04ld-%02u",
pcercuei 0:03b5121a232e 5929 labs(val->value.date.year),
pcercuei 0:03b5121a232e 5930 val->value.date.mon);
pcercuei 0:03b5121a232e 5931 else
pcercuei 0:03b5121a232e 5932 snprintf(buf, 35, "%04ld-%02u",
pcercuei 0:03b5121a232e 5933 val->value.date.year, val->value.date.mon);
pcercuei 0:03b5121a232e 5934 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 5935 }
pcercuei 0:03b5121a232e 5936 break;
pcercuei 0:03b5121a232e 5937 case XML_SCHEMAS_TIME:
pcercuei 0:03b5121a232e 5938 {
pcercuei 0:03b5121a232e 5939 char buf[30];
pcercuei 0:03b5121a232e 5940
pcercuei 0:03b5121a232e 5941 if (val->value.date.tz_flag) {
pcercuei 0:03b5121a232e 5942 xmlSchemaValPtr norm;
pcercuei 0:03b5121a232e 5943
pcercuei 0:03b5121a232e 5944 norm = xmlSchemaDateNormalize(val, 0);
pcercuei 0:03b5121a232e 5945 if (norm == NULL)
pcercuei 0:03b5121a232e 5946 return (-1);
pcercuei 0:03b5121a232e 5947 /*
pcercuei 0:03b5121a232e 5948 * TODO: Check if "%.14g" is portable.
pcercuei 0:03b5121a232e 5949 */
pcercuei 0:03b5121a232e 5950 snprintf(buf, 30,
pcercuei 0:03b5121a232e 5951 "%02u:%02u:%02.14gZ",
pcercuei 0:03b5121a232e 5952 norm->value.date.hour,
pcercuei 0:03b5121a232e 5953 norm->value.date.min,
pcercuei 0:03b5121a232e 5954 norm->value.date.sec);
pcercuei 0:03b5121a232e 5955 xmlSchemaFreeValue(norm);
pcercuei 0:03b5121a232e 5956 } else {
pcercuei 0:03b5121a232e 5957 snprintf(buf, 30,
pcercuei 0:03b5121a232e 5958 "%02u:%02u:%02.14g",
pcercuei 0:03b5121a232e 5959 val->value.date.hour,
pcercuei 0:03b5121a232e 5960 val->value.date.min,
pcercuei 0:03b5121a232e 5961 val->value.date.sec);
pcercuei 0:03b5121a232e 5962 }
pcercuei 0:03b5121a232e 5963 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 5964 }
pcercuei 0:03b5121a232e 5965 break;
pcercuei 0:03b5121a232e 5966 case XML_SCHEMAS_DATE:
pcercuei 0:03b5121a232e 5967 {
pcercuei 0:03b5121a232e 5968 char buf[30];
pcercuei 0:03b5121a232e 5969
pcercuei 0:03b5121a232e 5970 if (val->value.date.tz_flag) {
pcercuei 0:03b5121a232e 5971 xmlSchemaValPtr norm;
pcercuei 0:03b5121a232e 5972
pcercuei 0:03b5121a232e 5973 norm = xmlSchemaDateNormalize(val, 0);
pcercuei 0:03b5121a232e 5974 if (norm == NULL)
pcercuei 0:03b5121a232e 5975 return (-1);
pcercuei 0:03b5121a232e 5976 /*
pcercuei 0:03b5121a232e 5977 * TODO: Append the canonical value of the
pcercuei 0:03b5121a232e 5978 * recoverable timezone and not "Z".
pcercuei 0:03b5121a232e 5979 */
pcercuei 0:03b5121a232e 5980 snprintf(buf, 30,
pcercuei 0:03b5121a232e 5981 "%04ld:%02u:%02uZ",
pcercuei 0:03b5121a232e 5982 norm->value.date.year, norm->value.date.mon,
pcercuei 0:03b5121a232e 5983 norm->value.date.day);
pcercuei 0:03b5121a232e 5984 xmlSchemaFreeValue(norm);
pcercuei 0:03b5121a232e 5985 } else {
pcercuei 0:03b5121a232e 5986 snprintf(buf, 30,
pcercuei 0:03b5121a232e 5987 "%04ld:%02u:%02u",
pcercuei 0:03b5121a232e 5988 val->value.date.year, val->value.date.mon,
pcercuei 0:03b5121a232e 5989 val->value.date.day);
pcercuei 0:03b5121a232e 5990 }
pcercuei 0:03b5121a232e 5991 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 5992 }
pcercuei 0:03b5121a232e 5993 break;
pcercuei 0:03b5121a232e 5994 case XML_SCHEMAS_DATETIME:
pcercuei 0:03b5121a232e 5995 {
pcercuei 0:03b5121a232e 5996 char buf[50];
pcercuei 0:03b5121a232e 5997
pcercuei 0:03b5121a232e 5998 if (val->value.date.tz_flag) {
pcercuei 0:03b5121a232e 5999 xmlSchemaValPtr norm;
pcercuei 0:03b5121a232e 6000
pcercuei 0:03b5121a232e 6001 norm = xmlSchemaDateNormalize(val, 0);
pcercuei 0:03b5121a232e 6002 if (norm == NULL)
pcercuei 0:03b5121a232e 6003 return (-1);
pcercuei 0:03b5121a232e 6004 /*
pcercuei 0:03b5121a232e 6005 * TODO: Check if "%.14g" is portable.
pcercuei 0:03b5121a232e 6006 */
pcercuei 0:03b5121a232e 6007 snprintf(buf, 50,
pcercuei 0:03b5121a232e 6008 "%04ld:%02u:%02uT%02u:%02u:%02.14gZ",
pcercuei 0:03b5121a232e 6009 norm->value.date.year, norm->value.date.mon,
pcercuei 0:03b5121a232e 6010 norm->value.date.day, norm->value.date.hour,
pcercuei 0:03b5121a232e 6011 norm->value.date.min, norm->value.date.sec);
pcercuei 0:03b5121a232e 6012 xmlSchemaFreeValue(norm);
pcercuei 0:03b5121a232e 6013 } else {
pcercuei 0:03b5121a232e 6014 snprintf(buf, 50,
pcercuei 0:03b5121a232e 6015 "%04ld:%02u:%02uT%02u:%02u:%02.14g",
pcercuei 0:03b5121a232e 6016 val->value.date.year, val->value.date.mon,
pcercuei 0:03b5121a232e 6017 val->value.date.day, val->value.date.hour,
pcercuei 0:03b5121a232e 6018 val->value.date.min, val->value.date.sec);
pcercuei 0:03b5121a232e 6019 }
pcercuei 0:03b5121a232e 6020 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 6021 }
pcercuei 0:03b5121a232e 6022 break;
pcercuei 0:03b5121a232e 6023 case XML_SCHEMAS_HEXBINARY:
pcercuei 0:03b5121a232e 6024 *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.hex.str);
pcercuei 0:03b5121a232e 6025 break;
pcercuei 0:03b5121a232e 6026 case XML_SCHEMAS_BASE64BINARY:
pcercuei 0:03b5121a232e 6027 /*
pcercuei 0:03b5121a232e 6028 * TODO: Is the following spec piece implemented?:
pcercuei 0:03b5121a232e 6029 * SPEC: "Note: For some values the canonical form defined
pcercuei 0:03b5121a232e 6030 * above does not conform to [RFC 2045], which requires breaking
pcercuei 0:03b5121a232e 6031 * with linefeeds at appropriate intervals."
pcercuei 0:03b5121a232e 6032 */
pcercuei 0:03b5121a232e 6033 *retValue = BAD_CAST xmlStrdup(BAD_CAST val->value.base64.str);
pcercuei 0:03b5121a232e 6034 break;
pcercuei 0:03b5121a232e 6035 case XML_SCHEMAS_FLOAT: {
pcercuei 0:03b5121a232e 6036 char buf[30];
pcercuei 0:03b5121a232e 6037 /*
pcercuei 0:03b5121a232e 6038 * |m| < 16777216, -149 <= e <= 104.
pcercuei 0:03b5121a232e 6039 * TODO: Handle, NaN, INF, -INF. The format is not
pcercuei 0:03b5121a232e 6040 * yet conformant. The c type float does not cover
pcercuei 0:03b5121a232e 6041 * the whole range.
pcercuei 0:03b5121a232e 6042 */
pcercuei 0:03b5121a232e 6043 snprintf(buf, 30, "%01.14e", val->value.f);
pcercuei 0:03b5121a232e 6044 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 6045 }
pcercuei 0:03b5121a232e 6046 break;
pcercuei 0:03b5121a232e 6047 case XML_SCHEMAS_DOUBLE: {
pcercuei 0:03b5121a232e 6048 char buf[40];
pcercuei 0:03b5121a232e 6049 /* |m| < 9007199254740992, -1075 <= e <= 970 */
pcercuei 0:03b5121a232e 6050 /*
pcercuei 0:03b5121a232e 6051 * TODO: Handle, NaN, INF, -INF. The format is not
pcercuei 0:03b5121a232e 6052 * yet conformant. The c type float does not cover
pcercuei 0:03b5121a232e 6053 * the whole range.
pcercuei 0:03b5121a232e 6054 */
pcercuei 0:03b5121a232e 6055 snprintf(buf, 40, "%01.14e", val->value.d);
pcercuei 0:03b5121a232e 6056 *retValue = BAD_CAST xmlStrdup(BAD_CAST buf);
pcercuei 0:03b5121a232e 6057 }
pcercuei 0:03b5121a232e 6058 break;
pcercuei 0:03b5121a232e 6059 default:
pcercuei 0:03b5121a232e 6060 *retValue = BAD_CAST xmlStrdup(BAD_CAST "???");
pcercuei 0:03b5121a232e 6061 return (1);
pcercuei 0:03b5121a232e 6062 }
pcercuei 0:03b5121a232e 6063 if (*retValue == NULL)
pcercuei 0:03b5121a232e 6064 return(-1);
pcercuei 0:03b5121a232e 6065 return (0);
pcercuei 0:03b5121a232e 6066 }
pcercuei 0:03b5121a232e 6067
pcercuei 0:03b5121a232e 6068 /**
pcercuei 0:03b5121a232e 6069 * xmlSchemaGetCanonValueWhtsp:
pcercuei 0:03b5121a232e 6070 * @val: the precomputed value
pcercuei 0:03b5121a232e 6071 * @retValue: the returned value
pcercuei 0:03b5121a232e 6072 * @ws: the whitespace type of the value
pcercuei 0:03b5121a232e 6073 *
pcercuei 0:03b5121a232e 6074 * Get the canonical representation of the value.
pcercuei 0:03b5121a232e 6075 * The caller has to free the returned @retValue.
pcercuei 0:03b5121a232e 6076 *
pcercuei 0:03b5121a232e 6077 * Returns 0 if the value could be built, 1 if the value type is
pcercuei 0:03b5121a232e 6078 * not supported yet and -1 in case of API errors.
pcercuei 0:03b5121a232e 6079 */
pcercuei 0:03b5121a232e 6080 int
pcercuei 0:03b5121a232e 6081 xmlSchemaGetCanonValueWhtsp(xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 6082 const xmlChar **retValue,
pcercuei 0:03b5121a232e 6083 xmlSchemaWhitespaceValueType ws)
pcercuei 0:03b5121a232e 6084 {
pcercuei 0:03b5121a232e 6085 if ((retValue == NULL) || (val == NULL))
pcercuei 0:03b5121a232e 6086 return (-1);
pcercuei 0:03b5121a232e 6087 if ((ws == XML_SCHEMA_WHITESPACE_UNKNOWN) ||
pcercuei 0:03b5121a232e 6088 (ws > XML_SCHEMA_WHITESPACE_COLLAPSE))
pcercuei 0:03b5121a232e 6089 return (-1);
pcercuei 0:03b5121a232e 6090
pcercuei 0:03b5121a232e 6091 *retValue = NULL;
pcercuei 0:03b5121a232e 6092 switch (val->type) {
pcercuei 0:03b5121a232e 6093 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 6094 if (val->value.str == NULL)
pcercuei 0:03b5121a232e 6095 *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 6096 else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 6097 *retValue = xmlSchemaCollapseString(val->value.str);
pcercuei 0:03b5121a232e 6098 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 6099 *retValue = xmlSchemaWhiteSpaceReplace(val->value.str);
pcercuei 0:03b5121a232e 6100 if ((*retValue) == NULL)
pcercuei 0:03b5121a232e 6101 *retValue = BAD_CAST xmlStrdup(val->value.str);
pcercuei 0:03b5121a232e 6102 break;
pcercuei 0:03b5121a232e 6103 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 6104 if (val->value.str == NULL)
pcercuei 0:03b5121a232e 6105 *retValue = BAD_CAST xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 6106 else {
pcercuei 0:03b5121a232e 6107 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 6108 *retValue = xmlSchemaCollapseString(val->value.str);
pcercuei 0:03b5121a232e 6109 else
pcercuei 0:03b5121a232e 6110 *retValue = xmlSchemaWhiteSpaceReplace(val->value.str);
pcercuei 0:03b5121a232e 6111 if ((*retValue) == NULL)
pcercuei 0:03b5121a232e 6112 *retValue = BAD_CAST xmlStrdup(val->value.str);
pcercuei 0:03b5121a232e 6113 }
pcercuei 0:03b5121a232e 6114 break;
pcercuei 0:03b5121a232e 6115 default:
pcercuei 0:03b5121a232e 6116 return (xmlSchemaGetCanonValue(val, retValue));
pcercuei 0:03b5121a232e 6117 }
pcercuei 0:03b5121a232e 6118 return (0);
pcercuei 0:03b5121a232e 6119 }
pcercuei 0:03b5121a232e 6120
pcercuei 0:03b5121a232e 6121 /**
pcercuei 0:03b5121a232e 6122 * xmlSchemaGetValType:
pcercuei 0:03b5121a232e 6123 * @val: a schemas value
pcercuei 0:03b5121a232e 6124 *
pcercuei 0:03b5121a232e 6125 * Accessor for the type of a value
pcercuei 0:03b5121a232e 6126 *
pcercuei 0:03b5121a232e 6127 * Returns the xmlSchemaValType of the value
pcercuei 0:03b5121a232e 6128 */
pcercuei 0:03b5121a232e 6129 xmlSchemaValType
pcercuei 0:03b5121a232e 6130 xmlSchemaGetValType(xmlSchemaValPtr val)
pcercuei 0:03b5121a232e 6131 {
pcercuei 0:03b5121a232e 6132 if (val == NULL)
pcercuei 0:03b5121a232e 6133 return(XML_SCHEMAS_UNKNOWN);
pcercuei 0:03b5121a232e 6134 return (val->type);
pcercuei 0:03b5121a232e 6135 }
pcercuei 0:03b5121a232e 6136
pcercuei 0:03b5121a232e 6137 #define bottom_xmlschemastypes
pcercuei 0:03b5121a232e 6138 #include "elfgcchack.h"
pcercuei 0:03b5121a232e 6139 #endif /* LIBXML_SCHEMAS_ENABLED */
pcercuei 0:03b5121a232e 6140