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 >
*/
2017-08-28 14:30:43 +02:00
/* To avoid EBCDIC trouble when parsing on zOS */
# if defined(__MVS__)
# pragma convert("ISO8859-1")
# endif
2002-04-16 15:50:10 +00:00
# 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
2005-04-18 10:57:04 +00:00
# ifdef HAVE_FLOAT_H
# include <float.h>
# endif
2002-05-03 07:29:38 +00:00
2002-04-16 15:50:10 +00:00
# define DEBUG
2004-11-09 16:17:02 +00:00
# ifndef LIBXML_XPATH_ENABLED
extern double xmlXPathNAN ;
extern double xmlXPathPINF ;
extern double xmlXPathNINF ;
# endif
2012-09-11 13:26:36 +08:00
# define TODO \
2002-04-16 15:50:10 +00:00
xmlGenericError ( xmlGenericErrorContext , \
" Unimplemented block at %s:%d \n " , \
__FILE__ , __LINE__ ) ;
# define XML_SCHEMAS_NAMESPACE_NAME \
( const xmlChar * ) " http://www.w3.org/2001/XMLSchema "
2005-02-17 11:10:44 +00:00
# define IS_WSP_REPLACE_CH(c) ((((c) == 0x9) || ((c) == 0xa)) || \
( ( c ) = = 0xd ) )
# define IS_WSP_SPACE_CH(c) ((c) == 0x20)
2005-03-16 16:29:18 +00:00
# define IS_WSP_BLANK_CH(c) IS_BLANK_CH(c)
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 */
2016-04-11 20:03:19 +02:00
unsigned int hour : 5 ; /* 0 <= hour <= 24 */
2002-05-03 07:29:38 +00:00
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? */
2005-05-12 13:10:22 +00:00
signed int tzo : 12 ; /* -1440 <= tzo <= 1440;
currently only - 840 to + 840 are needed */
2002-05-03 07:29:38 +00:00
} ;
/* Duration value */
typedef struct _xmlSchemaValDuration xmlSchemaValDuration ;
typedef xmlSchemaValDuration * xmlSchemaValDurationPtr ;
struct _xmlSchemaValDuration {
long mon ; /* mon stores years also */
2012-09-11 13:26:36 +08:00
long day ;
2002-05-03 07:29:38 +00:00
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 ;
2005-06-09 10:32:53 +00:00
struct _xmlSchemaVal * next ;
2002-04-16 15:50:10 +00:00
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
/************************************************************************
* *
2012-09-11 13:26:36 +08:00
* Datatype error handlers *
2003-10-10 00:49:42 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* 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 ) ;
}
/************************************************************************
* *
2012-09-11 13:26:36 +08:00
* Base types support *
2003-10-10 00:49:42 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-09 10:32:53 +00:00
/**
* 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 ) ;
}
static xmlSchemaFacetPtr
xmlSchemaNewMinLengthFacet ( int value )
{
xmlSchemaFacetPtr ret ;
ret = xmlSchemaNewFacet ( ) ;
2006-03-09 18:41:40 +00:00
if ( ret = = NULL ) {
return ( NULL ) ;
}
2005-06-09 10:32:53 +00:00
ret - > type = XML_SCHEMA_FACET_MINLENGTH ;
ret - > val = xmlSchemaNewValue ( XML_SCHEMAS_NNINTEGER ) ;
2013-07-22 14:28:20 +08:00
if ( ret - > val = = NULL ) {
xmlFree ( ret ) ;
return ( NULL ) ;
}
2005-06-09 10:32:53 +00:00
ret - > val - > value . decimal . lo = value ;
return ( ret ) ;
}
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
*
2004-06-29 17:04:39 +00:00
* Initialize one primitive built - in type
2002-04-16 15:50:10 +00:00
*/
static xmlSchemaTypePtr
2012-09-11 13:26:36 +08:00
xmlSchemaInitBasicType ( const char * name , xmlSchemaValType type ,
2004-06-29 17:04:39 +00:00
xmlSchemaTypePtr baseType ) {
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 ;
2005-06-09 10:32:53 +00:00
ret - > targetNamespace = XML_SCHEMAS_NAMESPACE_NAME ;
2002-04-16 15:50:10 +00:00
ret - > type = XML_SCHEMA_TYPE_BASIC ;
2012-09-11 13:26:36 +08:00
ret - > baseType = baseType ;
2005-06-09 10:32:53 +00:00
ret - > contentType = XML_SCHEMA_CONTENT_BASIC ;
2004-06-29 17:04:39 +00:00
/*
2005-06-09 10:32:53 +00:00
* Primitive types .
2004-06-29 17:04:39 +00:00
*/
2012-09-11 13:26:36 +08:00
switch ( type ) {
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_DECIMAL :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
case XML_SCHEMAS_TIME :
case XML_SCHEMAS_GYEAR :
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_GMONTH :
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GDAY :
case XML_SCHEMAS_DURATION :
case XML_SCHEMAS_FLOAT :
case XML_SCHEMAS_DOUBLE :
case XML_SCHEMAS_BOOLEAN :
case XML_SCHEMAS_ANYURI :
case XML_SCHEMAS_HEXBINARY :
case XML_SCHEMAS_BASE64BINARY :
case XML_SCHEMAS_QNAME :
case XML_SCHEMAS_NOTATION :
2004-06-29 17:04:39 +00:00
ret - > flags | = XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE ;
2005-06-09 10:32:53 +00:00
break ;
2004-06-30 11:48:47 +00:00
default :
2005-06-09 10:32:53 +00:00
break ;
}
/*
* Set variety .
*/
switch ( type ) {
case XML_SCHEMAS_ANYTYPE :
case XML_SCHEMAS_ANYSIMPLETYPE :
break ;
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_NMTOKENS :
case XML_SCHEMAS_ENTITIES :
ret - > flags | = XML_SCHEMAS_TYPE_VARIETY_LIST ;
ret - > facets = xmlSchemaNewMinLengthFacet ( 1 ) ;
2012-09-11 13:26:36 +08:00
ret - > flags | = XML_SCHEMAS_TYPE_HAS_FACETS ;
2005-06-09 10:32:53 +00:00
break ;
default :
ret - > flags | = XML_SCHEMAS_TYPE_VARIETY_ATOMIC ;
break ;
2004-06-29 17:04:39 +00:00
}
2002-04-16 15:50:10 +00:00
xmlHashAddEntry2 ( xmlSchemaTypesBank , ret - > name ,
XML_SCHEMAS_NAMESPACE_NAME , ret ) ;
2004-06-29 17:04:39 +00:00
ret - > builtInType = type ;
2002-04-16 15:50:10 +00:00
return ( ret ) ;
}
2005-07-28 00:50:22 +00:00
/*
* WARNING : Those type reside normally in xmlschemas . c but are
* redefined here locally in oder of being able to use them for xs : anyType -
* TODO : Remove those definition if we move the types to a header file .
* TODO : Always keep those structs up - to - date with the originals .
*/
# define UNBOUNDED (1 << 30)
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem ;
typedef xmlSchemaTreeItem * xmlSchemaTreeItemPtr ;
struct _xmlSchemaTreeItem {
xmlSchemaTypeType type ;
xmlSchemaAnnotPtr annot ;
xmlSchemaTreeItemPtr next ;
xmlSchemaTreeItemPtr children ;
} ;
typedef struct _xmlSchemaParticle xmlSchemaParticle ;
typedef xmlSchemaParticle * xmlSchemaParticlePtr ;
struct _xmlSchemaParticle {
xmlSchemaTypeType type ;
xmlSchemaAnnotPtr annot ;
xmlSchemaTreeItemPtr next ;
xmlSchemaTreeItemPtr children ;
int minOccurs ;
int maxOccurs ;
xmlNodePtr node ;
} ;
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup ;
typedef xmlSchemaModelGroup * xmlSchemaModelGroupPtr ;
struct _xmlSchemaModelGroup {
xmlSchemaTypeType type ;
xmlSchemaAnnotPtr annot ;
xmlSchemaTreeItemPtr next ;
xmlSchemaTreeItemPtr children ;
xmlNodePtr node ;
} ;
static xmlSchemaParticlePtr
xmlSchemaAddParticle ( void )
{
xmlSchemaParticlePtr ret = NULL ;
ret = ( xmlSchemaParticlePtr )
xmlMalloc ( sizeof ( xmlSchemaParticle ) ) ;
if ( ret = = NULL ) {
xmlSchemaTypeErrMemory ( NULL , " allocating particle component " ) ;
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaParticle ) ) ;
ret - > type = XML_SCHEMA_TYPE_PARTICLE ;
ret - > minOccurs = 1 ;
ret - > maxOccurs = 1 ;
return ( ret ) ;
}
2002-04-16 15:50:10 +00:00
/*
* 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
2012-09-11 13:26:36 +08:00
2003-01-27 12:35:42 +00:00
/*
2004-06-29 17:04:39 +00:00
* 3.4 .7 Built - in Complex Type Definition
*/
2003-02-27 17:42:22 +00:00
xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType ( " anyType " ,
2012-09-11 13:26:36 +08:00
XML_SCHEMAS_ANYTYPE ,
2004-06-29 17:04:39 +00:00
NULL ) ;
xmlSchemaTypeAnyTypeDef - > baseType = xmlSchemaTypeAnyTypeDef ;
xmlSchemaTypeAnyTypeDef - > contentType = XML_SCHEMA_CONTENT_MIXED ;
2005-07-28 00:50:22 +00:00
/*
* Init the content type .
*/
2012-09-11 13:26:36 +08:00
xmlSchemaTypeAnyTypeDef - > contentType = XML_SCHEMA_CONTENT_MIXED ;
2004-06-29 17:04:39 +00:00
{
2005-07-28 00:50:22 +00:00
xmlSchemaParticlePtr particle ;
xmlSchemaModelGroupPtr sequence ;
2004-06-29 17:04:39 +00:00
xmlSchemaWildcardPtr wild ;
2005-07-28 00:50:22 +00:00
/* First particle. */
particle = xmlSchemaAddParticle ( ) ;
if ( particle = = NULL )
return ;
xmlSchemaTypeAnyTypeDef - > subtypes = ( xmlSchemaTypePtr ) particle ;
/* Sequence model group. */
sequence = ( xmlSchemaModelGroupPtr )
xmlMalloc ( sizeof ( xmlSchemaModelGroup ) ) ;
if ( sequence = = NULL ) {
xmlSchemaTypeErrMemory ( NULL , " allocating model group component " ) ;
return ;
}
memset ( sequence , 0 , sizeof ( xmlSchemaModelGroup ) ) ;
2012-09-11 13:26:36 +08:00
sequence - > type = XML_SCHEMA_TYPE_SEQUENCE ;
2005-07-28 00:50:22 +00:00
particle - > children = ( xmlSchemaTreeItemPtr ) sequence ;
/* Second particle. */
particle = xmlSchemaAddParticle ( ) ;
if ( particle = = NULL )
return ;
particle - > minOccurs = 0 ;
particle - > maxOccurs = UNBOUNDED ;
sequence - > children = ( xmlSchemaTreeItemPtr ) particle ;
/* The wildcard */
wild = ( xmlSchemaWildcardPtr ) xmlMalloc ( sizeof ( xmlSchemaWildcard ) ) ;
if ( wild = = NULL ) {
xmlSchemaTypeErrMemory ( NULL , " allocating wildcard component " ) ;
return ;
}
memset ( wild , 0 , sizeof ( xmlSchemaWildcard ) ) ;
wild - > type = XML_SCHEMA_TYPE_ANY ;
2012-09-11 13:26:36 +08:00
wild - > any = 1 ;
wild - > processContents = XML_SCHEMAS_ANY_LAX ;
particle - > children = ( xmlSchemaTreeItemPtr ) wild ;
2005-07-28 00:50:22 +00:00
/*
* Create the attribute wildcard .
*/
2004-06-29 17:04:39 +00:00
wild = ( xmlSchemaWildcardPtr ) xmlMalloc ( sizeof ( xmlSchemaWildcard ) ) ;
if ( wild = = NULL ) {
2005-07-28 00:50:22 +00:00
xmlSchemaTypeErrMemory ( NULL , " could not create an attribute "
" wildcard on anyType " ) ;
2004-06-29 17:04:39 +00:00
return ;
}
memset ( wild , 0 , sizeof ( xmlSchemaWildcard ) ) ;
wild - > any = 1 ;
2012-09-11 13:26:36 +08:00
wild - > processContents = XML_SCHEMAS_ANY_LAX ;
2004-06-29 17:04:39 +00:00
xmlSchemaTypeAnyTypeDef - > attributeWildcard = wild ;
}
2012-09-11 13:26:36 +08:00
xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType ( " anySimpleType " ,
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-20 23:09:47 +00:00
XML_SCHEMAS_ANYSIMPLETYPE ,
2004-06-29 17:04:39 +00:00
xmlSchemaTypeAnyTypeDef ) ;
/*
* primitive datatypes
*/
xmlSchemaTypeStringDef = xmlSchemaInitBasicType ( " string " ,
XML_SCHEMAS_STRING ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType ( " decimal " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_DECIMAL ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDateDef = xmlSchemaInitBasicType ( " date " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_DATE ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType ( " dateTime " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_DATETIME ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeTimeDef = xmlSchemaInitBasicType ( " time " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_TIME ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGYearDef = xmlSchemaInitBasicType ( " gYear " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_GYEAR ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType ( " gYearMonth " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_GYEARMONTH ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType ( " gMonth " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_GMONTH ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType ( " gMonthDay " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_GMONTHDAY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeGDayDef = xmlSchemaInitBasicType ( " gDay " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_GDAY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDurationDef = xmlSchemaInitBasicType ( " duration " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_DURATION ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeFloatDef = xmlSchemaInitBasicType ( " float " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_FLOAT ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType ( " double " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_DOUBLE ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType ( " boolean " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_BOOLEAN ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType ( " anyURI " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_ANYURI ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-07-06 21:13:49 +00:00
xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType ( " hexBinary " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_HEXBINARY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2003-08-27 14:15:15 +00:00
xmlSchemaTypeBase64BinaryDef
2004-06-29 17:04:39 +00:00
= xmlSchemaInitBasicType ( " base64Binary " , XML_SCHEMAS_BASE64BINARY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
xmlSchemaTypeNotationDef = xmlSchemaInitBasicType ( " NOTATION " ,
XML_SCHEMAS_NOTATION ,
2012-09-11 13:26:36 +08:00
xmlSchemaTypeAnySimpleTypeDef ) ;
2004-06-29 17:04:39 +00:00
xmlSchemaTypeQNameDef = xmlSchemaInitBasicType ( " QName " ,
XML_SCHEMAS_QNAME ,
xmlSchemaTypeAnySimpleTypeDef ) ;
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 " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_INTEGER ,
xmlSchemaTypeDecimalDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeNonPositiveIntegerDef =
xmlSchemaInitBasicType ( " nonPositiveInteger " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_NPINTEGER ,
xmlSchemaTypeIntegerDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeNegativeIntegerDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " negativeInteger " , XML_SCHEMAS_NINTEGER ,
xmlSchemaTypeNonPositiveIntegerDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeLongDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " long " , XML_SCHEMAS_LONG ,
xmlSchemaTypeIntegerDef ) ;
xmlSchemaTypeIntDef = xmlSchemaInitBasicType ( " int " , XML_SCHEMAS_INT ,
xmlSchemaTypeLongDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeShortDef = xmlSchemaInitBasicType ( " short " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_SHORT ,
xmlSchemaTypeIntDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeByteDef = xmlSchemaInitBasicType ( " byte " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_BYTE ,
xmlSchemaTypeShortDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeNonNegativeIntegerDef =
xmlSchemaInitBasicType ( " nonNegativeInteger " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_NNINTEGER ,
xmlSchemaTypeIntegerDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeUnsignedLongDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " unsignedLong " , XML_SCHEMAS_ULONG ,
xmlSchemaTypeNonNegativeIntegerDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeUnsignedIntDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " unsignedInt " , XML_SCHEMAS_UINT ,
xmlSchemaTypeUnsignedLongDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeUnsignedShortDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " unsignedShort " , XML_SCHEMAS_USHORT ,
xmlSchemaTypeUnsignedIntDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypeUnsignedByteDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " unsignedByte " , XML_SCHEMAS_UBYTE ,
xmlSchemaTypeUnsignedShortDef ) ;
2003-03-27 21:25:38 +00:00
xmlSchemaTypePositiveIntegerDef =
2004-06-29 17:04:39 +00:00
xmlSchemaInitBasicType ( " positiveInteger " , XML_SCHEMAS_PINTEGER ,
xmlSchemaTypeNonNegativeIntegerDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType ( " normalizedString " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_NORMSTRING ,
xmlSchemaTypeStringDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeTokenDef = xmlSchemaInitBasicType ( " token " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_TOKEN ,
xmlSchemaTypeNormStringDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType ( " language " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_LANGUAGE ,
xmlSchemaTypeTokenDef ) ;
xmlSchemaTypeNameDef = xmlSchemaInitBasicType ( " Name " ,
XML_SCHEMAS_NAME ,
xmlSchemaTypeTokenDef ) ;
xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType ( " NMTOKEN " ,
XML_SCHEMAS_NMTOKEN ,
2005-06-09 10:32:53 +00:00
xmlSchemaTypeTokenDef ) ;
2004-06-29 17:04:39 +00:00
xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType ( " NCName " ,
XML_SCHEMAS_NCNAME ,
xmlSchemaTypeNameDef ) ;
xmlSchemaTypeIdDef = xmlSchemaInitBasicType ( " ID " , XML_SCHEMAS_ID ,
2005-06-09 10:32:53 +00:00
xmlSchemaTypeNCNameDef ) ;
2003-02-27 17:42:22 +00:00
xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType ( " IDREF " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_IDREF ,
2012-09-11 13:26:36 +08:00
xmlSchemaTypeNCNameDef ) ;
2003-03-18 16:53:17 +00:00
xmlSchemaTypeEntityDef = xmlSchemaInitBasicType ( " ENTITY " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_ENTITY ,
xmlSchemaTypeNCNameDef ) ;
2005-06-09 10:32:53 +00:00
/*
* Derived list types .
*/
/* ENTITIES */
2003-03-18 16:53:17 +00:00
xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType ( " ENTITIES " ,
2004-06-29 17:04:39 +00:00
XML_SCHEMAS_ENTITIES ,
2005-06-09 10:32:53 +00:00
xmlSchemaTypeAnySimpleTypeDef ) ;
xmlSchemaTypeEntitiesDef - > subtypes = xmlSchemaTypeEntityDef ;
/* IDREFS */
xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType ( " IDREFS " ,
XML_SCHEMAS_IDREFS ,
xmlSchemaTypeAnySimpleTypeDef ) ;
xmlSchemaTypeIdrefsDef - > subtypes = xmlSchemaTypeIdrefDef ;
/* NMTOKENS */
xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType ( " NMTOKENS " ,
XML_SCHEMAS_NMTOKENS ,
xmlSchemaTypeAnySimpleTypeDef ) ;
xmlSchemaTypeNmtokensDef - > subtypes = xmlSchemaTypeNmtokenDef ;
2002-04-16 15:50:10 +00:00
xmlSchemaTypesInitialized = 1 ;
}
/**
* xmlSchemaCleanupTypes :
*
* Cleanup the default XML Schemas type library
*/
2012-09-11 13:26:36 +08:00
void
2002-04-16 15:50:10 +00:00
xmlSchemaCleanupTypes ( void ) {
if ( xmlSchemaTypesInitialized = = 0 )
return ;
2005-07-28 00:50:22 +00:00
/*
* Free xs : anyType .
*/
{
xmlSchemaParticlePtr particle ;
/* Attribute wildcard. */
xmlSchemaFreeWildcard ( xmlSchemaTypeAnyTypeDef - > attributeWildcard ) ;
/* Content type. */
particle = ( xmlSchemaParticlePtr ) xmlSchemaTypeAnyTypeDef - > subtypes ;
/* Wildcard. */
2012-09-11 13:26:36 +08:00
xmlSchemaFreeWildcard ( ( xmlSchemaWildcardPtr )
2005-07-28 00:50:22 +00:00
particle - > children - > children - > children ) ;
xmlFree ( ( xmlSchemaParticlePtr ) particle - > children - > children ) ;
/* Sequence model group. */
xmlFree ( ( xmlSchemaModelGroupPtr ) particle - > children ) ;
xmlFree ( ( xmlSchemaParticlePtr ) particle ) ;
2012-09-11 13:26:36 +08:00
xmlSchemaTypeAnyTypeDef - > subtypes = NULL ;
2005-07-28 00:50:22 +00:00
}
2002-04-16 15:50:10 +00:00
xmlHashFree ( xmlSchemaTypesBank , ( xmlHashDeallocator ) xmlSchemaFreeType ) ;
xmlSchemaTypesInitialized = 0 ;
}
2004-06-29 17:04:39 +00:00
/**
2004-10-27 17:29:04 +00:00
* xmlSchemaIsBuiltInTypeFacet :
2004-06-29 17:04:39 +00:00
* @ type : the built - in type
* @ facetType : the facet type
*
* Evaluates if a specific facet can be
* used in conjunction with a type .
*
* Returns 1 if the facet can be used with the given built - in type ,
* 0 otherwise and - 1 in case the type is not a built - in type .
*/
int
xmlSchemaIsBuiltInTypeFacet ( xmlSchemaTypePtr type , int facetType )
{
2004-11-05 17:22:25 +00:00
if ( type = = NULL )
return ( - 1 ) ;
2004-06-29 17:04:39 +00:00
if ( type - > type ! = XML_SCHEMA_TYPE_BASIC )
return ( - 1 ) ;
switch ( type - > builtInType ) {
case XML_SCHEMAS_BOOLEAN :
if ( ( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) )
return ( 1 ) ;
else
2012-09-11 13:26:36 +08:00
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NOTATION :
case XML_SCHEMAS_QNAME :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_ANYURI :
case XML_SCHEMAS_BASE64BINARY :
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_HEXBINARY :
if ( ( facetType = = XML_SCHEMA_FACET_LENGTH ) | |
( facetType = = XML_SCHEMA_FACET_MINLENGTH ) | |
( facetType = = XML_SCHEMA_FACET_MAXLENGTH ) | |
( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_ENUMERATION ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) )
return ( 1 ) ;
else
return ( 0 ) ;
case XML_SCHEMAS_DECIMAL :
if ( ( facetType = = XML_SCHEMA_FACET_TOTALDIGITS ) | |
( facetType = = XML_SCHEMA_FACET_FRACTIONDIGITS ) | |
( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) | |
( facetType = = XML_SCHEMA_FACET_ENUMERATION ) | |
( facetType = = XML_SCHEMA_FACET_MAXINCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MAXEXCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MININCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MINEXCLUSIVE ) )
return ( 1 ) ;
else
2012-09-11 13:26:36 +08:00
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_TIME :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_GDAY :
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_GMONTH :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GYEAR :
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
case XML_SCHEMAS_DURATION :
case XML_SCHEMAS_FLOAT :
case XML_SCHEMAS_DOUBLE :
if ( ( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_ENUMERATION ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) | |
( facetType = = XML_SCHEMA_FACET_MAXINCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MAXEXCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MININCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MINEXCLUSIVE ) )
return ( 1 ) ;
else
2012-09-11 13:26:36 +08:00
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
default :
2004-09-28 12:33:52 +00:00
break ;
2004-06-29 17:04:39 +00:00
}
return ( 0 ) ;
}
/**
* xmlSchemaGetBuiltInType :
* @ type : the type of the built in type
*
* Gives you the type struct for a built - in
* type by its type id .
*
* Returns the type if found , NULL otherwise .
*/
xmlSchemaTypePtr
xmlSchemaGetBuiltInType ( xmlSchemaValType type )
{
if ( xmlSchemaTypesInitialized = = 0 )
xmlSchemaInitTypes ( ) ;
switch ( type ) {
2012-09-11 13:26:36 +08:00
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_ANYSIMPLETYPE :
return ( xmlSchemaTypeAnySimpleTypeDef ) ;
case XML_SCHEMAS_STRING :
return ( xmlSchemaTypeStringDef ) ;
case XML_SCHEMAS_NORMSTRING :
return ( xmlSchemaTypeNormStringDef ) ;
case XML_SCHEMAS_DECIMAL :
return ( xmlSchemaTypeDecimalDef ) ;
case XML_SCHEMAS_TIME :
return ( xmlSchemaTypeTimeDef ) ;
case XML_SCHEMAS_GDAY :
return ( xmlSchemaTypeGDayDef ) ;
case XML_SCHEMAS_GMONTH :
return ( xmlSchemaTypeGMonthDef ) ;
case XML_SCHEMAS_GMONTHDAY :
2012-09-11 13:26:36 +08:00
return ( xmlSchemaTypeGMonthDayDef ) ;
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_GYEAR :
return ( xmlSchemaTypeGYearDef ) ;
case XML_SCHEMAS_GYEARMONTH :
return ( xmlSchemaTypeGYearMonthDef ) ;
case XML_SCHEMAS_DATE :
return ( xmlSchemaTypeDateDef ) ;
case XML_SCHEMAS_DATETIME :
return ( xmlSchemaTypeDatetimeDef ) ;
case XML_SCHEMAS_DURATION :
return ( xmlSchemaTypeDurationDef ) ;
case XML_SCHEMAS_FLOAT :
return ( xmlSchemaTypeFloatDef ) ;
case XML_SCHEMAS_DOUBLE :
return ( xmlSchemaTypeDoubleDef ) ;
case XML_SCHEMAS_BOOLEAN :
return ( xmlSchemaTypeBooleanDef ) ;
case XML_SCHEMAS_TOKEN :
return ( xmlSchemaTypeTokenDef ) ;
case XML_SCHEMAS_LANGUAGE :
return ( xmlSchemaTypeLanguageDef ) ;
case XML_SCHEMAS_NMTOKEN :
return ( xmlSchemaTypeNmtokenDef ) ;
case XML_SCHEMAS_NMTOKENS :
return ( xmlSchemaTypeNmtokensDef ) ;
case XML_SCHEMAS_NAME :
return ( xmlSchemaTypeNameDef ) ;
case XML_SCHEMAS_QNAME :
return ( xmlSchemaTypeQNameDef ) ;
case XML_SCHEMAS_NCNAME :
return ( xmlSchemaTypeNCNameDef ) ;
case XML_SCHEMAS_ID :
return ( xmlSchemaTypeIdDef ) ;
case XML_SCHEMAS_IDREF :
return ( xmlSchemaTypeIdrefDef ) ;
case XML_SCHEMAS_IDREFS :
return ( xmlSchemaTypeIdrefsDef ) ;
case XML_SCHEMAS_ENTITY :
return ( xmlSchemaTypeEntityDef ) ;
case XML_SCHEMAS_ENTITIES :
return ( xmlSchemaTypeEntitiesDef ) ;
case XML_SCHEMAS_NOTATION :
return ( xmlSchemaTypeNotationDef ) ;
case XML_SCHEMAS_ANYURI :
return ( xmlSchemaTypeAnyURIDef ) ;
case XML_SCHEMAS_INTEGER :
return ( xmlSchemaTypeIntegerDef ) ;
case XML_SCHEMAS_NPINTEGER :
return ( xmlSchemaTypeNonPositiveIntegerDef ) ;
case XML_SCHEMAS_NINTEGER :
return ( xmlSchemaTypeNegativeIntegerDef ) ;
case XML_SCHEMAS_NNINTEGER :
return ( xmlSchemaTypeNonNegativeIntegerDef ) ;
case XML_SCHEMAS_PINTEGER :
return ( xmlSchemaTypePositiveIntegerDef ) ;
case XML_SCHEMAS_INT :
return ( xmlSchemaTypeIntDef ) ;
case XML_SCHEMAS_UINT :
return ( xmlSchemaTypeUnsignedIntDef ) ;
case XML_SCHEMAS_LONG :
return ( xmlSchemaTypeLongDef ) ;
case XML_SCHEMAS_ULONG :
return ( xmlSchemaTypeUnsignedLongDef ) ;
case XML_SCHEMAS_SHORT :
return ( xmlSchemaTypeShortDef ) ;
case XML_SCHEMAS_USHORT :
return ( xmlSchemaTypeUnsignedShortDef ) ;
case XML_SCHEMAS_BYTE :
return ( xmlSchemaTypeByteDef ) ;
case XML_SCHEMAS_UBYTE :
return ( xmlSchemaTypeUnsignedByteDef ) ;
case XML_SCHEMAS_HEXBINARY :
return ( xmlSchemaTypeHexBinaryDef ) ;
case XML_SCHEMAS_BASE64BINARY :
return ( xmlSchemaTypeBase64BinaryDef ) ;
case XML_SCHEMAS_ANYTYPE :
2012-09-11 13:26:36 +08:00
return ( xmlSchemaTypeAnyTypeDef ) ;
2004-06-29 17:04:39 +00:00
default :
return ( NULL ) ;
}
}
2005-06-15 13:36:10 +00:00
/**
* xmlSchemaValueAppend :
* @ prev : the value
* @ cur : the value to be appended
*
* Appends a next sibling to a list of computed values .
*
* Returns 0 if succeeded and - 1 on API errors .
*/
2005-06-09 10:32:53 +00:00
int
xmlSchemaValueAppend ( xmlSchemaValPtr prev , xmlSchemaValPtr cur ) {
2002-04-16 15:50:10 +00:00
2005-06-09 10:32:53 +00:00
if ( ( prev = = NULL ) | | ( cur = = NULL ) )
return ( - 1 ) ;
prev - > next = cur ;
return ( 0 ) ;
}
2005-06-15 13:36:10 +00:00
/**
* xmlSchemaValueGetNext :
* @ cur : the value
*
* Accessor for the next sibling of a list of computed values .
*
* Returns the next value or NULL if there was none , or on
* API errors .
*/
2005-06-09 10:32:53 +00:00
xmlSchemaValPtr
xmlSchemaValueGetNext ( xmlSchemaValPtr cur ) {
if ( cur = = NULL )
return ( NULL ) ;
return ( cur - > next ) ;
}
2005-06-15 13:36:10 +00:00
/**
* xmlSchemaValueGetAsString :
* @ val : the value
*
* Accessor for the string value of a computed value .
*
* Returns the string value or NULL if there was none , or on
* API errors .
*/
2005-06-09 10:32:53 +00:00
const xmlChar *
xmlSchemaValueGetAsString ( xmlSchemaValPtr val )
2012-09-11 13:26:36 +08:00
{
2005-06-09 10:32:53 +00:00
if ( val = = NULL )
return ( NULL ) ;
switch ( val - > type ) {
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_ANYSIMPLETYPE :
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_ANYURI :
return ( BAD_CAST val - > value . str ) ;
default :
break ;
2002-04-16 15:50:10 +00:00
}
2005-06-09 10:32:53 +00:00
return ( NULL ) ;
}
2005-06-15 13:36:10 +00:00
/**
* xmlSchemaValueGetAsBoolean :
* @ val : the value
*
* Accessor for the boolean value of a computed value .
*
* Returns 1 if true and 0 if false , or in case of an error . Hmm .
*/
2005-06-09 10:32:53 +00:00
int
xmlSchemaValueGetAsBoolean ( xmlSchemaValPtr val )
2012-09-11 13:26:36 +08:00
{
2005-06-09 10:32:53 +00:00
if ( ( val = = NULL ) | | ( val - > type ! = XML_SCHEMAS_BOOLEAN ) )
return ( 0 ) ;
return ( val - > value . b ) ;
2002-04-16 15:50:10 +00:00
}
2005-02-17 11:10:44 +00:00
/**
* xmlSchemaNewStringValue :
* @ type : the value type
2005-02-19 18:27:14 +00:00
* @ value : the value
2005-02-17 11:10:44 +00:00
*
2012-09-11 13:26:36 +08:00
* Allocate a new simple type value . The type can be
* of XML_SCHEMAS_STRING .
2005-03-07 11:14:14 +00:00
* WARNING : This one is intended to be expanded for other
* string based types . We need this for anySimpleType as well .
2005-06-09 10:32:53 +00:00
* The given value is consumed and freed with the struct .
2005-02-17 11:10:44 +00:00
*
* Returns a pointer to the new value or NULL in case of error
*/
xmlSchemaValPtr
xmlSchemaNewStringValue ( xmlSchemaValType type ,
const xmlChar * value )
{
xmlSchemaValPtr val ;
if ( type ! = XML_SCHEMAS_STRING )
return ( NULL ) ;
val = ( xmlSchemaValPtr ) xmlMalloc ( sizeof ( xmlSchemaVal ) ) ;
if ( val = = NULL ) {
return ( NULL ) ;
}
memset ( val , 0 , sizeof ( xmlSchemaVal ) ) ;
val - > type = type ;
val - > value . str = ( xmlChar * ) value ;
return ( val ) ;
}
2005-02-17 19:00:23 +00:00
/**
* xmlSchemaNewNOTATIONValue :
2005-02-19 18:27:14 +00:00
* @ name : the notation name
* @ ns : the notation namespace name or NULL
2005-02-17 19:00:23 +00:00
*
* Allocate a new NOTATION value .
2005-06-09 10:32:53 +00:00
* The given values are consumed and freed with the struct .
2005-02-17 19:00:23 +00:00
*
* Returns a pointer to the new value or NULL in case of error
*/
xmlSchemaValPtr
xmlSchemaNewNOTATIONValue ( const xmlChar * name ,
const xmlChar * ns )
{
xmlSchemaValPtr val ;
val = xmlSchemaNewValue ( XML_SCHEMAS_NOTATION ) ;
if ( val = = NULL )
return ( NULL ) ;
2005-02-21 13:54:07 +00:00
val - > value . qname . name = ( xmlChar * ) name ;
2005-02-17 19:00:23 +00:00
if ( ns ! = NULL )
2005-02-21 13:54:07 +00:00
val - > value . qname . uri = ( xmlChar * ) ns ;
2005-02-17 19:00:23 +00:00
return ( val ) ;
}
2005-02-17 11:10:44 +00:00
2005-06-09 10:32:53 +00:00
/**
* xmlSchemaNewQNameValue :
* @ namespaceName : the namespace name
* @ localName : the local name
*
* Allocate a new QName value .
* The given values are consumed and freed with the struct .
*
* Returns a pointer to the new value or NULL in case of an error .
*/
xmlSchemaValPtr
xmlSchemaNewQNameValue ( const xmlChar * namespaceName ,
const xmlChar * localName )
{
xmlSchemaValPtr val ;
val = xmlSchemaNewValue ( XML_SCHEMAS_QNAME ) ;
if ( val = = NULL )
return ( NULL ) ;
val - > value . qname . name = ( xmlChar * ) localName ;
val - > value . qname . uri = ( xmlChar * ) namespaceName ;
return ( val ) ;
}
2002-04-16 15:50:10 +00:00
/**
* xmlSchemaFreeValue :
* @ value : the value to free
*
* Cleanup the default XML Schemas type library
*/
2012-09-11 13:26:36 +08:00
void
2002-04-16 15:50:10 +00:00
xmlSchemaFreeValue ( xmlSchemaValPtr value ) {
2005-06-09 10:32:53 +00:00
xmlSchemaValPtr prev ;
2012-09-11 13:26:36 +08:00
while ( value ! = NULL ) {
2005-06-09 10:32:53 +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 :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_ENTITIES :
2005-06-09 10:32:53 +00:00
case XML_SCHEMAS_ANYURI :
case XML_SCHEMAS_ANYSIMPLETYPE :
if ( value - > value . str ! = NULL )
xmlFree ( value - > value . str ) ;
break ;
case XML_SCHEMAS_NOTATION :
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 ;
case XML_SCHEMAS_HEXBINARY :
if ( value - > value . hex . str ! = NULL )
xmlFree ( value - > value . hex . str ) ;
break ;
case XML_SCHEMAS_BASE64BINARY :
if ( value - > value . base64 . str ! = NULL )
xmlFree ( value - > value . base64 . str ) ;
break ;
default :
break ;
}
prev = value ;
value = value - > next ;
xmlFree ( prev ) ;
2012-09-11 13:26:36 +08:00
}
2002-04-16 15:50:10 +00:00
}
/**
* 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
2004-06-29 17:04:39 +00:00
/**
* xmlSchemaGetBuiltInListSimpleTypeItemType :
* @ type : the built - in simple type .
*
2004-10-27 17:29:04 +00:00
* Lookup function
*
2004-08-10 14:17:33 +00:00
* Returns the item type of @ type as defined by the built - in datatype
* hierarchy of XML Schema Part 2 : Datatypes , or NULL in case of an error .
2004-06-29 17:04:39 +00:00
*/
xmlSchemaTypePtr
xmlSchemaGetBuiltInListSimpleTypeItemType ( xmlSchemaTypePtr type )
{
2004-11-08 10:52:06 +00:00
if ( ( type = = NULL ) | | ( type - > type ! = XML_SCHEMA_TYPE_BASIC ) )
2004-06-29 17:04:39 +00:00
return ( NULL ) ;
switch ( type - > builtInType ) {
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_NMTOKENS :
2004-06-29 17:04:39 +00:00
return ( xmlSchemaTypeNmtokenDef ) ;
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_IDREFS :
2004-06-29 17:04:39 +00:00
return ( xmlSchemaTypeIdrefDef ) ;
case XML_SCHEMAS_ENTITIES :
return ( xmlSchemaTypeEntityDef ) ;
default :
return ( NULL ) ;
}
}
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))
2005-05-12 13:16:01 +00:00
# define VALID_TZO(tzo) ((tzo > -840) && (tzo < 840))
2002-05-03 07:29:38 +00:00
# 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 ) )
2016-04-11 20:03:19 +02:00
# define VALID_END_OF_DAY(dt) \
( ( dt ) - > hour = = 24 & & ( dt ) - > min = = 0 & & ( dt ) - > sec = = 0 )
2002-05-03 07:29:38 +00:00
# define VALID_TIME(dt) \
2016-04-11 20:03:19 +02:00
( ( ( VALID_HOUR ( dt - > hour ) & & VALID_MIN ( dt - > min ) & & \
VALID_SEC ( dt - > sec ) ) | | VALID_END_OF_DAY ( dt ) ) & & \
VALID_TZO ( dt - > tzo ) )
2002-05-03 07:29:38 +00:00
# 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 ;
2005-04-19 15:58:31 +00:00
unsigned int value = 0 ;
2002-05-03 07:29:38 +00:00
2005-04-19 15:58:31 +00:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 07:29:38 +00:00
if ( ret ! = 0 )
return ret ;
2005-04-19 15:58:31 +00:00
if ( ! VALID_MONTH ( value ) )
2002-05-03 07:29:38 +00:00
return 2 ;
2005-04-19 15:58:31 +00:00
dt - > mon = value ;
2002-05-03 07:29:38 +00:00
* 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 ;
2005-04-19 15:58:31 +00:00
unsigned int value = 0 ;
2002-05-03 07:29:38 +00:00
2005-04-19 15:58:31 +00:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 07:29:38 +00:00
if ( ret ! = 0 )
return ret ;
2005-04-19 15:58:31 +00:00
if ( ! VALID_DAY ( value ) )
2002-05-03 07:29:38 +00:00
return 2 ;
2005-04-19 15:58:31 +00:00
dt - > day = value ;
2002-05-03 07:29:38 +00:00
* 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 ) {
2012-09-11 13:26:36 +08:00
const xmlChar * cur = * str ;
2002-05-03 07:29:38 +00:00
int ret = 0 ;
2005-05-12 13:10:22 +00:00
int value = 0 ;
2002-05-03 07:29:38 +00:00
2005-04-19 15:58:31 +00:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 07:29:38 +00:00
if ( ret ! = 0 )
2012-09-11 13:26:36 +08:00
return ret ;
2002-05-03 07:29:38 +00:00
if ( * cur ! = ' : ' )
return 1 ;
2016-04-11 20:03:19 +02:00
if ( ! VALID_HOUR ( value ) & & value ! = 24 /* Allow end-of-day hour */ )
2005-04-19 15:58:31 +00:00
return 2 ;
2002-05-03 07:29:38 +00:00
cur + + ;
/* the ':' insures this string is xs:time */
2005-04-19 15:58:31 +00:00
dt - > hour = value ;
2002-05-03 07:29:38 +00:00
2005-04-19 15:58:31 +00:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 07:29:38 +00:00
if ( ret ! = 0 )
return ret ;
2005-04-19 15:58:31 +00:00
if ( ! VALID_MIN ( value ) )
return 2 ;
dt - > min = value ;
2002-05-03 07:29:38 +00:00
if ( * cur ! = ' : ' )
return 1 ;
cur + + ;
PARSE_FLOAT ( dt - > sec , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
2016-04-11 20:03:19 +02:00
if ( ! VALID_TIME ( dt ) )
2002-05-03 07:29:38 +00:00
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 ) {
2006-03-09 18:41:40 +00:00
const xmlChar * cur ;
2002-05-03 07:29:38 +00:00
int ret = 0 ;
if ( str = = NULL )
return - 1 ;
2006-03-09 18:41:40 +00:00
cur = * str ;
2002-05-03 07:29:38 +00:00
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 ,
2005-06-09 10:32:53 +00:00
const xmlChar * dateTime , xmlSchemaValPtr * val ,
int collapse ) {
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 ;
2005-06-09 10:32:53 +00:00
if ( collapse )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2002-05-03 07:29:38 +00:00
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 + + ;
2012-09-11 13:26:36 +08:00
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
2003-04-09 11:24:17 +00:00
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 ) .
2005-06-09 10:32:53 +00:00
* FUTURE TODO : Zero will become valid in XML Schema 1.1
* probably .
2003-04-09 11:24:17 +00:00
*/
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 ) ;
2005-06-09 10:32:53 +00:00
if ( collapse )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-12-10 11:11:12 +00:00
if ( ( ret ! = 0 ) | | ( * cur ! = 0 ) | | ( ! ( VALID_DATETIME ( ( & ( dt - > value . date ) ) ) ) ) )
2002-05-03 07:29:38 +00:00
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 ,
2005-06-09 10:32:53 +00:00
const xmlChar * duration , xmlSchemaValPtr * val ,
int collapse ) {
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 ;
2005-06-09 10:32:53 +00:00
if ( collapse )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2002-05-03 07:29:38 +00:00
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? */
2005-04-18 10:57:04 +00:00
if ( ( + + seq = = 3 ) | | ( seq = = 6 ) )
2002-05-03 07:29:38 +00:00
goto error ;
}
2005-06-09 10:32:53 +00:00
cur + + ;
if ( collapse )
2012-09-11 13:26:36 +08:00
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2002-05-03 07:29:38 +00:00
}
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
2004-11-12 14:04:58 +00:00
/**
* xmlSchemaWhiteSpaceReplace :
* @ value : a value
*
* Replaces 0xd , 0x9 and 0xa with a space .
*
* Returns the new string or NULL if no change was required .
*/
xmlChar *
xmlSchemaWhiteSpaceReplace ( const xmlChar * value ) {
2012-09-11 13:26:36 +08:00
const xmlChar * cur = value ;
xmlChar * ret = NULL , * mcur ;
2004-11-12 14:04:58 +00:00
2012-09-11 13:26:36 +08:00
if ( value = = NULL )
2004-11-12 14:04:58 +00:00
return ( NULL ) ;
2012-09-11 13:26:36 +08:00
while ( ( * cur ! = 0 ) & &
2004-11-12 14:04:58 +00:00
( ( ( * cur ) ! = 0xd ) & & ( ( * cur ) ! = 0x9 ) & & ( ( * cur ) ! = 0xa ) ) ) {
cur + + ;
}
if ( * cur = = 0 )
return ( NULL ) ;
ret = xmlStrdup ( value ) ;
/* TODO FIXME: I guess gcc will bark at this. */
mcur = ( xmlChar * ) ( ret + ( cur - value ) ) ;
do {
if ( ( ( * mcur ) = = 0xd ) | | ( ( * mcur ) = = 0x9 ) | | ( ( * mcur ) = = 0xa ) )
* mcur = ' ' ;
mcur + + ;
2012-09-11 13:26:36 +08:00
} while ( * mcur ! = 0 ) ;
2004-11-12 14:04:58 +00:00
return ( ret ) ;
}
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 .
*/
2004-06-29 17:04:39 +00:00
xmlChar *
2003-03-29 16:41:55 +00:00
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 ) ;
}
2005-01-16 00:05:58 +00:00
if ( ret ! = NULL ) {
* ret = NULL ;
}
2003-03-18 11:39:17 +00:00
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 ) {
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 + + ;
}
2005-01-16 00:05:58 +00:00
/* TODO what return value ? c.f. bug #158628
2003-03-18 11:39:17 +00:00
if ( ret ! = NULL ) {
TODO
2005-01-16 00:05:58 +00:00
} */
xmlFree ( val ) ;
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 .
*
2005-03-15 15:50:17 +00:00
* Returns the number of significant digits in the number or
2008-04-03 10:43:52 +00:00
* - 1 if overflow of the capacity and - 2 if it ' s not a number .
2003-03-30 21:10:09 +00:00
*/
static int
xmlSchemaParseUInt ( const xmlChar * * str , unsigned long * llo ,
2005-03-16 16:29:18 +00:00
unsigned long * lmi , unsigned long * lhi ) {
2003-03-30 21:10:09 +00:00
unsigned long lo = 0 , mi = 0 , hi = 0 ;
const xmlChar * tmp , * cur = * str ;
int ret = 0 , i = 0 ;
2012-09-11 13:26:36 +08:00
if ( ! ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) )
2008-04-03 10:43:52 +00:00
return ( - 2 ) ;
2005-03-16 16:29:18 +00:00
while ( * cur = = ' 0 ' ) { /* ignore leading zeroes */
cur + + ;
2003-03-30 21:10:09 +00:00
}
tmp = cur ;
while ( ( * tmp ! = 0 ) & & ( * tmp > = ' 0 ' ) & & ( * tmp < = ' 9 ' ) ) {
2005-03-16 16:29:18 +00:00
i + + ; tmp + + ; ret + + ;
2003-03-30 21:10:09 +00:00
}
if ( i > 24 ) {
2005-03-16 16:29:18 +00:00
* str = tmp ;
return ( - 1 ) ;
2003-03-30 21:10:09 +00:00
}
while ( i > 16 ) {
2005-03-16 16:29:18 +00:00
hi = hi * 10 + ( * cur + + - ' 0 ' ) ;
i - - ;
2003-03-30 21:10:09 +00:00
}
while ( i > 8 ) {
2005-03-16 16:29:18 +00:00
mi = mi * 10 + ( * cur + + - ' 0 ' ) ;
i - - ;
2003-03-30 21:10:09 +00:00
}
while ( i > 0 ) {
2005-03-16 16:29:18 +00:00
lo = lo * 10 + ( * cur + + - ' 0 ' ) ;
i - - ;
2003-03-30 21:10:09 +00:00
}
* 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 .
2004-06-29 17:04:39 +00:00
* This checks the value space for list types as well ( IDREFS , NMTOKENS ) .
2002-04-16 15:50:10 +00:00
*
* 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 ,
2005-06-09 10:32:53 +00:00
xmlSchemaValPtr * val , xmlNodePtr node , int flags ,
xmlSchemaWhitespaceValueType ws ,
int normOnTheFly , int applyNorm , int createStringValue )
2003-08-27 14:15:15 +00:00
{
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 )
2004-06-29 17:04:39 +00:00
xmlSchemaInitTypes ( ) ;
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
2004-08-26 10:30:44 +00:00
/*
* validating a non existant text node is similar to validating
* an empty one .
*/
if ( value = = NULL )
value = BAD_CAST " " ;
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 ) ) {
2004-11-12 14:04:58 +00:00
2004-06-29 17:04:39 +00:00
if ( ( type - > builtInType ! = XML_SCHEMAS_STRING ) & &
2012-09-11 13:26:36 +08:00
( type - > builtInType ! = XML_SCHEMAS_ANYTYPE ) & &
2004-11-12 14:04:58 +00:00
( type - > builtInType ! = XML_SCHEMAS_ANYSIMPLETYPE ) ) {
if ( type - > builtInType = = XML_SCHEMAS_NORMSTRING )
norm = xmlSchemaWhiteSpaceReplace ( value ) ;
else
norm = xmlSchemaCollapseString ( value ) ;
2003-08-27 14:15:15 +00:00
if ( norm ! = NULL )
value = norm ;
}
2003-03-29 16:41:55 +00:00
}
2004-06-29 17:04:39 +00:00
switch ( type - > builtInType ) {
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_UNKNOWN :
2003-08-27 14:15:15 +00:00
goto error ;
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-20 23:09:47 +00:00
case XML_SCHEMAS_ANYTYPE :
case XML_SCHEMAS_ANYSIMPLETYPE :
2005-06-09 10:32:53 +00:00
if ( ( createStringValue ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_ANYSIMPLETYPE ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
2012-09-11 13:26:36 +08:00
}
2005-06-09 10:32:53 +00:00
}
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-20 23:09:47 +00:00
goto return0 ;
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_STRING :
2005-06-09 10:32:53 +00:00
if ( ! normOnTheFly ) {
const xmlChar * cur = value ;
if ( ws = = XML_SCHEMA_WHITESPACE_REPLACE ) {
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else {
cur + + ;
}
}
} else if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE ) {
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else if IS_WSP_SPACE_CH ( * cur ) {
cur + + ;
if IS_WSP_SPACE_CH ( * cur )
goto return1 ;
} else {
cur + + ;
}
}
}
}
if ( createStringValue & & ( val ! = NULL ) ) {
if ( applyNorm ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
norm = xmlSchemaCollapseString ( value ) ;
else if ( ws = = XML_SCHEMA_WHITESPACE_REPLACE )
norm = xmlSchemaWhiteSpaceReplace ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
v = xmlSchemaNewValue ( XML_SCHEMAS_STRING ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
2003-08-27 14:15:15 +00:00
goto return0 ;
2004-01-22 07:27:45 +00:00
case XML_SCHEMAS_NORMSTRING : {
2005-06-09 10:32:53 +00:00
if ( normOnTheFly ) {
if ( applyNorm ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
norm = xmlSchemaCollapseString ( value ) ;
else
norm = xmlSchemaWhiteSpaceReplace ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
} else {
const xmlChar * cur = value ;
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else {
cur + + ;
}
}
}
2004-01-22 07:27:45 +00:00
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 : {
2005-03-11 15:55:14 +00:00
const xmlChar * cur = value ;
2005-11-28 16:36:30 +00:00
unsigned int len , neg , integ , hasLeadingZeroes ;
2005-03-11 15:55:14 +00:00
xmlChar cval [ 25 ] ;
2012-09-11 13:26:36 +08:00
xmlChar * cptr = cval ;
2003-08-27 14:15:15 +00:00
2005-11-28 16:36:30 +00:00
if ( ( cur = = NULL ) | | ( * cur = = 0 ) )
2003-08-27 14:15:15 +00:00
goto return1 ;
2005-06-09 10:32:53 +00:00
2005-11-28 16:36:30 +00:00
/*
* xs : decimal has a whitespace - facet value of ' collapse ' .
*/
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-11-28 16:36:30 +00:00
/*
* First we handle an optional sign .
*/
neg = 0 ;
if ( * cur = = ' - ' ) {
neg = 1 ;
2003-08-27 14:15:15 +00:00
cur + + ;
2005-11-28 16:36:30 +00:00
} else if ( * cur = = ' + ' )
2003-08-27 14:15:15 +00:00
cur + + ;
2005-11-28 16:36:30 +00:00
/*
* Disallow : " " , " - " , " - "
*/
if ( * cur = = 0 )
goto return1 ;
2005-03-11 15:55:14 +00:00
/*
* Next we " pre-parse " the number , in preparation for calling
* the common routine xmlSchemaParseUInt . We get rid of any
* leading zeroes ( because we have reserved only 25 chars ) ,
2005-11-28 16:36:30 +00:00
* and note the position of a decimal point .
2005-03-11 15:55:14 +00:00
*/
len = 0 ;
2005-11-28 16:36:30 +00:00
integ = ~ 0u ;
hasLeadingZeroes = 0 ;
2005-04-18 10:57:04 +00:00
/*
* Skip leading zeroes .
*/
2005-11-28 16:36:30 +00:00
while ( * cur = = ' 0 ' ) {
2005-03-11 15:55:14 +00:00
cur + + ;
2005-11-28 16:36:30 +00:00
hasLeadingZeroes = 1 ;
}
2005-04-18 10:57:04 +00:00
if ( * cur ! = 0 ) {
2005-11-28 16:36:30 +00:00
do {
2005-04-18 10:57:04 +00:00
if ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
* cptr + + = * cur + + ;
len + + ;
} else if ( * cur = = ' . ' ) {
cur + + ;
2005-11-28 16:36:30 +00:00
integ = len ;
do {
if ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
* cptr + + = * cur + + ;
len + + ;
} else
break ;
} while ( len < 24 ) ;
/*
* Disallow " . " but allow " 00. "
*/
if ( ( len = = 0 ) & & ( ! hasLeadingZeroes ) )
2005-04-18 10:57:04 +00:00
goto return1 ;
break ;
} else
break ;
2005-11-28 16:36:30 +00:00
} while ( len < 24 ) ;
2005-03-11 15:55:14 +00:00
}
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-03-11 15:55:14 +00:00
if ( * cur ! = 0 )
2005-11-28 16:36:30 +00:00
goto return1 ; /* error if any extraneous chars */
2003-08-27 14:15:15 +00:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_DECIMAL ) ;
if ( v ! = NULL ) {
2005-03-11 15:55:14 +00:00
/*
2012-09-11 13:26:36 +08:00
* Now evaluate the significant digits of the number
*/
2005-11-28 16:36:30 +00:00
if ( len ! = 0 ) {
2012-09-11 13:26:36 +08:00
2005-11-28 16:36:30 +00:00
if ( integ ! = ~ 0u ) {
/*
* Get rid of trailing zeroes in the
* fractional part .
*/
while ( ( len ! = integ ) & & ( * ( cptr - 1 ) = = ' 0 ' ) ) {
cptr - - ;
len - - ;
}
}
/*
* Terminate the ( preparsed ) string .
*/
if ( len ! = 0 ) {
2008-04-03 10:43:52 +00:00
* cptr = 0 ;
2005-11-28 16:36:30 +00:00
cptr = cval ;
2008-04-03 10:43:52 +00:00
2005-11-28 16:36:30 +00:00
xmlSchemaParseUInt ( ( const xmlChar * * ) & cptr ,
& v - > value . decimal . lo ,
& v - > value . decimal . mi ,
& v - > value . decimal . hi ) ;
2005-03-11 15:55:14 +00:00
}
}
2005-04-18 10:57:04 +00:00
/*
* Set the total digits to 1 if a zero value .
*/
2003-08-27 14:15:15 +00:00
v - > value . decimal . sign = neg ;
2005-11-28 16:36:30 +00:00
if ( len = = 0 ) {
/* Speedup for zero values. */
v - > value . decimal . total = 1 ;
2005-03-11 15:55:14 +00:00
} else {
2005-04-18 10:57:04 +00:00
v - > value . decimal . total = len ;
2005-11-28 16:36:30 +00:00
if ( integ = = ~ 0u )
v - > value . decimal . frac = 0 ;
else
v - > value . decimal . frac = len - integ ;
2005-03-11 15:55:14 +00:00
}
2003-08-27 14:15:15 +00:00
* 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 :
2005-06-09 10:32:53 +00:00
ret = xmlSchemaValidateDates ( type - > builtInType , value , val ,
normOnTheFly ) ;
2003-08-27 14:15:15 +00:00
break ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_DURATION :
2005-06-09 10:32:53 +00:00
ret = xmlSchemaValidateDuration ( type , value , val ,
normOnTheFly ) ;
2003-08-27 14:15:15 +00:00
break ;
2003-03-29 16:41:55 +00:00
case XML_SCHEMAS_FLOAT :
2010-07-28 11:41:23 +02:00
case XML_SCHEMAS_DOUBLE : {
2003-08-27 14:15:15 +00:00
const xmlChar * cur = value ;
int neg = 0 ;
2010-07-28 11:41:23 +02:00
int digits_before = 0 ;
int digits_after = 0 ;
2003-08-27 14:15:15 +00:00
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-08-27 14:15:15 +00:00
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 + + ;
2010-07-28 11:41:23 +02:00
digits_before + + ;
2003-08-27 14:15:15 +00:00
}
if ( * cur = = ' . ' ) {
cur + + ;
2010-07-28 11:41:23 +02:00
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
2003-08-27 14:15:15 +00:00
cur + + ;
2010-07-28 11:41:23 +02:00
digits_after + + ;
}
2003-08-27 14:15:15 +00:00
}
2010-07-28 14:49:55 +02:00
if ( ( digits_before = = 0 ) & & ( digits_after = = 0 ) )
2010-07-28 11:41:23 +02:00
goto return1 ;
2003-08-27 14:15:15 +00:00
if ( ( * cur = = ' e ' ) | | ( * cur = = ' E ' ) ) {
cur + + ;
if ( ( * cur = = ' - ' ) | | ( * cur = = ' + ' ) )
cur + + ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) )
cur + + ;
}
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-08-27 14:15:15 +00:00
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
2005-03-15 14:58:11 +00:00
/*
* TODO : sscanf seems not to give the correct
* value for extremely high / low values .
* E . g . " 1E-149 " results in zero .
*/
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 ) {
2005-03-15 14:58:11 +00:00
* val = v ;
2003-08-27 14:15:15 +00:00
} else {
xmlSchemaFreeValue ( v ) ;
goto return1 ;
}
} else {
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
2005-03-15 14:58:11 +00:00
/*
* TODO : sscanf seems not to give the correct
* value for extremely high / low values .
*/
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 ;
2005-06-09 10:32:53 +00:00
if ( normOnTheFly ) {
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
if ( * cur = = ' 0 ' ) {
ret = 0 ;
cur + + ;
} else if ( * cur = = ' 1 ' ) {
ret = 1 ;
cur + + ;
} else if ( * cur = = ' t ' ) {
cur + + ;
if ( ( * cur + + = = ' r ' ) & & ( * cur + + = = ' u ' ) & &
( * cur + + = = ' e ' ) ) {
ret = 1 ;
} else
goto return1 ;
} else if ( * cur = = ' f ' ) {
cur + + ;
if ( ( * cur + + = = ' a ' ) & & ( * cur + + = = ' l ' ) & &
( * cur + + = = ' s ' ) & & ( * cur + + = = ' e ' ) ) {
ret = 0 ;
} else
goto return1 ;
2006-02-20 13:37:55 +00:00
} else
goto return1 ;
2005-06-09 10:32:53 +00:00
if ( * cur ! = 0 ) {
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
if ( * cur ! = 0 )
goto return1 ;
}
} else {
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 ;
}
2003-08-27 14:15:15 +00:00
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 ;
2005-06-09 10:32:53 +00:00
if ( ! normOnTheFly ) {
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 + + ;
}
2012-09-11 13:26:36 +08:00
}
}
2003-08-27 14:15:15 +00:00
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 :
2012-09-11 13:26:36 +08:00
if ( normOnTheFly ) {
2005-06-09 10:32:53 +00:00
norm = xmlSchemaCollapseString ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
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 ) ;
2005-01-16 19:00:15 +00:00
if ( ( ret = = 0 ) & & ( val ! = NULL ) & & ( value ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NAME ) ;
if ( v ! = NULL ) {
const xmlChar * start = value , * end ;
while ( IS_BLANK_CH ( * start ) ) start + + ;
end = start ;
while ( ( * end ! = 0 ) & & ( ! IS_BLANK_CH ( * end ) ) ) end + + ;
v - > value . str = xmlStrndup ( start , end - start ) ;
* val = v ;
} else {
goto error ;
}
2003-08-27 14:15:15 +00:00
}
goto done ;
case XML_SCHEMAS_QNAME : {
2005-06-09 14:54:59 +00:00
const xmlChar * uri = NULL ;
2003-08-27 14:15:15 +00:00
xmlChar * local = NULL ;
ret = xmlValidateQName ( value , 1 ) ;
2005-06-09 14:54:59 +00:00
if ( ret ! = 0 )
goto done ;
if ( node ! = NULL ) {
2003-08-27 14:15:15 +00:00
xmlChar * prefix ;
2005-06-09 14:54:59 +00:00
xmlNsPtr ns ;
2003-08-27 14:15:15 +00:00
local = xmlSplitQName2 ( value , & prefix ) ;
2005-06-09 14:54:59 +00:00
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ( ns = = NULL ) & & ( prefix ! = NULL ) ) {
xmlFree ( prefix ) ;
if ( local ! = NULL )
xmlFree ( local ) ;
goto return1 ;
}
if ( ns ! = NULL )
uri = ns - > href ;
2003-08-27 14:15:15 +00:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
2005-06-09 14:54:59 +00:00
if ( val ! = NULL ) {
2003-08-27 14:15:15 +00:00
v = xmlSchemaNewValue ( XML_SCHEMAS_QNAME ) ;
2005-06-09 14:54:59 +00:00
if ( v = = NULL ) {
if ( local ! = NULL )
xmlFree ( local ) ;
goto error ;
}
if ( local ! = NULL )
v - > value . qname . name = local ;
else
v - > value . qname . name = xmlStrdup ( value ) ;
if ( uri ! = NULL )
v - > value . qname . uri = xmlStrdup ( uri ) ;
* val = v ;
} else
if ( local ! = NULL )
xmlFree ( local ) ;
2003-08-27 14:15:15 +00:00
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 ) ) {
2005-02-17 11:10:44 +00:00
v = xmlSchemaNewValue ( XML_SCHEMAS_IDREF ) ;
if ( v = = NULL )
goto error ;
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
2003-08-27 14:15:15 +00:00
}
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
}
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_ANYURI : {
2004-03-14 12:20:15 +00:00
if ( * value ! = 0 ) {
2005-06-09 10:32:53 +00:00
xmlURIPtr uri ;
2009-08-07 16:42:24 +02:00
xmlChar * tmpval , * cur ;
2012-09-11 13:26:36 +08:00
if ( normOnTheFly ) {
2005-06-09 10:32:53 +00:00
norm = xmlSchemaCollapseString ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
2009-08-07 16:42:24 +02:00
tmpval = xmlStrdup ( value ) ;
for ( cur = tmpval ; * cur ; + + cur ) {
if ( * cur < 32 | | * cur > = 127 | | * cur = = ' ' | |
* cur = = ' < ' | | * cur = = ' > ' | | * cur = = ' " ' | |
* cur = = ' { ' | | * cur = = ' } ' | | * cur = = ' | ' | |
* cur = = ' \\ ' | | * cur = = ' ^ ' | | * cur = = ' ` ' | |
* cur = = ' \' ' )
* cur = ' _ ' ;
}
uri = xmlParseURI ( ( const char * ) tmpval ) ;
xmlFree ( tmpval ) ;
2004-03-14 12:20:15 +00:00
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 : {
2005-06-09 13:14:38 +00:00
const xmlChar * cur = value , * start ;
2003-08-27 14:15:15 +00:00
xmlChar * base ;
int total , i = 0 ;
2003-07-06 21:13:49 +00:00
2004-08-31 08:42:17 +00:00
if ( cur = = NULL )
2003-08-27 14:15:15 +00:00
goto return1 ;
2003-07-06 21:13:49 +00:00
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-06-09 13:14:38 +00:00
start = cur ;
2003-08-27 14:15:15 +00:00
while ( ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) | |
( ( * cur > = ' A ' ) & & ( * cur < = ' F ' ) ) | |
( ( * cur > = ' a ' ) & & ( * cur < = ' f ' ) ) ) {
i + + ;
cur + + ;
}
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) 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 ;
2005-06-09 10:32:53 +00:00
/*
* Copy only the normalized piece .
* CRITICAL TODO : Check this .
*/
2005-06-09 13:14:38 +00:00
cur = xmlStrndup ( start , i ) ;
2003-08-27 14:15:15 +00:00
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:
2012-09-11 13:26:36 +08:00
*
2003-08-27 14:15:15 +00:00
* Ignore all stray characters ? ( yes , currently )
* Worry about long lines ? ( no , currently )
2012-09-11 13:26:36 +08:00
*
2003-08-27 14:15:15 +00:00
* rfc2045 . txt :
2012-09-11 13:26:36 +08:00
*
2003-08-27 14:15:15 +00:00
* " 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 ;
2005-03-15 15:50:17 +00:00
int sign = 0 ;
2003-08-27 14:15:15 +00:00
if ( cur = = NULL )
goto return1 ;
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-08-27 14:15:15 +00:00
if ( * cur = = ' - ' ) {
sign = 1 ;
cur + + ;
} else if ( * cur = = ' + ' )
cur + + ;
2005-03-15 15:50:17 +00:00
ret = xmlSchemaParseUInt ( & cur , & lo , & mi , & hi ) ;
2008-04-03 10:43:52 +00:00
if ( ret < 0 )
2005-03-15 15:50:17 +00:00
goto return1 ;
2005-06-09 10:32:53 +00:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-03-15 15:50:17 +00:00
if ( * cur ! = 0 )
goto return1 ;
2004-06-29 17:04:39 +00:00
if ( type - > builtInType = = XML_SCHEMAS_NPINTEGER ) {
2003-08-27 14:15:15 +00:00
if ( ( sign = = 0 ) & &
( ( hi ! = 0 ) | | ( mi ! = 0 ) | | ( lo ! = 0 ) ) )
goto return1 ;
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_PINTEGER ) {
2003-08-27 14:15:15 +00:00
if ( sign = = 1 )
goto return1 ;
if ( ( hi = = 0 ) & & ( mi = = 0 ) & & ( lo = = 0 ) )
goto return1 ;
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_NINTEGER ) {
2003-08-27 14:15:15 +00:00
if ( sign = = 0 )
goto return1 ;
if ( ( hi = = 0 ) & & ( mi = = 0 ) & & ( lo = = 0 ) )
goto return1 ;
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_NNINTEGER ) {
2003-08-27 14:15:15 +00:00
if ( ( sign = = 1 ) & &
( ( hi ! = 0 ) | | ( mi ! = 0 ) | | ( lo ! = 0 ) ) )
goto return1 ;
}
2005-03-15 14:58:11 +00:00
if ( val ! = NULL ) {
2004-06-29 17:04:39 +00:00
v = xmlSchemaNewValue ( type - > builtInType ) ;
2003-08-27 14:15:15 +00:00
if ( v ! = NULL ) {
2005-04-18 10:57:04 +00:00
if ( ret = = 0 )
ret + + ;
2003-08-27 14:15:15 +00:00
v - > value . decimal . lo = lo ;
2005-03-15 14:58:11 +00:00
v - > value . decimal . mi = mi ;
v - > value . decimal . hi = hi ;
2003-08-27 14:15:15 +00:00
v - > value . decimal . sign = sign ;
v - > value . decimal . frac = 0 ;
2005-03-15 15:50:17 +00:00
v - > value . decimal . total = ret ;
2003-08-27 14:15:15 +00:00
* 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 : {
2008-04-03 10:43:52 +00:00
const xmlChar * cur = value ;
2003-08-27 14:15:15 +00:00
unsigned long lo , mi , hi ;
int sign = 0 ;
if ( cur = = NULL )
goto return1 ;
if ( * cur = = ' - ' ) {
sign = 1 ;
cur + + ;
} else if ( * cur = = ' + ' )
cur + + ;
2005-03-15 15:50:17 +00:00
ret = xmlSchemaParseUInt ( & cur , & lo , & mi , & hi ) ;
if ( ret < 0 )
goto return1 ;
if ( * cur ! = 0 )
goto return1 ;
2004-06-29 17:04:39 +00:00
if ( type - > builtInType = = XML_SCHEMAS_LONG ) {
2003-08-27 14:15:15 +00:00
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 ;
}
}
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_INT ) {
2003-08-27 14:15:15 +00:00
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 ;
}
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_SHORT ) {
2003-08-27 14:15:15 +00:00
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( ( sign = = 1 ) & & ( lo > 32768 ) )
goto return1 ;
if ( ( sign = = 0 ) & & ( lo > 32767 ) )
goto return1 ;
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_BYTE ) {
2003-08-27 14:15:15 +00:00
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( ( sign = = 1 ) & & ( lo > 128 ) )
goto return1 ;
if ( ( sign = = 0 ) & & ( lo > 127 ) )
goto return1 ;
}
if ( val ! = NULL ) {
2004-06-29 17:04:39 +00:00
v = xmlSchemaNewValue ( type - > builtInType ) ;
2003-08-27 14:15:15 +00:00
if ( v ! = NULL ) {
v - > value . decimal . lo = lo ;
2005-03-15 14:58:11 +00:00
v - > value . decimal . mi = mi ;
v - > value . decimal . hi = hi ;
2003-08-27 14:15:15 +00:00
v - > value . decimal . sign = sign ;
v - > value . decimal . frac = 0 ;
2005-03-15 15:50:17 +00:00
v - > value . decimal . total = ret ;
2003-08-27 14:15:15 +00:00
* 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 ;
if ( cur = = NULL )
goto return1 ;
2005-03-15 15:50:17 +00:00
ret = xmlSchemaParseUInt ( & cur , & lo , & mi , & hi ) ;
if ( ret < 0 )
goto return1 ;
if ( * cur ! = 0 )
goto return1 ;
2004-06-29 17:04:39 +00:00
if ( type - > builtInType = = XML_SCHEMAS_ULONG ) {
2003-08-27 14:15:15 +00:00
if ( hi > = 1844 ) {
if ( hi > 1844 )
goto return1 ;
if ( mi > = 67440737 ) {
if ( mi > 67440737 )
goto return1 ;
if ( lo > 9551615 )
goto return1 ;
}
}
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_UINT ) {
2003-08-27 14:15:15 +00:00
if ( hi ! = 0 )
goto return1 ;
if ( mi > = 42 ) {
if ( mi > 42 )
goto return1 ;
if ( lo > 94967295 )
goto return1 ;
}
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_USHORT ) {
2003-08-27 14:15:15 +00:00
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( lo > 65535 )
goto return1 ;
2004-06-29 17:04:39 +00:00
} else if ( type - > builtInType = = XML_SCHEMAS_UBYTE ) {
2003-08-27 14:15:15 +00:00
if ( ( mi ! = 0 ) | | ( hi ! = 0 ) )
goto return1 ;
if ( lo > 255 )
goto return1 ;
}
if ( val ! = NULL ) {
2004-06-29 17:04:39 +00:00
v = xmlSchemaNewValue ( type - > builtInType ) ;
2003-08-27 14:15:15 +00:00
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 ;
2005-03-15 15:50:17 +00:00
v - > value . decimal . total = ret ;
2003-08-27 14:15:15 +00:00
* 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 ) {
2005-06-09 10:32:53 +00:00
return ( xmlSchemaValAtomicType ( type , value , val , node , 0 ,
XML_SCHEMA_WHITESPACE_UNKNOWN , 1 , 1 , 0 ) ) ;
2002-04-16 15:50:10 +00:00
}
2004-08-10 14:17:33 +00:00
/**
* xmlSchemaValPredefTypeNodeNoNorm :
* @ 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 .
* This one does apply any normalization to the value .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
int
xmlSchemaValPredefTypeNodeNoNorm ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val , xmlNodePtr node ) {
2005-06-09 10:32:53 +00:00
return ( xmlSchemaValAtomicType ( type , value , val , node , 1 ,
XML_SCHEMA_WHITESPACE_UNKNOWN , 1 , 0 , 1 ) ) ;
2004-08-10 14:17:33 +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 ;
2005-03-11 15:55:14 +00:00
int order = 1 , integx , integy , dlen ;
unsigned long hi , mi , lo ;
2002-04-16 15:50:10 +00:00
2005-03-11 15:55:14 +00:00
/*
* First test : If x is - ve and not zero
*/
2012-09-11 13:26:36 +08:00
if ( ( x - > value . decimal . sign ) & &
2003-03-30 21:10:09 +00:00
( ( x - > value . decimal . lo ! = 0 ) | |
( x - > value . decimal . mi ! = 0 ) | |
( x - > value . decimal . hi ! = 0 ) ) ) {
2005-03-11 15:55:14 +00:00
/*
* Then if y is - ve and not zero reverse the compare
*/
2003-03-30 21:10:09 +00:00
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 ;
2005-03-11 15:55:14 +00:00
/*
* Otherwise ( y > = 0 ) we have the answer
*/
2003-03-28 13:29:53 +00:00
else
return ( - 1 ) ;
2005-03-11 15:55:14 +00:00
/*
* If x is not - ve and y is - ve we have the answer
*/
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
}
2005-03-11 15:55:14 +00:00
/*
* If it ' s not simply determined by a difference in sign ,
* then we need to compare the actual values of the two nums .
* To do this , we start by looking at the integral parts .
* If the number of integral digits differ , then we have our
* answer .
*/
integx = x - > value . decimal . total - x - > value . decimal . frac ;
integy = y - > value . decimal . total - y - > value . decimal . frac ;
2005-11-28 16:36:30 +00:00
/*
* NOTE : We changed the " total " for values like " 0.1 "
* ( or " -0.1 " or " .1 " ) to be 1 , which was 2 previously .
* Therefore the special case , when such values are
* compared with 0 , needs to be handled separately ;
* otherwise a zero would be recognized incorrectly as
* greater than those values . This has the nice side effect
* that we gain an overall optimized comparison with zeroes .
* Note that a " 0 " has a " total " of 1 already .
*/
if ( integx = = 1 ) {
if ( x - > value . decimal . lo = = 0 ) {
if ( integy ! = 1 )
return - order ;
else if ( y - > value . decimal . lo ! = 0 )
return - order ;
else
return ( 0 ) ;
}
}
if ( integy = = 1 ) {
if ( y - > value . decimal . lo = = 0 ) {
if ( integx ! = 1 )
return order ;
else if ( x - > value . decimal . lo ! = 0 )
return order ;
else
return ( 0 ) ;
}
}
2005-03-11 15:55:14 +00:00
if ( integx > integy )
return order ;
else if ( integy > integx )
return - order ;
2005-11-28 16:36:30 +00:00
2005-03-11 15:55:14 +00:00
/*
* If the number of integral digits is the same for both numbers ,
* then things get a little more complicated . We need to " normalize "
* the numbers in order to properly compare them . To do this , we
* look at the total length of each number ( length = > number of
* significant digits ) , and divide the " shorter " by 10 ( decreasing
* the length ) until they are of equal length .
*/
dlen = x - > value . decimal . total - y - > value . decimal . total ;
if ( dlen < 0 ) { /* y has more digits than x */
swp = x ;
hi = y - > value . decimal . hi ;
mi = y - > value . decimal . mi ;
lo = y - > value . decimal . lo ;
dlen = - dlen ;
order = - order ;
} else { /* x has more digits than y */
swp = y ;
hi = x - > value . decimal . hi ;
mi = x - > value . decimal . mi ;
lo = x - > value . decimal . lo ;
}
while ( dlen > 8 ) { /* in effect, right shift by 10**8 */
lo = mi ;
mi = hi ;
hi = 0 ;
dlen - = 8 ;
2002-04-16 15:50:10 +00:00
}
2005-03-11 15:55:14 +00:00
while ( dlen > 0 ) {
unsigned long rem1 , rem2 ;
rem1 = ( hi % 10 ) * 100000000L ;
hi = hi / 10 ;
rem2 = ( mi % 10 ) * 100000000L ;
mi = ( mi + rem1 ) / 10 ;
lo = ( lo + rem2 ) / 10 ;
dlen - - ;
}
if ( hi > swp - > value . decimal . hi ) {
return order ;
} else if ( hi = = swp - > value . decimal . hi ) {
if ( mi > swp - > value . decimal . mi ) {
return order ;
} else if ( mi = = swp - > value . decimal . mi ) {
if ( lo > swp - > value . decimal . lo ) {
return order ;
} else if ( lo = = swp - > value . decimal . lo ) {
if ( x - > value . decimal . total = = y - > value . decimal . total ) {
return 0 ;
} else {
return order ;
}
}
}
2002-04-16 15:50:10 +00:00
}
2005-03-11 15:55:14 +00:00
return - order ;
2002-04-16 15:50:10 +00:00
}
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 ;
2011-11-10 23:23:10 +08:00
carry = ( long ) ( sec / SECS_PER_DAY ) ;
sec - = ( ( double ) carry ) * SECS_PER_DAY ;
2002-05-03 07:29:38 +00:00
/* 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)
2004-05-29 20:12:46 +00:00
/**
* xmlSchemaDupVal :
* @ v : the # xmlSchemaValPtr value to duplicate
*
* Makes a copy of @ v . The calling program is responsible for freeing
* the returned value .
*
* returns a pointer to a duplicated # xmlSchemaValPtr or NULL if error .
*/
static xmlSchemaValPtr
xmlSchemaDupVal ( xmlSchemaValPtr v )
{
xmlSchemaValPtr ret = xmlSchemaNewValue ( v - > type ) ;
if ( ret = = NULL )
return NULL ;
2012-09-11 13:26:36 +08:00
2004-05-29 20:12:46 +00:00
memcpy ( ret , v , sizeof ( xmlSchemaVal ) ) ;
2005-06-09 10:32:53 +00:00
ret - > next = NULL ;
2004-05-29 20:12:46 +00:00
return ret ;
}
2005-03-04 18:04:59 +00:00
/**
* xmlSchemaCopyValue :
* @ val : the precomputed value to be copied
*
* Copies the precomputed value . This duplicates any string within .
*
* Returns the copy or NULL if a copy for a data - type is not implemented .
*/
xmlSchemaValPtr
xmlSchemaCopyValue ( xmlSchemaValPtr val )
{
2005-06-09 10:32:53 +00:00
xmlSchemaValPtr ret = NULL , prev = NULL , cur ;
2005-03-04 18:04:59 +00:00
/*
* Copy the string values .
*/
2005-06-09 10:32:53 +00:00
while ( val ! = NULL ) {
switch ( val - > type ) {
case XML_SCHEMAS_ANYTYPE :
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_ENTITIES :
case XML_SCHEMAS_NMTOKENS :
xmlSchemaFreeValue ( ret ) ;
return ( NULL ) ;
case XML_SCHEMAS_ANYSIMPLETYPE :
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_ANYURI :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . str ! = NULL )
cur - > value . str = xmlStrdup ( BAD_CAST val - > value . str ) ;
break ;
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_QNAME :
2005-06-09 10:32:53 +00:00
case XML_SCHEMAS_NOTATION :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . qname . name ! = NULL )
cur - > value . qname . name =
2005-03-04 18:04:59 +00:00
xmlStrdup ( BAD_CAST val - > value . qname . name ) ;
2005-06-09 10:32:53 +00:00
if ( val - > value . qname . uri ! = NULL )
cur - > value . qname . uri =
2005-03-04 18:04:59 +00:00
xmlStrdup ( BAD_CAST val - > value . qname . uri ) ;
2005-06-09 10:32:53 +00:00
break ;
case XML_SCHEMAS_HEXBINARY :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . hex . str ! = NULL )
cur - > value . hex . str = xmlStrdup ( BAD_CAST val - > value . hex . str ) ;
break ;
case XML_SCHEMAS_BASE64BINARY :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . base64 . str ! = NULL )
cur - > value . base64 . str =
2005-03-04 18:04:59 +00:00
xmlStrdup ( BAD_CAST val - > value . base64 . str ) ;
2005-06-09 10:32:53 +00:00
break ;
default :
cur = xmlSchemaDupVal ( val ) ;
break ;
}
if ( ret = = NULL )
ret = cur ;
else
prev - > next = cur ;
prev = cur ;
val = val - > next ;
2005-03-04 18:04:59 +00:00
}
2005-06-09 10:32:53 +00:00
return ( ret ) ;
2005-03-04 18:04:59 +00:00
}
2002-05-22 06:40:27 +00:00
/**
* _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 ,
2004-05-29 20:12:46 +00:00
* or # XML_SCHEMAS_GYEAR . The returned # xmlSchemaVal is the same type as
* @ dt . The calling program is responsible for freeing the returned value .
2002-05-22 06:40:27 +00:00
*
2004-05-29 20:12:46 +00:00
* Returns a pointer to a new # xmlSchemaVal or NULL if error .
2002-05-22 06:40:27 +00:00
*/
static xmlSchemaValPtr
_xmlSchemaDateAdd ( xmlSchemaValPtr dt , xmlSchemaValPtr dur )
{
2004-05-29 20:12:46 +00:00
xmlSchemaValPtr ret , tmp ;
2002-05-22 06:40:27 +00:00
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 ;
2004-05-29 20:12:46 +00:00
/* make a copy so we don't alter the original value */
tmp = xmlSchemaDupVal ( dt ) ;
if ( tmp = = NULL ) {
xmlSchemaFreeValue ( ret ) ;
return NULL ;
}
2002-05-22 06:40:27 +00:00
r = & ( ret - > value . date ) ;
2004-05-29 20:12:46 +00:00
d = & ( tmp - > value . date ) ;
2002-05-22 06:40:27 +00:00
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 ) {
2005-11-21 11:23:47 +00:00
long tmon = ( long ) MODULO_RANGE ( ( int ) r - > mon - 1 , 1 , 13 ) ;
long tyr = r - > year + ( long ) FQUOTIENT_RANGE ( ( int ) r - > mon - 1 , 1 , 13 ) ;
2002-05-22 06:40:27 +00:00
if ( tyr = = 0 )
tyr - - ;
2006-03-09 18:41:40 +00:00
/*
2012-09-11 13:26:36 +08:00
* Coverity detected an overrun in daysInMonth
2006-03-09 18:41:40 +00:00
* of size 12 at position 12 with index variable " ((r)->mon - 1) "
*/
2014-07-14 22:29:56 +08:00
if ( tmon < 1 )
tmon = 1 ;
2006-03-09 18:41:40 +00:00
if ( tmon > 12 )
tmon = 12 ;
2002-05-22 06:40:27 +00:00
tempdays + = MAX_DAYINMONTH ( tyr , tmon ) ;
carry = - 1 ;
2014-06-20 21:37:21 +01:00
} else if ( VALID_YEAR ( r - > year ) & & VALID_MONTH ( r - > mon ) & &
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 + + ;
}
}
2012-09-11 13:26:36 +08:00
2002-05-22 06:40:27 +00:00
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 ;
}
}
2004-05-29 20:12:46 +00:00
xmlSchemaFreeValue ( tmp ) ;
2002-05-22 06:40:27 +00:00
return ret ;
}
/**
* xmlSchemaDateNormalize :
2004-05-29 20:12:46 +00:00
* @ dt : an # xmlSchemaValPtr of a date / time type value .
* @ offset : number of seconds to adjust @ dt by .
2002-05-22 06:40:27 +00:00
*
2004-05-29 20:12:46 +00:00
* Normalize @ dt to GMT time . The @ offset parameter is subtracted from
* the return value is a time - zone offset is present on @ dt .
2002-05-22 06:40:27 +00:00
*
2004-05-29 20:12:46 +00:00
* Returns a normalized copy of @ dt or NULL if error .
2002-05-22 06:40:27 +00:00
*/
static xmlSchemaValPtr
xmlSchemaDateNormalize ( xmlSchemaValPtr dt , double offset )
{
xmlSchemaValPtr dur , ret ;
if ( dt = = NULL )
return NULL ;
if ( ( ( dt - > type ! = XML_SCHEMAS_TIME ) & &
2005-04-18 10:57:04 +00:00
( dt - > type ! = XML_SCHEMAS_DATETIME ) & &
( dt - > type ! = XML_SCHEMAS_DATE ) ) | | ( dt - > value . date . tzo = = 0 ) )
2002-05-22 06:40:27 +00:00
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
*
2012-09-11 13:26:36 +08:00
* Convert mon and year of @ dt to total number of days . Take the
2002-05-22 06:40:27 +00:00
* 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 ;
2004-09-23 16:24:36 +00:00
int mon ;
2002-05-22 06:40:27 +00:00
2004-09-23 16:24:36 +00:00
mon = dt - > value . date . mon ;
if ( mon < = 0 ) mon = 1 ; /* normalization */
if ( dt - > value . date . year < = 0 )
2002-05-22 06:40:27 +00:00
ret = ( dt - > value . date . year * 365 ) +
( ( ( dt - > value . date . year + 1 ) / 4 ) - ( ( dt - > value . date . year + 1 ) / 100 ) +
( ( dt - > value . date . year + 1 ) / 400 ) ) +
2004-09-23 16:24:36 +00:00
DAY_IN_YEAR ( 0 , mon , dt - > value . date . year ) ;
2002-05-22 06:40:27 +00:00
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 ) ) +
2004-09-23 16:24:36 +00:00
DAY_IN_YEAR ( 0 , mon , dt - > value . date . year ) ;
2002-05-22 06:40:27 +00:00
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 ;
2012-09-11 13:26:36 +08:00
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 ;
}
2005-02-17 11:10:44 +00:00
/**
* xmlSchemaComparePreserveReplaceStrings :
2005-03-16 16:29:18 +00:00
* @ x : a first string value
* @ y : a second string value
2005-02-17 11:10:44 +00:00
* @ invert : inverts the result if x < y or x > y .
*
* Compare 2 string for their normalized values .
* @ x is a string with whitespace of " preserve " , @ y is
* a string with a whitespace of " replace " . I . e . @ x could
* be an " xsd:string " and @ y an " xsd:normalizedString " .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 16:29:18 +00:00
xmlSchemaComparePreserveReplaceStrings ( const xmlChar * x ,
const xmlChar * y ,
2005-02-17 11:10:44 +00:00
int invert )
{
int tmp ;
2012-09-11 13:26:36 +08:00
2005-03-16 16:29:18 +00:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if ( IS_WSP_REPLACE_CH ( * y ) ) {
if ( ! IS_WSP_SPACE_CH ( * x ) ) {
if ( ( * x - 0x20 ) < 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
2012-09-11 13:26:36 +08:00
}
2005-02-17 11:10:44 +00:00
} else {
2005-03-16 16:29:18 +00:00
tmp = * x - * y ;
2005-02-17 11:10:44 +00:00
if ( tmp < 0 ) {
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
if ( tmp > 0 ) {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 16:29:18 +00:00
x + + ;
y + + ;
2005-02-17 11:10:44 +00:00
}
2005-03-16 16:29:18 +00:00
if ( * x ! = 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
2005-03-16 16:29:18 +00:00
if ( * y ! = 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
return ( 0 ) ;
}
/**
* xmlSchemaComparePreserveCollapseStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
* @ x is a string with whitespace of " preserve " , @ y is
* a string with a whitespace of " collapse " . I . e . @ x could
* be an " xsd:string " and @ y an " xsd:normalizedString " .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 16:29:18 +00:00
xmlSchemaComparePreserveCollapseStrings ( const xmlChar * x ,
const xmlChar * y ,
2005-02-17 11:10:44 +00:00
int invert )
{
int tmp ;
2012-09-11 13:26:36 +08:00
/*
2005-02-17 11:10:44 +00:00
* Skip leading blank chars of the collapsed string .
*/
2005-03-16 16:29:18 +00:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2005-02-17 11:10:44 +00:00
2005-03-16 16:29:18 +00:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if IS_WSP_BLANK_CH ( * y ) {
if ( ! IS_WSP_SPACE_CH ( * x ) ) {
2005-02-17 11:10:44 +00:00
/*
2005-03-16 16:29:18 +00:00
* The yv character would have been replaced to 0x20 .
2005-02-17 11:10:44 +00:00
*/
2005-03-16 16:29:18 +00:00
if ( ( * x - 0x20 ) < 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 16:29:18 +00:00
x + + ;
y + + ;
2005-02-17 11:10:44 +00:00
/*
* Skip contiguous blank chars of the collapsed string .
*/
2005-03-16 16:29:18 +00:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2005-02-17 11:10:44 +00:00
} else {
2005-03-16 16:29:18 +00:00
tmp = * x + + - * y + + ;
2005-02-17 11:10:44 +00:00
if ( tmp < 0 ) {
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
if ( tmp > 0 ) {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
}
2005-03-16 16:29:18 +00:00
if ( * x ! = 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
2005-03-16 16:29:18 +00:00
if ( * y ! = 0 ) {
2005-02-17 11:10:44 +00:00
/*
* Skip trailing blank chars of the collapsed string .
*/
2005-03-16 16:29:18 +00:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
if ( * y ! = 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
}
return ( 0 ) ;
}
/**
* xmlSchemaComparePreserveCollapseStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
* @ x is a string with whitespace of " preserve " , @ y is
* a string with a whitespace of " collapse " . I . e . @ x could
* be an " xsd:string " and @ y an " xsd:normalizedString " .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 16:29:18 +00:00
xmlSchemaCompareReplaceCollapseStrings ( const xmlChar * x ,
const xmlChar * y ,
2005-02-17 11:10:44 +00:00
int invert )
{
int tmp ;
2012-09-11 13:26:36 +08:00
/*
2005-02-17 11:10:44 +00:00
* Skip leading blank chars of the collapsed string .
*/
2005-03-16 16:29:18 +00:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2012-09-11 13:26:36 +08:00
2005-03-16 16:29:18 +00:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if IS_WSP_BLANK_CH ( * y ) {
if ( ! IS_WSP_BLANK_CH ( * x ) ) {
2005-02-17 11:10:44 +00:00
/*
2005-03-16 16:29:18 +00:00
* The yv character would have been replaced to 0x20 .
2005-02-17 11:10:44 +00:00
*/
2005-03-16 16:29:18 +00:00
if ( ( * x - 0x20 ) < 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 16:29:18 +00:00
x + + ;
2012-09-11 13:26:36 +08:00
y + + ;
/*
2005-02-17 11:10:44 +00:00
* Skip contiguous blank chars of the collapsed string .
*/
2005-03-16 16:29:18 +00:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2005-02-17 11:10:44 +00:00
} else {
2005-03-16 16:29:18 +00:00
if IS_WSP_BLANK_CH ( * x ) {
2005-02-17 11:10:44 +00:00
/*
2005-03-16 16:29:18 +00:00
* The xv character would have been replaced to 0x20 .
2005-02-17 11:10:44 +00:00
*/
2005-03-16 16:29:18 +00:00
if ( ( 0x20 - * y ) < 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 16:29:18 +00:00
tmp = * x + + - * y + + ;
2005-02-17 11:10:44 +00:00
if ( tmp < 0 )
return ( - 1 ) ;
if ( tmp > 0 )
return ( 1 ) ;
}
}
2005-03-16 16:29:18 +00:00
if ( * x ! = 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
2012-09-11 13:26:36 +08:00
}
2005-03-16 16:29:18 +00:00
if ( * y ! = 0 ) {
2005-02-17 11:10:44 +00:00
/*
* Skip trailing blank chars of the collapsed string .
*/
2005-03-16 16:29:18 +00:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
if ( * y ! = 0 ) {
2005-02-17 11:10:44 +00:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
}
return ( 0 ) ;
}
/**
* xmlSchemaCompareReplacedStrings :
* @ 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
2005-03-16 16:29:18 +00:00
xmlSchemaCompareReplacedStrings ( const xmlChar * x ,
const xmlChar * y )
2005-02-17 11:10:44 +00:00
{
int tmp ;
2012-09-11 13:26:36 +08:00
2005-03-16 16:29:18 +00:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if IS_WSP_BLANK_CH ( * y ) {
if ( ! IS_WSP_BLANK_CH ( * x ) ) {
if ( ( * x - 0x20 ) < 0 )
2012-09-11 13:26:36 +08:00
return ( - 1 ) ;
2005-02-17 11:10:44 +00:00
else
return ( 1 ) ;
2012-09-11 13:26:36 +08:00
}
2005-02-17 11:10:44 +00:00
} else {
2005-03-16 16:29:18 +00:00
if IS_WSP_BLANK_CH ( * x ) {
if ( ( 0x20 - * y ) < 0 )
2012-09-11 13:26:36 +08:00
return ( - 1 ) ;
2005-02-17 11:10:44 +00:00
else
return ( 1 ) ;
}
2005-03-16 16:29:18 +00:00
tmp = * x - * y ;
2005-02-17 11:10:44 +00:00
if ( tmp < 0 )
2012-09-11 13:26:36 +08:00
return ( - 1 ) ;
2005-02-17 11:10:44 +00:00
if ( tmp > 0 )
2012-09-11 13:26:36 +08:00
return ( 1 ) ;
2005-02-17 11:10:44 +00:00
}
2005-03-16 16:29:18 +00:00
x + + ;
y + + ;
2005-02-17 11:10:44 +00:00
}
2005-03-16 16:29:18 +00:00
if ( * x ! = 0 )
2005-02-17 11:10:44 +00:00
return ( 1 ) ;
2005-03-16 16:29:18 +00:00
if ( * y ! = 0 )
2005-02-17 11:10:44 +00:00
return ( - 1 ) ;
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
2005-03-16 16:29:18 +00:00
xmlSchemaCompareNormStrings ( const xmlChar * x ,
const xmlChar * y ) {
2003-03-29 10:53:38 +00:00
int tmp ;
2012-09-11 13:26:36 +08:00
2005-03-16 16:29:18 +00:00
while ( IS_BLANK_CH ( * x ) ) x + + ;
while ( IS_BLANK_CH ( * y ) ) y + + ;
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if ( IS_BLANK_CH ( * x ) ) {
if ( ! IS_BLANK_CH ( * y ) ) {
tmp = * x - * y ;
2003-03-29 10:53:38 +00:00
return ( tmp ) ;
}
2005-03-16 16:29:18 +00:00
while ( IS_BLANK_CH ( * x ) ) x + + ;
while ( IS_BLANK_CH ( * y ) ) y + + ;
2003-03-29 10:53:38 +00:00
} else {
2005-03-16 16:29:18 +00:00
tmp = * x + + - * y + + ;
2003-03-29 10:53:38 +00:00
if ( tmp < 0 )
return ( - 1 ) ;
if ( tmp > 0 )
return ( 1 ) ;
}
}
2005-03-16 16:29:18 +00:00
if ( * x ! = 0 ) {
while ( IS_BLANK_CH ( * x ) ) x + + ;
if ( * x ! = 0 )
2003-03-29 10:53:38 +00:00
return ( 1 ) ;
}
2005-03-16 16:29:18 +00:00
if ( * y ! = 0 ) {
while ( IS_BLANK_CH ( * y ) ) y + + ;
if ( * y ! = 0 )
2003-03-29 10:53:38 +00:00
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
2005-03-15 14:58:11 +00:00
* @ xvalue : the first value as a string ( optional )
2005-02-17 11:10:44 +00:00
* @ xwtsp : the whitespace type
2002-04-16 15:50:10 +00:00
* @ y : a second value
2005-03-15 14:58:11 +00:00
* @ xvalue : the second value as a string ( optional )
2005-02-17 11:10:44 +00:00
* @ ywtsp : the whitespace type
2002-04-16 15:50:10 +00:00
*
* Compare 2 values
*
2005-06-09 10:32:53 +00:00
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , 3 if not
* comparable and - 2 in case of error
2002-04-16 15:50:10 +00:00
*/
2005-02-17 11:10:44 +00:00
static int
2005-03-15 14:58:11 +00:00
xmlSchemaCompareValuesInternal ( xmlSchemaValType xtype ,
xmlSchemaValPtr x ,
const xmlChar * xvalue ,
2005-02-17 11:10:44 +00:00
xmlSchemaWhitespaceValueType xws ,
2005-03-15 14:58:11 +00:00
xmlSchemaValType ytype ,
2005-02-17 11:10:44 +00:00
xmlSchemaValPtr y ,
2005-03-15 14:58:11 +00:00
const xmlChar * yvalue ,
2005-03-16 16:29:18 +00:00
xmlSchemaWhitespaceValueType yws )
{
2005-03-15 14:58:11 +00:00
switch ( xtype ) {
2003-03-28 13:29:53 +00:00
case XML_SCHEMAS_UNKNOWN :
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-20 23:09:47 +00:00
case XML_SCHEMAS_ANYTYPE :
2003-03-28 13:29:53 +00:00
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 :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = xtype )
2003-03-28 13:29:53 +00:00
return ( xmlSchemaCompareDecimals ( x , y ) ) ;
2005-03-15 14:58:11 +00:00
if ( ( ytype = = XML_SCHEMAS_DECIMAL ) | |
( ytype = = XML_SCHEMAS_INTEGER ) | |
( ytype = = XML_SCHEMAS_NPINTEGER ) | |
( ytype = = XML_SCHEMAS_NINTEGER ) | |
( ytype = = XML_SCHEMAS_NNINTEGER ) | |
( ytype = = XML_SCHEMAS_PINTEGER ) | |
( ytype = = XML_SCHEMAS_INT ) | |
( ytype = = XML_SCHEMAS_UINT ) | |
( ytype = = XML_SCHEMAS_LONG ) | |
( ytype = = XML_SCHEMAS_ULONG ) | |
( ytype = = XML_SCHEMAS_SHORT ) | |
( ytype = = XML_SCHEMAS_USHORT ) | |
( ytype = = XML_SCHEMAS_BYTE ) | |
( ytype = = 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 :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-03-16 16:29:18 +00:00
if ( ytype = = XML_SCHEMAS_DURATION )
2002-05-03 07:29:38 +00:00
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 :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ( ytype = = XML_SCHEMAS_DATETIME ) | |
( ytype = = XML_SCHEMAS_TIME ) | |
( ytype = = XML_SCHEMAS_GDAY ) | |
( ytype = = XML_SCHEMAS_GMONTH ) | |
( ytype = = XML_SCHEMAS_GMONTHDAY ) | |
( ytype = = XML_SCHEMAS_GYEAR ) | |
( ytype = = XML_SCHEMAS_DATE ) | |
( ytype = = XML_SCHEMAS_GYEARMONTH ) )
2002-05-22 06:40:27 +00:00
return ( xmlSchemaCompareDates ( x , y ) ) ;
return ( - 2 ) ;
2012-09-11 13:26:36 +08:00
/*
2005-03-07 11:14:14 +00:00
* Note that we will support comparison of string types against
* anySimpleType as well .
*/
case XML_SCHEMAS_ANYSIMPLETYPE :
2005-02-17 11:10:44 +00:00
case XML_SCHEMAS_STRING :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_NORMSTRING :
2003-03-28 13:29:53 +00:00
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_ANYURI :
2005-03-15 14:58:11 +00:00
{
const xmlChar * xv , * yv ;
if ( x = = NULL )
xv = xvalue ;
else
xv = x - > value . str ;
if ( y = = NULL )
yv = yvalue ;
else
yv = y - > value . str ;
2005-02-17 11:10:44 +00:00
/*
* TODO : Compare those against QName .
*/
2012-09-11 13:26:36 +08:00
if ( ytype = = XML_SCHEMAS_QNAME ) {
2005-02-17 11:10:44 +00:00
TODO
2005-03-15 14:58:11 +00:00
if ( y = = NULL )
2012-09-11 13:26:36 +08:00
return ( - 2 ) ;
2005-02-17 11:10:44 +00:00
return ( - 2 ) ;
}
2005-03-15 14:58:11 +00:00
if ( ( ytype = = XML_SCHEMAS_ANYSIMPLETYPE ) | |
( ytype = = XML_SCHEMAS_STRING ) | |
( ytype = = XML_SCHEMAS_NORMSTRING ) | |
( ytype = = XML_SCHEMAS_TOKEN ) | |
( ytype = = XML_SCHEMAS_LANGUAGE ) | |
( ytype = = XML_SCHEMAS_NMTOKEN ) | |
( ytype = = XML_SCHEMAS_NAME ) | |
( ytype = = XML_SCHEMAS_NCNAME ) | |
( ytype = = XML_SCHEMAS_ID ) | |
( ytype = = XML_SCHEMAS_IDREF ) | |
( ytype = = XML_SCHEMAS_ENTITY ) | |
( ytype = = XML_SCHEMAS_ANYURI ) ) {
2005-02-17 11:10:44 +00:00
if ( xws = = XML_SCHEMA_WHITESPACE_PRESERVE ) {
if ( yws = = XML_SCHEMA_WHITESPACE_PRESERVE ) {
/* TODO: What about x < y or x > y. */
2005-03-15 14:58:11 +00:00
if ( xmlStrEqual ( xv , yv ) )
2005-02-17 11:10:44 +00:00
return ( 0 ) ;
2012-09-11 13:26:36 +08:00
else
2005-02-17 11:10:44 +00:00
return ( 2 ) ;
} else if ( yws = = XML_SCHEMA_WHITESPACE_REPLACE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaComparePreserveReplaceStrings ( xv , yv , 0 ) ) ;
2005-02-17 11:10:44 +00:00
else if ( yws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaComparePreserveCollapseStrings ( xv , yv , 0 ) ) ;
2005-02-17 11:10:44 +00:00
} else if ( xws = = XML_SCHEMA_WHITESPACE_REPLACE ) {
if ( yws = = XML_SCHEMA_WHITESPACE_PRESERVE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaComparePreserveReplaceStrings ( yv , xv , 1 ) ) ;
2005-02-17 11:10:44 +00:00
if ( yws = = XML_SCHEMA_WHITESPACE_REPLACE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaCompareReplacedStrings ( xv , yv ) ) ;
2005-02-17 11:10:44 +00:00
if ( yws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaCompareReplaceCollapseStrings ( xv , yv , 0 ) ) ;
2005-02-17 11:10:44 +00:00
} else if ( xws = = XML_SCHEMA_WHITESPACE_COLLAPSE ) {
if ( yws = = XML_SCHEMA_WHITESPACE_PRESERVE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaComparePreserveCollapseStrings ( yv , xv , 1 ) ) ;
2005-02-17 11:10:44 +00:00
if ( yws = = XML_SCHEMA_WHITESPACE_REPLACE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaCompareReplaceCollapseStrings ( yv , xv , 1 ) ) ;
2005-02-17 11:10:44 +00:00
if ( yws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaCompareNormStrings ( xv , yv ) ) ;
2005-02-17 11:10:44 +00:00
} else
return ( - 2 ) ;
2012-09-11 13:26:36 +08:00
2005-02-17 11:10:44 +00:00
}
2003-03-29 10:53:38 +00:00
return ( - 2 ) ;
2005-03-15 14:58:11 +00:00
}
2003-03-30 21:10:09 +00:00
case XML_SCHEMAS_QNAME :
2005-04-18 10:57:04 +00:00
case XML_SCHEMAS_NOTATION :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-04-18 10:57:04 +00:00
if ( ( ytype = = XML_SCHEMAS_QNAME ) | |
( ytype = = XML_SCHEMAS_NOTATION ) ) {
2003-03-30 21:10:09 +00:00
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 :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ( ytype = = XML_SCHEMAS_FLOAT ) | |
( ytype = = XML_SCHEMAS_DOUBLE ) )
2003-03-29 16:41:55 +00:00
return ( xmlSchemaCompareFloats ( x , y ) ) ;
return ( - 2 ) ;
2003-03-29 10:53:38 +00:00
case XML_SCHEMAS_BOOLEAN :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = XML_SCHEMAS_BOOLEAN ) {
2003-03-29 16:41:55 +00:00
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 :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = XML_SCHEMAS_HEXBINARY ) {
2003-08-08 14:00:28 +00:00
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 :
2005-03-15 14:58:11 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = XML_SCHEMAS_BASE64BINARY ) {
2003-08-27 14:15:15 +00:00
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 ) ;
2005-07-14 15:54:44 +00:00
else
return ( - 1 ) ;
2003-08-27 14:15:15 +00:00
}
else if ( x - > value . base64 . total > y - > value . base64 . total )
return ( 1 ) ;
else
return ( - 1 ) ;
}
2012-09-11 13:26:36 +08:00
return ( - 2 ) ;
2003-03-29 10:53:38 +00:00
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
}
2005-02-17 11:10:44 +00:00
/**
* xmlSchemaCompareValues :
* @ x : a first value
* @ y : a second 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
*/
int
xmlSchemaCompareValues ( xmlSchemaValPtr x , xmlSchemaValPtr y ) {
xmlSchemaWhitespaceValueType xws , yws ;
2005-02-18 19:36:12 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-02-17 11:10:44 +00:00
if ( x - > type = = XML_SCHEMAS_STRING )
xws = XML_SCHEMA_WHITESPACE_PRESERVE ;
else if ( x - > type = = XML_SCHEMAS_NORMSTRING )
xws = XML_SCHEMA_WHITESPACE_REPLACE ;
else
xws = XML_SCHEMA_WHITESPACE_COLLAPSE ;
if ( y - > type = = XML_SCHEMAS_STRING )
yws = XML_SCHEMA_WHITESPACE_PRESERVE ;
2013-11-28 22:50:57 +08:00
else if ( y - > type = = XML_SCHEMAS_NORMSTRING )
2005-02-17 11:10:44 +00:00
yws = XML_SCHEMA_WHITESPACE_REPLACE ;
else
yws = XML_SCHEMA_WHITESPACE_COLLAPSE ;
2005-03-15 14:58:11 +00:00
return ( xmlSchemaCompareValuesInternal ( x - > type , x , NULL , xws , y - > type ,
y , NULL , yws ) ) ;
2005-02-17 11:10:44 +00:00
}
/**
* xmlSchemaCompareValuesWhtsp :
* @ x : a first value
* @ xws : the whitespace value of x
* @ y : a second value
* @ yws : the whitespace value of y
*
* 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
*/
int
xmlSchemaCompareValuesWhtsp ( xmlSchemaValPtr x ,
2005-03-15 14:58:11 +00:00
xmlSchemaWhitespaceValueType xws ,
xmlSchemaValPtr y ,
xmlSchemaWhitespaceValueType yws )
{
2005-03-16 16:39:23 +00:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-03-15 14:58:11 +00:00
return ( xmlSchemaCompareValuesInternal ( x - > type , x , NULL , xws , y - > type ,
y , NULL , yws ) ) ;
}
/**
* xmlSchemaCompareValuesWhtspExt :
* @ x : a first value
* @ xws : the whitespace value of x
* @ y : a second value
* @ yws : the whitespace value of y
*
* 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
xmlSchemaCompareValuesWhtspExt ( xmlSchemaValType xtype ,
xmlSchemaValPtr x ,
const xmlChar * xvalue ,
xmlSchemaWhitespaceValueType xws ,
xmlSchemaValType ytype ,
xmlSchemaValPtr y ,
const xmlChar * yvalue ,
xmlSchemaWhitespaceValueType yws )
{
return ( xmlSchemaCompareValuesInternal ( xtype , x , xvalue , xws , ytype , y ,
yvalue , yws ) ) ;
2005-02-17 11:10:44 +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 ) ;
}
2004-10-27 17:29:04 +00:00
/**
* xmlSchemaGetFacetValueAsULong :
* @ facet : an schemas type facet
*
* Extract the value of a facet
*
* Returns the value as a long
*/
2004-08-10 14:17:33 +00:00
unsigned long
xmlSchemaGetFacetValueAsULong ( xmlSchemaFacetPtr facet )
{
/*
* TODO : Check if this is a decimal .
*/
2004-11-14 14:28:34 +00:00
if ( facet = = NULL )
return 0 ;
2004-08-10 14:17:33 +00:00
return ( ( unsigned long ) facet - > val - > value . decimal . lo ) ;
}
2004-06-29 17:04:39 +00:00
/**
* xmlSchemaValidateListSimpleTypeFacet :
* @ facet : the facet to check
* @ value : the lexical repr of the value to validate
* @ actualLen : the number of list items
* @ expectedLen : the resulting expected number of list items
*
* Checks the value of a list simple type against a facet .
*
* Returns 0 if the value is valid , a positive error code
* number otherwise and - 1 in case of an internal error .
*/
int
xmlSchemaValidateListSimpleTypeFacet ( xmlSchemaFacetPtr facet ,
const xmlChar * value ,
unsigned long actualLen ,
unsigned long * expectedLen )
{
2004-11-05 17:22:25 +00:00
if ( facet = = NULL )
return ( - 1 ) ;
2004-06-29 17:04:39 +00:00
/*
* TODO : Check if this will work with large numbers .
* ( compare value . decimal . mi and value . decimal . hi as well ? ) .
*/
if ( facet - > type = = XML_SCHEMA_FACET_LENGTH ) {
if ( actualLen ! = facet - > val - > value . decimal . lo ) {
2005-03-16 16:29:18 +00:00
if ( expectedLen ! = NULL )
2004-08-10 14:17:33 +00:00
* expectedLen = facet - > val - > value . decimal . lo ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_LENGTH_VALID ) ;
2012-09-11 13:26:36 +08:00
}
2004-06-29 17:04:39 +00:00
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
if ( actualLen < facet - > val - > value . decimal . lo ) {
2005-03-16 16:29:18 +00:00
if ( expectedLen ! = NULL )
2004-08-10 14:17:33 +00:00
* expectedLen = facet - > val - > value . decimal . lo ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MINLENGTH_VALID ) ;
}
} else if ( facet - > type = = XML_SCHEMA_FACET_MAXLENGTH ) {
if ( actualLen > facet - > val - > value . decimal . lo ) {
2005-03-16 16:29:18 +00:00
if ( expectedLen ! = NULL )
2004-08-10 14:17:33 +00:00
* expectedLen = facet - > val - > value . decimal . lo ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MAXLENGTH_VALID ) ;
}
} else
2012-09-11 13:26:36 +08:00
/*
* NOTE : That we can pass NULL as xmlSchemaValPtr to
2004-06-29 17:04:39 +00:00
* xmlSchemaValidateFacet , since the remaining facet types
2012-09-11 13:26:36 +08:00
* are : XML_SCHEMA_FACET_PATTERN , XML_SCHEMA_FACET_ENUMERATION .
2004-06-29 17:04:39 +00:00
*/
2012-09-11 13:26:36 +08:00
return ( xmlSchemaValidateFacet ( NULL , facet , value , NULL ) ) ;
2004-06-29 17:04:39 +00:00
return ( 0 ) ;
}
2004-08-10 14:17:33 +00:00
/**
2004-10-27 17:29:04 +00:00
* xmlSchemaValidateLengthFacet :
2004-08-10 14:17:33 +00:00
* @ type : the built - in type
* @ facet : the facet to check
* @ value : the lexical repr . of the value to be validated
* @ val : the precomputed value
2005-03-16 16:29:18 +00:00
* @ ws : the whitespace type of the value
2004-08-10 14:17:33 +00:00
* @ length : the actual length of the value
*
2012-09-11 13:26:36 +08:00
* Checka a value against a " length " , " minLength " and " maxLength "
2004-08-10 14:17:33 +00:00
* facet ; sets @ length to the computed length of @ value .
*
* Returns 0 if the value is valid , a positive error code
* otherwise and - 1 in case of an internal or API error .
*/
2005-03-16 16:29:18 +00:00
static int
xmlSchemaValidateLengthFacetInternal ( xmlSchemaFacetPtr facet ,
2012-02-29 09:44:35 +08:00
xmlSchemaValType valType ,
2005-03-16 16:29:18 +00:00
const xmlChar * value ,
2012-02-29 09:44:35 +08:00
xmlSchemaValPtr val ,
2005-03-16 16:29:18 +00:00
unsigned long * length ,
2012-09-11 13:26:36 +08:00
xmlSchemaWhitespaceValueType ws )
2004-08-10 14:17:33 +00:00
{
unsigned int len = 0 ;
2005-03-16 16:29:18 +00:00
if ( ( length = = NULL ) | | ( facet = = NULL ) )
2004-11-05 17:22:25 +00:00
return ( - 1 ) ;
2004-08-10 14:17:33 +00:00
* length = 0 ;
if ( ( facet - > type ! = XML_SCHEMA_FACET_LENGTH ) & &
( facet - > type ! = XML_SCHEMA_FACET_MAXLENGTH ) & &
( facet - > type ! = XML_SCHEMA_FACET_MINLENGTH ) )
return ( - 1 ) ;
2012-09-11 13:26:36 +08:00
2005-03-16 16:29:18 +00:00
/*
* TODO : length , maxLength and minLength must be of type
* nonNegativeInteger only . Check if decimal is used somehow .
*/
2004-08-10 14:17:33 +00:00
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_HEXBINARY ) )
len = val - > value . hex . total ;
else if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_BASE64BINARY ) )
len = val - > value . base64 . total ;
else {
2005-03-16 16:29:18 +00:00
switch ( valType ) {
case XML_SCHEMAS_STRING :
2004-08-10 14:17:33 +00:00
case XML_SCHEMAS_NORMSTRING :
2005-03-16 16:29:18 +00:00
if ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateLengthFacet ( ) . Anyway , this was and
* is not the correct handling .
* TODO : Get rid of this case somehow .
*/
if ( valType = = XML_SCHEMAS_STRING )
len = xmlUTF8Strlen ( value ) ;
else
len = xmlSchemaNormLen ( value ) ;
} else if ( value ! = NULL ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
len = xmlSchemaNormLen ( value ) ;
else
2012-09-11 13:26:36 +08:00
/*
2005-03-16 16:29:18 +00:00
* Should be OK for " preserve " as well .
*/
len = xmlUTF8Strlen ( value ) ;
}
break ;
case XML_SCHEMAS_IDREF :
2004-08-10 14:17:33 +00:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_ID :
2005-05-25 17:29:36 +00:00
/*
* FIXME : What exactly to do with anyURI ?
2005-03-16 16:29:18 +00:00
*/
2004-08-10 14:17:33 +00:00
case XML_SCHEMAS_ANYURI :
if ( value ! = NULL )
2005-03-16 16:29:18 +00:00
len = xmlSchemaNormLen ( value ) ;
2004-08-10 14:17:33 +00:00
break ;
2005-05-25 17:29:36 +00:00
case XML_SCHEMAS_QNAME :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_NOTATION :
/*
2005-06-09 10:32:53 +00:00
* For QName and NOTATION , those facets are
* deprecated and should be ignored .
2012-09-11 13:26:36 +08:00
*/
2005-05-25 17:29:36 +00:00
return ( 0 ) ;
2004-08-10 14:17:33 +00:00
default :
TODO
}
}
* length = ( unsigned long ) len ;
2005-03-16 16:29:18 +00:00
/*
* TODO : Return the whole expected value , i . e . " lo " , " mi " and " hi " .
*/
2004-08-10 14:17:33 +00:00
if ( facet - > type = = XML_SCHEMA_FACET_LENGTH ) {
if ( len ! = facet - > val - > value . decimal . lo )
return ( XML_SCHEMAV_CVC_LENGTH_VALID ) ;
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
if ( len < facet - > val - > value . decimal . lo )
return ( XML_SCHEMAV_CVC_MINLENGTH_VALID ) ;
} else {
if ( len > facet - > val - > value . decimal . lo )
return ( XML_SCHEMAV_CVC_MAXLENGTH_VALID ) ;
}
2012-09-11 13:26:36 +08:00
2004-08-10 14:17:33 +00:00
return ( 0 ) ;
}
2005-03-16 16:29:18 +00:00
/**
* xmlSchemaValidateLengthFacet :
* @ type : the built - in type
* @ facet : the facet to check
* @ value : the lexical repr . of the value to be validated
* @ val : the precomputed value
* @ length : the actual length of the value
*
2012-09-11 13:26:36 +08:00
* Checka a value against a " length " , " minLength " and " maxLength "
2005-03-16 16:29:18 +00:00
* facet ; sets @ length to the computed length of @ value .
*
* Returns 0 if the value is valid , a positive error code
* otherwise and - 1 in case of an internal or API error .
*/
int
2012-09-11 13:26:36 +08:00
xmlSchemaValidateLengthFacet ( xmlSchemaTypePtr type ,
2005-03-16 16:29:18 +00:00
xmlSchemaFacetPtr facet ,
const xmlChar * value ,
xmlSchemaValPtr val ,
2012-09-11 13:26:36 +08:00
unsigned long * length )
2005-03-16 16:29:18 +00:00
{
2005-03-16 21:55:35 +00:00
if ( type = = NULL )
return ( - 1 ) ;
2005-03-16 16:29:18 +00:00
return ( xmlSchemaValidateLengthFacetInternal ( facet ,
type - > builtInType , value , val , length ,
XML_SCHEMA_WHITESPACE_UNKNOWN ) ) ;
}
/**
2012-09-11 13:26:36 +08:00
* xmlSchemaValidateLengthFacetWhtsp :
2005-03-16 16:29:18 +00:00
* @ facet : the facet to check
* @ valType : the built - in type
* @ value : the lexical repr . of the value to be validated
* @ val : the precomputed value
* @ ws : the whitespace type of the value
* @ length : the actual length of the value
*
2012-09-11 13:26:36 +08:00
* Checka a value against a " length " , " minLength " and " maxLength "
2005-03-16 16:29:18 +00:00
* facet ; sets @ length to the computed length of @ value .
*
* Returns 0 if the value is valid , a positive error code
* otherwise and - 1 in case of an internal or API error .
*/
int
xmlSchemaValidateLengthFacetWhtsp ( xmlSchemaFacetPtr facet ,
xmlSchemaValType valType ,
const xmlChar * value ,
xmlSchemaValPtr val ,
unsigned long * length ,
xmlSchemaWhitespaceValueType ws )
{
return ( xmlSchemaValidateLengthFacetInternal ( facet , valType , value , val ,
length , ws ) ) ;
}
2002-04-16 15:50:10 +00:00
/**
2005-03-15 14:58:11 +00:00
* xmlSchemaValidateFacetInternal :
2002-04-16 15:50:10 +00:00
* @ facet : the facet to check
2005-03-16 16:29:18 +00:00
* @ fws : the whitespace type of the facet ' s value
* @ valType : the built - in type of the value
2002-04-16 15:50:10 +00:00
* @ value : the lexical repr of the value to validate
* @ val : the precomputed value
2005-03-16 16:29:18 +00:00
* @ ws : the whitespace type of the value
2002-04-16 15:50:10 +00:00
*
* 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 .
*/
2005-03-15 14:58:11 +00:00
static int
xmlSchemaValidateFacetInternal ( xmlSchemaFacetPtr facet ,
xmlSchemaWhitespaceValueType fws ,
2012-09-11 13:26:36 +08:00
xmlSchemaValType valType ,
2005-03-15 14:58:11 +00:00
const xmlChar * value ,
2005-03-16 16:29:18 +00:00
xmlSchemaValPtr val ,
2005-03-15 14:58:11 +00:00
xmlSchemaWhitespaceValueType ws )
2002-04-16 15:50:10 +00:00
{
int ret ;
2016-05-03 21:37:52 +08:00
int stringType ;
2002-04-16 15:50:10 +00:00
2005-03-15 14:58:11 +00:00
if ( facet = = NULL )
return ( - 1 ) ;
2002-04-16 15:50:10 +00:00
switch ( facet - > type ) {
case XML_SCHEMA_FACET_PATTERN :
2012-09-11 13:26:36 +08:00
/*
2005-03-15 14:58:11 +00:00
* NOTE that for patterns , the @ value needs to be the normalized
* value , * not * the lexical initial value or the canonical value .
*/
if ( value = = NULL )
return ( - 1 ) ;
2016-04-15 22:41:24 +08:00
/*
* If string - derived type , regexp must be tested on the value space of
* the datatype .
* See https : //www.w3.org/TR/xmlschema-2/#rf-pattern
*/
2016-05-03 21:37:52 +08:00
stringType = val & & ( ( val - > type > = XML_SCHEMAS_STRING & & val - > type < = XML_SCHEMAS_NORMSTRING )
| | ( val - > type > = XML_SCHEMAS_TOKEN & & val - > type < = XML_SCHEMAS_NCNAME ) ) ;
2016-04-15 22:41:24 +08:00
ret = xmlRegexpExec ( facet - > regexp ,
( stringType & & val - > value . str ) ? val - > value . str : value ) ;
2002-04-16 15:50:10 +00:00
if ( ret = = 1 )
return ( 0 ) ;
2005-03-15 14:58:11 +00:00
if ( ret = = 0 )
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_PATTERN_VALID ) ;
2002-04-16 15:50:10 +00:00
return ( ret ) ;
case XML_SCHEMA_FACET_MAXEXCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 14:58:11 +00:00
if ( ret = = - 2 )
2002-04-16 15:50:10 +00:00
return ( - 1 ) ;
if ( ret = = - 1 )
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID ) ;
2002-05-03 07:29:38 +00:00
case XML_SCHEMA_FACET_MAXINCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 14:58:11 +00:00
if ( ret = = - 2 )
2002-05-03 07:29:38 +00:00
return ( - 1 ) ;
if ( ( ret = = - 1 ) | | ( ret = = 0 ) )
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID ) ;
2002-05-03 07:29:38 +00:00
case XML_SCHEMA_FACET_MINEXCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 14:58:11 +00:00
if ( ret = = - 2 )
2002-05-03 07:29:38 +00:00
return ( - 1 ) ;
if ( ret = = 1 )
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID ) ;
2002-05-03 07:29:38 +00:00
case XML_SCHEMA_FACET_MININCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 14:58:11 +00:00
if ( ret = = - 2 )
2002-05-03 07:29:38 +00:00
return ( - 1 ) ;
if ( ( ret = = 1 ) | | ( ret = = 0 ) )
return ( 0 ) ;
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MININCLUSIVE_VALID ) ;
2002-04-17 09:06:27 +00:00
case XML_SCHEMA_FACET_WHITESPACE :
2003-02-27 17:42:22 +00:00
/* TODO whitespaces */
2004-06-29 17:04:39 +00:00
/*
* NOTE : Whitespace should be handled to normalize
* the value to be validated against a the facets ;
* not to normalize the value in - between .
*/
2002-04-17 09:06:27 +00:00
return ( 0 ) ;
2003-02-27 17:42:22 +00:00
case XML_SCHEMA_FACET_ENUMERATION :
2005-03-16 16:29:18 +00:00
if ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateFacet ( ) .
* TODO : Get rid of this case .
*/
2005-03-15 14:58:11 +00:00
if ( ( facet - > value ! = NULL ) & &
( xmlStrEqual ( facet - > value , value ) ) )
return ( 0 ) ;
} else {
ret = xmlSchemaCompareValuesWhtspExt ( facet - > val - > type ,
facet - > val , facet - > value , fws , valType , val ,
value , ws ) ;
if ( ret = = - 2 )
return ( - 1 ) ;
if ( ret = = 0 )
return ( 0 ) ;
}
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_ENUMERATION_VALID ) ;
2003-02-27 17:42:22 +00:00
case XML_SCHEMA_FACET_LENGTH :
2005-04-01 15:17:27 +00:00
/*
* SPEC ( 1.3 ) " if { primitive type definition } is QName or NOTATION ,
* then any { value } is facet - valid . "
*/
if ( ( valType = = XML_SCHEMAS_QNAME ) | |
( valType = = XML_SCHEMAS_NOTATION ) )
return ( 0 ) ;
2017-10-21 13:49:31 +02:00
/* Falls through. */
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
2005-06-09 10:32:53 +00:00
if ( ( valType = = XML_SCHEMAS_QNAME ) | |
( valType = = XML_SCHEMAS_NOTATION ) )
return ( 0 ) ;
2005-03-16 16:29:18 +00:00
/*
* TODO : length , maxLength and minLength must be of type
* nonNegativeInteger only . Check if decimal is used somehow .
*/
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 {
2005-03-15 14:58:11 +00:00
switch ( valType ) {
2005-03-16 16:29:18 +00:00
case XML_SCHEMAS_STRING :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_NORMSTRING :
2005-03-16 16:29:18 +00:00
if ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateFacet ( ) . Anyway , this was and
* is not the correct handling .
* TODO : Get rid of this case somehow .
*/
if ( valType = = XML_SCHEMAS_STRING )
len = xmlUTF8Strlen ( value ) ;
else
len = xmlSchemaNormLen ( value ) ;
} else if ( value ! = NULL ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
len = xmlSchemaNormLen ( value ) ;
else
2012-09-11 13:26:36 +08:00
/*
2005-03-16 16:29:18 +00:00
* Should be OK for " preserve " as well .
*/
len = xmlUTF8Strlen ( value ) ;
}
break ;
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_IDREF :
2003-07-06 21:13:49 +00:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
2004-06-29 17:04:39 +00:00
case XML_SCHEMAS_ANYURI :
2005-03-16 16:29:18 +00:00
if ( value ! = NULL )
2012-09-11 13:26:36 +08:00
len = xmlSchemaNormLen ( value ) ;
break ;
2003-07-06 21:13:49 +00:00
default :
TODO
2012-09-11 13:26:36 +08: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 )
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_LENGTH_VALID ) ;
2003-02-27 17:42:22 +00:00
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
2003-03-30 21:10:09 +00:00
if ( len < facet - > val - > value . decimal . lo )
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MINLENGTH_VALID ) ;
2003-02-27 17:42:22 +00:00
} else {
2003-03-30 21:10:09 +00:00
if ( len > facet - > val - > value . decimal . lo )
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_MAXLENGTH_VALID ) ;
2002-04-22 16:01:24 +00:00
}
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 ) | |
2005-11-07 14:02:44 +00:00
( ( facet - > val - > type ! = XML_SCHEMAS_PINTEGER ) & &
2003-07-06 21:13:49 +00:00
( 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 )
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_TOTALDIGITS_VALID ) ;
2003-07-06 21:13:49 +00:00
} else if ( facet - > type = = XML_SCHEMA_FACET_FRACTIONDIGITS ) {
if ( val - > value . decimal . frac > facet - > val - > value . decimal . lo )
2004-06-29 17:04:39 +00:00
return ( XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID ) ;
2003-07-06 21:13:49 +00:00
}
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
}
2005-03-15 14:58:11 +00:00
/**
* xmlSchemaValidateFacet :
* @ base : the base type
* @ 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
2005-03-16 16:39:23 +00:00
xmlSchemaValidateFacet ( xmlSchemaTypePtr base ,
2005-03-15 14:58:11 +00:00
xmlSchemaFacetPtr facet ,
const xmlChar * value ,
xmlSchemaValPtr val )
{
/*
* This tries to ensure API compatibility regarding the old
* xmlSchemaValidateFacet ( ) and the new xmlSchemaValidateFacetInternal ( ) and
* xmlSchemaValidateFacetWhtsp ( ) .
*/
2005-03-16 16:39:23 +00:00
if ( val ! = NULL )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaValidateFacetInternal ( facet ,
2005-03-16 16:39:23 +00:00
XML_SCHEMA_WHITESPACE_UNKNOWN , val - > type , value , val ,
2005-03-15 14:58:11 +00:00
XML_SCHEMA_WHITESPACE_UNKNOWN ) ) ;
2005-03-16 16:39:23 +00:00
else if ( base ! = NULL )
2005-03-15 14:58:11 +00:00
return ( xmlSchemaValidateFacetInternal ( facet ,
2005-03-16 16:39:23 +00:00
XML_SCHEMA_WHITESPACE_UNKNOWN , base - > builtInType , value , val ,
2005-03-16 16:29:18 +00:00
XML_SCHEMA_WHITESPACE_UNKNOWN ) ) ;
2005-03-16 16:39:23 +00:00
return ( - 1 ) ;
2005-03-15 14:58:11 +00:00
}
/**
* xmlSchemaValidateFacetWhtsp :
* @ facet : the facet to check
* @ fws : the whitespace type of the facet ' s value
* @ valType : the built - in type of the value
* @ value : the lexical ( or normalized for pattern ) repr of the value to validate
* @ val : the precomputed value
* @ ws : the whitespace type of the value
*
* Check a value against a facet condition . This takes value normalization
* according to the specified whitespace types into account .
* Note that @ value needs to be the * normalized * value if the facet
* is of type " pattern " .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
int
xmlSchemaValidateFacetWhtsp ( xmlSchemaFacetPtr facet ,
xmlSchemaWhitespaceValueType fws ,
2012-09-11 13:26:36 +08:00
xmlSchemaValType valType ,
2005-03-15 14:58:11 +00:00
const xmlChar * value ,
2005-03-16 16:29:18 +00:00
xmlSchemaValPtr val ,
2005-03-15 14:58:11 +00:00
xmlSchemaWhitespaceValueType ws )
{
return ( xmlSchemaValidateFacetInternal ( facet , fws , valType ,
2005-03-16 16:29:18 +00:00
value , val , ws ) ) ;
2005-03-15 14:58:11 +00:00
}
2005-04-18 10:57:04 +00:00
#if 0
# ifndef DBL_DIG
# define DBL_DIG 16
# endif
# ifndef DBL_EPSILON
# define DBL_EPSILON 1E-9
# endif
# define INTEGER_DIGITS DBL_DIG
# define FRACTION_DIGITS (DBL_DIG + 1)
# define EXPONENT_DIGITS (3 + 2)
/**
* xmlXPathFormatNumber :
* @ number : number to format
* @ buffer : output buffer
* @ buffersize : size of output buffer
*
* Convert the number into a string representation .
*/
static void
xmlSchemaFormatFloat ( double number , char buffer [ ] , int buffersize )
{
switch ( xmlXPathIsInf ( number ) ) {
case 1 :
if ( buffersize > ( int ) sizeof ( " INF " ) )
snprintf ( buffer , buffersize , " INF " ) ;
break ;
case - 1 :
if ( buffersize > ( int ) sizeof ( " -INF " ) )
snprintf ( buffer , buffersize , " -INF " ) ;
break ;
default :
if ( xmlXPathIsNaN ( number ) ) {
if ( buffersize > ( int ) sizeof ( " NaN " ) )
snprintf ( buffer , buffersize , " NaN " ) ;
} else if ( number = = 0 ) {
snprintf ( buffer , buffersize , " 0.0E0 " ) ;
} else {
/* 3 is sign, decimal point, and terminating zero */
char work [ DBL_DIG + EXPONENT_DIGITS + 3 ] ;
int integer_place , fraction_place ;
char * ptr ;
char * after_fraction ;
double absolute_value ;
int size ;
absolute_value = fabs ( number ) ;
/*
* Result is in work , and after_fraction points
* just past the fractional part .
2012-09-11 13:26:36 +08:00
* Use scientific notation
2005-04-18 10:57:04 +00:00
*/
integer_place = DBL_DIG + EXPONENT_DIGITS + 1 ;
fraction_place = DBL_DIG - 1 ;
snprintf ( work , sizeof ( work ) , " %*.*e " ,
integer_place , fraction_place , number ) ;
2012-09-11 13:26:36 +08:00
after_fraction = strchr ( work + DBL_DIG , ' e ' ) ;
2005-04-18 10:57:04 +00:00
/* Remove fractional trailing zeroes */
ptr = after_fraction ;
while ( * ( - - ptr ) = = ' 0 ' )
;
if ( * ptr ! = ' . ' )
ptr + + ;
while ( ( * ptr + + = * after_fraction + + ) ! = 0 ) ;
/* Finally copy result back to caller */
size = strlen ( work ) + 1 ;
if ( size > buffersize ) {
work [ buffersize - 1 ] = 0 ;
size = buffersize ;
}
memmove ( buffer , work , size ) ;
}
break ;
}
}
# endif
2005-02-17 11:10:44 +00:00
/**
* xmlSchemaGetCanonValue :
* @ val : the precomputed value
* @ retValue : the returned value
*
2013-11-29 23:26:26 +01:00
* Get the canonical lexical representation of the value .
2005-04-18 10:57:04 +00:00
* The caller has to FREE the returned retValue .
*
2005-03-16 16:29:18 +00:00
* WARNING : Some value types are not supported yet , resulting
* in a @ retValue of " ??? " .
2012-09-11 13:26:36 +08:00
*
2005-04-18 10:57:04 +00:00
* TODO : XML Schema 1.0 does not define canonical representations
* for : duration , gYearMonth , gYear , gMonthDay , gMonth , gDay ,
* anyURI , QName , NOTATION . This will be fixed in XML Schema 1.1 .
*
2005-02-17 11:10:44 +00:00
*
2005-04-18 10:57:04 +00:00
* Returns 0 if the value could be built , 1 if the value type is
* not supported yet and - 1 in case of API errors .
2005-02-17 11:10:44 +00:00
*/
int
2005-02-19 18:27:14 +00:00
xmlSchemaGetCanonValue ( xmlSchemaValPtr val , const xmlChar * * retValue )
2005-02-17 11:10:44 +00:00
{
2005-02-19 18:27:14 +00:00
if ( ( retValue = = NULL ) | | ( val = = NULL ) )
2005-02-17 11:10:44 +00:00
return ( - 1 ) ;
* retValue = NULL ;
switch ( val - > type ) {
2005-03-16 16:29:18 +00:00
case XML_SCHEMAS_STRING :
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else
2012-09-11 13:26:36 +08:00
* retValue =
2005-03-16 16:29:18 +00:00
BAD_CAST xmlStrdup ( ( const xmlChar * ) val - > value . str ) ;
break ;
2005-02-17 11:10:44 +00:00
case XML_SCHEMAS_NORMSTRING :
2005-03-16 16:29:18 +00:00
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else {
* retValue = xmlSchemaWhiteSpaceReplace (
( const xmlChar * ) val - > value . str ) ;
if ( ( * retValue ) = = NULL )
* retValue = BAD_CAST xmlStrdup (
( const xmlChar * ) val - > value . str ) ;
}
break ;
2005-02-17 11:10:44 +00:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
2012-09-11 13:26:36 +08:00
case XML_SCHEMAS_NAME :
2005-02-17 11:10:44 +00:00
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
2005-04-18 10:57:04 +00:00
case XML_SCHEMAS_NOTATION : /* Unclear */
case XML_SCHEMAS_ANYURI : /* Unclear */
2005-02-17 11:10:44 +00:00
if ( val - > value . str = = NULL )
2005-03-16 16:29:18 +00:00
return ( - 1 ) ;
2012-09-11 13:26:36 +08:00
* retValue =
2005-04-01 15:17:27 +00:00
BAD_CAST xmlSchemaCollapseString ( BAD_CAST val - > value . str ) ;
if ( * retValue = = NULL )
2012-09-11 13:26:36 +08:00
* retValue =
2005-04-01 15:17:27 +00:00
BAD_CAST xmlStrdup ( ( const xmlChar * ) val - > value . str ) ;
2005-03-16 16:29:18 +00:00
break ;
case XML_SCHEMAS_QNAME :
2005-04-18 10:57:04 +00:00
/* TODO: Unclear in XML Schema 1.0. */
2005-03-16 16:29:18 +00:00
if ( val - > value . qname . uri = = NULL ) {
* retValue = BAD_CAST xmlStrdup ( BAD_CAST val - > value . qname . name ) ;
return ( 0 ) ;
} else {
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " { " ) ;
* retValue = BAD_CAST xmlStrcat ( ( xmlChar * ) ( * retValue ) ,
BAD_CAST val - > value . qname . uri ) ;
* retValue = BAD_CAST xmlStrcat ( ( xmlChar * ) ( * retValue ) ,
BAD_CAST " } " ) ;
* retValue = BAD_CAST xmlStrcat ( ( xmlChar * ) ( * retValue ) ,
BAD_CAST val - > value . qname . uri ) ;
}
break ;
2005-04-18 10:57:04 +00:00
case XML_SCHEMAS_DECIMAL :
/*
* TODO : Lookout for a more simple implementation .
*/
2012-09-11 13:26:36 +08:00
if ( ( val - > value . decimal . total = = 1 ) & &
2005-04-18 10:57:04 +00:00
( val - > value . decimal . lo = = 0 ) ) {
* retValue = xmlStrdup ( BAD_CAST " 0.0 " ) ;
} else {
xmlSchemaValDecimal dec = val - > value . decimal ;
int bufsize ;
char * buf = NULL , * offs ;
/* Add room for the decimal point as well. */
bufsize = dec . total + 2 ;
if ( dec . sign )
bufsize + + ;
/* Add room for leading/trailing zero. */
if ( ( dec . frac = = 0 ) | | ( dec . frac = = dec . total ) )
bufsize + + ;
buf = xmlMalloc ( bufsize ) ;
2006-10-11 12:32:51 +00:00
if ( buf = = NULL )
return ( - 1 ) ;
2005-04-18 10:57:04 +00:00
offs = buf ;
if ( dec . sign )
* offs + + = ' - ' ;
if ( dec . frac = = dec . total ) {
* offs + + = ' 0 ' ;
* offs + + = ' . ' ;
}
if ( dec . hi ! = 0 )
snprintf ( offs , bufsize - ( offs - buf ) ,
" %lu%lu%lu " , dec . hi , dec . mi , dec . lo ) ;
else if ( dec . mi ! = 0 )
snprintf ( offs , bufsize - ( offs - buf ) ,
" %lu%lu " , dec . mi , dec . lo ) ;
else
snprintf ( offs , bufsize - ( offs - buf ) ,
" %lu " , dec . lo ) ;
2012-09-11 13:26:36 +08:00
2005-04-18 10:57:04 +00:00
if ( dec . frac ! = 0 ) {
if ( dec . frac ! = dec . total ) {
int diff = dec . total - dec . frac ;
/*
* Insert the decimal point .
*/
memmove ( offs + diff + 1 , offs + diff , dec . frac + 1 ) ;
offs [ diff ] = ' . ' ;
} else {
unsigned int i = 0 ;
/*
* Insert missing zeroes behind the decimal point .
2012-09-11 13:26:36 +08:00
*/
2005-04-18 10:57:04 +00:00
while ( * ( offs + i ) ! = 0 )
i + + ;
if ( i < dec . total ) {
memmove ( offs + ( dec . total - i ) , offs , i + 1 ) ;
memset ( offs , ' 0 ' , dec . total - i ) ;
}
}
} else {
/*
* Append decimal point and zero .
*/
offs = buf + bufsize - 1 ;
* offs - - = 0 ;
* offs - - = ' 0 ' ;
* offs - - = ' . ' ;
}
* retValue = BAD_CAST buf ;
}
break ;
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
case XML_SCHEMAS_NNINTEGER :
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_SHORT :
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_USHORT :
case XML_SCHEMAS_UBYTE :
if ( ( val - > value . decimal . total = = 1 ) & &
( val - > value . decimal . lo = = 0 ) )
* retValue = xmlStrdup ( BAD_CAST " 0 " ) ;
else {
xmlSchemaValDecimal dec = val - > value . decimal ;
int bufsize = dec . total + 1 ;
/* Add room for the decimal point as well. */
if ( dec . sign )
bufsize + + ;
* retValue = xmlMalloc ( bufsize ) ;
2006-10-11 12:32:51 +00:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 10:57:04 +00:00
if ( dec . hi ! = 0 ) {
if ( dec . sign )
snprintf ( ( char * ) * retValue , bufsize ,
" -%lu%lu%lu " , dec . hi , dec . mi , dec . lo ) ;
else
snprintf ( ( char * ) * retValue , bufsize ,
" %lu%lu%lu " , dec . hi , dec . mi , dec . lo ) ;
} else if ( dec . mi ! = 0 ) {
if ( dec . sign )
snprintf ( ( char * ) * retValue , bufsize ,
" -%lu%lu " , dec . mi , dec . lo ) ;
else
snprintf ( ( char * ) * retValue , bufsize ,
" %lu%lu " , dec . mi , dec . lo ) ;
} else {
if ( dec . sign )
snprintf ( ( char * ) * retValue , bufsize , " -%lu " , dec . lo ) ;
else
snprintf ( ( char * ) * retValue , bufsize , " %lu " , dec . lo ) ;
}
}
break ;
case XML_SCHEMAS_BOOLEAN :
if ( val - > value . b )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " true " ) ;
else
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " false " ) ;
break ;
case XML_SCHEMAS_DURATION : {
char buf [ 100 ] ;
unsigned long year ;
unsigned long mon , day , hour = 0 , min = 0 ;
double sec = 0 , left ;
/* TODO: Unclear in XML Schema 1.0 */
/*
* TODO : This results in a normalized output of the value
* - which is NOT conformant to the spec -
* since the exact values of each property are not
* recoverable . Think about extending the structure to
* provide a field for every property .
*/
year = ( unsigned long ) FQUOTIENT ( labs ( val - > value . dur . mon ) , 12 ) ;
mon = labs ( val - > value . dur . mon ) - 12 * year ;
day = ( unsigned long ) FQUOTIENT ( fabs ( val - > value . dur . sec ) , 86400 ) ;
left = fabs ( val - > value . dur . sec ) - day * 86400 ;
if ( left > 0 ) {
hour = ( unsigned long ) FQUOTIENT ( left , 3600 ) ;
left = left - ( hour * 3600 ) ;
if ( left > 0 ) {
min = ( unsigned long ) FQUOTIENT ( left , 60 ) ;
sec = left - ( min * 60 ) ;
}
}
if ( ( val - > value . dur . mon < 0 ) | | ( val - > value . dur . sec < 0 ) )
snprintf ( buf , 100 , " P%luY%luM%luDT%luH%luM%.14gS " ,
year , mon , day , hour , min , sec ) ;
else
snprintf ( buf , 100 , " -P%luY%luM%luDT%luH%luM%.14gS " ,
year , mon , day , hour , min , sec ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_GYEAR : {
char buf [ 30 ] ;
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
snprintf ( buf , 30 , " %04ld " , val - > value . date . year ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_GMONTH : {
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
2006-10-11 12:32:51 +00:00
* retValue = xmlMalloc ( 6 ) ;
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 10:57:04 +00:00
snprintf ( ( char * ) * retValue , 6 , " --%02u " ,
val - > value . date . mon ) ;
}
break ;
case XML_SCHEMAS_GDAY : {
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
* retValue = xmlMalloc ( 6 ) ;
2006-10-11 12:32:51 +00:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 10:57:04 +00:00
snprintf ( ( char * ) * retValue , 6 , " ---%02u " ,
val - > value . date . day ) ;
}
2012-09-11 13:26:36 +08:00
break ;
2005-04-18 10:57:04 +00:00
case XML_SCHEMAS_GMONTHDAY : {
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
* retValue = xmlMalloc ( 8 ) ;
2006-10-11 12:32:51 +00:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 10:57:04 +00:00
snprintf ( ( char * ) * retValue , 8 , " --%02u-%02u " ,
val - > value . date . mon , val - > value . date . day ) ;
}
break ;
case XML_SCHEMAS_GYEARMONTH : {
char buf [ 35 ] ;
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
if ( val - > value . date . year < 0 )
snprintf ( buf , 35 , " -%04ld-%02u " ,
2012-09-11 13:26:36 +08:00
labs ( val - > value . date . year ) ,
2005-04-18 10:57:04 +00:00
val - > value . date . mon ) ;
else
snprintf ( buf , 35 , " %04ld-%02u " ,
val - > value . date . year , val - > value . date . mon ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
2012-09-11 13:26:36 +08:00
break ;
2005-04-18 10:57:04 +00:00
case XML_SCHEMAS_TIME :
{
char buf [ 30 ] ;
if ( val - > value . date . tz_flag ) {
xmlSchemaValPtr norm ;
norm = xmlSchemaDateNormalize ( val , 0 ) ;
if ( norm = = NULL )
return ( - 1 ) ;
2012-09-11 13:26:36 +08:00
/*
* TODO : Check if " %.14g " is portable .
2005-04-18 10:57:04 +00:00
*/
snprintf ( buf , 30 ,
" %02u:%02u:%02.14gZ " ,
norm - > value . date . hour ,
norm - > value . date . min ,
norm - > value . date . sec ) ;
xmlSchemaFreeValue ( norm ) ;
} else {
snprintf ( buf , 30 ,
" %02u:%02u:%02.14g " ,
val - > value . date . hour ,
val - > value . date . min ,
val - > value . date . sec ) ;
}
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
2012-09-11 13:26:36 +08:00
}
2005-04-18 10:57:04 +00:00
break ;
case XML_SCHEMAS_DATE :
{
char buf [ 30 ] ;
if ( val - > value . date . tz_flag ) {
xmlSchemaValPtr norm ;
norm = xmlSchemaDateNormalize ( val , 0 ) ;
if ( norm = = NULL )
return ( - 1 ) ;
/*
* TODO : Append the canonical value of the
* recoverable timezone and not " Z " .
*/
snprintf ( buf , 30 ,
" %04ld:%02u:%02uZ " ,
norm - > value . date . year , norm - > value . date . mon ,
norm - > value . date . day ) ;
xmlSchemaFreeValue ( norm ) ;
} else {
snprintf ( buf , 30 ,
" %04ld:%02u:%02u " ,
val - > value . date . year , val - > value . date . mon ,
val - > value . date . day ) ;
}
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
2012-09-11 13:26:36 +08:00
}
2005-04-18 10:57:04 +00:00
break ;
case XML_SCHEMAS_DATETIME :
{
char buf [ 50 ] ;
if ( val - > value . date . tz_flag ) {
xmlSchemaValPtr norm ;
norm = xmlSchemaDateNormalize ( val , 0 ) ;
if ( norm = = NULL )
return ( - 1 ) ;
/*
* TODO : Check if " %.14g " is portable .
*/
snprintf ( buf , 50 ,
" %04ld:%02u:%02uT%02u:%02u:%02.14gZ " ,
norm - > value . date . year , norm - > value . date . mon ,
norm - > value . date . day , norm - > value . date . hour ,
norm - > value . date . min , norm - > value . date . sec ) ;
xmlSchemaFreeValue ( norm ) ;
} else {
snprintf ( buf , 50 ,
" %04ld:%02u:%02uT%02u:%02u:%02.14g " ,
val - > value . date . year , val - > value . date . mon ,
val - > value . date . day , val - > value . date . hour ,
val - > value . date . min , val - > value . date . sec ) ;
}
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_HEXBINARY :
* retValue = BAD_CAST xmlStrdup ( BAD_CAST val - > value . hex . str ) ;
break ;
case XML_SCHEMAS_BASE64BINARY :
/*
* TODO : Is the following spec piece implemented ? :
* SPEC : " Note: For some values the canonical form defined
* above does not conform to [ RFC 2045 ] , which requires breaking
* with linefeeds at appropriate intervals . "
*/
* retValue = BAD_CAST xmlStrdup ( BAD_CAST val - > value . base64 . str ) ;
break ;
case XML_SCHEMAS_FLOAT : {
2012-09-11 13:26:36 +08:00
char buf [ 30 ] ;
/*
2005-04-18 10:57:04 +00:00
* | m | < 16777216 , - 149 < = e < = 104.
* TODO : Handle , NaN , INF , - INF . The format is not
* yet conformant . The c type float does not cover
* the whole range .
*/
snprintf ( buf , 30 , " %01.14e " , val - > value . f ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_DOUBLE : {
char buf [ 40 ] ;
/* |m| < 9007199254740992, -1075 <= e <= 970 */
/*
* TODO : Handle , NaN , INF , - INF . The format is not
* yet conformant . The c type float does not cover
* the whole range .
*/
snprintf ( buf , 40 , " %01.14e " , val - > value . d ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
2012-09-11 13:26:36 +08:00
break ;
2005-02-17 11:10:44 +00:00
default :
2005-03-16 16:29:18 +00:00
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " ??? " ) ;
2005-04-18 10:57:04 +00:00
return ( 1 ) ;
2005-02-17 11:10:44 +00:00
}
2006-10-11 12:32:51 +00:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-03-16 16:29:18 +00:00
return ( 0 ) ;
}
2005-04-18 10:57:04 +00:00
/**
* xmlSchemaGetCanonValueWhtsp :
* @ val : the precomputed value
* @ retValue : the returned value
* @ ws : the whitespace type of the value
*
2013-11-29 23:26:26 +01:00
* Get the canonical representation of the value .
2005-04-18 10:57:04 +00:00
* The caller has to free the returned @ retValue .
*
* Returns 0 if the value could be built , 1 if the value type is
* not supported yet and - 1 in case of API errors .
*/
int
xmlSchemaGetCanonValueWhtsp ( xmlSchemaValPtr val ,
const xmlChar * * retValue ,
xmlSchemaWhitespaceValueType ws )
{
if ( ( retValue = = NULL ) | | ( val = = NULL ) )
return ( - 1 ) ;
if ( ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) | |
( ws > XML_SCHEMA_WHITESPACE_COLLAPSE ) )
return ( - 1 ) ;
* retValue = NULL ;
switch ( val - > type ) {
case XML_SCHEMAS_STRING :
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
* retValue = xmlSchemaCollapseString ( val - > value . str ) ;
else if ( ws = = XML_SCHEMA_WHITESPACE_REPLACE )
* retValue = xmlSchemaWhiteSpaceReplace ( val - > value . str ) ;
if ( ( * retValue ) = = NULL )
* retValue = BAD_CAST xmlStrdup ( val - > value . str ) ;
break ;
case XML_SCHEMAS_NORMSTRING :
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
* retValue = xmlSchemaCollapseString ( val - > value . str ) ;
else
* retValue = xmlSchemaWhiteSpaceReplace ( val - > value . str ) ;
if ( ( * retValue ) = = NULL )
* retValue = BAD_CAST xmlStrdup ( val - > value . str ) ;
}
break ;
default :
return ( xmlSchemaGetCanonValue ( val , retValue ) ) ;
2012-09-11 13:26:36 +08:00
}
2005-04-18 10:57:04 +00:00
return ( 0 ) ;
}
2005-04-01 17:15:17 +00:00
/**
* xmlSchemaGetValType :
* @ val : a schemas value
*
* Accessor for the type of a value
*
* Returns the xmlSchemaValType of the value
*/
2005-03-16 16:29:18 +00:00
xmlSchemaValType
xmlSchemaGetValType ( xmlSchemaValPtr val )
{
2005-04-01 17:15:17 +00:00
if ( val = = NULL )
return ( XML_SCHEMAS_UNKNOWN ) ;
2005-03-16 16:29:18 +00:00
return ( val - > type ) ;
2005-02-17 11:10:44 +00:00
}
2005-04-01 13:11:58 +00:00
# define bottom_xmlschemastypes
# include "elfgcchack.h"
2002-04-16 15:50:10 +00:00
# endif /* LIBXML_SCHEMAS_ENABLED */