Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
1062f0a4
Commit
1062f0a4
authored
May 05, 2015
by
Milo Yip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add allOf in schema
parent
c2649a36
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
266 additions
and
116 deletions
+266
-116
schema.h
include/rapidjson/schema.h
+235
-116
schematest.cpp
test/unittest/schematest.cpp
+31
-0
No files found.
include/rapidjson/schema.h
View file @
1062f0a4
...
...
@@ -56,17 +56,61 @@ enum SchemaType {
template
<
typename
Encoding
>
class
BaseSchema
;
template
<
typename
Encoding
,
typename
ValueType
>
inline
BaseSchema
<
Encoding
>*
CreateSchema
(
const
ValueType
&
value
,
const
ValueType
&
type
);
template
<
typename
Encoding
,
typename
ValueType
>
inline
BaseSchema
<
Encoding
>*
CreateSchema
(
const
ValueType
&
value
);
template
<
typename
Encoding
>
class
ISchemaValidator
{
public
:
typedef
typename
Encoding
::
Ch
Ch
;
virtual
~
ISchemaValidator
()
{};
virtual
bool
Null
()
=
0
;
virtual
bool
Bool
(
bool
)
=
0
;
virtual
bool
Int
(
int
)
=
0
;
virtual
bool
Uint
(
unsigned
)
=
0
;
virtual
bool
Int64
(
int64_t
)
=
0
;
virtual
bool
Uint64
(
uint64_t
)
=
0
;
virtual
bool
Double
(
double
)
=
0
;
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
=
0
;
virtual
bool
StartObject
()
=
0
;
virtual
bool
Key
(
const
Ch
*
,
SizeType
,
bool
)
=
0
;
virtual
bool
EndObject
(
SizeType
)
=
0
;
virtual
bool
StartArray
()
=
0
;
virtual
bool
EndArray
(
SizeType
)
=
0
;
};
template
<
typename
Encoding
>
class
ISchemaValidatorFactory
{
public
:
virtual
ISchemaValidator
<
Encoding
>*
CreateSchemaValidator
(
const
BaseSchema
<
Encoding
>&
root
)
=
0
;
};
template
<
typename
Encoding
>
struct
SchemaValidationContext
{
SchemaValidationContext
(
const
BaseSchema
<
Encoding
>*
s
)
:
schema
(
s
),
valueSchema
(),
multiTypeSchema
(),
objectDependencies
()
{}
SchemaValidationContext
(
ISchemaValidatorFactory
<
Encoding
>*
factory
,
const
BaseSchema
<
Encoding
>*
s
)
:
schemaValidatorFactory
(
factory
),
schema
(
s
),
valueSchema
(),
multiTypeSchema
(),
allOfValidators
(),
objectDependencies
()
{
}
~
SchemaValidationContext
()
{
if
(
allOfValidators
)
{
for
(
SizeType
i
=
0
;
i
<
allOfValidatorCount
;
i
++
)
delete
allOfValidators
[
i
];
delete
[]
allOfValidators
;
}
delete
[]
objectDependencies
;
}
ISchemaValidatorFactory
<
Encoding
>*
schemaValidatorFactory
;
const
BaseSchema
<
Encoding
>*
schema
;
const
BaseSchema
<
Encoding
>*
valueSchema
;
const
BaseSchema
<
Encoding
>*
multiTypeSchema
;
ISchemaValidator
<
Encoding
>**
allOfValidators
;
SizeType
allOfValidatorCount
;
SizeType
objectRequiredCount
;
SizeType
arrayElementIndex
;
bool
*
objectDependencies
;
...
...
@@ -78,10 +122,11 @@ public:
typedef
typename
Encoding
::
Ch
Ch
;
typedef
SchemaValidationContext
<
Encoding
>
Context
;
BaseSchema
()
{}
BaseSchema
()
:
allOf_
(),
allOfCount_
()
{
}
template
<
typename
ValueType
>
BaseSchema
(
const
ValueType
&
value
)
{
BaseSchema
(
const
ValueType
&
value
)
:
allOf_
(),
allOfCount_
()
{
typename
ValueType
::
ConstMemberIterator
enumItr
=
value
.
FindMember
(
"enum"
);
if
(
enumItr
!=
value
.
MemberEnd
())
{
if
(
enumItr
->
value
.
IsArray
()
&&
enumItr
->
value
.
Size
()
>
0
)
...
...
@@ -90,28 +135,66 @@ public:
// Error
}
}
typename
ValueType
::
ConstMemberIterator
allOfItr
=
value
.
FindMember
(
"allOf"
);
if
(
allOfItr
!=
value
.
MemberEnd
())
{
const
Value
&
allOf
=
allOfItr
->
value
;
if
(
allOf
.
IsArray
()
&&
allOf
.
Size
()
>
0
)
{
allOfCount_
=
allOf
.
Size
();
allOf_
=
new
BaseSchema
*
[
allOfCount_
];
memset
(
allOf_
,
0
,
sizeof
(
BaseSchema
*
)
*
allOfCount_
);
for
(
SizeType
i
=
0
;
i
<
allOfCount_
;
i
++
)
allOf_
[
i
]
=
CreateSchema
<
Encoding
>
(
allOf
[
i
]);
}
else
{
// Error
}
}
}
virtual
~
BaseSchema
()
{}
virtual
~
BaseSchema
()
{
if
(
allOf_
)
{
for
(
SizeType
i
=
0
;
i
<
allOfCount_
;
i
++
)
delete
allOf_
[
i
];
delete
[]
allOf_
;
}
}
virtual
SchemaType
GetSchemaType
()
const
=
0
;
virtual
bool
HandleMultiType
(
Context
&
,
SchemaType
)
const
{
return
true
;
}
virtual
bool
BeginValue
(
Context
&
)
const
{
return
true
;
}
virtual
bool
Null
()
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
().
Move
());
}
virtual
bool
Bool
(
bool
b
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
b
).
Move
());
}
virtual
bool
Int
(
int
i
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
i
).
Move
());
}
virtual
bool
Uint
(
unsigned
u
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
u
).
Move
());
}
virtual
bool
Int64
(
int64_t
i
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
i
).
Move
());
}
virtual
bool
Uint64
(
uint64_t
u
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
u
).
Move
());
}
virtual
bool
Double
(
double
d
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
d
).
Move
());
}
virtual
bool
String
(
const
Ch
*
s
,
SizeType
length
,
bool
)
const
{
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
s
,
length
).
Move
());
}
virtual
bool
StartObject
(
Context
&
)
const
{
return
true
;
}
virtual
bool
Key
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
true
;
}
virtual
bool
EndObject
(
Context
&
,
SizeType
)
const
{
return
true
;
}
virtual
bool
StartArray
(
Context
&
)
const
{
return
true
;
}
virtual
bool
EndArray
(
Context
&
,
SizeType
)
const
{
return
true
;
}
#define RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_(context, method_call)\
if (allOf_) {\
CreateAllOfSchemaValidators(context);\
for (SizeType i = 0; i < allOfCount_; i++)\
if (!context.allOfValidators[i]->method_call)\
return false;\
}\
return true
#define RAPIDJSON_BASESCHEMA_HANDLER_(context, arg, method_call)\
if (enum_.IsArray() && !CheckEnum(GenericValue<Encoding> arg .Move()))\
return false;\
RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_(context, method_call);
virtual
bool
Null
(
Context
&
context
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(),
Null
());
}
virtual
bool
Bool
(
Context
&
context
,
bool
b
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
b
),
Bool
(
b
));
}
virtual
bool
Int
(
Context
&
context
,
int
i
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
i
),
Int
(
i
));
}
virtual
bool
Uint
(
Context
&
context
,
unsigned
u
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
u
),
Uint
(
u
));
}
virtual
bool
Int64
(
Context
&
context
,
int64_t
i
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
i
),
Int64
(
i
));
}
virtual
bool
Uint64
(
Context
&
context
,
uint64_t
u
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
u
),
Int
(
i
));
}
virtual
bool
Double
(
Context
&
context
,
double
d
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
d
),
Double
(
d
));
}
virtual
bool
String
(
Context
&
context
,
const
Ch
*
s
,
SizeType
length
,
bool
copy
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_
(
context
,
(
s
,
length
),
String
(
s
,
length
,
copy
));
}
virtual
bool
StartObject
(
Context
&
context
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
(
context
,
StartObject
());
}
virtual
bool
Key
(
Context
&
context
,
const
Ch
*
s
,
SizeType
length
,
bool
copy
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
(
context
,
Key
(
s
,
length
,
copy
));
}
virtual
bool
EndObject
(
Context
&
context
,
SizeType
memberCount
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
(
context
,
EndObject
(
memberCount
));
}
virtual
bool
StartArray
(
Context
&
context
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
(
context
,
StartArray
());
}
virtual
bool
EndArray
(
Context
&
context
,
SizeType
elementCount
)
const
{
RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
(
context
,
EndArray
(
elementCount
));
}
#undef RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
#undef RAPIDJSON_BASESCHEMA_HANDLER_
protected
:
bool
CheckEnum
(
const
GenericValue
<
Encoding
>&
v
)
const
{
...
...
@@ -121,16 +204,21 @@ protected:
return
false
;
}
void
CreateAllOfSchemaValidators
(
Context
&
context
)
const
{
if
(
!
context
.
allOfValidators
)
{
context
.
allOfValidators
=
new
ISchemaValidator
<
Encoding
>*
[
allOfCount_
];
context
.
allOfValidatorCount
=
allOfCount_
;
for
(
SizeType
i
=
0
;
i
<
allOfCount_
;
i
++
)
context
.
allOfValidators
[
i
]
=
context
.
schemaValidatorFactory
->
CreateSchemaValidator
(
*
allOf_
[
i
]);
}
}
MemoryPoolAllocator
<>
allocator_
;
GenericValue
<
Encoding
>
enum_
;
BaseSchema
<
Encoding
>**
allOf_
;
SizeType
allOfCount_
;
};
template
<
typename
Encoding
,
typename
ValueType
>
inline
BaseSchema
<
Encoding
>*
CreateSchema
(
const
ValueType
&
value
,
const
ValueType
&
type
);
template
<
typename
Encoding
,
typename
ValueType
>
inline
BaseSchema
<
Encoding
>*
CreateSchema
(
const
ValueType
&
value
);
template
<
typename
Encoding
>
class
TypelessSchema
:
public
BaseSchema
<
Encoding
>
{
public
:
...
...
@@ -207,14 +295,14 @@ public:
virtual
SchemaType
GetSchemaType
()
const
{
return
kNullSchemaType
;
}
virtual
bool
Null
(
)
const
{
return
BaseSchema
<
Encoding
>::
Null
(
);
}
virtual
bool
Bool
(
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
double
)
const
{
return
false
;
}
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
context
)
const
{
return
BaseSchema
<
Encoding
>::
Null
(
context
);
}
virtual
bool
Bool
(
Context
&
,
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
Context
&
,
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
Context
&
,
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
Context
&
,
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
Context
&
,
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
Context
&
,
double
)
const
{
return
false
;
}
virtual
bool
String
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
StartObject
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Key
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
EndObject
(
Context
&
,
SizeType
)
const
{
return
false
;
}
...
...
@@ -233,14 +321,14 @@ public:
virtual
SchemaType
GetSchemaType
()
const
{
return
kBooleanSchemaType
;
}
virtual
bool
Null
()
const
{
return
false
;
}
virtual
bool
Bool
(
bool
b
)
const
{
return
BaseSchema
<
Encoding
>::
Bool
(
b
);
}
virtual
bool
Int
(
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
double
)
const
{
return
false
;
}
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Bool
(
Context
&
context
,
bool
b
)
const
{
return
BaseSchema
<
Encoding
>::
Bool
(
context
,
b
);
}
virtual
bool
Int
(
Context
&
,
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
Context
&
,
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
Context
&
,
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
Context
&
,
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
Context
&
,
double
)
const
{
return
false
;
}
virtual
bool
String
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
StartObject
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Key
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
EndObject
(
Context
&
,
SizeType
)
const
{
return
false
;
}
...
...
@@ -408,16 +496,19 @@ public:
virtual
SchemaType
GetSchemaType
()
const
{
return
kObjectSchemaType
;
}
virtual
bool
Null
()
const
{
return
false
;
}
virtual
bool
Bool
(
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
double
)
const
{
return
false
;
}
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Bool
(
Context
&
,
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
Context
&
,
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
Context
&
,
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
Context
&
,
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
Context
&
,
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
Context
&
,
double
)
const
{
return
false
;
}
virtual
bool
String
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
StartObject
(
Context
&
context
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
StartObject
(
context
))
return
false
;
context
.
objectRequiredCount
=
0
;
if
(
hasDependencies_
)
{
context
.
objectDependencies
=
new
bool
[
propertyCount_
];
...
...
@@ -426,7 +517,10 @@ public:
return
true
;
}
virtual
bool
Key
(
Context
&
context
,
const
Ch
*
str
,
SizeType
len
,
bool
)
const
{
virtual
bool
Key
(
Context
&
context
,
const
Ch
*
str
,
SizeType
len
,
bool
copy
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
Key
(
context
,
str
,
len
,
copy
))
return
false
;
SizeType
index
;
if
(
FindPropertyIndex
(
str
,
len
,
&
index
))
{
context
.
valueSchema
=
properties_
[
index
].
schema
;
...
...
@@ -469,6 +563,9 @@ public:
}
virtual
bool
EndObject
(
Context
&
context
,
SizeType
memberCount
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
EndObject
(
context
,
memberCount
))
return
false
;
if
(
context
.
objectRequiredCount
!=
requiredCount_
||
memberCount
<
minProperties_
||
memberCount
>
maxProperties_
)
return
false
;
...
...
@@ -643,24 +740,30 @@ public:
return
true
;
}
virtual
bool
Null
()
const
{
return
false
;
}
virtual
bool
Bool
(
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
double
)
const
{
return
false
;
}
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Bool
(
Context
&
,
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
Context
&
,
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
Context
&
,
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
Context
&
,
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
Context
&
,
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
Context
&
,
double
)
const
{
return
false
;
}
virtual
bool
String
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
StartObject
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Key
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
EndObject
(
Context
&
,
SizeType
)
const
{
return
false
;
}
virtual
bool
StartArray
(
Context
&
context
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
StartArray
(
context
))
return
false
;
context
.
arrayElementIndex
=
0
;
return
true
;
}
virtual
bool
EndArray
(
Context
&
,
SizeType
elementCount
)
const
{
virtual
bool
EndArray
(
Context
&
context
,
SizeType
elementCount
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
EndArray
(
context
,
elementCount
))
return
false
;
return
elementCount
>=
minItems_
&&
elementCount
<=
maxItems_
;
}
...
...
@@ -738,17 +841,18 @@ public:
virtual
SchemaType
GetSchemaType
()
const
{
return
kStringSchemaType
;
}
virtual
bool
Null
()
const
{
return
false
;
}
virtual
bool
Bool
(
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
double
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Bool
(
Context
&
,
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
Context
&
,
int
)
const
{
return
false
;
}
virtual
bool
Uint
(
Context
&
,
unsigned
)
const
{
return
false
;
}
virtual
bool
Int64
(
Context
&
,
int64_t
)
const
{
return
false
;
}
virtual
bool
Uint64
(
Context
&
,
uint64_t
)
const
{
return
false
;
}
virtual
bool
Double
(
Context
&
,
double
)
const
{
return
false
;
}
virtual
bool
String
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
String
(
str
,
length
,
copy
))
virtual
bool
String
(
Context
&
context
,
const
Ch
*
str
,
SizeType
length
,
bool
copy
)
const
{
if
(
!
BaseSchema
<
Encoding
>::
String
(
context
,
str
,
length
,
copy
))
return
false
;
if
(
length
<
minLength_
||
length
>
maxLength_
)
return
false
;
...
...
@@ -844,16 +948,14 @@ public:
virtual
SchemaType
GetSchemaType
()
const
{
return
kIntegerSchemaType
;
}
virtual
bool
Null
()
const
{
return
false
;
}
virtual
bool
Bool
(
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
int
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int64
(
i
)
&&
Int64
(
i
);
}
virtual
bool
Uint
(
unsigned
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint64
(
u
)
&&
Uint64
(
u
);
}
virtual
bool
Int64
(
int64_t
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int64
(
i
)
&&
CheckInt64
(
i
);
}
virtual
bool
Uint64
(
uint64_t
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint64
(
u
)
&&
CheckUint64
(
u
);
}
virtual
bool
Double
(
double
)
const
{
return
false
;
}
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Bool
(
Context
&
,
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
Context
&
context
,
int
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int64
(
context
,
i
)
&&
CheckInt64
(
i
);
}
virtual
bool
Uint
(
Context
&
context
,
unsigned
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint64
(
context
,
u
)
&&
CheckUint64
(
u
);
}
virtual
bool
Int64
(
Context
&
context
,
int64_t
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int64
(
context
,
i
)
&&
CheckInt64
(
i
);
}
virtual
bool
Uint64
(
Context
&
context
,
uint64_t
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint64
(
context
,
u
)
&&
CheckUint64
(
u
);
}
virtual
bool
Double
(
Context
&
,
double
)
const
{
return
false
;
}
virtual
bool
String
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
StartObject
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Key
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
EndObject
(
Context
&
,
SizeType
)
const
{
return
false
;
}
...
...
@@ -991,16 +1093,16 @@ public:
virtual
SchemaType
GetSchemaType
()
const
{
return
kNumberSchemaType
;
}
virtual
bool
Null
()
const
{
return
false
;
}
virtual
bool
Bool
(
bool
)
const
{
return
false
;
}
virtual
bool
Null
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Bool
(
Context
&
,
bool
)
const
{
return
false
;
}
virtual
bool
Int
(
int
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int
(
i
)
&&
CheckDouble
(
i
);
}
virtual
bool
Uint
(
unsigned
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint
(
u
)
&&
CheckDouble
(
u
);
}
virtual
bool
Int64
(
int64_t
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int64
(
i
)
&&
CheckDouble
(
i
);
}
virtual
bool
Uint64
(
uint64_t
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint64
(
u
)
&&
CheckDouble
(
u
);
}
virtual
bool
Double
(
double
d
)
const
{
return
BaseSchema
<
Encoding
>::
Double
(
d
)
&&
CheckDouble
(
d
);
}
virtual
bool
Int
(
Context
&
context
,
int
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int
(
context
,
i
)
&&
CheckDouble
(
i
);
}
virtual
bool
Uint
(
Context
&
context
,
unsigned
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint
(
context
,
u
)
&&
CheckDouble
(
u
);
}
virtual
bool
Int64
(
Context
&
context
,
int64_t
i
)
const
{
return
BaseSchema
<
Encoding
>::
Int64
(
context
,
i
)
&&
CheckDouble
(
i
);
}
virtual
bool
Uint64
(
Context
&
context
,
uint64_t
u
)
const
{
return
BaseSchema
<
Encoding
>::
Uint64
(
context
,
u
)
&&
CheckDouble
(
u
);
}
virtual
bool
Double
(
Context
&
context
,
double
d
)
const
{
return
BaseSchema
<
Encoding
>::
Double
(
context
,
d
)
&&
CheckDouble
(
d
);
}
virtual
bool
String
(
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
String
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
StartObject
(
Context
&
)
const
{
return
false
;
}
virtual
bool
Key
(
Context
&
,
const
Ch
*
,
SizeType
,
bool
)
const
{
return
false
;
}
virtual
bool
EndObject
(
Context
&
,
SizeType
)
const
{
return
false
;
}
...
...
@@ -1071,7 +1173,7 @@ private:
typedef
GenericSchema
<
UTF8
<>
>
Schema
;
template
<
typename
Encoding
,
typename
OutputHandler
=
BaseReaderHandler
<
Encoding
>
,
typename
Allocator
=
CrtAllocator
>
class
GenericSchemaValidator
{
class
GenericSchemaValidator
:
public
ISchemaValidator
<
Encoding
>
,
public
ISchemaValidatorFactory
<
Encoding
>
{
public
:
typedef
typename
Encoding
::
Ch
Ch
;
//!< Character type derived from Encoding.
typedef
GenericSchema
<
Encoding
>
SchemaT
;
...
...
@@ -1079,13 +1181,13 @@ public:
GenericSchemaValidator
(
const
SchemaT
&
schema
,
Allocator
*
allocator
=
0
,
size_t
schemaStackCapacity
=
kDefaultSchemaStackCapacity
,
size_t
documentStackCapacity
=
kDefaultDocumentStackCapacity
)
size_t
schemaStackCapacity
=
kDefaultSchemaStackCapacity
/*
,
size_t documentStackCapacity = kDefaultDocumentStackCapacity
*/
)
:
schema_
(
schema
),
root_
(
*
schema
.
root_
),
outputHandler_
(
nullOutputHandler_
),
schemaStack_
(
allocator
,
schemaStackCapacity
)
,
documentStack_
(
allocator
,
documentStackCapacity
)
schemaStack_
(
allocator
,
schemaStackCapacity
)
// ,
documentStack_(allocator, documentStackCapacity)
{
}
...
...
@@ -1093,13 +1195,13 @@ public:
const
SchemaT
&
schema
,
OutputHandler
&
outputHandler
,
Allocator
*
allocator
=
0
,
size_t
schemaStackCapacity
=
kDefaultSchemaStackCapacity
,
size_t
documentStackCapacity
=
kDefaultDocumentStackCapacity
)
size_t
schemaStackCapacity
=
kDefaultSchemaStackCapacity
/*
,
size_t documentStackCapacity = kDefaultDocumentStackCapacity
*/
)
:
schema_
(
schema
),
root_
(
*
schema
.
root_
),
outputHandler_
(
outputHandler
),
schemaStack_
(
allocator
,
schemaStackCapacity
)
,
documentStack_
(
allocator
,
documentStackCapacity
)
schemaStack_
(
allocator
,
schemaStackCapacity
)
// ,
documentStack_(allocator, documentStackCapacity)
{
}
...
...
@@ -1110,32 +1212,49 @@ public:
void
Reset
()
{
while
(
!
schemaStack_
.
Empty
())
PopSchema
();
documentStack_
.
Clear
();
//
documentStack_.Clear();
};
bool
Null
()
{
return
BeginValue
(
kNullSchemaType
)
&&
CurrentSchema
().
Null
()
&&
EndValue
()
&&
outputHandler_
.
Null
();
}
bool
Bool
(
bool
b
)
{
return
BeginValue
(
kBooleanSchemaType
)
&&
CurrentSchema
().
Bool
(
b
)
&&
EndValue
()
&&
outputHandler_
.
Bool
(
b
);
}
bool
Int
(
int
i
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Int
(
i
)
&&
EndValue
()
&&
outputHandler_
.
Int
(
i
);
}
bool
Uint
(
unsigned
u
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Uint
(
u
)
&&
EndValue
()
&&
outputHandler_
.
Uint
(
u
);
}
bool
Int64
(
int64_t
i64
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Int64
(
i64
)
&&
EndValue
()
&&
outputHandler_
.
Int64
(
i64
);
}
bool
Uint64
(
uint64_t
u64
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Uint64
(
u64
)
&&
EndValue
()
&&
outputHandler_
.
Uint64
(
u64
);
}
bool
Double
(
double
d
)
{
return
BeginValue
(
kNumberSchemaType
)
&&
CurrentSchema
().
Double
(
d
)
&&
EndValue
()
&&
outputHandler_
.
Double
(
d
);
}
bool
String
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
)
{
return
BeginValue
(
kStringSchemaType
)
&&
CurrentSchema
().
String
(
str
,
length
,
copy
)
&&
EndValue
()
&&
outputHandler_
.
String
(
str
,
length
,
copy
);
}
bool
StartObject
()
{
return
BeginValue
(
kObjectSchemaType
)
&&
CurrentSchema
().
StartObject
(
CurrentContext
())
&&
outputHandler_
.
StartObject
();
}
bool
Key
(
const
Ch
*
str
,
SizeType
len
,
bool
copy
)
{
return
CurrentSchema
().
Key
(
CurrentContext
(),
str
,
len
,
copy
)
&&
outputHandler_
.
Key
(
str
,
len
,
copy
);
}
bool
EndObject
(
SizeType
memberCount
)
{
return
CurrentSchema
().
EndObject
(
CurrentContext
(),
memberCount
)
&&
EndValue
()
&&
outputHandler_
.
EndObject
(
memberCount
);
}
bool
StartArray
()
{
return
BeginValue
(
kArraySchemaType
)
&&
CurrentSchema
().
StartArray
(
CurrentContext
())
?
outputHandler_
.
StartArray
()
:
false
;
}
bool
EndArray
(
SizeType
elementCount
)
{
return
CurrentSchema
().
EndArray
(
CurrentContext
(),
elementCount
)
&&
EndValue
()
&&
outputHandler_
.
EndArray
(
elementCount
);
}
// Implementation of ISchemaValidator<Encoding>
virtual
bool
Null
()
{
return
BeginValue
(
kNullSchemaType
)
&&
CurrentSchema
().
Null
(
CurrentContext
()
)
&&
EndValue
()
&&
outputHandler_
.
Null
(
);
}
virtual
bool
Bool
(
bool
b
)
{
return
BeginValue
(
kBooleanSchemaType
)
&&
CurrentSchema
().
Bool
(
CurrentContext
(),
b
)
&&
EndValue
()
&&
outputHandler_
.
Bool
(
b
);
}
virtual
bool
Int
(
int
i
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Int
(
CurrentContext
(),
i
)
&&
EndValue
()
&&
outputHandler_
.
Int
(
i
);
}
virtual
bool
Uint
(
unsigned
u
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Uint
(
CurrentContext
(),
u
)
&&
EndValue
()
&&
outputHandler_
.
Uint
(
u
);
}
virtual
bool
Int64
(
int64_t
i64
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Int64
(
CurrentContext
(),
i64
)
&&
EndValue
()
&&
outputHandler_
.
Int64
(
i64
);
}
virtual
bool
Uint64
(
uint64_t
u64
)
{
return
BeginValue
(
kIntegerSchemaType
)
&&
CurrentSchema
().
Uint64
(
CurrentContext
(),
u64
)
&&
EndValue
()
&&
outputHandler_
.
Uint64
(
u64
);
}
virtual
bool
Double
(
double
d
)
{
return
BeginValue
(
kNumberSchemaType
)
&&
CurrentSchema
().
Double
(
CurrentContext
(),
d
)
&&
EndValue
()
&&
outputHandler_
.
Double
(
d
);
}
virtual
bool
String
(
const
Ch
*
str
,
SizeType
length
,
bool
copy
)
{
return
BeginValue
(
kStringSchemaType
)
&&
CurrentSchema
().
String
(
CurrentContext
(),
str
,
length
,
copy
)
&&
EndValue
()
&&
outputHandler_
.
String
(
str
,
length
,
copy
);
}
virtual
bool
StartObject
()
{
return
BeginValue
(
kObjectSchemaType
)
&&
CurrentSchema
().
StartObject
(
CurrentContext
())
&&
outputHandler_
.
StartObject
();
}
virtual
bool
Key
(
const
Ch
*
str
,
SizeType
len
,
bool
copy
)
{
return
CurrentSchema
().
Key
(
CurrentContext
(),
str
,
len
,
copy
)
&&
outputHandler_
.
Key
(
str
,
len
,
copy
);
}
virtual
bool
EndObject
(
SizeType
memberCount
)
{
return
CurrentSchema
().
EndObject
(
CurrentContext
(),
memberCount
)
&&
EndValue
()
&&
outputHandler_
.
EndObject
(
memberCount
);
}
virtual
bool
StartArray
()
{
return
BeginValue
(
kArraySchemaType
)
&&
CurrentSchema
().
StartArray
(
CurrentContext
())
?
outputHandler_
.
StartArray
()
:
false
;
}
virtual
bool
EndArray
(
SizeType
elementCount
)
{
return
CurrentSchema
().
EndArray
(
CurrentContext
(),
elementCount
)
&&
EndValue
()
&&
outputHandler_
.
EndArray
(
elementCount
);
}
// Implementation of ISchemaValidatorFactory<Encoding>
virtual
ISchemaValidator
<
Encoding
>*
CreateSchemaValidator
(
const
BaseSchema
<
Encoding
>&
root
)
{
return
new
GenericSchemaValidator
(
root
);
}
private
:
typedef
BaseSchema
<
Encoding
>
BaseSchemaType
;
typedef
typename
BaseSchemaType
::
Context
Context
;
GenericSchemaValidator
(
const
BaseSchemaType
&
root
,
Allocator
*
allocator
=
0
,
size_t
schemaStackCapacity
=
kDefaultSchemaStackCapacity
/*,
size_t documentStackCapacity = kDefaultDocumentStackCapacity*/
)
:
root_
(
root
),
outputHandler_
(
nullOutputHandler_
),
schemaStack_
(
allocator
,
schemaStackCapacity
)
// , documentStack_(allocator, documentStackCapacity)
{
}
bool
BeginValue
(
SchemaType
schemaType
)
{
if
(
schemaStack_
.
Empty
())
PushSchema
(
*
schema_
.
root_
);
PushSchema
(
root_
);
else
{
if
(
!
CurrentSchema
().
BeginValue
(
CurrentContext
()))
return
false
;
...
...
@@ -1160,18 +1279,18 @@ private:
return
true
;
}
void
PushSchema
(
const
BaseSchemaType
&
schema
)
{
*
schemaStack_
.
template
Push
<
Context
>
()
=
Context
(
&
schema
);
}
void
PushSchema
(
const
BaseSchemaType
&
schema
)
{
*
schemaStack_
.
template
Push
<
Context
>
()
=
Context
(
this
,
&
schema
);
}
void
PopSchema
()
{
schemaStack_
.
template
Pop
<
Context
>
(
1
)
->~
Context
();
}
const
BaseSchemaType
&
CurrentSchema
()
{
return
*
schemaStack_
.
template
Top
<
Context
>
()
->
schema
;
}
Context
&
CurrentContext
()
{
return
*
schemaStack_
.
template
Top
<
Context
>
();
}
static
const
size_t
kDefaultSchemaStackCapacity
=
256
;
static
const
size_t
kDefaultDocumentStackCapacity
=
256
;
const
SchemaT
&
schema
_
;
//
static const size_t kDefaultDocumentStackCapacity = 256;
const
BaseSchemaType
&
root
_
;
BaseReaderHandler
<
Encoding
>
nullOutputHandler_
;
OutputHandler
&
outputHandler_
;
internal
::
Stack
<
Allocator
>
schemaStack_
;
//!< stack to store the current path of schema (BaseSchemaType *)
internal
::
Stack
<
Allocator
>
documentStack_
;
//!< stack to store the current path of validating document (Value *)
//
internal::Stack<Allocator> documentStack_; //!< stack to store the current path of validating document (Value *)
};
typedef
GenericSchemaValidator
<
UTF8
<>
>
SchemaValidator
;
...
...
test/unittest/schematest.cpp
View file @
1062f0a4
...
...
@@ -539,3 +539,34 @@ TEST(SchemaValidator, MultiTypeWithObject) {
VALIDATE
(
s
,
"{
\"
tel
\"
:
\"
fail
\"
}"
,
false
);
}
TEST
(
SchemaValidator
,
AllOf
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
allOf
\"
: [{
\"
type
\"
:
\"
string
\"
,
\"
minLength
\"
: 2 }, {
\"
type
\"
:
\"
string
\"
,
\"
maxLength
\"
: 5 }]}"
);
Schema
s
(
sd
);
VALIDATE
(
s
,
"
\"
ok
\"
"
,
true
);
VALIDATE
(
s
,
"
\"
n
\"
"
,
false
);
VALIDATE
(
s
,
"
\"
too long
\"
"
,
false
);
VALIDATE
(
s
,
"123"
,
false
);
}
TEST
(
SchemaValidator
,
AllOf_Nested
)
{
Document
sd
;
sd
.
Parse
(
"{"
"
\"
allOf
\"
: ["
" {
\"
type
\"
:
\"
string
\"
,
\"
minLength
\"
: 2 },"
" {
\"
type
\"
:
\"
string
\"
,
\"
maxLength
\"
: 5 },"
" {
\"
allOf
\"
: [ {
\"
enum
\"
: [
\"
ok
\"
,
\"
okay
\"
,
\"
OK
\"
,
\"
o
\"
] }, {
\"
enum
\"
: [
\"
ok
\"
,
\"
OK
\"
,
\"
o
\"
]} ] }"
" ]"
"}"
);
Schema
s
(
sd
);
VALIDATE
(
s
,
"
\"
ok
\"
"
,
true
);
VALIDATE
(
s
,
"
\"
OK
\"
"
,
true
);
VALIDATE
(
s
,
"
\"
okay
\"
"
,
false
);
VALIDATE
(
s
,
"
\"
o
\"
"
,
false
);
VALIDATE
(
s
,
"
\"
n
\"
"
,
false
);
VALIDATE
(
s
,
"
\"
too long
\"
"
,
false
);
VALIDATE
(
s
,
"123"
,
false
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment