2002-04-16 15:50:10 +00:00
/*
* schemastypes . c : implementation of the XML Schema Datatypes
* definition and validity checking
*
* See Copyright for the status of this software .
*
* Daniel Veillard < veillard @ redhat . com >
*/
# define IN_LIBXML
# include "libxml.h"
# ifdef LIBXML_SCHEMAS_ENABLED
# include <string.h>
# include <libxml/xmlmemory.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/hash.h>
# include <libxml/valid.h>
2003-02-06 08:22:32 +00:00
# include <libxml/xpath.h>
# include <libxml/uri.h>
2002-04-16 15:50:10 +00:00
# include <libxml/xmlschemas.h>
# include <libxml/schemasInternals.h>
# include <libxml/xmlschemastypes.h>
2002-05-03 07:29:38 +00:00
# ifdef HAVE_MATH_H
# include <math.h>
# endif
2002-04-16 15:50:10 +00:00
# define DEBUG
# define TODO \
xmlGenericError ( xmlGenericErrorContext , \
" Unimplemented block at %s:%d \n " , \
__FILE__ , __LINE__ ) ;
# define XML_SCHEMAS_NAMESPACE_NAME \
( const xmlChar * ) " http://www.w3.org/2001/XMLSchema "
typedef enum {
XML_SCHEMAS_UNKNOWN = 0 ,
XML_SCHEMAS_STRING ,
2003-02-27 17:42:22 +00:00
XML_SCHEMAS_NORMSTRING ,
2002-04-16 15:50:10 +00:00
XML_SCHEMAS_DECIMAL ,
2002-05-03 07:29:38 +00:00
XML_SCHEMAS_TIME ,
XML_SCHEMAS_GDAY ,
XML_SCHEMAS_GMONTH ,
XML_SCHEMAS_GMONTHDAY ,
XML_SCHEMAS_GYEAR ,
XML_SCHEMAS_GYEARMONTH ,
XML_SCHEMAS_DATE ,
XML_SCHEMAS_DATETIME ,
XML_SCHEMAS_DURATION ,
2002-09-16 10:51:38 +00:00
XML_SCHEMAS_FLOAT ,
XML_SCHEMAS_DOUBLE ,
2003-02-06 23:41:59 +00:00
XML_SCHEMAS_BOOLEAN ,
2003-02-27 17:42:22 +00:00
XML_SCHEMAS_TOKEN ,
XML_SCHEMAS_LANGUAGE ,
XML_SCHEMAS_NMTOKEN ,
XML_SCHEMAS_NMTOKENS ,
XML_SCHEMAS_NAME ,
XML_SCHEMAS_QNAME ,
XML_SCHEMAS_NCNAME ,
XML_SCHEMAS_ID ,
XML_SCHEMAS_IDREF ,
XML_SCHEMAS_IDREFS ,
XML_SCHEMAS_ENTITY ,
XML_SCHEMAS_ENTITIES ,
XML_SCHEMAS_NOTATION ,
XML_SCHEMAS_ANYURI ,
XML_SCHEMAS_INTEGER ,
XML_SCHEMAS_NPINTEGER ,
XML_SCHEMAS_NINTEGER ,
XML_SCHEMAS_NNINTEGER ,
XML_SCHEMAS_PINTEGER ,
2003-02-06 08:22:32 +00:00
XML_SCHEMAS_INT ,
2003-02-27 17:42:22 +00:00
XML_SCHEMAS_UINT ,
XML_SCHEMAS_LONG ,
XML_SCHEMAS_ULONG ,
XML_SCHEMAS_SHORT ,
XML_SCHEMAS_USHORT ,
XML_SCHEMAS_BYTE ,
2003-07-06 21:13:49 +00:00
XML_SCHEMAS_UBYTE ,
2003-08-27 14:15:15 +00:00
XML_SCHEMAS_HEXBINARY ,
XML_SCHEMAS_BASE64BINARY
2002-04-16 15:50:10 +00:00
} xmlSchemaValType ;
2003-03-05 10:01:43 +00:00
static unsigned long powten [ 10 ] = {
2002-04-16 15:50:10 +00:00
1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 , 10000000L ,
100000000L , 1000000000L
} ;
2002-05-03 07:29:38 +00:00
/* Date value */
typedef struct _xmlSchemaValDate xmlSchemaValDate ;
typedef xmlSchemaValDate * xmlSchemaValDatePtr ;
struct _xmlSchemaValDate {
long year ;
unsigned int mon : 4 ; /* 1 <= mon <= 12 */
unsigned int day : 5 ; /* 1 <= day <= 31 */
unsigned int hour : 5 ; /* 0 <= hour <= 23 */
unsigned int min : 6 ; /* 0 <= min <= 59 */
double sec ;
2003-05-09 23:09:55 +00:00
unsigned int tz_flag : 1 ; /* is tzo explicitely set? */
2002-05-03 07:29:38 +00:00
int tzo : 11 ; /* -1440 <= tzo <= 1440 */
} ;
/* Duration value */
typedef struct _xmlSchemaValDuration xmlSchemaValDuration ;
typedef xmlSchemaValDuration * xmlSchemaValDurationPtr ;
struct _xmlSchemaValDuration {
long mon ; /* mon stores years also */
long day ;
double sec ; /* sec stores min and hour also */
} ;
2002-04-16 15:50:10 +00:00
typedef struct _xmlSchemaValDecimal xmlSchemaValDecimal ;
typedef xmlSchemaValDecimal * xmlSchemaValDecimalPtr ;
struct _xmlSchemaValDecimal {
/* would use long long but not portable */
2003-03-30 21:10:09 +00:00
unsigned long lo ;
unsigned long mi ;
unsigned long hi ;
2002-04-16 15:50:10 +00:00
unsigned int extra ;
2002-05-22 06:40:27 +00:00
unsigned int sign : 1 ;
2003-08-05 15:52:22 +00:00
unsigned int frac : 7 ;
unsigned int total : 8 ;
2002-04-16 15:50:10 +00:00
} ;
2003-03-30 21:10:09 +00:00
typedef struct _xmlSchemaValQName xmlSchemaValQName ;
typedef xmlSchemaValQName * xmlSchemaValQNamePtr ;
struct _xmlSchemaValQName {
xmlChar * name ;
xmlChar * uri ;
} ;
2003-08-08 14:00:28 +00:00
typedef struct _xmlSchemaValHex xmlSchemaValHex ;
typedef xmlSchemaValHex * xmlSchemaValHexPtr ;
struct _xmlSchemaValHex {
xmlChar * str ;
unsigned int total ;
} ;
2003-08-27 14:15:15 +00:00
typedef struct _xmlSchemaValBase64 xmlSchemaValBase64 ;
typedef xmlSchemaValBase64 * xmlSchemaValBase64Ptr ;
struct _xmlSchemaValBase64 {
xmlChar * str ;
unsigned int total ;
} ;
2002-04-16 15:50:10 +00:00
struct _xmlSchemaVal {
xmlSchemaValType type ;
union {
2002-05-22 06:40:27 +00:00
xmlSchemaValDecimal decimal ;
2002-05-03 07:29:38 +00:00
xmlSchemaValDate date ;
xmlSchemaValDuration dur ;
2003-03-30 21:10:09 +00:00
xmlSchemaValQName qname ;
2003-08-08 14:00:28 +00:00
xmlSchemaValHex hex ;
2003-08-27 14:15:15 +00:00
xmlSchemaValBase64 base64 ;
2002-09-16 10:51:38 +00:00
float f ;
double d ;
2003-02-06 23:41:59 +00:00
int b ;
2003-03-29 10:53:38 +00:00
xmlChar * str ;
2002-04-16 15:50:10 +00:00
} value ;
} ;
static int xmlSchemaTypesInitialized = 0 ;
static xmlHashTablePtr xmlSchemaTypesBank = NULL ;
2003-01-27 12:35:42 +00:00
/*
* Basic types
*/
2002-04-16 15:50:10 +00:00
static xmlSchemaTypePtr xmlSchemaTypeStringDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeAnyTypeDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeAnySimpleTypeDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeDecimalDef = NULL ;
2002-05-03 07:29:38 +00:00
static xmlSchemaTypePtr xmlSchemaTypeDatetimeDef = NULL ;
2002-04-16 15:50:10 +00:00
static xmlSchemaTypePtr xmlSchemaTypeDateDef = NULL ;
2002-05-03 07:29:38 +00:00
static xmlSchemaTypePtr xmlSchemaTypeTimeDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGYearDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGYearMonthDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL ;
2002-09-16 10:51:38 +00:00
static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL ;
2003-02-06 23:41:59 +00:00
static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL ;
2002-09-16 10:51:38 +00:00
static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL ;
2003-07-06 21:13:49 +00:00
static xmlSchemaTypePtr xmlSchemaTypeHexBinaryDef = NULL ;
2003-08-27 14:15:15 +00:00
static xmlSchemaTypePtr xmlSchemaTypeBase64BinaryDef = NULL ;
2003-02-04 14:43:39 +00:00
static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL ;
2002-04-16 15:50:10 +00:00
2003-01-27 12:35:42 +00:00
/*
* Derived types
*/
static xmlSchemaTypePtr xmlSchemaTypePositiveIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNonPositiveIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNegativeIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNonNegativeIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeLongDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIntDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeShortDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeByteDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedLongDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedIntDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedShortDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedByteDef = NULL ;
2003-02-27 17:42:22 +00:00
static xmlSchemaTypePtr xmlSchemaTypeNormStringDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeTokenDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeLanguageDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNameDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeQNameDef = NULL ;
2003-02-04 14:43:39 +00:00
static xmlSchemaTypePtr xmlSchemaTypeNCNameDef = NULL ;
2003-02-27 17:42:22 +00:00
static xmlSchemaTypePtr xmlSchemaTypeIdDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIdrefDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIdrefsDef = NULL ;
2003-03-18 16:53:17 +00:00
static xmlSchemaTypePtr xmlSchemaTypeEntityDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeEntitiesDef = NULL ;
2003-03-30 21:10:09 +00:00
static xmlSchemaTypePtr xmlSchemaTypeNotationDef = NULL ;
2003-02-27 17:42:22 +00:00
static xmlSchemaTypePtr xmlSchemaTypeNmtokenDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL ;
2003-01-27 12:35:42 +00:00
2003-10-10 00:49:42 +00:00
/************************************************************************
* *
* Datatype error handlers *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaTypeErrMemory :
* @ extra : extra informations
*
* Handle an out of memory condition
*/
static void
xmlSchemaTypeErrMemory ( xmlNodePtr node , const char * extra )
{
__xmlSimpleError ( XML_FROM_DATATYPE , XML_ERR_NO_MEMORY , node , NULL , extra ) ;
}
/************************************************************************
* *
* Base types support *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-04-16 15:50:10 +00:00
/*
* xmlSchemaInitBasicType :
* @ name : the type name
2003-02-27 17:42:22 +00:00
* @ type : the value type associated
2002-04-16 15:50:10 +00:00
*
* Initialize one default type
*/
static xmlSchemaTypePtr
2003-02-27 17:42:22 +00:00
xmlSchemaInitBasicType ( const char * name , xmlSchemaValType type ) {
2002-04-16 15:50:10 +00:00
xmlSchemaTypePtr ret ;
ret = ( xmlSchemaTypePtr ) xmlMalloc ( sizeof ( xmlSchemaType ) ) ;
if ( ret = = NULL ) {
2003-10-10 00:49:42 +00:00
xmlSchemaTypeErrMemory ( NULL , " could not initialize basic types " ) ;
2002-04-16 15:50:10 +00:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaType ) ) ;
2003-11-22 20:37:51 +00:00
ret - > name = ( const xmlChar * ) name ;
2002-04-16 15:50:10 +00:00
ret - > type = XML_SCHEMA_TYPE_BASIC ;
2003-02-27 17:42:22 +00:00
ret - > flags = type ;
2002-04-16 15:50:10 +00:00
ret - > contentType = XML_SCHEMA_CONTENT_BASIC ;
xmlHashAddEntry2 ( xmlSchemaTypesBank , ret - > name ,
XML_SCHEMAS_NAMESPACE_NAME , ret ) ;
return ( ret ) ;
}
/*
* xmlSchemaInitTypes :
*
* Initialize the default XML Schemas type library
*/
void
2003-03-27 21:25:38 +00:00
xmlSchemaInitTypes ( void )
{
2002-04-16 15:50:10 +00:00
if ( xmlSchemaTypesInitialized ! = 0 )
2003-03-27 21:25:38 +00:00
return ;
2002-04-16 15:50:10 +00:00
xmlSchemaTypesBank = xmlHashCreate ( 40 ) ;
2003-03-27 21:25:38 +00:00
2003-01-27 12:35:42 +00:00
/*
* primitive datatypes
*/
2003-02-27 17:42:22 +00:00
xmlSchemaTypeStringDef = xmlSchemaInitBasicType ( " string " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_STRING ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType ( " anyType " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_UNKNOWN ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType ( " anySimpleType " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_UNKNOWN ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType ( " decimal " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_DECIMAL ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDateDef = xmlSchemaInitBasicType ( " date " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_DATE ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType ( " dateTime " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_DATETIME ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeTimeDef = xmlSchemaInitBasicType ( " time " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_TIME ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGYearDef = xmlSchemaInitBasicType ( " gYear " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_GYEAR ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType ( " gYearMonth " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_GYEARMONTH ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType ( " gMonth " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_GMONTH ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType ( " gMonthDay " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_GMONTHDAY ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGDayDef = xmlSchemaInitBasicType ( " gDay " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_GDAY ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDurationDef = xmlSchemaInitBasicType ( " duration " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_DURATION ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeFloatDef = xmlSchemaInitBasicType ( " float " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_FLOAT ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType ( " double " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_DOUBLE ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType ( " boolean " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_BOOLEAN ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType ( " anyURI " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_ANYURI ) ;
2003-07-06 21:13:49 +00:00
xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType ( " hexBinary " ,
XML_SCHEMAS_HEXBINARY ) ;
2003-08-27 14:15:15 +00:00
xmlSchemaTypeBase64BinaryDef
= xmlSchemaInitBasicType ( " base64Binary " , XML_SCHEMAS_BASE64BINARY ) ;
2002-04-16 15:50:10 +00:00
2003-01-27 12:35:42 +00:00
/*
* derived datatypes
*/
2003-02-27 17:42:22 +00:00
xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType ( " integer " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_INTEGER ) ; ;
xmlSchemaTypeNonPositiveIntegerDef =
xmlSchemaInitBasicType ( " nonPositiveInteger " ,
XML_SCHEMAS_NPINTEGER ) ; ;
xmlSchemaTypeNegativeIntegerDef =
xmlSchemaInitBasicType ( " negativeInteger " , XML_SCHEMAS_NINTEGER ) ; ;
xmlSchemaTypeLongDef =
xmlSchemaInitBasicType ( " long " , XML_SCHEMAS_LONG ) ; ;
xmlSchemaTypeIntDef = xmlSchemaInitBasicType ( " int " , XML_SCHEMAS_INT ) ; ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeShortDef = xmlSchemaInitBasicType ( " short " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_SHORT ) ; ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeByteDef = xmlSchemaInitBasicType ( " byte " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_BYTE ) ; ;
xmlSchemaTypeNonNegativeIntegerDef =
xmlSchemaInitBasicType ( " nonNegativeInteger " ,
XML_SCHEMAS_NNINTEGER ) ;
xmlSchemaTypeUnsignedLongDef =
xmlSchemaInitBasicType ( " unsignedLong " , XML_SCHEMAS_ULONG ) ; ;
xmlSchemaTypeUnsignedIntDef =
xmlSchemaInitBasicType ( " unsignedInt " , XML_SCHEMAS_UINT ) ; ;
xmlSchemaTypeUnsignedShortDef =
2003-03-30 21:10:09 +00:00
xmlSchemaInitBasicType ( " unsignedShort " , XML_SCHEMAS_USHORT ) ; ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeUnsignedByteDef =
xmlSchemaInitBasicType ( " unsignedByte " , XML_SCHEMAS_UBYTE ) ; ;
xmlSchemaTypePositiveIntegerDef =
xmlSchemaInitBasicType ( " positiveInteger " , XML_SCHEMAS_PINTEGER ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType ( " normalizedString " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_NORMSTRING ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeTokenDef = xmlSchemaInitBasicType ( " token " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_TOKEN ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType ( " language " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_LANGUAGE ) ;
xmlSchemaTypeIdDef = xmlSchemaInitBasicType ( " ID " , XML_SCHEMAS_ID ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType ( " IDREF " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_IDREF ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType ( " IDREFS " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_IDREFS ) ;
2003-03-18 16:53:17 +00:00
xmlSchemaTypeEntityDef = xmlSchemaInitBasicType ( " ENTITY " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_ENTITY ) ;
2003-03-18 16:53:17 +00:00
xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType ( " ENTITIES " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_ENTITIES ) ;
2003-03-30 21:10:09 +00:00
xmlSchemaTypeNotationDef = xmlSchemaInitBasicType ( " NOTATION " ,
XML_SCHEMAS_NOTATION ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeNameDef = xmlSchemaInitBasicType ( " Name " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_NAME ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeQNameDef = xmlSchemaInitBasicType ( " QName " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_QNAME ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType ( " NCName " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_NCNAME ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType ( " NMTOKEN " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_NMTOKEN ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType ( " NMTOKENS " ,
2003-03-27 21:25:38 +00:00
XML_SCHEMAS_NMTOKENS ) ;
2002-04-16 15:50:10 +00:00
xmlSchemaTypesInitialized = 1 ;
}
/**
* xmlSchemaCleanupTypes :
*
* Cleanup the default XML Schemas type library
*/
void
xmlSchemaCleanupTypes ( void ) {
if ( xmlSchemaTypesInitialized = = 0 )
return ;
xmlHashFree ( xmlSchemaTypesBank , ( xmlHashDeallocator ) xmlSchemaFreeType ) ;
xmlSchemaTypesInitialized = 0 ;
}
/**
* xmlSchemaNewValue :
* @ type : the value type
*
* Allocate a new simple type value
*
* Returns a pointer to the new value or NULL in case of error
*/
static xmlSchemaValPtr
xmlSchemaNewValue ( xmlSchemaValType type ) {
xmlSchemaValPtr value ;
value = ( xmlSchemaValPtr ) xmlMalloc ( sizeof ( xmlSchemaVal ) ) ;
if ( value = = NULL ) {
return ( NULL ) ;
}
memset ( value , 0 , sizeof ( xmlSchemaVal ) ) ;
value - > type = type ;
return ( value ) ;
}
/**
* xmlSchemaFreeValue :
* @ value : the value to free
*
* Cleanup the default XML Schemas type library
*/
void
xmlSchemaFreeValue ( xmlSchemaValPtr value ) {
if ( value = = NULL )
return ;
2003-03-29 10:53:38 +00:00
switch ( value - > type ) {
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NMTOKENS :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_ENTITY :
case XML_SCHEMAS_ENTITIES :
case XML_SCHEMAS_NOTATION :
case XML_SCHEMAS_ANYURI :
if ( value - > value . str ! = NULL )
xmlFree ( value - > value . str ) ;
break ;
2003-03-30 21:10:09 +00:00
case XML_SCHEMAS_QNAME :
if ( value - > value . qname . uri ! = NULL )
xmlFree ( value - > value . qname . uri ) ;
if ( value - > value . qname . name ! = NULL )
xmlFree ( value - > value . qname . name ) ;
break ;
2003-08-08 14:00:28 +00:00
case XML_SCHEMAS_HEXBINARY :
if ( value - > value . hex . str ! = NULL )
xmlFree ( value - > value . hex . str ) ;
break ;
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_BASE64BINARY :
if ( value - > value . base64 . str ! = NULL )
xmlFree ( value - > value . base64 . str ) ;
break ;
2003-03-29 10:53:38 +00:00
default :
break ;
}
2002-04-16 15:50:10 +00:00
xmlFree ( value ) ;
}
/**
* xmlSchemaGetPredefinedType :
* @ name : the type name
* @ ns : the URI of the namespace usually " http://www.w3.org/2001/XMLSchema "
*
* Lookup a type in the default XML Schemas type library
*
* Returns the type if found , NULL otherwise
*/
xmlSchemaTypePtr
xmlSchemaGetPredefinedType ( const xmlChar * name , const xmlChar * ns ) {
if ( xmlSchemaTypesInitialized = = 0 )
xmlSchemaInitTypes ( ) ;
if ( name = = NULL )
return ( NULL ) ;
return ( ( xmlSchemaTypePtr ) xmlHashLookup2 ( xmlSchemaTypesBank , name , ns ) ) ;
}
2002-05-03 07:29:38 +00:00
/****************************************************************
* *
* Convenience macros and functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define IS_TZO_CHAR(c) \
( ( c = = 0 ) | | ( c = = ' Z ' ) | | ( c = = ' + ' ) | | ( c = = ' - ' ) )
# define VALID_YEAR(yr) (yr != 0)
# define VALID_MONTH(mon) ((mon >= 1) && (mon <= 12))
/* VALID_DAY should only be used when month is unknown */
# define VALID_DAY(day) ((day >= 1) && (day <= 31))
# define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
# define VALID_MIN(min) ((min >= 0) && (min <= 59))
# define VALID_SEC(sec) ((sec >= 0) && (sec < 60))
# define VALID_TZO(tzo) ((tzo > -1440) && (tzo < 1440))
# define IS_LEAP(y) \
( ( ( y % 4 = = 0 ) & & ( y % 100 ! = 0 ) ) | | ( y % 400 = = 0 ) )
2004-03-25 09:35:49 +00:00
static const unsigned int daysInMonth [ 12 ] =
2002-05-03 07:29:38 +00:00
{ 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
2004-03-25 09:35:49 +00:00
static const unsigned int daysInMonthLeap [ 12 ] =
2002-05-03 07:29:38 +00:00
{ 31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
2002-05-22 06:40:27 +00:00
# define MAX_DAYINMONTH(yr,mon) \
( IS_LEAP ( yr ) ? daysInMonthLeap [ mon - 1 ] : daysInMonth [ mon - 1 ] )
2002-05-03 07:29:38 +00:00
# define VALID_MDAY(dt) \
( IS_LEAP ( dt - > year ) ? \
( dt - > day < = daysInMonthLeap [ dt - > mon - 1 ] ) : \
( dt - > day < = daysInMonth [ dt - > mon - 1 ] ) )
# define VALID_DATE(dt) \
( VALID_YEAR ( dt - > year ) & & VALID_MONTH ( dt - > mon ) & & VALID_MDAY ( dt ) )
# define VALID_TIME(dt) \
( VALID_HOUR ( dt - > hour ) & & VALID_MIN ( dt - > min ) & & \
VALID_SEC ( dt - > sec ) & & VALID_TZO ( dt - > tzo ) )
# define VALID_DATETIME(dt) \
( VALID_DATE ( dt ) & & VALID_TIME ( dt ) )
# define SECS_PER_MIN (60)
# define SECS_PER_HOUR (60 * SECS_PER_MIN)
# define SECS_PER_DAY (24 * SECS_PER_HOUR)
2002-05-22 06:40:27 +00:00
static const long dayInYearByMonth [ 12 ] =
{ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 } ;
static const long dayInLeapYearByMonth [ 12 ] =
{ 0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335 } ;
# define DAY_IN_YEAR(day, month, year) \
( ( IS_LEAP ( year ) ? \
dayInLeapYearByMonth [ month - 1 ] : \
dayInYearByMonth [ month - 1 ] ) + day )
# ifdef DEBUG
# define DEBUG_DATE(dt) \
xmlGenericError ( xmlGenericErrorContext , \
" type=%o %04ld-%02u-%02uT%02u:%02u:%03f " , \
dt - > type , dt - > value . date . year , dt - > value . date . mon , \
dt - > value . date . day , dt - > value . date . hour , dt - > value . date . min , \
dt - > value . date . sec ) ; \
if ( dt - > value . date . tz_flag ) \
if ( dt - > value . date . tzo ! = 0 ) \
xmlGenericError ( xmlGenericErrorContext , \
" %+05d \n " , dt - > value . date . tzo ) ; \
else \
xmlGenericError ( xmlGenericErrorContext , " Z \n " ) ; \
else \
xmlGenericError ( xmlGenericErrorContext , " \n " )
# else
# define DEBUG_DATE(dt)
# endif
2002-05-03 07:29:38 +00:00
/**
* _xmlSchemaParseGYear :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : gYear without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* xs : gYear . It is supposed that @ dt - > year is big enough to contain
* the year .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseGYear ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str , * firstChar ;
int isneg = 0 , digcnt = 0 ;
if ( ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) & &
( * cur ! = ' - ' ) & & ( * cur ! = ' + ' ) )
return - 1 ;
if ( * cur = = ' - ' ) {
isneg = 1 ;
cur + + ;
}
firstChar = cur ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
dt - > year = dt - > year * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
digcnt + + ;
}
/* year must be at least 4 digits (CCYY); over 4
* digits cannot have a leading zero . */
if ( ( digcnt < 4 ) | | ( ( digcnt > 4 ) & & ( * firstChar = = ' 0 ' ) ) )
return 1 ;
if ( isneg )
dt - > year = - dt - > year ;
if ( ! VALID_YEAR ( dt - > year ) )
return 2 ;
* str = cur ;
return 0 ;
}
/**
* PARSE_2_DIGITS :
* @ num : the integer to fill in
* @ cur : an # xmlChar *
* @ invalid : an integer
*
* Parses a 2 - digits integer and updates @ num with the value . @ cur is
* updated to point just after the integer .
* In case of error , @ invalid is set to % TRUE , values of @ num and
* @ cur are undefined .
*/
# define PARSE_2_DIGITS(num, cur, invalid) \
if ( ( cur [ 0 ] < ' 0 ' ) | | ( cur [ 0 ] > ' 9 ' ) | | \
( cur [ 1 ] < ' 0 ' ) | | ( cur [ 1 ] > ' 9 ' ) ) \
invalid = 1 ; \
else \
num = ( cur [ 0 ] - ' 0 ' ) * 10 + ( cur [ 1 ] - ' 0 ' ) ; \
cur + = 2 ;
/**
* PARSE_FLOAT :
* @ num : the double to fill in
* @ cur : an # xmlChar *
* @ invalid : an integer
*
* Parses a float and updates @ num with the value . @ cur is
* updated to point just after the float . The float must have a
* 2 - digits integer part and may or may not have a decimal part .
* In case of error , @ invalid is set to % TRUE , values of @ num and
* @ cur are undefined .
*/
# define PARSE_FLOAT(num, cur, invalid) \
PARSE_2_DIGITS ( num , cur , invalid ) ; \
if ( ! invalid & & ( * cur = = ' . ' ) ) { \
double mult = 1 ; \
cur + + ; \
if ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) \
invalid = 1 ; \
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) { \
mult / = 10 ; \
num + = ( * cur - ' 0 ' ) * mult ; \
cur + + ; \
} \
}
/**
* _xmlSchemaParseGMonth :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : gMonth without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* xs : gMonth .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseGMonth ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str ;
int ret = 0 ;
PARSE_2_DIGITS ( dt - > mon , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_MONTH ( dt - > mon ) )
return 2 ;
* str = cur ;
return 0 ;
}
/**
* _xmlSchemaParseGDay :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : gDay without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* xs : gDay .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseGDay ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str ;
int ret = 0 ;
PARSE_2_DIGITS ( dt - > day , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_DAY ( dt - > day ) )
return 2 ;
* str = cur ;
return 0 ;
}
/**
* _xmlSchemaParseTime :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : time without time zone and fills in the appropriate
* fields of the @ dt structure . @ str is updated to point just after the
* xs : time .
* In case of error , values of @ dt fields are undefined .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseTime ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str ;
unsigned int hour = 0 ; /* use temp var in case str is not xs:time */
int ret = 0 ;
PARSE_2_DIGITS ( hour , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( * cur ! = ' : ' )
return 1 ;
cur + + ;
/* the ':' insures this string is xs:time */
dt - > hour = hour ;
PARSE_2_DIGITS ( dt - > min , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( * cur ! = ' : ' )
return 1 ;
cur + + ;
PARSE_FLOAT ( dt - > sec , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_TIME ( dt ) )
return 2 ;
* str = cur ;
return 0 ;
}
/**
* _xmlSchemaParseTimeZone :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a time zone without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* time zone .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseTimeZone ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str ;
int ret = 0 ;
if ( str = = NULL )
return - 1 ;
switch ( * cur ) {
case 0 :
dt - > tz_flag = 0 ;
dt - > tzo = 0 ;
break ;
case ' Z ' :
dt - > tz_flag = 1 ;
dt - > tzo = 0 ;
cur + + ;
break ;
case ' + ' :
case ' - ' : {
int isneg = 0 , tmp = 0 ;
isneg = ( * cur = = ' - ' ) ;
cur + + ;
PARSE_2_DIGITS ( tmp , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_HOUR ( tmp ) )
return 2 ;
if ( * cur ! = ' : ' )
return 1 ;
cur + + ;
dt - > tzo = tmp * 60 ;
PARSE_2_DIGITS ( tmp , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_MIN ( tmp ) )
return 2 ;
dt - > tzo + = tmp ;
if ( isneg )
dt - > tzo = - dt - > tzo ;
if ( ! VALID_TZO ( dt - > tzo ) )
return 2 ;
2002-05-22 06:40:27 +00:00
dt - > tz_flag = 1 ;
2002-05-03 07:29:38 +00:00
break ;
}
default :
return 1 ;
}
* str = cur ;
return 0 ;
}
2003-08-27 14:15:15 +00:00
/**
* _xmlSchemaBase64Decode :
* @ ch : a character
*
* Converts a base64 encoded character to its base 64 value .
*
* Returns 0 - 63 ( value ) , 64 ( pad ) , or - 1 ( not recognized )
*/
static int
_xmlSchemaBase64Decode ( const xmlChar ch ) {
if ( ( ' A ' < = ch ) & & ( ch < = ' Z ' ) ) return ch - ' A ' ;
if ( ( ' a ' < = ch ) & & ( ch < = ' z ' ) ) return ch - ' a ' + 26 ;
if ( ( ' 0 ' < = ch ) & & ( ch < = ' 9 ' ) ) return ch - ' 0 ' + 52 ;
if ( ' + ' = = ch ) return 62 ;
if ( ' / ' = = ch ) return 63 ;
if ( ' = ' = = ch ) return 64 ;
return - 1 ;
}
2002-05-03 07:29:38 +00:00
/****************************************************************
* *
* XML Schema Dates / Times Datatypes Handling *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* PARSE_DIGITS :
* @ num : the integer to fill in
* @ cur : an # xmlChar *
* @ num_type : an integer flag
*
* Parses a digits integer and updates @ num with the value . @ cur is
* updated to point just after the integer .
* In case of error , @ num_type is set to - 1 , values of @ num and
* @ cur are undefined .
*/
# define PARSE_DIGITS(num, cur, num_type) \
if ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) \
num_type = - 1 ; \
else \
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) { \
num = num * 10 + ( * cur - ' 0 ' ) ; \
cur + + ; \
}
/**
* PARSE_NUM :
* @ num : the double to fill in
* @ cur : an # xmlChar *
* @ num_type : an integer flag
*
* Parses a float or integer and updates @ num with the value . @ cur is
* updated to point just after the number . If the number is a float ,
* then it must have an integer part and a decimal part ; @ num_type will
* be set to 1. If there is no decimal part , @ num_type is set to zero .
* In case of error , @ num_type is set to - 1 , values of @ num and
* @ cur are undefined .
*/
# define PARSE_NUM(num, cur, num_type) \
num = 0 ; \
PARSE_DIGITS ( num , cur , num_type ) ; \
if ( ! num_type & & ( * cur = = ' . ' ) ) { \
double mult = 1 ; \
cur + + ; \
if ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) \
num_type = - 1 ; \
else \
num_type = 1 ; \
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) { \
mult / = 10 ; \
num + = ( * cur - ' 0 ' ) * mult ; \
cur + + ; \
} \
}
/**
2002-05-22 06:40:27 +00:00
* xmlSchemaValidateDates :
2003-03-31 10:13:23 +00:00
* @ type : the expected type or XML_SCHEMAS_UNKNOWN
2002-05-03 07:29:38 +00:00
* @ dateTime : string to analyze
* @ val : the return computed value
*
* Check that @ dateTime conforms to the lexical space of one of the date types .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
static int
2003-03-31 10:13:23 +00:00
xmlSchemaValidateDates ( xmlSchemaValType type ,
2002-09-24 14:13:13 +00:00
const xmlChar * dateTime , xmlSchemaValPtr * val ) {
2002-05-03 07:29:38 +00:00
xmlSchemaValPtr dt ;
int ret ;
const xmlChar * cur = dateTime ;
# define RETURN_TYPE_IF_VALID(t) \
if ( IS_TZO_CHAR ( * cur ) ) { \
ret = _xmlSchemaParseTimeZone ( & ( dt - > value . date ) , & cur ) ; \
if ( ret = = 0 ) { \
if ( * cur ! = 0 ) \
goto error ; \
dt - > type = t ; \
2003-03-31 10:13:23 +00:00
goto done ; \
2002-05-03 07:29:38 +00:00
} \
}
if ( dateTime = = NULL )
return - 1 ;
if ( ( * cur ! = ' - ' ) & & ( * cur < ' 0 ' ) & & ( * cur > ' 9 ' ) )
return 1 ;
dt = xmlSchemaNewValue ( XML_SCHEMAS_UNKNOWN ) ;
if ( dt = = NULL )
return - 1 ;
if ( ( cur [ 0 ] = = ' - ' ) & & ( cur [ 1 ] = = ' - ' ) ) {
/*
* It ' s an incomplete date ( xs : gMonthDay , xs : gMonth or
* xs : gDay )
*/
cur + = 2 ;
/* is it an xs:gDay? */
if ( * cur = = ' - ' ) {
2003-03-31 10:13:23 +00:00
if ( type = = XML_SCHEMAS_GMONTH )
goto error ;
2002-05-03 07:29:38 +00:00
+ + cur ;
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GDAY ) ;
goto error ;
}
/*
* it should be an xs : gMonthDay or xs : gMonth
*/
ret = _xmlSchemaParseGMonth ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
2003-04-09 11:24:17 +00:00
/*
* a ' - ' char could indicate this type is xs : gMonthDay or
* a negative time zone offset . Check for xs : gMonthDay first .
* Also the first three char ' s of a negative tzo ( - MM : SS ) can
* appear to be a valid day ; so even if the day portion
* of the xs : gMonthDay verifies , we must insure it was not
* a tzo .
*/
if ( * cur = = ' - ' ) {
const xmlChar * rewnd = cur ;
cur + + ;
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
if ( ( ret = = 0 ) & & ( ( * cur = = 0 ) | | ( * cur ! = ' : ' ) ) ) {
/*
* we can use the VALID_MDAY macro to validate the month
* and day because the leap year test will flag year zero
* as a leap year ( even though zero is an invalid year ) .
*/
if ( VALID_MDAY ( ( & ( dt - > value . date ) ) ) ) {
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GMONTHDAY ) ;
2002-05-03 07:29:38 +00:00
2003-04-09 11:24:17 +00:00
goto error ;
}
}
/*
* not xs : gMonthDay so rewind and check if just xs : gMonth
* with an optional time zone .
*/
cur = rewnd ;
}
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GMONTH ) ;
2002-05-03 07:29:38 +00:00
goto error ;
}
/*
* It ' s a right - truncated date or an xs : time .
* Try to parse an xs : time then fallback on right - truncated dates .
*/
if ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
ret = _xmlSchemaParseTime ( & ( dt - > value . date ) , & cur ) ;
if ( ret = = 0 ) {
/* it's an xs:time */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_TIME ) ;
}
}
/* fallback on date parsing */
cur = dateTime ;
ret = _xmlSchemaParseGYear ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
/* is it an xs:gYear? */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GYEAR ) ;
if ( * cur ! = ' - ' )
goto error ;
cur + + ;
ret = _xmlSchemaParseGMonth ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
/* is it an xs:gYearMonth? */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GYEARMONTH ) ;
if ( * cur ! = ' - ' )
goto error ;
cur + + ;
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
if ( ( ret ! = 0 ) | | ! VALID_DATE ( ( & ( dt - > value . date ) ) ) )
goto error ;
/* is it an xs:date? */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_DATE ) ;
if ( * cur ! = ' T ' )
goto error ;
cur + + ;
/* it should be an xs:dateTime */
ret = _xmlSchemaParseTime ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
ret = _xmlSchemaParseTimeZone ( & ( dt - > value . date ) , & cur ) ;
if ( ( ret ! = 0 ) | | ( * cur ! = 0 ) | | ! VALID_DATETIME ( ( & ( dt - > value . date ) ) ) )
goto error ;
2003-03-31 10:13:23 +00:00
2002-05-03 07:29:38 +00:00
dt - > type = XML_SCHEMAS_DATETIME ;
2003-03-31 10:13:23 +00:00
done :
2003-04-09 11:24:17 +00:00
# if 1
if ( ( type ! = XML_SCHEMAS_UNKNOWN ) & & ( type ! = dt - > type ) )
goto error ;
# else
/*
* insure the parsed type is equal to or less significant ( right
* truncated ) than the desired type .
*/
if ( ( type ! = XML_SCHEMAS_UNKNOWN ) & & ( type ! = dt - > type ) ) {
/* time only matches time */
if ( ( type = = XML_SCHEMAS_TIME ) & & ( dt - > type = = XML_SCHEMAS_TIME ) )
goto error ;
if ( ( type = = XML_SCHEMAS_DATETIME ) & &
( ( dt - > type ! = XML_SCHEMAS_DATE ) | |
( dt - > type ! = XML_SCHEMAS_GYEARMONTH ) | |
( dt - > type ! = XML_SCHEMAS_GYEAR ) ) )
goto error ;
if ( ( type = = XML_SCHEMAS_DATE ) & &
( ( dt - > type ! = XML_SCHEMAS_GYEAR ) | |
( dt - > type ! = XML_SCHEMAS_GYEARMONTH ) ) )
goto error ;
if ( ( type = = XML_SCHEMAS_GYEARMONTH ) & & ( dt - > type ! = XML_SCHEMAS_GYEAR ) )
goto error ;
if ( ( type = = XML_SCHEMAS_GMONTHDAY ) & & ( dt - > type ! = XML_SCHEMAS_GMONTH ) )
goto error ;
}
2003-03-31 10:13:23 +00:00
# endif
2002-05-03 07:29:38 +00:00
if ( val ! = NULL )
* val = dt ;
2003-03-28 13:29:53 +00:00
else
xmlSchemaFreeValue ( dt ) ;
2002-05-03 07:29:38 +00:00
return 0 ;
error :
if ( dt ! = NULL )
xmlSchemaFreeValue ( dt ) ;
return 1 ;
}
/**
2002-05-22 06:40:27 +00:00
* xmlSchemaValidateDuration :
2002-05-03 07:29:38 +00:00
* @ type : the predefined type
* @ duration : string to analyze
* @ val : the return computed value
*
* Check that @ duration conforms to the lexical space of the duration type .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
static int
2002-09-26 09:47:36 +00:00
xmlSchemaValidateDuration ( xmlSchemaTypePtr type ATTRIBUTE_UNUSED ,
2002-09-24 14:13:13 +00:00
const xmlChar * duration , xmlSchemaValPtr * val ) {
2002-05-03 07:29:38 +00:00
const xmlChar * cur = duration ;
xmlSchemaValPtr dur ;
int isneg = 0 ;
unsigned int seq = 0 ;
2003-04-09 11:24:17 +00:00
double num ;
int num_type = 0 ; /* -1 = invalid, 0 = int, 1 = floating */
const xmlChar desig [ ] = { ' Y ' , ' M ' , ' D ' , ' H ' , ' M ' , ' S ' } ;
const double multi [ ] = { 0.0 , 0.0 , 86400.0 , 3600.0 , 60.0 , 1.0 , 0.0 } ;
2002-05-03 07:29:38 +00:00
if ( duration = = NULL )
return - 1 ;
if ( * cur = = ' - ' ) {
isneg = 1 ;
cur + + ;
}
/* duration must start with 'P' (after sign) */
if ( * cur + + ! = ' P ' )
return 1 ;
2003-03-28 13:29:53 +00:00
if ( * cur = = 0 )
return 1 ;
2002-05-03 07:29:38 +00:00
dur = xmlSchemaNewValue ( XML_SCHEMAS_DURATION ) ;
if ( dur = = NULL )
return - 1 ;
while ( * cur ! = 0 ) {
/* input string should be empty or invalid date/time item */
if ( seq > = sizeof ( desig ) )
goto error ;
/* T designator must be present for time items */
if ( * cur = = ' T ' ) {
if ( seq < = 3 ) {
seq = 3 ;
cur + + ;
} else
return 1 ;
} else if ( seq = = 3 )
goto error ;
/* parse the number portion of the item */
PARSE_NUM ( num , cur , num_type ) ;
if ( ( num_type = = - 1 ) | | ( * cur = = 0 ) )
goto error ;
/* update duration based on item type */
while ( seq < sizeof ( desig ) ) {
if ( * cur = = desig [ seq ] ) {
/* verify numeric type; only seconds can be float */
if ( ( num_type ! = 0 ) & & ( seq < ( sizeof ( desig ) - 1 ) ) )
goto error ;
switch ( seq ) {
case 0 :
dur - > value . dur . mon = ( long ) num * 12 ;
break ;
case 1 :
dur - > value . dur . mon + = ( long ) num ;
break ;
default :
/* convert to seconds using multiplier */
dur - > value . dur . sec + = num * multi [ seq ] ;
seq + + ;
break ;
}
break ; /* exit loop */
}
/* no date designators found? */
if ( + + seq = = 3 )
goto error ;
}
cur + + ;
}
if ( isneg ) {
dur - > value . dur . mon = - dur - > value . dur . mon ;
dur - > value . dur . day = - dur - > value . dur . day ;
dur - > value . dur . sec = - dur - > value . dur . sec ;
}
if ( val ! = NULL )
* val = dur ;
2003-03-28 13:29:53 +00:00
else
xmlSchemaFreeValue ( dur ) ;
2002-05-03 07:29:38 +00:00
return 0 ;
error :
if ( dur ! = NULL )
xmlSchemaFreeValue ( dur ) ;
return 1 ;
}
2003-03-18 16:53:17 +00:00
/**
* xmlSchemaStrip :
* @ value : a value
*
* Removes the leading and ending spaces of a string
*
* Returns the new string or NULL if no change was required .
*/
static xmlChar *
xmlSchemaStrip ( const xmlChar * value ) {
const xmlChar * start = value , * end , * f ;
if ( value = = NULL ) return ( NULL ) ;
2003-10-18 16:20:14 +00:00
while ( ( * start ! = 0 ) & & ( IS_BLANK_CH ( * start ) ) ) start + + ;
2003-03-18 16:53:17 +00:00
end = start ;
while ( * end ! = 0 ) end + + ;
f = end ;
end - - ;
2003-10-18 16:20:14 +00:00
while ( ( end > start ) & & ( IS_BLANK_CH ( * end ) ) ) end - - ;
2003-03-18 16:53:17 +00:00
end + + ;
if ( ( start = = value ) & & ( f = = end ) ) return ( NULL ) ;
return ( xmlStrndup ( start , end - start ) ) ;
}
2003-02-06 08:22:32 +00:00
2003-03-29 16:41:55 +00:00
/**
* xmlSchemaCollapseString :
* @ value : a value
*
* Removes and normalize white spaces in the string
*
* Returns the new string or NULL if no change was required .
*/
static xmlChar *
xmlSchemaCollapseString ( const xmlChar * value ) {
const xmlChar * start = value , * end , * f ;
xmlChar * g ;
int col = 0 ;
if ( value = = NULL ) return ( NULL ) ;
2003-10-18 16:20:14 +00:00
while ( ( * start ! = 0 ) & & ( IS_BLANK_CH ( * start ) ) ) start + + ;
2003-03-29 16:41:55 +00:00
end = start ;
while ( * end ! = 0 ) {
2003-10-18 16:20:14 +00:00
if ( ( * end = = ' ' ) & & ( IS_BLANK_CH ( end [ 1 ] ) ) ) {
2003-03-29 16:41:55 +00:00
col = end - start ;
break ;
} else if ( ( * end = = 0xa ) | | ( * end = = 0x9 ) | | ( * end = = 0xd ) ) {
col = end - start ;
break ;
}
end + + ;
}
if ( col = = 0 ) {
f = end ;
end - - ;
2003-10-18 16:20:14 +00:00
while ( ( end > start ) & & ( IS_BLANK_CH ( * end ) ) ) end - - ;
2003-03-29 16:41:55 +00:00
end + + ;
if ( ( start = = value ) & & ( f = = end ) ) return ( NULL ) ;
return ( xmlStrndup ( start , end - start ) ) ;
}
start = xmlStrdup ( start ) ;
if ( start = = NULL ) return ( NULL ) ;
g = ( xmlChar * ) ( start + col ) ;
end = g ;
while ( * end ! = 0 ) {
2003-10-18 16:20:14 +00:00
if ( IS_BLANK_CH ( * end ) ) {
2003-03-29 16:41:55 +00:00
end + + ;
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * end ) ) end + + ;
2003-03-29 16:41:55 +00:00
if ( * end ! = 0 )
* g + + = ' ' ;
} else
* g + + = * end + + ;
}
* g = 0 ;
return ( ( xmlChar * ) start ) ;
}
2003-03-18 11:39:17 +00:00
/**
* xmlSchemaValAtomicListNode :
* @ type : the predefined atomic type for a token in the list
* @ value : the list value to check
* @ ret : the return computed value
* @ node : the node containing the value
*
* Check that a value conforms to the lexical space of the predefined
* list type . if true a value is computed and returned in @ ret .
*
2003-03-18 16:53:17 +00:00
* Returns the number of items if this validates , a negative error code
* number otherwise
2003-03-18 11:39:17 +00:00
*/
static int
xmlSchemaValAtomicListNode ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * ret , xmlNodePtr node ) {
xmlChar * val , * cur , * endval ;
int nb_values = 0 ;
2003-03-21 21:22:48 +00:00
int tmp = 0 ;
2003-03-18 11:39:17 +00:00
if ( value = = NULL ) {
return ( - 1 ) ;
}
val = xmlStrdup ( value ) ;
if ( val = = NULL ) {
return ( - 1 ) ;
}
cur = val ;
/*
* Split the list
*/
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * cur ) ) * cur + + = 0 ;
2003-03-18 11:39:17 +00:00
while ( * cur ! = 0 ) {
2003-10-18 16:20:14 +00:00
if ( IS_BLANK_CH ( * cur ) ) {
2003-03-18 11:39:17 +00:00
* cur = 0 ;
cur + + ;
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * cur ) ) * cur + + = 0 ;
2003-03-18 11:39:17 +00:00
} else {
nb_values + + ;
cur + + ;
2003-10-18 16:20:14 +00:00
while ( ( * cur ! = 0 ) & & ( ! IS_BLANK_CH ( * cur ) ) ) cur + + ;
2003-03-18 11:39:17 +00:00
}
}
if ( nb_values = = 0 ) {
if ( ret ! = NULL ) {
TODO
}
xmlFree ( val ) ;
2003-03-18 16:53:17 +00:00
return ( nb_values ) ;
2003-03-18 11:39:17 +00:00
}
endval = cur ;
cur = val ;
while ( ( * cur = = 0 ) & & ( cur ! = endval ) ) cur + + ;
while ( cur ! = endval ) {
tmp = xmlSchemaValPredefTypeNode ( type , cur , NULL , node ) ;
if ( tmp ! = 0 )
break ;
while ( * cur ! = 0 ) cur + + ;
while ( ( * cur = = 0 ) & & ( cur ! = endval ) ) cur + + ;
}
xmlFree ( val ) ;
if ( ret ! = NULL ) {
TODO
}
2003-03-18 16:53:17 +00:00
if ( tmp = = 0 )
return ( nb_values ) ;
return ( - 1 ) ;
2003-03-18 11:39:17 +00:00
}
2003-03-30 21:10:09 +00:00
/**
* xmlSchemaParseUInt :
* @ str : pointer to the string R / W
* @ llo : pointer to the low result
* @ lmi : pointer to the mid result
* @ lhi : pointer to the high result
*
* Parse an unsigned long into 3 fields .
*
* Returns the number of chars parsed or - 1 if overflow of the capacity
*/
static int
xmlSchemaParseUInt ( const xmlChar * * str , unsigned long * llo ,
unsigned long * lmi , unsigned long * lhi ) {
unsigned long lo = 0 , mi = 0 , hi = 0 ;
const xmlChar * tmp , * cur = * str ;
int ret = 0 , i = 0 ;
while ( * cur = = ' 0 ' ) {
ret + + ;
cur + + ;
}
tmp = cur ;
while ( ( * tmp ! = 0 ) & & ( * tmp > = ' 0 ' ) & & ( * tmp < = ' 9 ' ) ) {
i + + ; tmp + + ; ret + + ;
}
if ( i > 24 ) {
* str = tmp ;
return ( - 1 ) ;
}
while ( i > 16 ) {
hi = hi * 10 + ( * cur + + - ' 0 ' ) ;
i - - ;
}
while ( i > 8 ) {
mi = mi * 10 + ( * cur + + - ' 0 ' ) ;
i - - ;
}
while ( i > 0 ) {
lo = lo * 10 + ( * cur + + - ' 0 ' ) ;
i - - ;
}
* str = cur ;
* llo = lo ;
* lmi = mi ;
* lhi = hi ;
return ( ret ) ;
}
2002-04-16 15:50:10 +00:00
/**
2003-03-29 16:41:55 +00:00
* xmlSchemaValAtomicType :
2002-04-16 15:50:10 +00:00
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
2003-03-18 00:31:04 +00:00
* @ node : the node containing the value
2003-03-29 16:41:55 +00:00
* flags : flags to control the vlidation
2002-04-16 15:50:10 +00:00
*
2003-03-29 16:41:55 +00:00
* Check that a value conforms to the lexical space of the atomic type .
2002-04-16 15:50:10 +00:00
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
2003-03-29 16:41:55 +00:00
static int
2003-08-27 14:15:15 +00:00
xmlSchemaValAtomicType ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val , xmlNodePtr node , int flags )
{
2002-04-16 15:50:10 +00:00
xmlSchemaValPtr v ;
2003-03-29 16:41:55 +00:00
xmlChar * norm = NULL ;
2003-04-09 11:24:17 +00:00
int ret = 0 ;
2002-04-16 15:50:10 +00:00
if ( xmlSchemaTypesInitialized = = 0 )
2003-08-27 14:15:15 +00:00
return ( - 1 ) ;
2002-04-16 15:50:10 +00:00
if ( type = = NULL )
2003-08-27 14:15:15 +00:00
return ( - 1 ) ;
2002-05-22 06:40:27 +00:00
2002-04-16 15:50:10 +00:00
if ( val ! = NULL )
2003-08-27 14:15:15 +00:00
* val = NULL ;
2003-03-29 16:41:55 +00:00
if ( ( flags = = 0 ) & & ( value ! = NULL ) ) {
2003-08-27 14:15:15 +00:00
if ( ( type - > flags ! = XML_SCHEMAS_STRING ) & &
( type - > flags ! = XML_SCHEMAS_NORMSTRING ) ) {
norm = xmlSchemaCollapseString ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
2003-03-29 16:41:55 +00:00
}
switch ( type - > flags ) {
case XML_SCHEMAS_UNKNOWN :
2003-08-27 14:15:15 +00:00
if ( type = = xmlSchemaTypeAnyTypeDef )
goto return0 ;
goto error ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_STRING :
2003-08-27 14:15:15 +00:00
goto return0 ;
2004-01-22 07:27:45 +00:00
case XML_SCHEMAS_NORMSTRING : {
const xmlChar * cur = value ;
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else {
cur + + ;
}
}
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NORMSTRING ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_DECIMAL : {
const xmlChar * cur = value , * tmp ;
unsigned int frac = 0 , len , neg = 0 ;
unsigned long base = 0 ;
if ( cur = = NULL )
goto return1 ;
if ( * cur = = ' + ' )
cur + + ;
else if ( * cur = = ' - ' ) {
neg = 1 ;
cur + + ;
}
tmp = cur ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
base = base * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
}
len = cur - tmp ;
if ( * cur = = ' . ' ) {
cur + + ;
tmp = cur ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
base = base * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
}
frac = cur - tmp ;
}
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_DECIMAL ) ;
if ( v ! = NULL ) {
v - > value . decimal . lo = base ;
v - > value . decimal . sign = neg ;
v - > value . decimal . frac = frac ;
v - > value . decimal . total = frac + len ;
* val = v ;
}
}
goto return0 ;
}
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_TIME :
case XML_SCHEMAS_GDAY :
case XML_SCHEMAS_GMONTH :
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GYEAR :
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
2003-08-27 14:15:15 +00:00
ret = xmlSchemaValidateDates ( type - > flags , value , val ) ;
break ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_DURATION :
2003-08-27 14:15:15 +00:00
ret = xmlSchemaValidateDuration ( type , value , val ) ;
break ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_FLOAT :
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_DOUBLE : {
const xmlChar * cur = value ;
int neg = 0 ;
if ( cur = = NULL )
goto return1 ;
if ( ( cur [ 0 ] = = ' N ' ) & & ( cur [ 1 ] = = ' a ' ) & & ( cur [ 2 ] = = ' N ' ) ) {
cur + = 3 ;
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
v - > value . f = ( float ) xmlXPathNAN ;
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
v - > value . d = xmlXPathNAN ;
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
}
* val = v ;
}
goto return0 ;
}
if ( * cur = = ' - ' ) {
neg = 1 ;
cur + + ;
}
if ( ( cur [ 0 ] = = ' I ' ) & & ( cur [ 1 ] = = ' N ' ) & & ( cur [ 2 ] = = ' F ' ) ) {
cur + = 3 ;
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
if ( neg )
v - > value . f = ( float ) xmlXPathNINF ;
else
v - > value . f = ( float ) xmlXPathPINF ;
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
if ( neg )
v - > value . d = xmlXPathNINF ;
else
v - > value . d = xmlXPathPINF ;
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
}
* val = v ;
}
goto return0 ;
}
if ( ( neg = = 0 ) & & ( * cur = = ' + ' ) )
cur + + ;
if ( ( cur [ 0 ] = = 0 ) | | ( cur [ 0 ] = = ' + ' ) | | ( cur [ 0 ] = = ' - ' ) )
goto return1 ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
cur + + ;
}
if ( * cur = = ' . ' ) {
cur + + ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) )
cur + + ;
}
if ( ( * cur = = ' e ' ) | | ( * cur = = ' E ' ) ) {
cur + + ;
if ( ( * cur = = ' - ' ) | | ( * cur = = ' + ' ) )
cur + + ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) )
cur + + ;
}
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
2003-10-10 00:49:42 +00:00
if ( sscanf ( ( const char * ) value , " %f " ,
2003-08-27 14:15:15 +00:00
& ( v - > value . f ) ) = = 1 ) {
* val = v ;
} else {
xmlSchemaFreeValue ( v ) ;
goto return1 ;
}
} else {
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
2003-10-10 00:49:42 +00:00
if ( sscanf ( ( const char * ) value , " %lf " ,
2003-08-27 14:15:15 +00:00
& ( v - > value . d ) ) = = 1 ) {
* val = v ;
} else {
xmlSchemaFreeValue ( v ) ;
goto return1 ;
}
} else {
goto error ;
}
}
}
goto return0 ;
}
case XML_SCHEMAS_BOOLEAN : {
const xmlChar * cur = value ;
if ( ( cur [ 0 ] = = ' 0 ' ) & & ( cur [ 1 ] = = 0 ) )
ret = 0 ;
else if ( ( cur [ 0 ] = = ' 1 ' ) & & ( cur [ 1 ] = = 0 ) )
ret = 1 ;
else if ( ( cur [ 0 ] = = ' t ' ) & & ( cur [ 1 ] = = ' r ' )
& & ( cur [ 2 ] = = ' u ' ) & & ( cur [ 3 ] = = ' e ' )
& & ( cur [ 4 ] = = 0 ) )
ret = 1 ;
else if ( ( cur [ 0 ] = = ' f ' ) & & ( cur [ 1 ] = = ' a ' )
& & ( cur [ 2 ] = = ' l ' ) & & ( cur [ 3 ] = = ' s ' )
& & ( cur [ 4 ] = = ' e ' ) & & ( cur [ 5 ] = = 0 ) )
ret = 0 ;
else
goto return1 ;
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_BOOLEAN ) ;
if ( v ! = NULL ) {
v - > value . b = ret ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
case XML_SCHEMAS_TOKEN : {
const xmlChar * cur = value ;
2003-10-18 16:20:14 +00:00
if ( IS_BLANK_CH ( * cur ) )
2003-08-27 14:15:15 +00:00
goto return1 ;
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else if ( * cur = = ' ' ) {
cur + + ;
if ( * cur = = 0 )
goto return1 ;
if ( * cur = = ' ' )
goto return1 ;
} else {
cur + + ;
}
}
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_TOKEN ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_LANGUAGE :
2003-08-27 14:15:15 +00:00
if ( xmlCheckLanguageID ( value ) = = 1 ) {
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_LANGUAGE ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
goto return1 ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_NMTOKEN :
2003-08-27 14:15:15 +00:00
if ( xmlValidateNMToken ( value , 1 ) = = 0 ) {
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NMTOKEN ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
goto return1 ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_NMTOKENS :
2003-08-27 14:15:15 +00:00
ret = xmlSchemaValAtomicListNode ( xmlSchemaTypeNmtokenDef ,
value , val , node ) ;
if ( ret > 0 )
ret = 0 ;
else
ret = 1 ;
goto done ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_NAME :
2003-08-27 14:15:15 +00:00
ret = xmlValidateName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
TODO ;
}
goto done ;
case XML_SCHEMAS_QNAME : {
xmlChar * uri = NULL ;
xmlChar * local = NULL ;
ret = xmlValidateQName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) ) {
xmlChar * prefix ;
local = xmlSplitQName2 ( value , & prefix ) ;
if ( prefix ! = NULL ) {
xmlNsPtr ns ;
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ns = = NULL )
ret = 1 ;
else if ( val ! = NULL )
uri = xmlStrdup ( ns - > href ) ;
}
if ( ( local ! = NULL ) & & ( ( val = = NULL ) | | ( ret ! = 0 ) ) )
xmlFree ( local ) ;
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_QNAME ) ;
if ( v ! = NULL ) {
if ( local ! = NULL )
v - > value . qname . name = local ;
else
v - > value . qname . name = xmlStrdup ( value ) ;
if ( uri ! = NULL )
v - > value . qname . uri = uri ;
* val = v ;
} else {
if ( local ! = NULL )
xmlFree ( local ) ;
if ( uri ! = NULL )
xmlFree ( uri ) ;
goto error ;
}
}
goto done ;
}
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_NCNAME :
2003-08-27 14:15:15 +00:00
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NCNAME ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto done ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_ID :
2003-08-27 14:15:15 +00:00
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_ID ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
/*
* NOTE : the IDness might have already be declared in the DTD
*/
if ( attr - > atype ! = XML_ATTRIBUTE_ID ) {
xmlIDPtr res ;
xmlChar * strip ;
strip = xmlSchemaStrip ( value ) ;
if ( strip ! = NULL ) {
res = xmlAddID ( NULL , node - > doc , strip , attr ) ;
xmlFree ( strip ) ;
} else
res = xmlAddID ( NULL , node - > doc , value , attr ) ;
if ( res = = NULL ) {
ret = 2 ;
} else {
attr - > atype = XML_ATTRIBUTE_ID ;
}
}
}
goto done ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_IDREF :
2003-08-27 14:15:15 +00:00
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
TODO ;
}
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
xmlChar * strip ;
strip = xmlSchemaStrip ( value ) ;
if ( strip ! = NULL ) {
xmlAddRef ( NULL , node - > doc , strip , attr ) ;
xmlFree ( strip ) ;
} else
xmlAddRef ( NULL , node - > doc , value , attr ) ;
attr - > atype = XML_ATTRIBUTE_IDREF ;
}
goto done ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_IDREFS :
2003-08-27 14:15:15 +00:00
ret = xmlSchemaValAtomicListNode ( xmlSchemaTypeIdrefDef ,
value , val , node ) ;
if ( ret < 0 )
ret = 2 ;
else
ret = 0 ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
2003-03-19 21:02:29 +00:00
2003-08-27 14:15:15 +00:00
attr - > atype = XML_ATTRIBUTE_IDREFS ;
}
goto done ;
case XML_SCHEMAS_ENTITY : {
xmlChar * strip ;
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( node = = NULL ) | | ( node - > doc = = NULL ) )
ret = 3 ;
if ( ret = = 0 ) {
xmlEntityPtr ent ;
strip = xmlSchemaStrip ( value ) ;
if ( strip ! = NULL ) {
ent = xmlGetDocEntity ( node - > doc , strip ) ;
xmlFree ( strip ) ;
} else {
ent = xmlGetDocEntity ( node - > doc , value ) ;
}
if ( ( ent = = NULL ) | |
( ent - > etype ! =
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ) )
ret = 4 ;
}
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
TODO ;
}
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
2003-03-18 16:53:17 +00:00
2003-08-27 14:15:15 +00:00
attr - > atype = XML_ATTRIBUTE_ENTITY ;
}
goto done ;
}
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_ENTITIES :
2003-08-27 14:15:15 +00:00
if ( ( node = = NULL ) | | ( node - > doc = = NULL ) )
goto return3 ;
ret = xmlSchemaValAtomicListNode ( xmlSchemaTypeEntityDef ,
value , val , node ) ;
if ( ret < = 0 )
ret = 1 ;
else
ret = 0 ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
attr - > atype = XML_ATTRIBUTE_ENTITIES ;
}
goto done ;
case XML_SCHEMAS_NOTATION : {
xmlChar * uri = NULL ;
xmlChar * local = NULL ;
ret = xmlValidateQName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) ) {
xmlChar * prefix ;
local = xmlSplitQName2 ( value , & prefix ) ;
if ( prefix ! = NULL ) {
xmlNsPtr ns ;
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ns = = NULL )
ret = 1 ;
else if ( val ! = NULL )
uri = xmlStrdup ( ns - > href ) ;
}
if ( ( local ! = NULL ) & & ( ( val = = NULL ) | | ( ret ! = 0 ) ) )
xmlFree ( local ) ;
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
if ( ( node = = NULL ) | | ( node - > doc = = NULL ) )
ret = 3 ;
if ( ret = = 0 ) {
ret = xmlValidateNotationUse ( NULL , node - > doc , value ) ;
if ( ret = = 1 )
ret = 0 ;
else
ret = 1 ;
}
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NOTATION ) ;
if ( v ! = NULL ) {
if ( local ! = NULL )
v - > value . qname . name = local ;
else
v - > value . qname . name = xmlStrdup ( value ) ;
if ( uri ! = NULL )
v - > value . qname . uri = uri ;
* val = v ;
} else {
if ( local ! = NULL )
xmlFree ( local ) ;
if ( uri ! = NULL )
xmlFree ( uri ) ;
goto error ;
}
}
goto done ;
2003-07-06 21:13:49 +00:00
}
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_ANYURI : {
2004-03-14 12:20:15 +00:00
if ( * value ! = 0 ) {
xmlURIPtr uri = xmlParseURI ( ( const char * ) value ) ;
if ( uri = = NULL )
goto return1 ;
xmlFreeURI ( uri ) ;
}
2003-07-06 21:13:49 +00:00
2003-08-27 14:15:15 +00:00
if ( val ! = NULL ) {
2004-03-14 12:20:15 +00:00
v = xmlSchemaNewValue ( XML_SCHEMAS_ANYURI ) ;
if ( v = = NULL )
goto error ;
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
2003-08-27 14:15:15 +00:00
}
goto return0 ;
}
case XML_SCHEMAS_HEXBINARY : {
const xmlChar * cur = value ;
xmlChar * base ;
int total , i = 0 ;
2003-07-06 21:13:49 +00:00
2003-08-27 14:15:15 +00:00
if ( cur = = NULL )
goto return1 ;
2003-07-06 21:13:49 +00:00
2003-08-27 14:15:15 +00:00
while ( ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) | |
( ( * cur > = ' A ' ) & & ( * cur < = ' F ' ) ) | |
( ( * cur > = ' a ' ) & & ( * cur < = ' f ' ) ) ) {
i + + ;
cur + + ;
}
2003-07-06 21:13:49 +00:00
2003-08-27 14:15:15 +00:00
if ( * cur ! = 0 )
goto return1 ;
if ( ( i % 2 ) ! = 0 )
2003-08-08 14:00:28 +00:00
goto return1 ;
2003-07-06 21:13:49 +00:00
2003-08-27 14:15:15 +00:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_HEXBINARY ) ;
if ( v = = NULL )
goto error ;
cur = xmlStrdup ( value ) ;
if ( cur = = NULL ) {
2003-10-10 00:49:42 +00:00
xmlSchemaTypeErrMemory ( node , " allocating hexbin data " ) ;
2003-08-27 14:15:15 +00:00
xmlFree ( v ) ;
goto return1 ;
}
total = i / 2 ; /* number of octets */
2003-08-08 14:00:28 +00:00
2003-08-27 14:15:15 +00:00
base = ( xmlChar * ) cur ;
while ( i - - > 0 ) {
if ( * base > = ' a ' )
* base = * base - ( ' a ' - ' A ' ) ;
base + + ;
}
2003-08-08 14:00:28 +00:00
2003-08-27 14:15:15 +00:00
v - > value . hex . str = ( xmlChar * ) cur ;
v - > value . hex . total = total ;
* val = v ;
}
goto return0 ;
}
case XML_SCHEMAS_BASE64BINARY : {
/* ISSUE:
*
* Ignore all stray characters ? ( yes , currently )
* Worry about long lines ? ( no , currently )
*
* rfc2045 . txt :
*
* " The encoded output stream must be represented in lines of
* no more than 76 characters each . All line breaks or other
* characters not found in Table 1 must be ignored by decoding
* software . In base64 data , characters other than those in
* Table 1 , line breaks , and other white space probably
* indicate a transmission error , about which a warning
* message or even a message rejection might be appropriate
* under some circumstances . " */
const xmlChar * cur = value ;
xmlChar * base ;
int total , i = 0 , pad = 0 ;
if ( cur = = NULL )
goto return1 ;
for ( ; * cur ; + + cur ) {
int decc ;
decc = _xmlSchemaBase64Decode ( * cur ) ;
if ( decc < 0 ) ;
else if ( decc < 64 )
i + + ;
else
break ;
}
for ( ; * cur ; + + cur ) {
int decc ;
decc = _xmlSchemaBase64Decode ( * cur ) ;
if ( decc < 0 ) ;
else if ( decc < 64 )
goto return1 ;
if ( decc = = 64 )
pad + + ;
}
/* rfc2045.txt: "Special processing is performed if fewer than
* 24 bits are available at the end of the data being encoded .
* A full encoding quantum is always completed at the end of a
* body . When fewer than 24 input bits are available in an
* input group , zero bits are added ( on the right ) to form an
* integral number of 6 - bit groups . Padding at the end of the
* data is performed using the " = " character . Since all
* base64 input is an integral number of octets , only the
* following cases can arise : ( 1 ) the final quantum of
* encoding input is an integral multiple of 24 bits ; here ,
* the final unit of encoded output will be an integral
* multiple ofindent : Standard input : 701 : Warning : old style
* assignment ambiguity in " =* " . Assuming " = * " 4 characters
* with no " = " padding , ( 2 ) the final
* quantum of encoding input is exactly 8 bits ; here , the
* final unit of encoded output will be two characters
* followed by two " = " padding characters , or ( 3 ) the final
* quantum of encoding input is exactly 16 bits ; here , the
* final unit of encoded output will be three characters
* followed by one " = " padding character . " */
total = 3 * ( i / 4 ) ;
if ( pad = = 0 ) {
if ( i % 4 ! = 0 )
goto return1 ;
} else if ( pad = = 1 ) {
int decc ;
if ( i % 4 ! = 3 )
goto return1 ;
for ( decc = _xmlSchemaBase64Decode ( * cur ) ;
( decc < 0 ) | | ( decc > 63 ) ;
decc = _xmlSchemaBase64Decode ( * cur ) )
- - cur ;
/* 16bits in 24bits means 2 pad bits: nnnnnn nnmmmm mmmm00*/
/* 00111100 -> 0x3c */
if ( decc & ~ 0x3c )
goto return1 ;
total + = 2 ;
} else if ( pad = = 2 ) {
int decc ;
if ( i % 4 ! = 2 )
goto return1 ;
for ( decc = _xmlSchemaBase64Decode ( * cur ) ;
( decc < 0 ) | | ( decc > 63 ) ;
decc = _xmlSchemaBase64Decode ( * cur ) )
- - cur ;
/* 8bits in 12bits means 4 pad bits: nnnnnn nn0000 */
/* 00110000 -> 0x30 */
if ( decc & ~ 0x30 )
goto return1 ;
total + = 1 ;
} else
goto return1 ;
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_BASE64BINARY ) ;
if ( v = = NULL )
goto error ;
base =
( xmlChar * ) xmlMallocAtomic ( ( i + pad + 1 ) *
sizeof ( xmlChar ) ) ;
if ( base = = NULL ) {
2003-10-10 00:49:42 +00:00
xmlSchemaTypeErrMemory ( node , " allocating base64 data " ) ;
2003-08-27 14:15:15 +00:00
xmlFree ( v ) ;
goto return1 ;
}
v - > value . base64 . str = base ;
for ( cur = value ; * cur ; + + cur )
if ( _xmlSchemaBase64Decode ( * cur ) > = 0 ) {
* base = * cur ;
+ + base ;
}
* base = 0 ;
v - > value . base64 . total = total ;
* val = v ;
}
goto return0 ;
2003-08-08 14:00:28 +00:00
}
2003-03-30 21:10:09 +00:00
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_NNINTEGER : {
const xmlChar * cur = value ;
unsigned long lo , mi , hi ;
int sign = 0 ;
if ( cur = = NULL )
goto return1 ;
if ( * cur = = ' - ' ) {
sign = 1 ;
cur + + ;
} else if ( * cur = = ' + ' )
cur + + ;
ret = xmlSchemaParseUInt ( & cur , & lo , & mi , & hi ) ;
if ( ret = = 0 )
goto return1 ;
if ( * cur ! = 0 )
goto return1 ;
if ( type - > flags = = XML_SCHEMAS_NPINTEGER ) {
if ( ( sign = = 0 ) & &
( ( hi ! = 0 ) | | ( mi ! = 0 ) | | ( lo ! = 0 ) ) )
goto return1 ;
} else if ( type - > flags = = XML_SCHEMAS_PINTEGER ) {
if ( sign = = 1 )
goto return1 ;
if ( ( hi = = 0 ) & & ( mi = = 0 ) & & ( lo = = 0 ) )
goto return1 ;
} else if ( type - > flags = = XML_SCHEMAS_NINTEGER ) {
if ( sign = = 0 )
goto return1 ;
if ( ( hi = = 0 ) & & ( mi = = 0 ) & & ( lo = = 0 ) )
goto return1 ;
} else if ( type - > flags = = XML_SCHEMAS_NNINTEGER ) {
if ( ( sign = = 1 ) & &
( ( hi ! = 0 ) | | ( mi ! = 0 ) | | ( lo ! = 0 ) ) )
goto return1 ;
}
/*
* We can store a value only if no overflow occured
*/
if ( ( ret > 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( type - > flags ) ;
if ( v ! = NULL ) {
v - > value . decimal . lo = lo ;
v - > value . decimal . mi = lo ;
v - > value . decimal . hi = lo ;
v - > value . decimal . sign = sign ;
v - > value . decimal . frac = 0 ;
v - > value . decimal . total = cur - value ;
* val = v ;
}
}
goto return0 ;
}
2003-03-30 21:10:09 +00:00
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_SHORT :
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_INT : {
const xmlChar * cur = value ;
unsigned long lo , mi , hi ;
int total = 0 ;
int sign = 0 ;
if ( cur = = NULL )
goto return1 ;
if ( * cur = = ' - ' ) {
sign = 1 ;
cur + + ;
} else if ( * cur = = ' + ' )
cur + + ;
ret = xmlSchemaParseUInt ( & cur , & lo , & mi , & hi ) ;
if ( ret < = 0 )
goto return1 ;
if ( * cur ! = 0 )
goto return1 ;
if ( type - > flags = = XML_SCHEMAS_LONG ) {
if ( hi > = 922 ) {
if ( hi > 922 )
goto return1 ;
if ( mi > = 33720368 ) {
if ( mi > 33720368 )
goto return1 ;
if ( ( sign = = 0 ) & & ( lo > 54775807 ) )
goto return1 ;
if ( ( sign = = 1 ) & & ( lo > 54775808 ) )
goto return1 ;
}
}
} else if ( type - > flags = = XML_SCHEMAS_INT ) {
if ( hi ! = 0 )
goto return1 ;
if ( mi > = 21 ) {
if ( mi > 21 )
goto return1 ;
if ( ( sign = = 0 ) & & ( lo > 47483647 ) )
goto return1 ;
if ( ( sign = = 1 ) & & ( lo > 47483648 ) )
goto return1 ;
}
} else if ( type - > flags = = XML_SCHEMAS_SHORT ) {
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( ( sign = = 1 ) & & ( lo > 32768 ) )
goto return1 ;
if ( ( sign = = 0 ) & & ( lo > 32767 ) )
goto return1 ;
} else if ( type - > flags = = XML_SCHEMAS_BYTE ) {
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( ( sign = = 1 ) & & ( lo > 128 ) )
goto return1 ;
if ( ( sign = = 0 ) & & ( lo > 127 ) )
goto return1 ;
}
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( type - > flags ) ;
if ( v ! = NULL ) {
v - > value . decimal . lo = lo ;
v - > value . decimal . mi = lo ;
v - > value . decimal . hi = lo ;
v - > value . decimal . sign = sign ;
v - > value . decimal . frac = 0 ;
v - > value . decimal . total = total ;
* val = v ;
}
}
goto return0 ;
}
2003-03-30 21:10:09 +00:00
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_USHORT :
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_UBYTE : {
const xmlChar * cur = value ;
unsigned long lo , mi , hi ;
int total = 0 ;
if ( cur = = NULL )
goto return1 ;
ret = xmlSchemaParseUInt ( & cur , & lo , & mi , & hi ) ;
if ( ret < = 0 )
goto return1 ;
if ( * cur ! = 0 )
goto return1 ;
if ( type - > flags = = XML_SCHEMAS_ULONG ) {
if ( hi > = 1844 ) {
if ( hi > 1844 )
goto return1 ;
if ( mi > = 67440737 ) {
if ( mi > 67440737 )
goto return1 ;
if ( lo > 9551615 )
goto return1 ;
}
}
} else if ( type - > flags = = XML_SCHEMAS_UINT ) {
if ( hi ! = 0 )
goto return1 ;
if ( mi > = 42 ) {
if ( mi > 42 )
goto return1 ;
if ( lo > 94967295 )
goto return1 ;
}
} else if ( type - > flags = = XML_SCHEMAS_USHORT ) {
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( lo > 65535 )
goto return1 ;
} else if ( type - > flags = = XML_SCHEMAS_UBYTE ) {
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( lo > 255 )
goto return1 ;
}
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( type - > flags ) ;
if ( v ! = NULL ) {
v - > value . decimal . lo = lo ;
v - > value . decimal . mi = mi ;
v - > value . decimal . hi = hi ;
v - > value . decimal . sign = 0 ;
v - > value . decimal . frac = 0 ;
v - > value . decimal . total = total ;
* val = v ;
}
}
goto return0 ;
}
2002-04-16 15:50:10 +00:00
}
2003-03-29 16:41:55 +00:00
2003-08-27 14:15:15 +00:00
done :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( ret ) ;
return3 :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( 3 ) ;
return1 :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( 1 ) ;
return0 :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( 0 ) ;
error :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( - 1 ) ;
2003-03-29 16:41:55 +00:00
}
/**
* xmlSchemaValPredefTypeNode :
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
* @ node : the node containing the value
*
* Check that a value conforms to the lexical space of the predefined type .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
int
xmlSchemaValPredefTypeNode ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val , xmlNodePtr node ) {
return ( xmlSchemaValAtomicType ( type , value , val , node , 0 ) ) ;
2002-04-16 15:50:10 +00:00
}
2003-03-18 00:31:04 +00:00
/**
* xmlSchemaValidatePredefinedType :
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
*
* Check that a value conforms to the lexical space of the predefined type .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
int
xmlSchemaValidatePredefinedType ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val ) {
return ( xmlSchemaValPredefTypeNode ( type , value , val , NULL ) ) ;
}
2002-04-16 15:50:10 +00:00
/**
* xmlSchemaCompareDecimals :
* @ x : a first decimal value
* @ y : a second decimal value
*
* Compare 2 decimals
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y and - 2 in case of error
*/
static int
xmlSchemaCompareDecimals ( xmlSchemaValPtr x , xmlSchemaValPtr y )
{
xmlSchemaValPtr swp ;
2003-03-30 21:10:09 +00:00
int order = 1 , p ;
2002-04-16 15:50:10 +00:00
unsigned long tmp ;
2003-03-30 21:10:09 +00:00
if ( ( x - > value . decimal . sign ) & &
( ( x - > value . decimal . lo ! = 0 ) | |
( x - > value . decimal . mi ! = 0 ) | |
( x - > value . decimal . hi ! = 0 ) ) ) {
if ( ( y - > value . decimal . sign ) & &
( ( y - > value . decimal . lo ! = 0 ) | |
( y - > value . decimal . mi ! = 0 ) | |
( y - > value . decimal . hi ! = 0 ) ) )
2003-03-28 13:29:53 +00:00
order = - 1 ;
else
return ( - 1 ) ;
2003-03-30 21:10:09 +00:00
} else if ( ( y - > value . decimal . sign ) & &
( ( y - > value . decimal . lo ! = 0 ) | |
( y - > value . decimal . mi ! = 0 ) | |
( y - > value . decimal . hi ! = 0 ) ) ) {
2002-04-16 15:50:10 +00:00
return ( 1 ) ;
2003-03-28 13:29:53 +00:00
}
2002-04-16 15:50:10 +00:00
if ( x - > value . decimal . frac = = y - > value . decimal . frac ) {
2003-03-30 21:10:09 +00:00
if ( x - > value . decimal . hi < y - > value . decimal . hi )
return ( - order ) ;
if ( x - > value . decimal . hi < y - > value . decimal . hi )
return ( order ) ;
if ( x - > value . decimal . mi < y - > value . decimal . mi )
return ( - order ) ;
if ( x - > value . decimal . mi < y - > value . decimal . mi )
return ( order ) ;
if ( x - > value . decimal . lo < y - > value . decimal . lo )
2003-03-28 13:29:53 +00:00
return ( - order ) ;
2003-03-30 21:10:09 +00:00
if ( x - > value . decimal . lo > y - > value . decimal . lo )
2003-03-28 13:29:53 +00:00
return ( order ) ;
return ( 0 ) ;
2002-04-16 15:50:10 +00:00
}
if ( y - > value . decimal . frac > x - > value . decimal . frac ) {
swp = y ;
y = x ;
x = swp ;
order = - order ;
}
2003-03-30 21:10:09 +00:00
p = powten [ x - > value . decimal . frac - y - > value . decimal . frac ] ;
tmp = x - > value . decimal . lo / p ;
if ( tmp > y - > value . decimal . lo )
2002-04-16 15:50:10 +00:00
return ( order ) ;
2003-03-30 21:10:09 +00:00
if ( tmp < y - > value . decimal . lo )
2002-04-16 15:50:10 +00:00
return ( - order ) ;
2003-03-30 21:10:09 +00:00
tmp = y - > value . decimal . lo * p ;
if ( x - > value . decimal . lo < tmp )
2002-04-16 15:50:10 +00:00
return ( - order ) ;
2003-03-30 21:10:09 +00:00
if ( x - > value . decimal . lo = = tmp )
2002-04-16 15:50:10 +00:00
return ( 0 ) ;
return ( order ) ;
}
2002-05-03 07:29:38 +00:00
/**
* xmlSchemaCompareDurations :
* @ x : a first duration value
* @ y : a second duration value
*
* Compare 2 durations
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareDurations ( xmlSchemaValPtr x , xmlSchemaValPtr y )
{
long carry , mon , day ;
double sec ;
2003-03-28 13:29:53 +00:00
int invert = 1 ;
long xmon , xday , myear , minday , maxday ;
2002-05-03 07:29:38 +00:00
static const long dayRange [ 2 ] [ 12 ] = {
{ 0 , 28 , 59 , 89 , 120 , 150 , 181 , 212 , 242 , 273 , 303 , 334 , } ,
{ 0 , 31 , 62 , 92 , 123 , 153 , 184 , 215 , 245 , 276 , 306 , 337 } } ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
2002-05-22 06:40:27 +00:00
return - 2 ;
2002-05-03 07:29:38 +00:00
/* months */
mon = x - > value . dur . mon - y - > value . dur . mon ;
/* seconds */
sec = x - > value . dur . sec - y - > value . dur . sec ;
carry = ( long ) sec / SECS_PER_DAY ;
sec - = ( double ) ( carry * SECS_PER_DAY ) ;
/* days */
day = x - > value . dur . day - y - > value . dur . day + carry ;
/* easy test */
if ( mon = = 0 ) {
if ( day = = 0 )
if ( sec = = 0.0 )
return 0 ;
else if ( sec < 0.0 )
return - 1 ;
else
return 1 ;
else if ( day < 0 )
return - 1 ;
else
return 1 ;
}
if ( mon > 0 ) {
if ( ( day > = 0 ) & & ( sec > = 0.0 ) )
return 1 ;
else {
xmon = mon ;
xday = - day ;
}
} else if ( ( day < = 0 ) & & ( sec < = 0.0 ) ) {
return - 1 ;
} else {
2003-03-28 13:29:53 +00:00
invert = - 1 ;
2002-05-03 07:29:38 +00:00
xmon = - mon ;
xday = day ;
}
myear = xmon / 12 ;
2003-03-28 13:29:53 +00:00
if ( myear = = 0 ) {
minday = 0 ;
maxday = 0 ;
} else {
maxday = 366 * ( ( myear + 3 ) / 4 ) +
365 * ( ( myear - 1 ) % 4 ) ;
minday = maxday - 1 ;
}
2002-05-03 07:29:38 +00:00
xmon = xmon % 12 ;
minday + = dayRange [ 0 ] [ xmon ] ;
maxday + = dayRange [ 1 ] [ xmon ] ;
2003-03-28 13:29:53 +00:00
if ( ( maxday = = minday ) & & ( maxday = = xday ) )
return ( 0 ) ; /* can this really happen ? */
2002-05-03 07:29:38 +00:00
if ( maxday < xday )
2003-03-28 13:29:53 +00:00
return ( - invert ) ;
if ( minday > xday )
return ( invert ) ;
2002-05-03 07:29:38 +00:00
/* indeterminate */
2002-05-22 06:40:27 +00:00
return 2 ;
}
/*
* macros for adding date / times and durations
*/
# define FQUOTIENT(a,b) (floor(((double)a / (double)b)))
# define MODULO(a,b) (a - FQUOTIENT(a,b) * b)
# define FQUOTIENT_RANGE(a,low,high) (FQUOTIENT((a-low),(high-low)))
# define MODULO_RANGE(a,low,high) ((MODULO((a-low),(high-low)))+low)
/**
* _xmlSchemaDateAdd :
* @ dt : an # xmlSchemaValPtr
* @ dur : an # xmlSchemaValPtr of type # XS_DURATION
*
* Compute a new date / time from @ dt and @ dur . This function assumes @ dt
* is either # XML_SCHEMAS_DATETIME , # XML_SCHEMAS_DATE , # XML_SCHEMAS_GYEARMONTH ,
* or # XML_SCHEMAS_GYEAR .
*
* Returns date / time pointer or NULL .
*/
static xmlSchemaValPtr
_xmlSchemaDateAdd ( xmlSchemaValPtr dt , xmlSchemaValPtr dur )
{
xmlSchemaValPtr ret ;
long carry , tempdays , temp ;
xmlSchemaValDatePtr r , d ;
xmlSchemaValDurationPtr u ;
if ( ( dt = = NULL ) | | ( dur = = NULL ) )
return NULL ;
ret = xmlSchemaNewValue ( dt - > type ) ;
if ( ret = = NULL )
return NULL ;
r = & ( ret - > value . date ) ;
d = & ( dt - > value . date ) ;
u = & ( dur - > value . dur ) ;
/* normalization */
if ( d - > mon = = 0 )
d - > mon = 1 ;
/* normalize for time zone offset */
u - > sec - = ( d - > tzo * 60 ) ;
d - > tzo = 0 ;
/* normalization */
if ( d - > day = = 0 )
d - > day = 1 ;
/* month */
carry = d - > mon + u - > mon ;
2004-03-25 09:35:49 +00:00
r - > mon = ( unsigned int ) MODULO_RANGE ( carry , 1 , 13 ) ;
carry = ( long ) FQUOTIENT_RANGE ( carry , 1 , 13 ) ;
2002-05-22 06:40:27 +00:00
/* year (may be modified later) */
r - > year = d - > year + carry ;
if ( r - > year = = 0 ) {
if ( d - > year > 0 )
r - > year - - ;
else
r - > year + + ;
}
/* time zone */
r - > tzo = d - > tzo ;
r - > tz_flag = d - > tz_flag ;
/* seconds */
r - > sec = d - > sec + u - > sec ;
2004-03-25 09:35:49 +00:00
carry = ( long ) FQUOTIENT ( ( long ) r - > sec , 60 ) ;
2002-05-22 06:40:27 +00:00
if ( r - > sec ! = 0.0 ) {
r - > sec = MODULO ( r - > sec , 60.0 ) ;
}
/* minute */
carry + = d - > min ;
2004-03-25 09:35:49 +00:00
r - > min = ( unsigned int ) MODULO ( carry , 60 ) ;
carry = ( long ) FQUOTIENT ( carry , 60 ) ;
2002-05-22 06:40:27 +00:00
/* hours */
carry + = d - > hour ;
2004-03-25 09:35:49 +00:00
r - > hour = ( unsigned int ) MODULO ( carry , 24 ) ;
carry = ( long ) FQUOTIENT ( carry , 24 ) ;
2002-05-22 06:40:27 +00:00
/*
* days
* Note we use tempdays because the temporary values may need more
* than 5 bits
*/
if ( ( VALID_YEAR ( r - > year ) ) & & ( VALID_MONTH ( r - > mon ) ) & &
( d - > day > MAX_DAYINMONTH ( r - > year , r - > mon ) ) )
tempdays = MAX_DAYINMONTH ( r - > year , r - > mon ) ;
else if ( d - > day < 1 )
tempdays = 1 ;
else
tempdays = d - > day ;
tempdays + = u - > day + carry ;
while ( 1 ) {
if ( tempdays < 1 ) {
2004-03-25 09:35:49 +00:00
long tmon = ( long ) MODULO_RANGE ( r - > mon - 1 , 1 , 13 ) ;
long tyr = r - > year + ( long ) FQUOTIENT_RANGE ( r - > mon - 1 , 1 , 13 ) ;
2002-05-22 06:40:27 +00:00
if ( tyr = = 0 )
tyr - - ;
tempdays + = MAX_DAYINMONTH ( tyr , tmon ) ;
carry = - 1 ;
2004-03-25 09:35:49 +00:00
} else if ( tempdays > ( long ) MAX_DAYINMONTH ( r - > year , r - > mon ) ) {
2002-05-22 06:40:27 +00:00
tempdays = tempdays - MAX_DAYINMONTH ( r - > year , r - > mon ) ;
carry = 1 ;
} else
break ;
temp = r - > mon + carry ;
2004-03-25 09:35:49 +00:00
r - > mon = ( unsigned int ) MODULO_RANGE ( temp , 1 , 13 ) ;
r - > year = r - > year + ( unsigned int ) FQUOTIENT_RANGE ( temp , 1 , 13 ) ;
2002-05-22 06:40:27 +00:00
if ( r - > year = = 0 ) {
if ( temp < 1 )
r - > year - - ;
else
r - > year + + ;
}
}
r - > day = tempdays ;
/*
* adjust the date / time type to the date values
*/
if ( ret - > type ! = XML_SCHEMAS_DATETIME ) {
if ( ( r - > hour ) | | ( r - > min ) | | ( r - > sec ) )
ret - > type = XML_SCHEMAS_DATETIME ;
else if ( ret - > type ! = XML_SCHEMAS_DATE ) {
if ( ( r - > mon ! = 1 ) & & ( r - > day ! = 1 ) )
ret - > type = XML_SCHEMAS_DATE ;
else if ( ( ret - > type ! = XML_SCHEMAS_GYEARMONTH ) & & ( r - > mon ! = 1 ) )
ret - > type = XML_SCHEMAS_GYEARMONTH ;
}
}
return ret ;
}
/**
* xmlSchemaDupVal :
* @ v : value to duplicate
*
* returns a duplicated value .
*/
static xmlSchemaValPtr
xmlSchemaDupVal ( xmlSchemaValPtr v )
{
xmlSchemaValPtr ret = xmlSchemaNewValue ( v - > type ) ;
if ( ret = = NULL )
return ret ;
memcpy ( ret , v , sizeof ( xmlSchemaVal ) ) ;
return ret ;
}
/**
* xmlSchemaDateNormalize :
* @ dt : an # xmlSchemaValPtr
*
* Normalize @ dt to GMT time .
*
*/
static xmlSchemaValPtr
xmlSchemaDateNormalize ( xmlSchemaValPtr dt , double offset )
{
xmlSchemaValPtr dur , ret ;
if ( dt = = NULL )
return NULL ;
if ( ( ( dt - > type ! = XML_SCHEMAS_TIME ) & &
( dt - > type ! = XML_SCHEMAS_DATETIME ) ) | | ( dt - > value . date . tzo = = 0 ) )
return xmlSchemaDupVal ( dt ) ;
dur = xmlSchemaNewValue ( XML_SCHEMAS_DURATION ) ;
if ( dur = = NULL )
return NULL ;
dur - > value . date . sec - = offset ;
ret = _xmlSchemaDateAdd ( dt , dur ) ;
if ( ret = = NULL )
return NULL ;
xmlSchemaFreeValue ( dur ) ;
/* ret->value.date.tzo = 0; */
return ret ;
}
/**
* _xmlSchemaDateCastYMToDays :
* @ dt : an # xmlSchemaValPtr
*
* Convert mon and year of @ dt to total number of days . Take the
* number of years since ( or before ) 1 AD and add the number of leap
* years . This is a function because negative
* years must be handled a little differently and there is no zero year .
*
* Returns number of days .
*/
static long
_xmlSchemaDateCastYMToDays ( const xmlSchemaValPtr dt )
{
long ret ;
if ( dt - > value . date . year < 0 )
ret = ( dt - > value . date . year * 365 ) +
( ( ( dt - > value . date . year + 1 ) / 4 ) - ( ( dt - > value . date . year + 1 ) / 100 ) +
( ( dt - > value . date . year + 1 ) / 400 ) ) +
DAY_IN_YEAR ( 0 , dt - > value . date . mon , dt - > value . date . year ) ;
else
ret = ( ( dt - > value . date . year - 1 ) * 365 ) +
( ( ( dt - > value . date . year - 1 ) / 4 ) - ( ( dt - > value . date . year - 1 ) / 100 ) +
( ( dt - > value . date . year - 1 ) / 400 ) ) +
DAY_IN_YEAR ( 0 , dt - > value . date . mon , dt - > value . date . year ) ;
return ret ;
}
/**
* TIME_TO_NUMBER :
* @ dt : an # xmlSchemaValPtr
*
* Calculates the number of seconds in the time portion of @ dt .
*
* Returns seconds .
*/
# define TIME_TO_NUMBER(dt) \
( ( double ) ( ( dt - > value . date . hour * SECS_PER_HOUR ) + \
2003-03-31 11:22:25 +00:00
( dt - > value . date . min * SECS_PER_MIN ) + \
( dt - > value . date . tzo * SECS_PER_MIN ) ) + \
dt - > value . date . sec )
2002-05-22 06:40:27 +00:00
/**
* xmlSchemaCompareDates :
* @ x : a first date / time value
* @ y : a second date / time value
*
* Compare 2 date / times
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareDates ( xmlSchemaValPtr x , xmlSchemaValPtr y )
{
unsigned char xmask , ymask , xor_mask , and_mask ;
xmlSchemaValPtr p1 , p2 , q1 , q2 ;
long p1d , p2d , q1d , q2d ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
return - 2 ;
if ( x - > value . date . tz_flag ) {
if ( ! y - > value . date . tz_flag ) {
p1 = xmlSchemaDateNormalize ( x , 0 ) ;
p1d = _xmlSchemaDateCastYMToDays ( p1 ) + p1 - > value . date . day ;
/* normalize y + 14:00 */
q1 = xmlSchemaDateNormalize ( y , ( 14 * SECS_PER_HOUR ) ) ;
q1d = _xmlSchemaDateCastYMToDays ( q1 ) + q1 - > value . date . day ;
2002-07-01 21:52:03 +00:00
if ( p1d < q1d ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 06:40:27 +00:00
return - 1 ;
2002-07-01 21:52:03 +00:00
} else if ( p1d = = q1d ) {
2002-05-22 06:40:27 +00:00
double sec ;
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q1 ) ;
2002-07-01 21:52:03 +00:00
if ( sec < 0.0 ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 06:40:27 +00:00
return - 1 ;
2002-07-01 21:52:03 +00:00
} else {
2003-10-17 12:43:59 +00:00
int ret = 0 ;
2002-05-22 06:40:27 +00:00
/* normalize y - 14:00 */
q2 = xmlSchemaDateNormalize ( y , - ( 14 * SECS_PER_HOUR ) ) ;
q2d = _xmlSchemaDateCastYMToDays ( q2 ) + q2 - > value . date . day ;
if ( p1d > q2d )
2003-10-17 12:43:59 +00:00
ret = 1 ;
2002-05-22 06:40:27 +00:00
else if ( p1d = = q2d ) {
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q2 ) ;
if ( sec > 0.0 )
2003-10-17 12:43:59 +00:00
ret = 1 ;
2002-05-22 06:40:27 +00:00
else
2003-10-17 12:43:59 +00:00
ret = 2 ; /* indeterminate */
2002-05-22 06:40:27 +00:00
}
2003-10-17 12:43:59 +00:00
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
xmlSchemaFreeValue ( q2 ) ;
if ( ret ! = 0 )
return ( ret ) ;
2002-05-22 06:40:27 +00:00
}
2002-07-01 21:52:03 +00:00
} else {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
}
2002-05-22 06:40:27 +00:00
}
} else if ( y - > value . date . tz_flag ) {
q1 = xmlSchemaDateNormalize ( y , 0 ) ;
q1d = _xmlSchemaDateCastYMToDays ( q1 ) + q1 - > value . date . day ;
/* normalize x - 14:00 */
p1 = xmlSchemaDateNormalize ( x , - ( 14 * SECS_PER_HOUR ) ) ;
p1d = _xmlSchemaDateCastYMToDays ( p1 ) + p1 - > value . date . day ;
2002-07-01 21:52:03 +00:00
if ( p1d < q1d ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 06:40:27 +00:00
return - 1 ;
2002-07-01 21:52:03 +00:00
} else if ( p1d = = q1d ) {
2002-05-22 06:40:27 +00:00
double sec ;
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q1 ) ;
2002-07-01 21:52:03 +00:00
if ( sec < 0.0 ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 06:40:27 +00:00
return - 1 ;
2002-07-01 21:52:03 +00:00
} else {
2003-10-17 12:43:59 +00:00
int ret = 0 ;
2002-05-22 06:40:27 +00:00
/* normalize x + 14:00 */
p2 = xmlSchemaDateNormalize ( x , ( 14 * SECS_PER_HOUR ) ) ;
p2d = _xmlSchemaDateCastYMToDays ( p2 ) + p2 - > value . date . day ;
2003-03-27 21:25:38 +00:00
if ( p2d > q1d ) {
2003-10-17 12:43:59 +00:00
ret = 1 ;
2003-03-27 21:25:38 +00:00
} else if ( p2d = = q1d ) {
2002-05-22 06:40:27 +00:00
sec = TIME_TO_NUMBER ( p2 ) - TIME_TO_NUMBER ( q1 ) ;
if ( sec > 0.0 )
2003-10-17 12:43:59 +00:00
ret = 1 ;
2002-05-22 06:40:27 +00:00
else
2003-10-17 12:43:59 +00:00
ret = 2 ; /* indeterminate */
2002-05-22 06:40:27 +00:00
}
2003-03-27 21:25:38 +00:00
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
xmlSchemaFreeValue ( p2 ) ;
2003-10-17 12:43:59 +00:00
if ( ret ! = 0 )
return ( ret ) ;
2002-05-22 06:40:27 +00:00
}
2002-07-01 21:52:03 +00:00
} else {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 06:40:27 +00:00
}
}
/*
* if the same type then calculate the difference
*/
if ( x - > type = = y - > type ) {
2003-10-17 12:43:59 +00:00
int ret = 0 ;
2002-05-22 06:40:27 +00:00
q1 = xmlSchemaDateNormalize ( y , 0 ) ;
q1d = _xmlSchemaDateCastYMToDays ( q1 ) + q1 - > value . date . day ;
p1 = xmlSchemaDateNormalize ( x , 0 ) ;
p1d = _xmlSchemaDateCastYMToDays ( p1 ) + p1 - > value . date . day ;
2002-07-01 21:52:03 +00:00
if ( p1d < q1d ) {
2003-10-17 12:43:59 +00:00
ret = - 1 ;
2002-07-01 21:52:03 +00:00
} else if ( p1d > q1d ) {
2003-10-17 12:43:59 +00:00
ret = 1 ;
2002-07-01 21:52:03 +00:00
} else {
2002-05-22 06:40:27 +00:00
double sec ;
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q1 ) ;
if ( sec < 0.0 )
2003-10-17 12:43:59 +00:00
ret = - 1 ;
2002-05-22 06:40:27 +00:00
else if ( sec > 0.0 )
2003-10-17 12:43:59 +00:00
ret = 1 ;
2002-05-22 06:40:27 +00:00
}
2003-10-17 12:43:59 +00:00
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
return ( ret ) ;
2002-05-22 06:40:27 +00:00
}
switch ( x - > type ) {
case XML_SCHEMAS_DATETIME :
xmask = 0xf ;
break ;
case XML_SCHEMAS_DATE :
xmask = 0x7 ;
break ;
case XML_SCHEMAS_GYEAR :
xmask = 0x1 ;
break ;
case XML_SCHEMAS_GMONTH :
xmask = 0x2 ;
break ;
case XML_SCHEMAS_GDAY :
xmask = 0x3 ;
break ;
case XML_SCHEMAS_GYEARMONTH :
xmask = 0x3 ;
break ;
case XML_SCHEMAS_GMONTHDAY :
xmask = 0x6 ;
break ;
case XML_SCHEMAS_TIME :
xmask = 0x8 ;
break ;
default :
xmask = 0 ;
break ;
}
switch ( y - > type ) {
case XML_SCHEMAS_DATETIME :
ymask = 0xf ;
break ;
case XML_SCHEMAS_DATE :
ymask = 0x7 ;
break ;
case XML_SCHEMAS_GYEAR :
ymask = 0x1 ;
break ;
case XML_SCHEMAS_GMONTH :
ymask = 0x2 ;
break ;
case XML_SCHEMAS_GDAY :
ymask = 0x3 ;
break ;
case XML_SCHEMAS_GYEARMONTH :
ymask = 0x3 ;
break ;
case XML_SCHEMAS_GMONTHDAY :
ymask = 0x6 ;
break ;
case XML_SCHEMAS_TIME :
ymask = 0x8 ;
break ;
default :
ymask = 0 ;
break ;
}
xor_mask = xmask ^ ymask ; /* mark type differences */
and_mask = xmask & ymask ; /* mark field specification */
/* year */
if ( xor_mask & 1 )
return 2 ; /* indeterminate */
else if ( and_mask & 1 ) {
if ( x - > value . date . year < y - > value . date . year )
return - 1 ;
else if ( x - > value . date . year > y - > value . date . year )
return 1 ;
}
/* month */
if ( xor_mask & 2 )
return 2 ; /* indeterminate */
else if ( and_mask & 2 ) {
if ( x - > value . date . mon < y - > value . date . mon )
return - 1 ;
else if ( x - > value . date . mon > y - > value . date . mon )
return 1 ;
}
/* day */
if ( xor_mask & 4 )
return 2 ; /* indeterminate */
else if ( and_mask & 4 ) {
if ( x - > value . date . day < y - > value . date . day )
return - 1 ;
else if ( x - > value . date . day > y - > value . date . day )
return 1 ;
}
/* time */
if ( xor_mask & 8 )
return 2 ; /* indeterminate */
else if ( and_mask & 8 ) {
if ( x - > value . date . hour < y - > value . date . hour )
return - 1 ;
else if ( x - > value . date . hour > y - > value . date . hour )
return 1 ;
else if ( x - > value . date . min < y - > value . date . min )
return - 1 ;
else if ( x - > value . date . min > y - > value . date . min )
return 1 ;
else if ( x - > value . date . sec < y - > value . date . sec )
return - 1 ;
else if ( x - > value . date . sec > y - > value . date . sec )
return 1 ;
}
2002-05-03 07:29:38 +00:00
return 0 ;
}
2003-03-29 10:53:38 +00:00
/**
* xmlSchemaCompareNormStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareNormStrings ( xmlSchemaValPtr x , xmlSchemaValPtr y ) {
const xmlChar * utf1 ;
const xmlChar * utf2 ;
int tmp ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
utf1 = x - > value . str ;
utf2 = y - > value . str ;
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * utf1 ) ) utf1 + + ;
while ( IS_BLANK_CH ( * utf2 ) ) utf2 + + ;
2003-03-29 10:53:38 +00:00
while ( ( * utf1 ! = 0 ) & & ( * utf2 ! = 0 ) ) {
2003-10-18 16:20:14 +00:00
if ( IS_BLANK_CH ( * utf1 ) ) {
if ( ! IS_BLANK_CH ( * utf2 ) ) {
2003-03-29 10:53:38 +00:00
tmp = * utf1 - * utf2 ;
return ( tmp ) ;
}
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * utf1 ) ) utf1 + + ;
while ( IS_BLANK_CH ( * utf2 ) ) utf2 + + ;
2003-03-29 10:53:38 +00:00
} else {
tmp = * utf1 + + - * utf2 + + ;
if ( tmp < 0 )
return ( - 1 ) ;
if ( tmp > 0 )
return ( 1 ) ;
}
}
if ( * utf1 ! = 0 ) {
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * utf1 ) ) utf1 + + ;
2003-03-29 10:53:38 +00:00
if ( * utf1 ! = 0 )
return ( 1 ) ;
}
if ( * utf2 ! = 0 ) {
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * utf2 ) ) utf2 + + ;
2003-03-29 10:53:38 +00:00
if ( * utf2 ! = 0 )
return ( - 1 ) ;
}
return ( 0 ) ;
}
2003-03-29 16:41:55 +00:00
/**
* xmlSchemaCompareFloats :
* @ x : a first float or double value
* @ y : a second float or double value
*
* Compare 2 values
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareFloats ( xmlSchemaValPtr x , xmlSchemaValPtr y ) {
double d1 , d2 ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
/*
* Cast everything to doubles .
*/
if ( x - > type = = XML_SCHEMAS_DOUBLE )
d1 = x - > value . d ;
else if ( x - > type = = XML_SCHEMAS_FLOAT )
d1 = x - > value . f ;
else
return ( - 2 ) ;
if ( y - > type = = XML_SCHEMAS_DOUBLE )
d2 = y - > value . d ;
else if ( y - > type = = XML_SCHEMAS_FLOAT )
d2 = y - > value . f ;
else
return ( - 2 ) ;
/*
* Check for special cases .
*/
if ( xmlXPathIsNaN ( d1 ) ) {
if ( xmlXPathIsNaN ( d2 ) )
return ( 0 ) ;
return ( 1 ) ;
}
if ( xmlXPathIsNaN ( d2 ) )
return ( - 1 ) ;
if ( d1 = = xmlXPathPINF ) {
if ( d2 = = xmlXPathPINF )
return ( 0 ) ;
return ( 1 ) ;
}
if ( d2 = = xmlXPathPINF )
return ( - 1 ) ;
if ( d1 = = xmlXPathNINF ) {
if ( d2 = = xmlXPathNINF )
return ( 0 ) ;
return ( - 1 ) ;
}
if ( d2 = = xmlXPathNINF )
return ( 1 ) ;
/*
* basic tests , the last one we should have equality , but
* portability is more important than speed and handling
* NaN or Inf in a portable way is always a challenge , so . . .
*/
if ( d1 < d2 )
return ( - 1 ) ;
if ( d1 > d2 )
return ( 1 ) ;
if ( d1 = = d2 )
return ( 0 ) ;
return ( 2 ) ;
}
2002-04-16 15:50:10 +00:00
/**
* xmlSchemaCompareValues :
* @ x : a first value
* @ y : a second value
*
* Compare 2 values
*
2002-05-22 06:40:27 +00:00
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
2002-04-16 15:50:10 +00:00
*/
2003-03-28 13:29:53 +00:00
int
2002-04-16 15:50:10 +00:00
xmlSchemaCompareValues ( xmlSchemaValPtr x , xmlSchemaValPtr y ) {
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
switch ( x - > type ) {
2003-03-28 13:29:53 +00:00
case XML_SCHEMAS_UNKNOWN :
return ( - 2 ) ;
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
case XML_SCHEMAS_NNINTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_SHORT :
case XML_SCHEMAS_USHORT :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_UBYTE :
2002-04-16 15:50:10 +00:00
case XML_SCHEMAS_DECIMAL :
2003-03-28 13:29:53 +00:00
if ( y - > type = = x - > type )
return ( xmlSchemaCompareDecimals ( x , y ) ) ;
if ( ( y - > type = = XML_SCHEMAS_DECIMAL ) | |
( y - > type = = XML_SCHEMAS_INTEGER ) | |
( y - > type = = XML_SCHEMAS_NPINTEGER ) | |
( y - > type = = XML_SCHEMAS_NINTEGER ) | |
( y - > type = = XML_SCHEMAS_NNINTEGER ) | |
( y - > type = = XML_SCHEMAS_PINTEGER ) | |
( y - > type = = XML_SCHEMAS_INT ) | |
( y - > type = = XML_SCHEMAS_UINT ) | |
( y - > type = = XML_SCHEMAS_LONG ) | |
( y - > type = = XML_SCHEMAS_ULONG ) | |
( y - > type = = XML_SCHEMAS_SHORT ) | |
( y - > type = = XML_SCHEMAS_USHORT ) | |
( y - > type = = XML_SCHEMAS_BYTE ) | |
( y - > type = = XML_SCHEMAS_UBYTE ) )
2002-04-16 15:50:10 +00:00
return ( xmlSchemaCompareDecimals ( x , y ) ) ;
2002-05-22 06:40:27 +00:00
return ( - 2 ) ;
2002-05-03 07:29:38 +00:00
case XML_SCHEMAS_DURATION :
if ( y - > type = = XML_SCHEMAS_DURATION )
return ( xmlSchemaCompareDurations ( x , y ) ) ;
2002-05-22 06:40:27 +00:00
return ( - 2 ) ;
case XML_SCHEMAS_TIME :
case XML_SCHEMAS_GDAY :
case XML_SCHEMAS_GMONTH :
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GYEAR :
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
if ( ( y - > type = = XML_SCHEMAS_DATETIME ) | |
( y - > type = = XML_SCHEMAS_TIME ) | |
( y - > type = = XML_SCHEMAS_GDAY ) | |
( y - > type = = XML_SCHEMAS_GMONTH ) | |
( y - > type = = XML_SCHEMAS_GMONTHDAY ) | |
( y - > type = = XML_SCHEMAS_GYEAR ) | |
( y - > type = = XML_SCHEMAS_DATE ) | |
( y - > type = = XML_SCHEMAS_GYEARMONTH ) )
return ( xmlSchemaCompareDates ( x , y ) ) ;
return ( - 2 ) ;
2003-03-28 13:29:53 +00:00
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
case XML_SCHEMAS_NOTATION :
case XML_SCHEMAS_ANYURI :
2003-03-29 10:53:38 +00:00
if ( ( y - > type = = XML_SCHEMAS_NORMSTRING ) | |
( y - > type = = XML_SCHEMAS_TOKEN ) | |
( y - > type = = XML_SCHEMAS_LANGUAGE ) | |
( y - > type = = XML_SCHEMAS_NMTOKEN ) | |
( y - > type = = XML_SCHEMAS_NAME ) | |
( y - > type = = XML_SCHEMAS_QNAME ) | |
( y - > type = = XML_SCHEMAS_NCNAME ) | |
( y - > type = = XML_SCHEMAS_ID ) | |
( y - > type = = XML_SCHEMAS_IDREF ) | |
( y - > type = = XML_SCHEMAS_ENTITY ) | |
( y - > type = = XML_SCHEMAS_NOTATION ) | |
( y - > type = = XML_SCHEMAS_ANYURI ) )
return ( xmlSchemaCompareNormStrings ( x , y ) ) ;
return ( - 2 ) ;
2003-03-30 21:10:09 +00:00
case XML_SCHEMAS_QNAME :
if ( y - > type = = XML_SCHEMAS_QNAME ) {
if ( ( xmlStrEqual ( x - > value . qname . name , y - > value . qname . name ) ) & &
( xmlStrEqual ( x - > value . qname . uri , y - > value . qname . uri ) ) )
return ( 0 ) ;
return ( 2 ) ;
}
return ( - 2 ) ;
2003-03-29 10:53:38 +00:00
case XML_SCHEMAS_FLOAT :
case XML_SCHEMAS_DOUBLE :
2003-03-29 16:41:55 +00:00
if ( ( y - > type = = XML_SCHEMAS_FLOAT ) | |
( y - > type = = XML_SCHEMAS_DOUBLE ) )
return ( xmlSchemaCompareFloats ( x , y ) ) ;
return ( - 2 ) ;
2003-03-29 10:53:38 +00:00
case XML_SCHEMAS_BOOLEAN :
2003-03-29 16:41:55 +00:00
if ( y - > type = = XML_SCHEMAS_BOOLEAN ) {
if ( x - > value . b = = y - > value . b )
return ( 0 ) ;
if ( x - > value . b = = 0 )
return ( - 1 ) ;
return ( 1 ) ;
}
return ( - 2 ) ;
2003-07-06 21:13:49 +00:00
case XML_SCHEMAS_HEXBINARY :
2003-08-08 14:00:28 +00:00
if ( y - > type = = XML_SCHEMAS_HEXBINARY ) {
if ( x - > value . hex . total = = y - > value . hex . total ) {
int ret = xmlStrcmp ( x - > value . hex . str , y - > value . hex . str ) ;
if ( ret > 0 )
return ( 1 ) ;
else if ( ret = = 0 )
return ( 0 ) ;
}
else if ( x - > value . hex . total > y - > value . hex . total )
return ( 1 ) ;
return ( - 1 ) ;
}
2003-07-06 21:13:49 +00:00
return ( - 2 ) ;
2003-08-27 14:15:15 +00:00
case XML_SCHEMAS_BASE64BINARY :
if ( y - > type = = XML_SCHEMAS_BASE64BINARY ) {
if ( x - > value . base64 . total = = y - > value . base64 . total ) {
int ret = xmlStrcmp ( x - > value . base64 . str ,
y - > value . base64 . str ) ;
if ( ret > 0 )
return ( 1 ) ;
else if ( ret = = 0 )
return ( 0 ) ;
}
else if ( x - > value . base64 . total > y - > value . base64 . total )
return ( 1 ) ;
else
return ( - 1 ) ;
}
return ( - 2 ) ;
2003-03-29 10:53:38 +00:00
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_ENTITIES :
case XML_SCHEMAS_NMTOKENS :
TODO
break ;
2002-04-16 15:50:10 +00:00
}
2002-05-22 06:40:27 +00:00
return - 2 ;
2002-04-16 15:50:10 +00:00
}
2003-03-29 10:53:38 +00:00
/**
* xmlSchemaNormLen :
* @ value : a string
*
* Computes the UTF8 length of the normalized value of the string
*
* Returns the length or - 1 in case of error .
*/
static int
xmlSchemaNormLen ( const xmlChar * value ) {
const xmlChar * utf ;
int ret = 0 ;
if ( value = = NULL )
return ( - 1 ) ;
utf = value ;
2003-10-18 16:20:14 +00:00
while ( IS_BLANK_CH ( * utf ) ) utf + + ;
2003-03-29 10:53:38 +00:00
while ( * utf ! = 0 ) {
if ( utf [ 0 ] & 0x80 ) {
if ( ( utf [ 1 ] & 0xc0 ) ! = 0x80 )
return ( - 1 ) ;
if ( ( utf [ 0 ] & 0xe0 ) = = 0xe0 ) {
if ( ( utf [ 2 ] & 0xc0 ) ! = 0x80 )
return ( - 1 ) ;
if ( ( utf [ 0 ] & 0xf0 ) = = 0xf0 ) {
if ( ( utf [ 0 ] & 0xf8 ) ! = 0xf0 | | ( utf [ 3 ] & 0xc0 ) ! = 0x80 )
return ( - 1 ) ;
utf + = 4 ;
} else {
utf + = 3 ;
}
} else {
utf + = 2 ;
}
2003-10-18 16:20:14 +00:00
} else if ( IS_BLANK_CH ( * utf ) ) {
while ( IS_BLANK_CH ( * utf ) ) utf + + ;
2003-03-29 10:53:38 +00:00
if ( * utf = = 0 )
break ;
} else {
utf + + ;
}
ret + + ;
}
return ( ret ) ;
}
2002-04-16 15:50:10 +00:00
/**
* xmlSchemaValidateFacet :
2002-12-10 15:19:08 +00:00
* @ base : the base type
2002-04-16 15:50:10 +00:00
* @ facet : the facet to check
* @ value : the lexical repr of the value to validate
* @ val : the precomputed value
*
* Check a value against a facet condition
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
int
2002-09-26 09:47:36 +00:00
xmlSchemaValidateFacet ( xmlSchemaTypePtr base ATTRIBUTE_UNUSED ,
2002-09-24 14:13:13 +00:00
xmlSchemaFacetPtr facet ,
2002-04-16 15:50:10 +00:00
const xmlChar * value , xmlSchemaValPtr val )
{
int ret ;
switch ( facet - > type ) {
case XML_SCHEMA_FACET_PATTERN :
ret = xmlRegexpExec ( facet - > regexp , value ) ;
if ( ret = = 1 )
return ( 0 ) ;
if ( ret = = 0 ) {
2003-02-27 17:42:22 +00:00
/* TODO error code */
2002-04-16 15:50:10 +00:00
return ( 1 ) ;
}
return ( ret ) ;
case XML_SCHEMA_FACET_MAXEXCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
if ( ret = = - 2 ) {
2003-02-27 17:42:22 +00:00
/* TODO error code */
2002-04-16 15:50:10 +00:00
return ( - 1 ) ;
}
if ( ret = = - 1 )
return ( 0 ) ;
2002-05-22 06:40:27 +00:00
/* error code */
2002-04-16 15:50:10 +00:00
return ( 1 ) ;
2002-05-03 07:29:38 +00:00
case XML_SCHEMA_FACET_MAXINCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
if ( ret = = - 2 ) {
2003-02-27 17:42:22 +00:00
/* TODO error code */
2002-05-03 07:29:38 +00:00
return ( - 1 ) ;
}
if ( ( ret = = - 1 ) | | ( ret = = 0 ) )
return ( 0 ) ;
2002-05-22 06:40:27 +00:00
/* error code */
2002-05-03 07:29:38 +00:00
return ( 1 ) ;
case XML_SCHEMA_FACET_MINEXCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
if ( ret = = - 2 ) {
2003-02-27 17:42:22 +00:00
/* TODO error code */
2002-05-03 07:29:38 +00:00
return ( - 1 ) ;
}
if ( ret = = 1 )
return ( 0 ) ;
2002-05-22 06:40:27 +00:00
/* error code */
2002-05-03 07:29:38 +00:00
return ( 1 ) ;
case XML_SCHEMA_FACET_MININCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
if ( ret = = - 2 ) {
2003-02-27 17:42:22 +00:00
/* TODO error code */
2002-05-03 07:29:38 +00:00
return ( - 1 ) ;
}
if ( ( ret = = 1 ) | | ( ret = = 0 ) )
return ( 0 ) ;
2002-05-22 06:40:27 +00:00
/* error code */
2002-05-03 07:29:38 +00:00
return ( 1 ) ;
2002-04-17 09:06:27 +00:00
case XML_SCHEMA_FACET_WHITESPACE :
2003-02-27 17:42:22 +00:00
/* TODO whitespaces */
2002-04-17 09:06:27 +00:00
return ( 0 ) ;
2003-02-27 17:42:22 +00:00
case XML_SCHEMA_FACET_ENUMERATION :
if ( ( facet - > value ! = NULL ) & &
( xmlStrEqual ( facet - > value , value ) ) )
return ( 0 ) ;
return ( 1 ) ;
case XML_SCHEMA_FACET_LENGTH :
2002-04-22 16:01:24 +00:00
case XML_SCHEMA_FACET_MAXLENGTH :
2003-02-27 17:42:22 +00:00
case XML_SCHEMA_FACET_MINLENGTH : {
unsigned int len = 0 ;
2002-04-22 16:01:24 +00:00
2003-02-27 17:42:22 +00:00
if ( ( facet - > val = = NULL ) | |
2003-03-30 21:10:09 +00:00
( ( facet - > val - > type ! = XML_SCHEMAS_DECIMAL ) & &
( facet - > val - > type ! = XML_SCHEMAS_NNINTEGER ) ) | |
2003-02-27 17:42:22 +00:00
( facet - > val - > value . decimal . frac ! = 0 ) ) {
return ( - 1 ) ;
}
2003-07-06 21:13:49 +00:00
if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_HEXBINARY ) )
2003-08-08 14:00:28 +00:00
len = val - > value . hex . total ;
2003-08-27 14:15:15 +00:00
else if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_BASE64BINARY ) )
len = val - > value . base64 . total ;
else {
2003-08-08 14:00:28 +00:00
switch ( base - > flags ) {
2003-07-06 21:13:49 +00:00
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
2003-08-08 14:00:28 +00:00
len = xmlSchemaNormLen ( value ) ;
break ;
2003-07-06 21:13:49 +00:00
case XML_SCHEMAS_STRING :
2004-02-03 17:55:56 +00:00
if ( value ! = NULL )
len = xmlUTF8Strlen ( value ) ;
2003-08-08 14:00:28 +00:00
break ;
2003-07-06 21:13:49 +00:00
default :
TODO
2003-08-08 14:00:28 +00:00
}
2003-02-27 17:42:22 +00:00
}
if ( facet - > type = = XML_SCHEMA_FACET_LENGTH ) {
2003-03-30 21:10:09 +00:00
if ( len ! = facet - > val - > value . decimal . lo )
2003-02-27 17:42:22 +00:00
return ( 1 ) ;
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
2003-03-30 21:10:09 +00:00
if ( len < facet - > val - > value . decimal . lo )
2002-04-22 16:01:24 +00:00
return ( 1 ) ;
2003-02-27 17:42:22 +00:00
} else {
2003-03-30 21:10:09 +00:00
if ( len > facet - > val - > value . decimal . lo )
2002-04-22 16:01:24 +00:00
return ( 1 ) ;
}
2003-02-27 17:42:22 +00:00
break ;
}
2003-07-06 21:13:49 +00:00
case XML_SCHEMA_FACET_TOTALDIGITS :
case XML_SCHEMA_FACET_FRACTIONDIGITS :
if ( ( facet - > val = = NULL ) | |
( ( facet - > val - > type ! = XML_SCHEMAS_DECIMAL ) & &
( facet - > val - > type ! = XML_SCHEMAS_NNINTEGER ) ) | |
( facet - > val - > value . decimal . frac ! = 0 ) ) {
return ( - 1 ) ;
}
if ( ( val = = NULL ) | |
( ( val - > type ! = XML_SCHEMAS_DECIMAL ) & &
( val - > type ! = XML_SCHEMAS_INTEGER ) & &
( val - > type ! = XML_SCHEMAS_NPINTEGER ) & &
( val - > type ! = XML_SCHEMAS_NINTEGER ) & &
( val - > type ! = XML_SCHEMAS_NNINTEGER ) & &
( val - > type ! = XML_SCHEMAS_PINTEGER ) & &
( val - > type ! = XML_SCHEMAS_INT ) & &
( val - > type ! = XML_SCHEMAS_UINT ) & &
( val - > type ! = XML_SCHEMAS_LONG ) & &
( val - > type ! = XML_SCHEMAS_ULONG ) & &
( val - > type ! = XML_SCHEMAS_SHORT ) & &
( val - > type ! = XML_SCHEMAS_USHORT ) & &
( val - > type ! = XML_SCHEMAS_BYTE ) & &
( val - > type ! = XML_SCHEMAS_UBYTE ) ) ) {
return ( - 1 ) ;
}
if ( facet - > type = = XML_SCHEMA_FACET_TOTALDIGITS ) {
if ( val - > value . decimal . total > facet - > val - > value . decimal . lo )
return ( 1 ) ;
} else if ( facet - > type = = XML_SCHEMA_FACET_FRACTIONDIGITS ) {
if ( val - > value . decimal . frac > facet - > val - > value . decimal . lo )
return ( 1 ) ;
}
break ;
2002-04-16 15:50:10 +00:00
default :
TODO
}
return ( 0 ) ;
2003-03-29 16:41:55 +00:00
2002-04-16 15:50:10 +00:00
}
# endif /* LIBXML_SCHEMAS_ENABLED */