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
0fb2b803
Commit
0fb2b803
authored
May 15, 2015
by
Milo Yip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change $ref handling mechnism
parent
e0a8a327
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
48 deletions
+81
-48
schema.h
include/rapidjson/schema.h
+81
-48
No files found.
include/rapidjson/schema.h
View file @
0fb2b803
...
...
@@ -208,7 +208,6 @@ struct SchemaValidationContext {
hasher
(),
patternPropertiesSchemas
(),
notValidator
(),
refValidator
(),
patternPropertiesSchemaCount
(),
valuePatternValidatorType
(
kPatternValidatorOnly
),
objectDependencies
(),
...
...
@@ -221,7 +220,6 @@ struct SchemaValidationContext {
~
SchemaValidationContext
()
{
delete
hasher
;
delete
notValidator
;
delete
refValidator
;
delete
[]
patternPropertiesSchemas
;
delete
[]
objectDependencies
;
}
...
...
@@ -239,7 +237,6 @@ struct SchemaValidationContext {
SchemaValidatorArray
patternPropertiesValidators
;
const
SchemaType
**
patternPropertiesSchemas
;
ISchemaValidator
*
notValidator
;
ISchemaValidator
*
refValidator
;
SizeType
patternPropertiesSchemaCount
;
PatternValidatorType
valuePatternValidatorType
;
PatternValidatorType
objectPatternValidatorType
;
...
...
@@ -274,7 +271,6 @@ public:
enum_
(),
enumCount_
(),
not_
(),
ref_
(),
type_
((
1
<<
kTotalSchemaType
)
-
1
),
// typeless
properties_
(),
additionalPropertiesSchema_
(),
...
...
@@ -332,10 +328,10 @@ public:
AssigIfExist
(
oneOf_
,
document
,
p
,
value
,
"oneOf"
);
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"not"
))
not_
=
document
->
CreateSchema
(
p
.
Append
(
"not"
),
*
v
);
document
->
CreateSchema
(
&
not_
,
p
.
Append
(
"not"
),
*
v
);
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"$ref"
))
document
->
AddRefSchema
(
this
,
*
v
);
//
if (const ValueType* v = GetMember(value, "$ref"))
//
document->AddRefSchema(this, *v);
// Object
...
...
@@ -379,7 +375,7 @@ public:
for
(
ConstMemberIterator
itr
=
properties
->
MemberBegin
();
itr
!=
properties
->
MemberEnd
();
++
itr
)
{
SizeType
index
;
if
(
FindPropertyIndex
(
itr
->
name
,
&
index
))
{
properties_
[
index
].
schema
=
document
->
CreateSchema
(
q
.
Append
(
itr
->
name
),
itr
->
value
);
document
->
CreateSchema
(
&
properties_
[
index
].
schema
,
q
.
Append
(
itr
->
name
),
itr
->
value
);
properties_
[
index
].
typeless
=
false
;
}
}
...
...
@@ -393,7 +389,7 @@ public:
for
(
ConstMemberIterator
itr
=
v
->
MemberBegin
();
itr
!=
v
->
MemberEnd
();
++
itr
)
{
new
(
&
patternProperties_
[
patternPropertyCount_
])
PatternProperty
();
patternProperties_
[
patternPropertyCount_
].
pattern
=
CreatePattern
(
itr
->
name
);
patternProperties_
[
patternPropertyCount_
].
schema
=
document
->
CreateSchema
(
q
.
Append
(
itr
->
name
),
itr
->
value
);
document
->
CreateSchema
(
&
patternProperties_
[
patternPropertyCount_
].
schema
,
q
.
Append
(
itr
->
name
),
itr
->
value
);
patternPropertyCount_
++
;
}
}
...
...
@@ -425,7 +421,7 @@ public:
}
else
if
(
itr
->
value
.
IsObject
())
{
hasSchemaDependencies_
=
true
;
properties_
[
sourceIndex
].
dependenciesSchema
=
document
->
CreateSchema
(
q
.
Append
(
itr
->
name
),
itr
->
value
);
document
->
CreateSchema
(
&
properties_
[
sourceIndex
].
dependenciesSchema
,
q
.
Append
(
itr
->
name
),
itr
->
value
);
}
}
}
...
...
@@ -435,7 +431,7 @@ public:
if
(
v
->
IsBool
())
additionalProperties_
=
v
->
GetBool
();
else
if
(
v
->
IsObject
())
additionalPropertiesSchema_
=
document
->
CreateSchema
(
p
.
Append
(
"additionalProperties"
),
*
v
);
document
->
CreateSchema
(
&
additionalPropertiesSchema_
,
p
.
Append
(
"additionalProperties"
),
*
v
);
}
AssignIfExist
(
minProperties_
,
value
,
"minProperties"
);
...
...
@@ -444,13 +440,13 @@ public:
// Array
if
(
const
ValueType
*
v
=
GetMember
(
value
,
"items"
))
{
if
(
v
->
IsObject
())
// List validation
itemsList_
=
document
->
CreateSchema
(
p
,
*
v
);
document
->
CreateSchema
(
&
itemsList_
,
p
,
*
v
);
else
if
(
v
->
IsArray
())
{
// Tuple validation
PointerType
q
=
p
.
Append
(
"items"
);
itemsTuple_
=
static_cast
<
const
Schema
**>
(
allocator_
->
Malloc
(
sizeof
(
const
Schema
*
)
*
v
->
Size
()));
SizeType
index
=
0
;
for
(
ConstValueIterator
itr
=
v
->
Begin
();
itr
!=
v
->
End
();
++
itr
,
index
++
)
itemsTuple_
[
itemsTupleCount_
++
]
=
document
->
CreateSchema
(
q
.
Append
(
index
),
*
itr
);
document
->
CreateSchema
(
&
itemsTuple_
[
itemsTupleCount_
++
],
q
.
Append
(
index
),
*
itr
);
}
}
...
...
@@ -461,7 +457,7 @@ public:
if
(
v
->
IsBool
())
additionalItems_
=
v
->
GetBool
();
else
if
(
v
->
IsObject
())
additionalItemsSchema_
=
document
->
CreateSchema
(
p
.
Append
(
"additionalItems"
),
*
v
);
document
->
CreateSchema
(
&
additionalItemsSchema_
,
p
.
Append
(
"additionalItems"
),
*
v
);
}
AssignIfExist
(
uniqueItems_
,
value
,
"uniqueItems"
);
...
...
@@ -600,9 +596,6 @@ public:
if
(
not_
&&
context
.
notValidator
->
IsValid
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
"not"
);
if
(
ref_
&&
!
context
.
refValidator
->
IsValid
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
"$ref"
);
return
true
;
}
...
...
@@ -867,7 +860,7 @@ private:
out
.
schemas
=
static_cast
<
const
Schema
**>
(
allocator_
->
Malloc
(
out
.
count
*
sizeof
(
const
Schema
*
)));
memset
(
out
.
schemas
,
0
,
sizeof
(
Schema
*
)
*
out
.
count
);
for
(
SizeType
i
=
0
;
i
<
out
.
count
;
i
++
)
out
.
schemas
[
i
]
=
document
->
CreateSchema
(
q
.
Append
(
i
),
(
*
v
)[
i
]);
document
->
CreateSchema
(
&
out
.
schemas
[
i
],
q
.
Append
(
i
),
(
*
v
)[
i
]);
}
}
}
...
...
@@ -921,9 +914,6 @@ private:
if
(
not_
&&
!
context
.
notValidator
)
context
.
notValidator
=
context
.
factory
->
CreateSchemaValidator
(
*
not_
);
if
(
ref_
&&
!
context
.
refValidator
)
context
.
refValidator
=
context
.
factory
->
CreateSchemaValidator
(
*
ref_
);
if
(
hasSchemaDependencies_
&&
!
context
.
dependencyValidators
.
validators
)
{
context
.
dependencyValidators
.
validators
=
new
ISchemaValidator
*
[
propertyCount_
];
context
.
dependencyValidators
.
count
=
propertyCount_
;
...
...
@@ -1082,7 +1072,6 @@ private:
SchemaArray
anyOf_
;
SchemaArray
oneOf_
;
const
SchemaType
*
not_
;
const
SchemaType
*
ref_
;
unsigned
type_
;
// bitmask of kSchemaType
Property
*
properties_
;
...
...
@@ -1150,6 +1139,7 @@ public:
friend
class
GenericSchemaValidator
;
GenericSchemaDocument
(
const
ValueType
&
document
,
IRemoteSchemaDocumentProviderType
*
remoteProvider
=
0
,
Allocator
*
allocator
=
0
)
:
document_
(
&
document
),
remoteProvider_
(
remoteProvider
),
allocator_
(
allocator
),
ownAllocator_
(),
...
...
@@ -1162,24 +1152,36 @@ public:
// Generate root schema, it will call CreateSchema() to create sub-schemas,
// And call AddRefSchema() if there are $ref.
root_
=
CreateSchemaRecursive
(
PointerType
(),
static_cast
<
const
ValueType
&>
(
document
));
CreateSchemaRecursive
(
&
root_
,
PointerType
(),
static_cast
<
const
ValueType
&>
(
document
));
// Resolve $ref
while
(
!
schemaRef_
.
Empty
())
{
SchemaEntry
*
refEntry
=
schemaRef_
.
template
Pop
<
SchemaEntry
>
(
1
);
refEntry
->
schema
->
ref_
=
GetSchema
(
refEntry
->
pointer
);
refEntry
->~
SchemaEntry
();
SchemaRefEntry
*
refEntry
=
schemaRef_
.
template
Pop
<
SchemaRefEntry
>
(
1
);
if
(
const
SchemaType
*
s
=
GetSchema
(
refEntry
->
target
))
{
*
refEntry
->
schema
=
s
;
// Create entry in map if not exist
if
(
!
GetSchema
(
refEntry
->
source
))
{
new
(
schemaMap_
.
template
Push
<
SchemaEntry
>
())
SchemaEntry
(
refEntry
->
source
,
const_cast
<
SchemaType
*>
(
s
),
false
);
}
}
refEntry
->~
SchemaRefEntry
();
}
RAPIDJSON_ASSERT
(
root_
!=
0
);
schemaRef_
.
ShrinkToFit
();
// Deallocate all memory for ref
}
~
GenericSchemaDocument
()
{
while
(
!
schemaMap_
.
Empty
())
{
SchemaEntry
*
e
=
schemaMap_
.
template
Pop
<
SchemaEntry
>
(
1
);
if
(
e
->
owned
)
{
e
->
schema
->~
SchemaType
();
Allocator
::
Free
(
e
->
schema
);
e
->~
SchemaEntry
();
}
}
RAPIDJSON_DELETE
(
ownAllocator_
);
}
...
...
@@ -1187,39 +1189,60 @@ public:
const
SchemaType
&
GetRoot
()
const
{
return
*
root_
;
}
private
:
struct
SchemaRefEntry
{
SchemaRefEntry
(
const
PointerType
&
s
,
const
PointerType
&
t
,
const
SchemaType
**
outSchema
)
:
source
(
s
),
target
(
t
),
schema
(
outSchema
)
{}
PointerType
source
;
PointerType
target
;
const
SchemaType
**
schema
;
};
struct
SchemaEntry
{
SchemaEntry
(
const
PointerType
&
p
,
SchemaType
*
s
)
:
pointer
(
p
),
schema
(
s
)
{}
SchemaEntry
(
const
PointerType
&
p
,
SchemaType
*
s
,
bool
o
)
:
pointer
(
p
),
schema
(
s
),
owned
(
o
)
{}
PointerType
pointer
;
SchemaType
*
schema
;
bool
owned
;
};
const
SchemaType
*
CreateSchemaRecursive
(
const
PointerType
&
pointer
,
const
ValueType
&
v
)
{
void
CreateSchemaRecursive
(
const
SchemaType
**
schema
,
const
PointerType
&
pointer
,
const
ValueType
&
v
)
{
*
schema
=
SchemaType
::
GetTypeless
();
if
(
v
.
GetType
()
==
kObjectType
)
{
const
SchemaType
*
s
=
GetSchema
(
pointer
);
if
(
!
s
)
s
=
CreateSchema
(
pointer
,
v
);
CreateSchema
(
schema
,
pointer
,
v
);
else
*
schema
=
s
;
for
(
typename
ValueType
::
ConstMemberIterator
itr
=
v
.
MemberBegin
();
itr
!=
v
.
MemberEnd
();
++
itr
)
CreateSchemaRecursive
(
pointer
.
Append
(
itr
->
name
),
itr
->
value
);
return
s
;
CreateSchemaRecursive
(
&
s
,
pointer
.
Append
(
itr
->
name
),
itr
->
value
);
}
else
if
(
v
.
GetType
()
==
kArrayType
)
else
if
(
v
.
GetType
()
==
kArrayType
)
{
const
SchemaType
*
s
;
for
(
SizeType
i
=
0
;
i
<
v
.
Size
();
i
++
)
CreateSchemaRecursive
(
pointer
.
Append
(
i
),
v
[
i
]);
return
0
;
CreateSchemaRecursive
(
&
s
,
pointer
.
Append
(
i
),
v
[
i
]);
}
}
const
SchemaType
*
CreateSchema
(
const
PointerType
&
pointer
,
const
ValueType
&
v
)
{
void
CreateSchema
(
const
SchemaType
**
schema
,
const
PointerType
&
pointer
,
const
ValueType
&
v
)
{
RAPIDJSON_ASSERT
(
pointer
.
IsValid
());
SchemaType
*
schema
=
new
(
allocator_
->
Malloc
(
sizeof
(
SchemaType
)))
SchemaType
(
this
,
allocator_
,
pointer
,
v
);
new
(
schemaMap_
.
template
Push
<
SchemaEntry
>
())
SchemaEntry
(
pointer
,
schema
);
return
schema
;
if
(
v
.
IsObject
())
{
if
(
!
HandleRefSchema
(
pointer
,
schema
,
v
))
{
SchemaType
*
s
=
new
(
allocator_
->
Malloc
(
sizeof
(
SchemaType
)))
SchemaType
(
this
,
allocator_
,
pointer
,
v
);
new
(
schemaMap_
.
template
Push
<
SchemaEntry
>
())
SchemaEntry
(
pointer
,
s
,
true
);
*
schema
=
s
;
}
}
}
void
AddRefSchema
(
SchemaType
*
schema
,
const
ValueType
&
v
)
{
if
(
v
.
IsString
())
{
SizeType
len
=
v
.
GetStringLength
();
bool
HandleRefSchema
(
const
Pointer
&
source
,
const
SchemaType
**
schema
,
const
ValueType
&
v
)
{
typename
ValueType
::
ConstMemberIterator
itr
=
v
.
FindMember
(
"$ref"
);
if
(
itr
==
v
.
MemberEnd
())
return
false
;
if
(
itr
->
value
.
IsString
())
{
SizeType
len
=
itr
->
value
.
GetStringLength
();
if
(
len
>
0
)
{
const
Ch
*
s
=
v
.
GetString
();
const
Ch
*
s
=
itr
->
value
.
GetString
();
SizeType
i
=
0
;
while
(
i
<
len
&&
s
[
i
]
!=
'#'
)
// Find the first #
i
++
;
...
...
@@ -1228,18 +1251,29 @@ private:
if
(
remoteProvider_
)
{
if
(
const
GenericSchemaDocument
*
remoteDocument
=
remoteProvider_
->
GetRemoteDocument
(
s
,
i
-
1
))
{
PointerType
pointer
(
&
s
[
i
],
len
-
i
);
if
(
pointer
.
IsValid
())
schema
->
ref_
=
remoteDocument
->
GetSchema
(
pointer
);
if
(
pointer
.
IsValid
())
{
if
(
const
SchemaType
*
s
=
remoteDocument
->
GetSchema
(
pointer
))
{
*
schema
=
s
;
return
true
;
}
}
}
}
}
else
if
(
s
[
i
]
==
'#'
)
{
// Local reference, defer resolution
PointerType
pointer
(
&
s
[
i
],
len
-
i
);
if
(
pointer
.
IsValid
())
new
(
schemaRef_
.
template
Push
<
SchemaEntry
>
())
SchemaEntry
(
pointer
,
schema
);
if
(
pointer
.
IsValid
())
{
if
(
const
ValueType
*
nv
=
pointer
.
Get
(
*
document_
))
if
(
HandleRefSchema
(
source
,
schema
,
*
nv
))
return
true
;
new
(
schemaRef_
.
template
Push
<
SchemaRefEntry
>
())
SchemaRefEntry
(
source
,
pointer
,
schema
);
return
true
;
}
}
}
}
return
false
;
}
const
SchemaType
*
GetSchema
(
const
PointerType
&
pointer
)
const
{
...
...
@@ -1259,6 +1293,7 @@ private:
static
const
size_t
kInitialSchemaMapSize
=
64
;
static
const
size_t
kInitialSchemaRefSize
=
64
;
const
ValueType
*
document_
;
//!< Only temporarily for constructor
IRemoteSchemaDocumentProviderType
*
remoteProvider_
;
Allocator
*
allocator_
;
Allocator
*
ownAllocator_
;
...
...
@@ -1360,8 +1395,6 @@ public:
static_cast<GenericSchemaValidator*>(context->oneOfValidators.validators[i_])->method arg2;\
if (context->notValidator)\
static_cast<GenericSchemaValidator*>(context->notValidator)->method arg2;\
if (context->refValidator)\
static_cast<GenericSchemaValidator*>(context->refValidator)->method arg2;\
if (context->dependencyValidators.validators)\
for (SizeType i_ = 0; i_ < context->dependencyValidators.count; i_++)\
if (context->dependencyValidators.validators[i_])\
...
...
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