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
bbbd1c6f
Commit
bbbd1c6f
authored
May 07, 2015
by
miloyip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Schema code simplification
parent
838e29f4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
156 additions
and
320 deletions
+156
-320
schema.h
include/rapidjson/schema.h
+156
-319
schematest.cpp
test/unittest/schematest.cpp
+0
-1
No files found.
include/rapidjson/schema.h
View file @
bbbd1c6f
...
...
@@ -89,8 +89,8 @@ struct BaseSchemaArray {
template
<
typename
Encoding
>
struct
SchemaValidationContext
{
SchemaValidationContext
(
/*ISchemaValidatorFactory<Encoding>* factory, */
const
BaseSchema
<
Encoding
>*
s
)
:
/*schemaValidatorFactory(factory), */
schema
(
s
),
valueSchema
(),
multiTypeSchema
(),
notValidator
(),
objectDependencies
(),
inArray
(
false
)
SchemaValidationContext
(
const
BaseSchema
<
Encoding
>*
s
)
:
schema
(
s
),
valueSchema
(),
multiTypeSchema
(),
notValidator
(),
objectDependencies
(),
inArray
(
false
)
{
}
...
...
@@ -99,7 +99,6 @@ struct SchemaValidationContext {
delete
[]
objectDependencies
;
}
//ISchemaValidatorFactory<Encoding>* schemaValidatorFactory;
const
BaseSchema
<
Encoding
>*
schema
;
const
BaseSchema
<
Encoding
>*
valueSchema
;
const
BaseSchema
<
Encoding
>*
multiTypeSchema
;
...
...
@@ -122,6 +121,7 @@ public:
template
<
typename
ValueType
>
BaseSchema
(
const
ValueType
&
value
)
:
not_
(),
type_
((
1
<<
kTotalSchemaType
)
-
1
),
// typeless
properties_
(),
additionalPropertySchema_
(),
#if RAPIDJSON_SCHEMA_HAS_REGEX
...
...
@@ -152,328 +152,158 @@ public:
exclusiveMinimum_
(
false
),
exclusiveMaximum_
(
false
)
{
type_
=
(
1
<<
kTotalSchemaType
)
-
1
;
// typeless
typename
ValueType
::
ConstMemberIterator
typeItr
=
value
.
FindMember
(
"type"
);
if
(
typeItr
!=
value
.
MemberEnd
())
{
if
(
typeItr
->
value
.
IsString
())
{
type_
=
0
;
AddType
(
typeItr
->
value
);
}
else
if
(
typeItr
->
value
.
IsArray
())
{
type_
=
0
;
for
(
typename
ValueType
::
ConstValueIterator
itr
=
typeItr
->
value
.
Begin
();
itr
!=
typeItr
->
value
.
End
();
++
itr
)
typedef
typename
ValueType
::
ConstValueIterator
ConstValueIterator
;
typedef
typename
ValueType
::
ConstMemberIterator
ConstMemberIterator
;
if
(
!
value
.
IsObject
())
return
;
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"type"
))
{
type_
=
0
;
if
(
v
->
IsString
())
AddType
(
*
v
);
else
if
(
v
->
IsArray
())
for
(
ConstValueIterator
itr
=
v
->
Begin
();
itr
!=
v
->
End
();
++
itr
)
AddType
(
*
itr
);
}
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
enumItr
=
value
.
FindMember
(
"enum"
);
if
(
enumItr
!=
value
.
MemberEnd
())
{
if
(
enumItr
->
value
.
IsArray
()
&&
enumItr
->
value
.
Size
()
>
0
)
enum_
.
CopyFrom
(
enumItr
->
value
,
allocator_
);
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
allOfItr
=
value
.
FindMember
(
"allOf"
);
if
(
allOfItr
!=
value
.
MemberEnd
())
CreateLogicalSchemas
(
allOfItr
->
value
,
allOf_
);
typename
ValueType
::
ConstMemberIterator
anyOfItr
=
value
.
FindMember
(
"anyOf"
);
if
(
anyOfItr
!=
value
.
MemberEnd
())
CreateLogicalSchemas
(
anyOfItr
->
value
,
anyOf_
);
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"enum"
))
if
(
v
->
IsArray
()
&&
v
->
Size
()
>
0
)
enum_
.
CopyFrom
(
*
v
,
allocator_
);
typename
ValueType
::
ConstMemberIterator
oneOfItr
=
value
.
FindMember
(
"one
Of"
);
if
(
oneOfItr
!=
value
.
MemberEnd
())
CreateLogicalSchemas
(
oneOfItr
->
value
,
oneOf_
);
AssigIfExist
(
allOf_
,
value
,
"all
Of"
);
AssigIfExist
(
anyOf_
,
value
,
"anyOf"
);
AssigIfExist
(
oneOf_
,
value
,
"oneOf"
);
typename
ValueType
::
ConstMemberIterator
notItr
=
value
.
FindMember
(
"not"
);
if
(
notItr
!=
value
.
MemberEnd
())
{
if
(
notItr
->
value
.
IsObject
())
not_
=
new
BaseSchema
<
Encoding
>
(
notItr
->
value
);
}
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"not"
))
not_
=
new
BaseSchema
<
Encoding
>
(
*
v
);
// Object
typename
ValueType
::
ConstMemberIterator
propretiesItr
=
value
.
FindMember
(
"properties"
);
if
(
propretiesItr
!=
value
.
MemberEnd
())
{
const
ValueType
&
properties
=
propretiesItr
->
value
;
properties_
=
new
Property
[
properties
.
MemberCount
()];
propertyCount_
=
0
;
for
(
typename
ValueType
::
ConstMemberIterator
propertyItr
=
properties
.
MemberBegin
();
propertyItr
!=
properties
.
MemberEnd
();
++
propertyItr
)
{
properties_
[
propertyCount_
].
name
.
SetString
(
propertyItr
->
name
.
GetString
(),
propertyItr
->
name
.
GetStringLength
(),
BaseSchema
<
Encoding
>::
allocator_
);
properties_
[
propertyCount_
].
schema
=
new
BaseSchema
(
propertyItr
->
value
);
// TODO: Check error
propertyCount_
++
;
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"properties"
))
if
(
v
->
IsObject
())
{
properties_
=
new
Property
[
v
->
MemberCount
()];
propertyCount_
=
0
;
for
(
ConstMemberIterator
itr
=
v
->
MemberBegin
();
itr
!=
v
->
MemberEnd
();
++
itr
)
{
properties_
[
propertyCount_
].
name
.
SetString
(
itr
->
name
.
GetString
(),
itr
->
name
.
GetStringLength
(),
allocator_
);
properties_
[
propertyCount_
].
schema
=
new
BaseSchema
(
itr
->
value
);
propertyCount_
++
;
}
}
}
#if RAPIDJSON_SCHEMA_HAS_REGEX
typename
ValueType
::
ConstMemberIterator
patternPropretiesItr
=
value
.
FindMember
(
"patternProperties"
);
if
(
patternPropretiesItr
!=
value
.
MemberEnd
())
{
const
ValueType
&
patternProperties
=
patternPropretiesItr
->
value
;
patternProperties_
=
new
PatternProperty
[
patternProperties
.
MemberCount
()];
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"patternProperties"
))
{
patternProperties_
=
new
PatternProperty
[
v
->
MemberCount
()];
patternPropertyCount_
=
0
;
for
(
typename
ValueType
::
ConstMemberIterator
propertyItr
=
patternProperties
.
MemberBegin
();
propertyItr
!=
patternProperties
.
MemberEnd
();
++
propertyItr
)
{
#if RAPIDJSON_SCHEMA_USE_STDREGEX
try
{
patternProperties_
[
patternPropertyCount_
].
pattern
=
new
std
::
basic_regex
<
Ch
>
(
propertyItr
->
name
.
GetString
(),
std
::
size_t
(
propertyItr
->
name
.
GetStringLength
()),
std
::
regex_constants
::
ECMAScript
);
}
catch
(
const
std
::
regex_error
&
)
{
// Error
}
#endif
patternProperties_
[
patternPropertyCount_
].
schema
=
new
BaseSchema
<
Encoding
>
(
propertyItr
->
value
);
// TODO: Check error
for
(
ConstMemberIterator
itr
=
v
->
MemberBegin
();
itr
!=
v
->
MemberEnd
();
++
itr
)
{
patternProperties_
[
patternPropertyCount_
].
pattern
=
CreatePattern
(
itr
->
name
);
patternProperties_
[
patternPropertyCount_
].
schema
=
new
BaseSchema
<
Encoding
>
(
itr
->
value
);
// TODO: Check error
patternPropertyCount_
++
;
}
}
#endif
// Establish required after properties
typename
ValueType
::
ConstMemberIterator
requiredItr
=
value
.
FindMember
(
"required"
);
if
(
requiredItr
!=
value
.
MemberEnd
())
{
if
(
requiredItr
->
value
.
IsArray
())
{
for
(
typename
ValueType
::
ConstValueIterator
itr
=
requiredItr
->
value
.
Begin
();
itr
!=
requiredItr
->
value
.
End
();
++
itr
)
{
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"required"
))
if
(
v
->
IsArray
())
for
(
ConstValueIterator
itr
=
v
->
Begin
();
itr
!=
v
->
End
();
++
itr
)
if
(
itr
->
IsString
())
{
SizeType
index
;
if
(
FindPropertyIndex
(
*
itr
,
&
index
))
{
properties_
[
index
].
required
=
true
;
requiredCount_
++
;
}
else
{
// Error
}
}
else
{
// Error
}
}
}
else
{
// Error
}
}
// Establish dependencies after properties
typename
ValueType
::
ConstMemberIterator
dependenciesItr
=
value
.
FindMember
(
"dependencies"
);
if
(
dependenciesItr
!=
value
.
MemberEnd
())
{
if
(
dependenciesItr
->
value
.
IsObject
())
{
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"dependencies"
))
if
(
v
->
IsObject
())
{
hasDependencies_
=
true
;
for
(
typename
ValueType
::
ConstMemberIterator
itr
=
dependenciesItr
->
value
.
MemberBegin
();
itr
!=
dependenciesItr
->
value
.
MemberEnd
();
++
itr
)
{
for
(
ConstMemberIterator
itr
=
v
->
MemberBegin
();
itr
!=
v
->
MemberEnd
();
++
itr
)
{
SizeType
sourceIndex
;
if
(
FindPropertyIndex
(
itr
->
name
,
&
sourceIndex
))
{
properties_
[
sourceIndex
].
dependencies
=
new
bool
[
propertyCount_
];
std
::
memset
(
properties_
[
sourceIndex
].
dependencies
,
0
,
sizeof
(
bool
)
*
propertyCount_
);
if
(
itr
->
value
.
IsArray
())
{
for
(
typename
ValueType
::
ConstValueIterator
targetItr
=
itr
->
value
.
Begin
();
targetItr
!=
itr
->
value
.
End
();
++
targetItr
)
{
properties_
[
sourceIndex
].
dependencies
=
new
bool
[
propertyCount_
];
std
::
memset
(
properties_
[
sourceIndex
].
dependencies
,
0
,
sizeof
(
bool
)
*
propertyCount_
);
for
(
ConstValueIterator
targetItr
=
itr
->
value
.
Begin
();
targetItr
!=
itr
->
value
.
End
();
++
targetItr
)
{
SizeType
targetIndex
;
if
(
FindPropertyIndex
(
*
targetItr
,
&
targetIndex
))
{
if
(
FindPropertyIndex
(
*
targetItr
,
&
targetIndex
))
properties_
[
sourceIndex
].
dependencies
[
targetIndex
]
=
true
;
}
else
{
// Error
}
}
}
else
{
//
Error
else
if
(
itr
->
value
.
IsObject
())
{
//
TODO
}
}
else
{
// Error
}
}
}
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
additionalPropretiesItr
=
value
.
FindMember
(
"additionalProperties"
);
if
(
additionalPropretiesItr
!=
value
.
MemberEnd
())
{
if
(
additionalPropretiesItr
->
value
.
IsBool
())
additionalProperty_
=
additionalPropretiesItr
->
value
.
GetBool
();
else
if
(
additionalPropretiesItr
->
value
.
IsObject
())
additionalPropertySchema_
=
new
BaseSchema
<
Encoding
>
(
additionalPropretiesItr
->
value
);
else
{
// Error
}
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"additionalProperties"
))
{
if
(
v
->
IsBool
())
additionalProperty_
=
v
->
GetBool
();
else
if
(
v
->
IsObject
())
additionalPropertySchema_
=
new
BaseSchema
<
Encoding
>
(
*
v
);
}
typename
ValueType
::
ConstMemberIterator
minPropertiesItr
=
value
.
FindMember
(
"minProperties"
);
if
(
minPropertiesItr
!=
value
.
MemberEnd
())
{
if
(
minPropertiesItr
->
value
.
IsUint64
()
&&
minPropertiesItr
->
value
.
GetUint64
()
<=
SizeType
(
~
0
))
minProperties_
=
static_cast
<
SizeType
>
(
minPropertiesItr
->
value
.
GetUint64
());
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
maxPropertiesItr
=
value
.
FindMember
(
"maxProperties"
);
if
(
maxPropertiesItr
!=
value
.
MemberEnd
())
{
if
(
maxPropertiesItr
->
value
.
IsUint64
()
&&
maxPropertiesItr
->
value
.
GetUint64
()
<=
SizeType
(
~
0
))
maxProperties_
=
static_cast
<
SizeType
>
(
maxPropertiesItr
->
value
.
GetUint64
());
else
{
// Error
}
}
AssignIfExist
(
minProperties_
,
value
,
"minProperties"
);
AssignIfExist
(
maxProperties_
,
value
,
"maxProperties"
);
// Array
typename
ValueType
::
ConstMemberIterator
itemsItr
=
value
.
FindMember
(
"items"
);
if
(
itemsItr
!=
value
.
MemberEnd
())
{
if
(
itemsItr
->
value
.
IsObject
())
itemsList_
=
new
BaseSchema
<
Encoding
>
(
itemsItr
->
value
);
// List validation
else
if
(
itemsItr
->
value
.
IsArray
())
{
// Tuple validation
itemsTuple_
=
new
BaseSchema
<
Encoding
>*
[
itemsItr
->
value
.
Size
()];
for
(
typename
ValueType
::
ConstValueIterator
itr
=
itemsItr
->
value
.
Begin
();
itr
!=
itemsItr
->
value
.
End
();
++
itr
)
{
itemsTuple_
[
itemsTupleCount_
]
=
new
BaseSchema
<
Encoding
>
(
*
itr
);
itemsTupleCount_
++
;
}
}
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
minItemsItr
=
value
.
FindMember
(
"minItems"
);
if
(
minItemsItr
!=
value
.
MemberEnd
())
{
if
(
minItemsItr
->
value
.
IsUint64
()
&&
minItemsItr
->
value
.
GetUint64
()
<=
SizeType
(
~
0
))
minItems_
=
static_cast
<
SizeType
>
(
minItemsItr
->
value
.
GetUint64
());
else
{
// Error
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"items"
))
{
if
(
v
->
IsObject
())
// List validation
itemsList_
=
new
BaseSchema
<
Encoding
>
(
*
v
);
else
if
(
v
->
IsArray
())
{
// Tuple validation
itemsTuple_
=
new
BaseSchema
<
Encoding
>*
[
v
->
Size
()];
for
(
ConstValueIterator
itr
=
v
->
Begin
();
itr
!=
v
->
End
();
++
itr
)
itemsTuple_
[
itemsTupleCount_
++
]
=
new
BaseSchema
<
Encoding
>
(
*
itr
);
}
}
typename
ValueType
::
ConstMemberIterator
maxItemsItr
=
value
.
FindMember
(
"maxItems"
);
if
(
maxItemsItr
!=
value
.
MemberEnd
())
{
if
(
maxItemsItr
->
value
.
IsUint64
()
&&
maxItemsItr
->
value
.
GetUint64
()
<=
SizeType
(
~
0
))
maxItems_
=
static_cast
<
SizeType
>
(
maxItemsItr
->
value
.
GetUint64
());
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
additionalItemsItr
=
value
.
FindMember
(
"additionalItems"
);
if
(
additionalItemsItr
!=
value
.
MemberEnd
())
{
if
(
additionalItemsItr
->
value
.
IsBool
())
additionalItems_
=
additionalItemsItr
->
value
.
GetBool
();
else
{
// Error
}
}
AssignIfExist
(
minItems_
,
value
,
"minItems"
);
AssignIfExist
(
maxItems_
,
value
,
"maxItems"
);
AssignIfExist
(
additionalItems_
,
value
,
"additionalItems"
);
// String
typename
ValueType
::
ConstMemberIterator
minLengthItr
=
value
.
FindMember
(
"minLength"
);
if
(
minLengthItr
!=
value
.
MemberEnd
())
{
if
(
minLengthItr
->
value
.
IsUint64
()
&&
minLengthItr
->
value
.
GetUint64
()
<=
~
SizeType
(
0
))
minLength_
=
static_cast
<
SizeType
>
(
minLengthItr
->
value
.
GetUint64
());
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
maxLengthItr
=
value
.
FindMember
(
"maxLength"
);
if
(
maxLengthItr
!=
value
.
MemberEnd
())
{
if
(
maxLengthItr
->
value
.
IsUint64
()
&&
maxLengthItr
->
value
.
GetUint64
()
<=
~
SizeType
(
0
))
maxLength_
=
static_cast
<
SizeType
>
(
maxLengthItr
->
value
.
GetUint64
());
else
{
// Error
}
}
AssignIfExist
(
minLength_
,
value
,
"minLength"
);
AssignIfExist
(
maxLength_
,
value
,
"maxLength"
);
#if RAPIDJSON_SCHEMA_HAS_REGEX
typename
ValueType
::
ConstMemberIterator
patternItr
=
value
.
FindMember
(
"pattern"
);
if
(
patternItr
!=
value
.
MemberEnd
())
{
if
(
patternItr
->
value
.
IsString
())
{
#if RAPIDJSON_SCHEMA_USE_STDREGEX
try
{
pattern_
=
new
std
::
basic_regex
<
Ch
>
(
patternItr
->
value
.
GetString
(),
std
::
size_t
(
patternItr
->
value
.
GetStringLength
()),
std
::
regex_constants
::
ECMAScript
);
}
catch
(
const
std
::
regex_error
&
)
{
// Error
}
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
}
else
{
// Error
}
}
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"pattern"
))
pattern_
=
CreatePattern
(
*
v
);
#endif // RAPIDJSON_SCHEMA_HAS_REGEX
// Number
typename
ValueType
::
ConstMemberIterator
minimumItr
=
value
.
FindMember
(
"minimum"
);
if
(
minimumItr
!=
value
.
MemberEnd
())
{
ConstMemberIterator
minimumItr
=
value
.
FindMember
(
"minimum"
);
if
(
minimumItr
!=
value
.
MemberEnd
())
if
(
minimumItr
->
value
.
IsNumber
())
minimum_
=
minimumItr
->
value
.
GetDouble
();
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
maximumItr
=
value
.
FindMember
(
"maximum"
);
if
(
maximumItr
!=
value
.
MemberEnd
())
{
ConstMemberIterator
maximumItr
=
value
.
FindMember
(
"maximum"
);
if
(
maximumItr
!=
value
.
MemberEnd
())
if
(
maximumItr
->
value
.
IsNumber
())
maximum_
=
maximumItr
->
value
.
GetDouble
();
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
exclusiveMinimumItr
=
value
.
FindMember
(
"exclusiveMinimum"
);
if
(
exclusiveMinimumItr
!=
value
.
MemberEnd
())
{
if
(
exclusiveMinimumItr
->
value
.
IsBool
())
exclusiveMinimum_
=
exclusiveMinimumItr
->
value
.
GetBool
();
else
{
// Error
}
}
typename
ValueType
::
ConstMemberIterator
exclusiveMaximumItr
=
value
.
FindMember
(
"exclusiveMaximum"
);
if
(
exclusiveMaximumItr
!=
value
.
MemberEnd
())
{
if
(
exclusiveMaximumItr
->
value
.
IsBool
())
exclusiveMaximum_
=
exclusiveMaximumItr
->
value
.
GetBool
();
else
{
// Error
}
}
AssignIfExist
(
exclusiveMinimum_
,
value
,
"exclusiveMinimum"
);
AssignIfExist
(
exclusiveMaximum_
,
value
,
"exclusiveMaximum"
);
typename
ValueType
::
ConstMemberIterator
multipleOfItr
=
value
.
FindMember
(
"multipleOf"
);
ConstMemberIterator
multipleOfItr
=
value
.
FindMember
(
"multipleOf"
);
if
(
multipleOfItr
!=
value
.
MemberEnd
())
{
if
(
multipleOfItr
->
value
.
IsNumber
())
{
multipleOf_
=
multipleOfItr
->
value
.
GetDouble
();
hasMultipleOf_
=
true
;
}
else
{
// Error
}
}
}
~
BaseSchema
()
{
delete
not_
;
delete
[]
properties_
;
delete
additionalPropertySchema_
;
#if RAPIDJSON_SCHEMA_HAS_REGEX
delete
[]
patternProperties_
;
#endif
delete
itemsList_
;
for
(
SizeType
i
=
0
;
i
<
itemsTupleCount_
;
i
++
)
delete
itemsTuple_
[
i
];
delete
[]
itemsTuple_
;
#if RAPIDJSON_SCHEMA_USE_STDREGEX
delete
pattern_
;
#endif
...
...
@@ -500,21 +330,19 @@ public:
}
bool
EndValue
(
Context
&
context
)
const
{
if
(
allOf_
.
schemas
)
{
if
(
allOf_
.
schemas
)
for
(
SizeType
i_
=
0
;
i_
<
allOf_
.
count
;
i_
++
)
if
(
!
context
.
allOfValidators
.
validators
[
i_
]
->
IsValid
())
return
false
;
}
if
(
anyOf_
.
schemas
)
{
bool
anyValid
=
false
;
for
(
SizeType
i_
=
0
;
i_
<
anyOf_
.
count
;
i_
++
)
if
(
context
.
anyOfValidators
.
validators
[
i_
]
->
IsValid
())
{
anyValid
=
true
;
break
;
}
if
(
!
anyValid
)
return
false
;
if
(
context
.
anyOfValidators
.
validators
[
i_
]
->
IsValid
())
goto
foundAny
;
return
false
;
foundAny
:
;
}
if
(
oneOf_
.
schemas
)
{
CreateSchemaValidators
(
context
,
context
.
oneOfValidators
,
oneOf_
);
bool
oneValid
=
false
;
...
...
@@ -528,11 +356,8 @@ public:
if
(
!
oneValid
)
return
false
;
}
if
(
not_
)
{
if
(
context
.
notValidator
->
IsValid
())
return
false
;
}
return
true
;
return
!
not_
||
!
context
.
notValidator
->
IsValid
();
}
bool
Null
(
Context
&
context
)
const
{
...
...
@@ -599,14 +424,9 @@ public:
return
false
;
#if RAPIDJSON_SCHEMA_HAS_REGEX
if
(
pattern_
)
{
#if RAPIDJSON_SCHEMA_USE_STDREGEX
std
::
match_results
<
const
Ch
*>
r
;
if
(
!
std
::
regex_search
(
str
,
str
+
length
,
r
,
*
pattern_
))
return
false
;
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
}
#endif // RAPIDJSON_SCHEMA_HAS_REGEX
if
(
pattern_
&&
!
IsPatternMatch
(
*
pattern_
,
str
,
length
))
return
false
;
#endif
return
!
enum_
.
IsArray
()
||
CheckEnum
(
GenericValue
<
Encoding
>
(
str
,
length
).
Move
());
}
...
...
@@ -643,19 +463,12 @@ public:
}
#if RAPIDJSON_SCHEMA_HAS_REGEX
if
(
patternProperties_
)
{
for
(
SizeType
i
=
0
;
i
<
patternPropertyCount_
;
i
++
)
{
#if RAPIDJSON_SCHEMA_USE_STDREGEX
if
(
patternProperties_
[
i
].
pattern
)
{
std
::
match_results
<
const
Ch
*>
r
;
if
(
std
::
regex_search
(
str
,
str
+
len
,
r
,
*
patternProperties_
[
i
].
pattern
))
{
context
.
valueSchema
=
patternProperties_
[
i
].
schema
;
return
true
;
}
if
(
patternProperties_
)
for
(
SizeType
i
=
0
;
i
<
patternPropertyCount_
;
i
++
)
if
(
patternProperties_
[
i
].
pattern
&&
IsPatternMatch
(
*
patternProperties_
[
i
].
pattern
,
str
,
len
))
{
context
.
valueSchema
=
patternProperties_
[
i
].
schema
;
return
true
;
}
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
}
}
#endif
if
(
additionalPropertySchema_
)
{
...
...
@@ -678,13 +491,12 @@ public:
if
(
context
.
objectRequiredCount
!=
requiredCount_
||
memberCount
<
minProperties_
||
memberCount
>
maxProperties_
)
return
false
;
if
(
hasDependencies_
)
{
if
(
hasDependencies_
)
for
(
SizeType
sourceIndex
=
0
;
sourceIndex
<
propertyCount_
;
sourceIndex
++
)
if
(
context
.
objectDependencies
[
sourceIndex
]
&&
properties_
[
sourceIndex
].
dependencies
)
for
(
SizeType
targetIndex
=
0
;
targetIndex
<
propertyCount_
;
targetIndex
++
)
if
(
properties_
[
sourceIndex
].
dependencies
[
targetIndex
]
&&
!
context
.
objectDependencies
[
targetIndex
])
return
false
;
}
return
true
;
}
...
...
@@ -708,39 +520,70 @@ public:
return
elementCount
>=
minItems_
&&
elementCount
<=
maxItems_
;
}
#undef RAPIDJSON_BASESCHEMA_HANDLER_LGOICAL_
#undef RAPIDJSON_BASESCHEMA_HANDLER_
protected
:
private
:
static
const
BaseSchema
<
Encoding
>*
GetTypeless
()
{
static
BaseSchema
<
Encoding
>
typeless
(
Value
(
kObjectType
).
Move
());
return
&
typeless
;
}
void
AddType
(
const
Value
&
type
)
{
if
(
type
==
Value
(
"null"
).
Move
())
type_
|=
1
<<
kNullSchemaType
;
else
if
(
type
==
Value
(
"boolean"
).
Move
())
type_
|=
1
<<
kBooleanSchemaType
;
else
if
(
type
==
Value
(
"object"
).
Move
())
type_
|=
1
<<
kObjectSchemaType
;
else
if
(
type
==
Value
(
"array"
).
Move
())
type_
|=
1
<<
kArraySchemaType
;
else
if
(
type
==
Value
(
"string"
).
Move
())
type_
|=
1
<<
kStringSchemaType
;
else
if
(
type
==
Value
(
"integer"
).
Move
())
type_
|=
1
<<
kIntegerSchemaType
;
else
if
(
type
==
Value
(
"number"
).
Move
())
type_
|=
(
1
<<
kNumberSchemaType
)
|
(
1
<<
kIntegerSchemaType
);
else
{
// Error
}
template
<
typename
ValueType
>
static
const
ValueType
*
GetMember
(
const
ValueType
&
value
,
const
char
*
name
)
{
typename
ValueType
::
ConstMemberIterator
itr
=
value
.
FindMember
(
name
);
return
itr
!=
value
.
MemberEnd
()
?
&
(
itr
->
value
)
:
0
;
}
void
CreateLogicalSchemas
(
const
Value
&
logic
,
BaseSchemaArray
<
Encoding
>&
logicSchemas
)
{
if
(
logic
.
IsArray
()
&&
logic
.
Size
()
>
0
)
{
logicSchemas
.
count
=
logic
.
Size
();
logicSchemas
.
schemas
=
new
BaseSchema
*
[
logicSchemas
.
count
];
memset
(
logicSchemas
.
schemas
,
0
,
sizeof
(
BaseSchema
*
)
*
logicSchemas
.
count
);
for
(
SizeType
i
=
0
;
i
<
logicSchemas
.
count
;
i
++
)
logicSchemas
.
schemas
[
i
]
=
new
BaseSchema
<
Encoding
>
(
logic
[
i
]);
}
else
{
// Error
}
template
<
typename
ValueType
>
static
void
AssignIfExist
(
bool
&
out
,
const
ValueType
&
value
,
const
char
*
name
)
{
if
(
const
ValueType
*
v
=
GetMember
(
value
,
name
))
if
(
v
->
IsBool
())
out
=
v
->
GetBool
();
}
template
<
typename
ValueType
>
static
void
AssignIfExist
(
SizeType
&
out
,
const
ValueType
&
value
,
const
char
*
name
)
{
if
(
const
ValueType
*
v
=
GetMember
(
value
,
name
))
if
(
v
->
IsUint64
()
&&
v
->
GetUint64
()
<=
SizeType
(
~
0
))
out
=
static_cast
<
SizeType
>
(
v
->
GetUint64
());
}
template
<
typename
ValueType
>
static
void
AssigIfExist
(
BaseSchemaArray
<
Encoding
>&
out
,
const
ValueType
&
value
,
const
char
*
name
)
{
if
(
const
ValueType
*
v
=
GetMember
(
value
,
name
))
if
(
v
->
IsArray
()
&&
v
->
Size
()
>
0
)
{
out
.
count
=
v
->
Size
();
out
.
schemas
=
new
BaseSchema
*
[
out
.
count
];
memset
(
out
.
schemas
,
0
,
sizeof
(
BaseSchema
*
)
*
out
.
count
);
for
(
SizeType
i
=
0
;
i
<
out
.
count
;
i
++
)
out
.
schemas
[
i
]
=
new
BaseSchema
<
Encoding
>
((
*
v
)[
i
]);
}
}
#if RAPIDJSON_SCHEMA_USE_STDREGEX
template
<
typename
ValueType
>
static
std
::
basic_regex
<
Ch
>*
CreatePattern
(
const
ValueType
&
value
)
{
if
(
value
.
IsString
())
try
{
return
new
std
::
basic_regex
<
Ch
>
(
value
.
GetString
(),
std
::
size_t
(
value
.
GetStringLength
()),
std
::
regex_constants
::
ECMAScript
);
}
catch
(
const
std
::
regex_error
&
)
{
}
return
0
;
}
static
bool
IsPatternMatch
(
const
std
::
basic_regex
<
Ch
>&
pattern
,
const
Ch
*
str
,
SizeType
length
)
{
std
::
match_results
<
const
Ch
*>
r
;
return
std
::
regex_search
(
str
,
str
+
length
,
r
,
pattern
);
}
#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
void
AddType
(
const
Value
&
type
)
{
if
(
type
==
"null"
)
type_
|=
1
<<
kNullSchemaType
;
else
if
(
type
==
"boolean"
)
type_
|=
1
<<
kBooleanSchemaType
;
else
if
(
type
==
"object"
)
type_
|=
1
<<
kObjectSchemaType
;
else
if
(
type
==
"array"
)
type_
|=
1
<<
kArraySchemaType
;
else
if
(
type
==
"string"
)
type_
|=
1
<<
kStringSchemaType
;
else
if
(
type
==
"integer"
)
type_
|=
1
<<
kIntegerSchemaType
;
else
if
(
type
==
"number"
)
type_
|=
(
1
<<
kNumberSchemaType
)
|
(
1
<<
kIntegerSchemaType
);
}
bool
CheckEnum
(
const
GenericValue
<
Encoding
>&
v
)
const
{
...
...
@@ -755,7 +598,7 @@ protected:
if
(
anyOf_
.
schemas
)
CreateSchemaValidators
(
context
,
context
.
anyOfValidators
,
anyOf_
);
if
(
oneOf_
.
schemas
)
CreateSchemaValidators
(
context
,
context
.
oneOfValidators
,
oneOf_
);
if
(
not_
&&
!
context
.
notValidator
)
context
.
notValidator
=
new
GenericSchemaValidator
<
Encoding
>
(
*
not_
);
//context.schemaValidatorFactory->CreateSchemaValidator(*not_);
context
.
notValidator
=
new
GenericSchemaValidator
<
Encoding
>
(
*
not_
);
}
void
CreateSchemaValidators
(
Context
&
context
,
SchemaValidatorArray
<
Encoding
>&
validators
,
const
BaseSchemaArray
<
Encoding
>&
schemas
)
const
{
...
...
@@ -770,25 +613,21 @@ protected:
// O(n)
template
<
typename
ValueType
>
bool
FindPropertyIndex
(
const
ValueType
&
name
,
SizeType
*
outIndex
)
const
{
for
(
SizeType
index
=
0
;
index
<
propertyCount_
;
index
++
)
{
for
(
SizeType
index
=
0
;
index
<
propertyCount_
;
index
++
)
if
(
properties_
[
index
].
name
==
name
)
{
*
outIndex
=
index
;
return
true
;
}
}
return
false
;
}
// O(n)
bool
FindPropertyIndex
(
const
Ch
*
str
,
SizeType
length
,
SizeType
*
outIndex
)
const
{
for
(
SizeType
index
=
0
;
index
<
propertyCount_
;
index
++
)
{
if
(
properties_
[
index
].
name
.
GetStringLength
()
==
length
&&
std
::
memcmp
(
properties_
[
index
].
name
.
GetString
(),
str
,
length
)
==
0
)
{
for
(
SizeType
index
=
0
;
index
<
propertyCount_
;
index
++
)
if
(
properties_
[
index
].
name
.
GetStringLength
()
==
length
&&
std
::
memcmp
(
properties_
[
index
].
name
.
GetString
(),
str
,
length
)
==
0
)
{
*
outIndex
=
index
;
return
true
;
}
}
return
false
;
}
...
...
@@ -884,8 +723,6 @@ public:
delete
root_
;
}
bool
IsValid
()
const
{
return
root_
!=
0
;
}
private
:
BaseSchema
<
Encoding
>*
root_
;
};
...
...
test/unittest/schematest.cpp
View file @
bbbd1c6f
...
...
@@ -21,7 +21,6 @@ using namespace rapidjson;
#define VALIDATE(schema, json, expected) \
{\
ASSERT_TRUE(schema.IsValid());\
SchemaValidator validator(schema);\
Document d;\
/*printf("\n%s\n", json);*/
\
...
...
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