| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1 |
// Tencent is pleased to support the open source community by making RapidJSON available-> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
3 |
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
4 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
5 |
// Licensed under the MIT License (the "License"); you may not use this file except |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
6 |
// in compliance with the License-> You may obtain a copy of the License at |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
7 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
8 |
// http://opensource->org/licenses/MIT |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
9 |
// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
10 |
// Unless required by applicable law or agreed to in writing, software distributed |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
11 |
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
12 |
// CONDITIONS OF ANY KIND, either express or implied-> See the License for the |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
13 |
// specific language governing permissions and limitations under the License-> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
14 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
15 |
#ifndef CEREAL_RAPIDJSON_SCHEMA_H_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
16 |
#define CEREAL_RAPIDJSON_SCHEMA_H_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
17 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
18 |
#include "document.h" |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
19 |
#include "pointer.h" |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
20 |
#include <cmath> // abs, floor |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
21 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
22 |
#if !defined(CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
23 |
#define CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
24 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
25 |
#define CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
26 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
27 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
28 |
#if !CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
29 |
#define CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX 1 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
30 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
31 |
#define CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX 0 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
32 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
33 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
34 |
#if CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
35 |
#include "internal/regex.h" |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
36 |
#elif CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
37 |
#include <regex> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
38 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
39 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
40 |
#if CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX || CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
41 |
#define CEREAL_RAPIDJSON_SCHEMA_HAS_REGEX 1 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
42 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
43 |
#define CEREAL_RAPIDJSON_SCHEMA_HAS_REGEX 0 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
44 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
45 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
46 |
#ifndef CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
47 |
#define CEREAL_RAPIDJSON_SCHEMA_VERBOSE 0 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
48 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
49 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
50 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
51 |
#include "stringbuffer.h" |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
52 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
53 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
54 |
CEREAL_RAPIDJSON_DIAG_PUSH |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
55 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
56 |
#if defined(__GNUC__) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
57 |
CEREAL_RAPIDJSON_DIAG_OFF(effc++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
58 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
59 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
60 |
#ifdef __clang__ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
61 |
CEREAL_RAPIDJSON_DIAG_OFF(weak-vtables) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
62 |
CEREAL_RAPIDJSON_DIAG_OFF(exit-time-destructors) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
63 |
CEREAL_RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
64 |
CEREAL_RAPIDJSON_DIAG_OFF(variadic-macros) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
65 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
66 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
67 |
#ifdef _MSC_VER |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
68 |
CEREAL_RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
69 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
70 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
71 |
CEREAL_RAPIDJSON_NAMESPACE_BEGIN |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
72 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
73 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
74 |
// Verbose Utilities |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
75 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
76 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
77 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
78 |
namespace internal { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
79 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
80 |
inline void PrintInvalidKeyword(const char* keyword) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
81 |
printf("Fail keyword: %s\n", keyword); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
82 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
83 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
84 |
inline void PrintInvalidKeyword(const wchar_t* keyword) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
85 |
wprintf(L"Fail keyword: %ls\n", keyword); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
86 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
87 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
88 |
inline void PrintInvalidDocument(const char* document) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
89 |
printf("Fail document: %s\n\n", document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
90 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
91 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
92 |
inline void PrintInvalidDocument(const wchar_t* document) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
93 |
wprintf(L"Fail document: %ls\n\n", document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
94 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
95 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
96 |
inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
97 |
printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
98 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
99 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
100 |
inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
101 |
wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
102 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
103 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
104 |
} // namespace internal |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
105 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
106 |
#endif // CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
107 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
108 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
109 |
// CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
110 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
111 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
112 |
#define CEREAL_RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
113 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
114 |
#define CEREAL_RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
115 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
116 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
117 |
#define CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
118 |
CEREAL_RAPIDJSON_MULTILINEMACRO_BEGIN\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
119 |
context.invalidKeyword = keyword.GetString();\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
120 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
121 |
return false;\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
122 |
CEREAL_RAPIDJSON_MULTILINEMACRO_END |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
123 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
124 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
125 |
// Forward declarations |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
126 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
127 |
template <typename ValueType, typename Allocator> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
128 |
class GenericSchemaDocument; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
129 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
130 |
namespace internal { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
131 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
132 |
template <typename SchemaDocumentType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
133 |
class Schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
134 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
135 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
136 |
// ISchemaValidator |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
137 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
138 |
class ISchemaValidator { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
139 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
140 |
virtual ~ISchemaValidator() {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
141 |
virtual bool IsValid() const = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
142 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
143 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
144 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
145 |
// ISchemaStateFactory |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
146 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
147 |
template <typename SchemaType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
148 |
class ISchemaStateFactory { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
149 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
150 |
virtual ~ISchemaStateFactory() {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
151 |
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
152 |
virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
153 |
virtual void* CreateHasher() = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
154 |
virtual uint64_t GetHashCode(void* hasher) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
155 |
virtual void DestroryHasher(void* hasher) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
156 |
virtual void* MallocState(size_t size) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
157 |
virtual void FreeState(void* p) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
158 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
159 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
160 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
161 |
// Hasher |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
162 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
163 |
// For comparison of compound value |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
164 |
template<typename Encoding, typename Allocator> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
165 |
class Hasher { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
166 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
167 |
typedef typename Encoding::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
168 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
169 |
Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
170 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
171 |
bool Null() { return WriteType(kNullType); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
172 |
bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
173 |
bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
174 |
bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
175 |
bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
176 |
bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
177 |
bool Double(double d) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
178 |
Number n; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
179 |
if (d < 0) n.u.i = static_cast<int64_t>(d); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
180 |
else n.u.u = static_cast<uint64_t>(d); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
181 |
n.d = d; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
182 |
return WriteNumber(n); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
183 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
184 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
185 |
bool RawNumber(const Ch* str, SizeType len, bool) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
186 |
WriteBuffer(kNumberType, str, len * sizeof(Ch)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
187 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
188 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
189 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
190 |
bool String(const Ch* str, SizeType len, bool) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
191 |
WriteBuffer(kStringType, str, len * sizeof(Ch)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
192 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
193 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
194 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
195 |
bool StartObject() { return true; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
196 |
bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
197 |
bool EndObject(SizeType memberCount) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
198 |
uint64_t h = Hash(0, kObjectType); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
199 |
uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
200 |
for (SizeType i = 0; i < memberCount; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
201 |
h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
202 |
*stack_.template Push<uint64_t>() = h; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
203 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
204 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
205 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
206 |
bool StartArray() { return true; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
207 |
bool EndArray(SizeType elementCount) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
208 |
uint64_t h = Hash(0, kArrayType); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
209 |
uint64_t* e = stack_.template Pop<uint64_t>(elementCount); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
210 |
for (SizeType i = 0; i < elementCount; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
211 |
h = Hash(h, e[i]); // Use hash to achieve element order sensitive |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
212 |
*stack_.template Push<uint64_t>() = h; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
213 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
214 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
215 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
216 |
bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
217 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
218 |
uint64_t GetHashCode() const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
219 |
CEREAL_RAPIDJSON_ASSERT(IsValid()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
220 |
return *stack_.template Top<uint64_t>(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
221 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
222 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
223 |
private: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
224 |
static const size_t kDefaultSize = 256; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
225 |
struct Number { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
226 |
union U { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
227 |
uint64_t u; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
228 |
int64_t i; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
229 |
}u; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
230 |
double d; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
231 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
232 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
233 |
bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
234 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
235 |
bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
236 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
237 |
bool WriteBuffer(Type type, const void* data, size_t len) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
238 |
// FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
239 |
uint64_t h = Hash(CEREAL_RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
240 |
const unsigned char* d = static_cast<const unsigned char*>(data); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
241 |
for (size_t i = 0; i < len; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
242 |
h = Hash(h, d[i]); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
243 |
*stack_.template Push<uint64_t>() = h; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
244 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
245 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
246 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
247 |
static uint64_t Hash(uint64_t h, uint64_t d) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
248 |
static const uint64_t kPrime = CEREAL_RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
249 |
h ^= d; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
250 |
h *= kPrime; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
251 |
return h; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
252 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
253 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
254 |
Stack<Allocator> stack_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
255 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
256 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
257 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
258 |
// SchemaValidationContext |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
259 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
260 |
template <typename SchemaDocumentType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
261 |
struct SchemaValidationContext { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
262 |
typedef Schema<SchemaDocumentType> SchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
263 |
typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
264 |
typedef typename SchemaType::ValueType ValueType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
265 |
typedef typename ValueType::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
266 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
267 |
enum PatternValidatorType { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
268 |
kPatternValidatorOnly, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
269 |
kPatternValidatorWithProperty, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
270 |
kPatternValidatorWithAdditionalProperty |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
271 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
272 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
273 |
SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) : |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
274 |
factory(f), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
275 |
schema(s), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
276 |
valueSchema(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
277 |
invalidKeyword(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
278 |
hasher(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
279 |
arrayElementHashCodes(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
280 |
validators(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
281 |
validatorCount(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
282 |
patternPropertiesValidators(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
283 |
patternPropertiesValidatorCount(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
284 |
patternPropertiesSchemas(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
285 |
patternPropertiesSchemaCount(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
286 |
valuePatternValidatorType(kPatternValidatorOnly), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
287 |
propertyExist(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
288 |
inArray(false), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
289 |
valueUniqueness(false), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
290 |
arrayUniqueness(false) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
291 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
292 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
293 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
294 |
~SchemaValidationContext() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
295 |
if (hasher) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
296 |
factory.DestroryHasher(hasher); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
297 |
if (validators) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
298 |
for (SizeType i = 0; i < validatorCount; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
299 |
factory.DestroySchemaValidator(validators[i]); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
300 |
factory.FreeState(validators); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
301 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
302 |
if (patternPropertiesValidators) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
303 |
for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
304 |
factory.DestroySchemaValidator(patternPropertiesValidators[i]); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
305 |
factory.FreeState(patternPropertiesValidators); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
306 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
307 |
if (patternPropertiesSchemas) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
308 |
factory.FreeState(patternPropertiesSchemas); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
309 |
if (propertyExist) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
310 |
factory.FreeState(propertyExist); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
311 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
312 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
313 |
SchemaValidatorFactoryType& factory; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
314 |
const SchemaType* schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
315 |
const SchemaType* valueSchema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
316 |
const Ch* invalidKeyword; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
317 |
void* hasher; // Only validator access |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
318 |
void* arrayElementHashCodes; // Only validator access this |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
319 |
ISchemaValidator** validators; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
320 |
SizeType validatorCount; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
321 |
ISchemaValidator** patternPropertiesValidators; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
322 |
SizeType patternPropertiesValidatorCount; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
323 |
const SchemaType** patternPropertiesSchemas; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
324 |
SizeType patternPropertiesSchemaCount; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
325 |
PatternValidatorType valuePatternValidatorType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
326 |
PatternValidatorType objectPatternValidatorType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
327 |
SizeType arrayElementIndex; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
328 |
bool* propertyExist; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
329 |
bool inArray; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
330 |
bool valueUniqueness; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
331 |
bool arrayUniqueness; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
332 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
333 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
334 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
335 |
// Schema |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
336 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
337 |
template <typename SchemaDocumentType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
338 |
class Schema { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
339 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
340 |
typedef typename SchemaDocumentType::ValueType ValueType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
341 |
typedef typename SchemaDocumentType::AllocatorType AllocatorType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
342 |
typedef typename SchemaDocumentType::PointerType PointerType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
343 |
typedef typename ValueType::EncodingType EncodingType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
344 |
typedef typename EncodingType::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
345 |
typedef SchemaValidationContext<SchemaDocumentType> Context; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
346 |
typedef Schema<SchemaDocumentType> SchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
347 |
typedef GenericValue<EncodingType, AllocatorType> SValue; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
348 |
friend class GenericSchemaDocument<ValueType, AllocatorType>; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
349 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
350 |
Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
351 |
allocator_(allocator), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
352 |
enum_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
353 |
enumCount_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
354 |
not_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
355 |
type_((1 << kTotalSchemaType) - 1), // typeless |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
356 |
validatorCount_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
357 |
properties_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
358 |
additionalPropertiesSchema_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
359 |
patternProperties_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
360 |
patternPropertyCount_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
361 |
propertyCount_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
362 |
minProperties_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
363 |
maxProperties_(SizeType(~0)), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
364 |
additionalProperties_(true), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
365 |
hasDependencies_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
366 |
hasRequired_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
367 |
hasSchemaDependencies_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
368 |
additionalItemsSchema_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
369 |
itemsList_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
370 |
itemsTuple_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
371 |
itemsTupleCount_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
372 |
minItems_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
373 |
maxItems_(SizeType(~0)), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
374 |
additionalItems_(true), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
375 |
uniqueItems_(false), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
376 |
pattern_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
377 |
minLength_(0), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
378 |
maxLength_(~SizeType(0)), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
379 |
exclusiveMinimum_(false), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
380 |
exclusiveMaximum_(false) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
381 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
382 |
typedef typename SchemaDocumentType::ValueType ValueType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
383 |
typedef typename ValueType::ConstValueIterator ConstValueIterator; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
384 |
typedef typename ValueType::ConstMemberIterator ConstMemberIterator; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
385 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
386 |
if (!value.IsObject()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
387 |
return; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
388 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
389 |
if (const ValueType* v = GetMember(value, GetTypeString())) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
390 |
type_ = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
391 |
if (v->IsString()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
392 |
AddType(*v); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
393 |
else if (v->IsArray()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
394 |
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
395 |
AddType(*itr); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
396 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
397 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
398 |
if (const ValueType* v = GetMember(value, GetEnumString())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
399 |
if (v->IsArray() && v->Size() > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
400 |
enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
401 |
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
402 |
typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
403 |
char buffer[256 + 24]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
404 |
MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
405 |
EnumHasherType h(&hasherAllocator, 256); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
406 |
itr->Accept(h); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
407 |
enum_[enumCount_++] = h.GetHashCode(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
408 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
409 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
410 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
411 |
if (schemaDocument) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
412 |
AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
413 |
AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
414 |
AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
415 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
416 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
417 |
if (const ValueType* v = GetMember(value, GetNotString())) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
418 |
schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
419 |
notValidatorIndex_ = validatorCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
420 |
validatorCount_++; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
421 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
422 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
423 |
// Object |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
424 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
425 |
const ValueType* properties = GetMember(value, GetPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
426 |
const ValueType* required = GetMember(value, GetRequiredString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
427 |
const ValueType* dependencies = GetMember(value, GetDependenciesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
428 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
429 |
// Gather properties from properties/required/dependencies |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
430 |
SValue allProperties(kArrayType); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
431 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
432 |
if (properties && properties->IsObject()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
433 |
for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
434 |
AddUniqueElement(allProperties, itr->name); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
435 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
436 |
if (required && required->IsArray()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
437 |
for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
438 |
if (itr->IsString()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
439 |
AddUniqueElement(allProperties, *itr); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
440 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
441 |
if (dependencies && dependencies->IsObject()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
442 |
for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
443 |
AddUniqueElement(allProperties, itr->name); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
444 |
if (itr->value.IsArray()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
445 |
for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
446 |
if (i->IsString()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
447 |
AddUniqueElement(allProperties, *i); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
448 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
449 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
450 |
if (allProperties.Size() > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
451 |
propertyCount_ = allProperties.Size(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
452 |
properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
453 |
for (SizeType i = 0; i < propertyCount_; i++) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
454 |
new (&properties_[i]) Property(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
455 |
properties_[i].name = allProperties[i]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
456 |
properties_[i].schema = GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
457 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
458 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
459 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
460 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
461 |
if (properties && properties->IsObject()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
462 |
PointerType q = p.Append(GetPropertiesString(), allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
463 |
for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
464 |
SizeType index; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
465 |
if (FindPropertyIndex(itr->name, &index)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
466 |
schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
467 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
468 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
469 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
470 |
if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
471 |
PointerType q = p.Append(GetPatternPropertiesString(), allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
472 |
patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
473 |
patternPropertyCount_ = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
474 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
475 |
for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
476 |
new (&patternProperties_[patternPropertyCount_]) PatternProperty(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
477 |
patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
478 |
schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
479 |
patternPropertyCount_++; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
480 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
481 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
482 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
483 |
if (required && required->IsArray()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
484 |
for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
485 |
if (itr->IsString()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
486 |
SizeType index; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
487 |
if (FindPropertyIndex(*itr, &index)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
488 |
properties_[index].required = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
489 |
hasRequired_ = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
490 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
491 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
492 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
493 |
if (dependencies && dependencies->IsObject()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
494 |
PointerType q = p.Append(GetDependenciesString(), allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
495 |
hasDependencies_ = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
496 |
for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
497 |
SizeType sourceIndex; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
498 |
if (FindPropertyIndex(itr->name, &sourceIndex)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
499 |
if (itr->value.IsArray()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
500 |
properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
501 |
std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
502 |
for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
503 |
SizeType targetIndex; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
504 |
if (FindPropertyIndex(*targetItr, &targetIndex)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
505 |
properties_[sourceIndex].dependencies[targetIndex] = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
506 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
507 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
508 |
else if (itr->value.IsObject()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
509 |
hasSchemaDependencies_ = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
510 |
schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
511 |
properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
512 |
validatorCount_++; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
513 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
514 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
515 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
516 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
517 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
518 |
if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
519 |
if (v->IsBool()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
520 |
additionalProperties_ = v->GetBool(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
521 |
else if (v->IsObject()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
522 |
schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
523 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
524 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
525 |
AssignIfExist(minProperties_, value, GetMinPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
526 |
AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
527 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
528 |
// Array |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
529 |
if (const ValueType* v = GetMember(value, GetItemsString())) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
530 |
PointerType q = p.Append(GetItemsString(), allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
531 |
if (v->IsObject()) // List validation |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
532 |
schemaDocument->CreateSchema(&itemsList_, q, *v, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
533 |
else if (v->IsArray()) { // Tuple validation |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
534 |
itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
535 |
SizeType index = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
536 |
for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
537 |
schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
538 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
539 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
540 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
541 |
AssignIfExist(minItems_, value, GetMinItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
542 |
AssignIfExist(maxItems_, value, GetMaxItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
543 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
544 |
if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
545 |
if (v->IsBool()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
546 |
additionalItems_ = v->GetBool(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
547 |
else if (v->IsObject()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
548 |
schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
549 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
550 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
551 |
AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
552 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
553 |
// String |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
554 |
AssignIfExist(minLength_, value, GetMinLengthString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
555 |
AssignIfExist(maxLength_, value, GetMaxLengthString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
556 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
557 |
if (const ValueType* v = GetMember(value, GetPatternString())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
558 |
pattern_ = CreatePattern(*v); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
559 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
560 |
// Number |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
561 |
if (const ValueType* v = GetMember(value, GetMinimumString())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
562 |
if (v->IsNumber()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
563 |
minimum_.CopyFrom(*v, *allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
564 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
565 |
if (const ValueType* v = GetMember(value, GetMaximumString())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
566 |
if (v->IsNumber()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
567 |
maximum_.CopyFrom(*v, *allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
568 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
569 |
AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
570 |
AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
571 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
572 |
if (const ValueType* v = GetMember(value, GetMultipleOfString())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
573 |
if (v->IsNumber() && v->GetDouble() > 0.0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
574 |
multipleOf_.CopyFrom(*v, *allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
575 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
576 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
577 |
~Schema() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
578 |
if (allocator_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
579 |
allocator_->Free(enum_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
580 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
581 |
if (properties_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
582 |
for (SizeType i = 0; i < propertyCount_; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
583 |
properties_[i].~Property(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
584 |
AllocatorType::Free(properties_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
585 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
586 |
if (patternProperties_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
587 |
for (SizeType i = 0; i < patternPropertyCount_; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
588 |
patternProperties_[i].~PatternProperty(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
589 |
AllocatorType::Free(patternProperties_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
590 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
591 |
AllocatorType::Free(itemsTuple_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
592 |
#if CEREAL_RAPIDJSON_SCHEMA_HAS_REGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
593 |
if (pattern_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
594 |
pattern_->~RegexType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
595 |
allocator_->Free(pattern_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
596 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
597 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
598 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
599 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
600 |
bool BeginValue(Context& context) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
601 |
if (context.inArray) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
602 |
if (uniqueItems_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
603 |
context.valueUniqueness = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
604 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
605 |
if (itemsList_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
606 |
context.valueSchema = itemsList_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
607 |
else if (itemsTuple_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
608 |
if (context.arrayElementIndex < itemsTupleCount_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
609 |
context.valueSchema = itemsTuple_[context.arrayElementIndex]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
610 |
else if (additionalItemsSchema_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
611 |
context.valueSchema = additionalItemsSchema_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
612 |
else if (additionalItems_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
613 |
context.valueSchema = GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
614 |
else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
615 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
616 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
617 |
else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
618 |
context.valueSchema = GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
619 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
620 |
context.arrayElementIndex++; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
621 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
622 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
623 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
624 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
625 |
CEREAL_RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
626 |
if (context.patternPropertiesValidatorCount > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
627 |
bool otherValid = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
628 |
SizeType count = context.patternPropertiesValidatorCount; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
629 |
if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
630 |
otherValid = context.patternPropertiesValidators[--count]->IsValid(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
631 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
632 |
bool patternValid = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
633 |
for (SizeType i = 0; i < count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
634 |
if (!context.patternPropertiesValidators[i]->IsValid()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
635 |
patternValid = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
636 |
break; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
637 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
638 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
639 |
if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
640 |
if (!patternValid) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
641 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
642 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
643 |
else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
644 |
if (!patternValid || !otherValid) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
645 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
646 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
647 |
else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
648 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
649 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
650 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
651 |
if (enum_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
652 |
const uint64_t h = context.factory.GetHashCode(context.hasher); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
653 |
for (SizeType i = 0; i < enumCount_; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
654 |
if (enum_[i] == h) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
655 |
goto foundEnum; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
656 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
657 |
foundEnum:; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
658 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
659 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
660 |
if (allOf_.schemas) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
661 |
for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
662 |
if (!context.validators[i]->IsValid()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
663 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
664 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
665 |
if (anyOf_.schemas) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
666 |
for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
667 |
if (context.validators[i]->IsValid()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
668 |
goto foundAny; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
669 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
670 |
foundAny:; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
671 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
672 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
673 |
if (oneOf_.schemas) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
674 |
bool oneValid = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
675 |
for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
676 |
if (context.validators[i]->IsValid()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
677 |
if (oneValid) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
678 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
679 |
else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
680 |
oneValid = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
681 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
682 |
if (!oneValid) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
683 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
684 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
685 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
686 |
if (not_ && context.validators[notValidatorIndex_]->IsValid()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
687 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
688 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
689 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
690 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
691 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
692 |
bool Null(Context& context) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
693 |
if (!(type_ & (1 << kNullSchemaType))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
694 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
695 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
696 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
697 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
698 |
bool Bool(Context& context, bool) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
699 |
if (!(type_ & (1 << kBooleanSchemaType))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
700 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
701 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
702 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
703 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
704 |
bool Int(Context& context, int i) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
705 |
if (!CheckInt(context, i)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
706 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
707 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
708 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
709 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
710 |
bool Uint(Context& context, unsigned u) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
711 |
if (!CheckUint(context, u)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
712 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
713 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
714 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
715 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
716 |
bool Int64(Context& context, int64_t i) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
717 |
if (!CheckInt(context, i)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
718 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
719 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
720 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
721 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
722 |
bool Uint64(Context& context, uint64_t u) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
723 |
if (!CheckUint(context, u)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
724 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
725 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
726 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
727 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
728 |
bool Double(Context& context, double d) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
729 |
if (!(type_ & (1 << kNumberSchemaType))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
730 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
731 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
732 |
if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
733 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
734 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
735 |
if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
736 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
737 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
738 |
if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
739 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
740 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
741 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
742 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
743 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
744 |
bool String(Context& context, const Ch* str, SizeType length, bool) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
745 |
if (!(type_ & (1 << kStringSchemaType))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
746 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
747 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
748 |
if (minLength_ != 0 || maxLength_ != SizeType(~0)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
749 |
SizeType count; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
750 |
if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
751 |
if (count < minLength_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
752 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
753 |
if (count > maxLength_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
754 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
755 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
756 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
757 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
758 |
if (pattern_ && !IsPatternMatch(pattern_, str, length)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
759 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
760 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
761 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
762 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
763 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
764 |
bool StartObject(Context& context) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
765 |
if (!(type_ & (1 << kObjectSchemaType))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
766 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
767 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
768 |
if (hasDependencies_ || hasRequired_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
769 |
context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
770 |
std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
771 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
772 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
773 |
if (patternProperties_) { // pre-allocate schema array |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
774 |
SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
775 |
context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
776 |
context.patternPropertiesSchemaCount = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
777 |
std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
778 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
779 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
780 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
781 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
782 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
783 |
bool Key(Context& context, const Ch* str, SizeType len, bool) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
784 |
if (patternProperties_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
785 |
context.patternPropertiesSchemaCount = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
786 |
for (SizeType i = 0; i < patternPropertyCount_; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
787 |
if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
788 |
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
789 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
790 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
791 |
SizeType index; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
792 |
if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
793 |
if (context.patternPropertiesSchemaCount > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
794 |
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
795 |
context.valueSchema = GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
796 |
context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
797 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
798 |
else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
799 |
context.valueSchema = properties_[index].schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
800 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
801 |
if (context.propertyExist) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
802 |
context.propertyExist[index] = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
803 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
804 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
805 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
806 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
807 |
if (additionalPropertiesSchema_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
808 |
if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
809 |
context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
810 |
context.valueSchema = GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
811 |
context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
812 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
813 |
else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
814 |
context.valueSchema = additionalPropertiesSchema_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
815 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
816 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
817 |
else if (additionalProperties_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
818 |
context.valueSchema = GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
819 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
820 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
821 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
822 |
if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
823 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
824 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
825 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
826 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
827 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
828 |
bool EndObject(Context& context, SizeType memberCount) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
829 |
if (hasRequired_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
830 |
for (SizeType index = 0; index < propertyCount_; index++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
831 |
if (properties_[index].required) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
832 |
if (!context.propertyExist[index]) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
833 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
834 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
835 |
if (memberCount < minProperties_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
836 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
837 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
838 |
if (memberCount > maxProperties_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
839 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
840 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
841 |
if (hasDependencies_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
842 |
for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
843 |
if (context.propertyExist[sourceIndex]) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
844 |
if (properties_[sourceIndex].dependencies) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
845 |
for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
846 |
if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex]) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
847 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
848 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
849 |
else if (properties_[sourceIndex].dependenciesSchema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
850 |
if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
851 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
852 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
853 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
854 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
855 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
856 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
857 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
858 |
bool StartArray(Context& context) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
859 |
if (!(type_ & (1 << kArraySchemaType))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
860 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
861 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
862 |
context.arrayElementIndex = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
863 |
context.inArray = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
864 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
865 |
return CreateParallelValidator(context); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
866 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
867 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
868 |
bool EndArray(Context& context, SizeType elementCount) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
869 |
context.inArray = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
870 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
871 |
if (elementCount < minItems_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
872 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
873 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
874 |
if (elementCount > maxItems_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
875 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
876 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
877 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
878 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
879 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
880 |
// Generate functions for string literal according to Ch |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
881 |
#define CEREAL_RAPIDJSON_STRING_(name, ...) \ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
882 |
static const ValueType& Get##name##String() {\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
883 |
static const Ch s[] = { __VA_ARGS__, '\0' };\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
884 |
static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
885 |
return v;\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
886 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
887 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
888 |
CEREAL_RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
889 |
CEREAL_RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
890 |
CEREAL_RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
891 |
CEREAL_RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
892 |
CEREAL_RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
893 |
CEREAL_RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
894 |
CEREAL_RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
895 |
CEREAL_RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
896 |
CEREAL_RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
897 |
CEREAL_RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
898 |
CEREAL_RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
899 |
CEREAL_RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
900 |
CEREAL_RAPIDJSON_STRING_(Not, 'n', 'o', 't') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
901 |
CEREAL_RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
902 |
CEREAL_RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
903 |
CEREAL_RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
904 |
CEREAL_RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
905 |
CEREAL_RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
906 |
CEREAL_RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
907 |
CEREAL_RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
908 |
CEREAL_RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
909 |
CEREAL_RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
910 |
CEREAL_RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
911 |
CEREAL_RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
912 |
CEREAL_RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
913 |
CEREAL_RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
914 |
CEREAL_RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
915 |
CEREAL_RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
916 |
CEREAL_RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
917 |
CEREAL_RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
918 |
CEREAL_RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
919 |
CEREAL_RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
920 |
CEREAL_RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
921 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
922 |
#undef CEREAL_RAPIDJSON_STRING_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
923 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
924 |
private: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
925 |
enum SchemaValueType { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
926 |
kNullSchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
927 |
kBooleanSchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
928 |
kObjectSchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
929 |
kArraySchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
930 |
kStringSchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
931 |
kNumberSchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
932 |
kIntegerSchemaType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
933 |
kTotalSchemaType |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
934 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
935 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
936 |
#if CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
937 |
typedef internal::GenericRegex<EncodingType> RegexType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
938 |
#elif CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
939 |
typedef std::basic_regex<Ch> RegexType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
940 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
941 |
typedef char RegexType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
942 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
943 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
944 |
struct SchemaArray { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
945 |
SchemaArray() : schemas(), count() {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
946 |
~SchemaArray() { AllocatorType::Free(schemas); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
947 |
const SchemaType** schemas; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
948 |
SizeType begin; // begin index of context.validators |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
949 |
SizeType count; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
950 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
951 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
952 |
static const SchemaType* GetTypeless() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
953 |
static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
954 |
return &typeless; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
955 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
956 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
957 |
template <typename V1, typename V2> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
958 |
void AddUniqueElement(V1& a, const V2& v) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
959 |
for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
960 |
if (*itr == v) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
961 |
return; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
962 |
V1 c(v, *allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
963 |
a.PushBack(c, *allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
964 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
965 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
966 |
static const ValueType* GetMember(const ValueType& value, const ValueType& name) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
967 |
typename ValueType::ConstMemberIterator itr = value.FindMember(name); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
968 |
return itr != value.MemberEnd() ? &(itr->value) : 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
969 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
970 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
971 |
static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
972 |
if (const ValueType* v = GetMember(value, name)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
973 |
if (v->IsBool()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
974 |
out = v->GetBool(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
975 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
976 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
977 |
static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
978 |
if (const ValueType* v = GetMember(value, name)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
979 |
if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
980 |
out = static_cast<SizeType>(v->GetUint64()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
981 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
982 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
983 |
void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
984 |
if (const ValueType* v = GetMember(value, name)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
985 |
if (v->IsArray() && v->Size() > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
986 |
PointerType q = p.Append(name, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
987 |
out.count = v->Size(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
988 |
out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
989 |
memset(out.schemas, 0, sizeof(Schema*)* out.count); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
990 |
for (SizeType i = 0; i < out.count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
991 |
schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
992 |
out.begin = validatorCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
993 |
validatorCount_ += out.count; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
994 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
995 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
996 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
997 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
998 |
#if CEREAL_RAPIDJSON_SCHEMA_USE_INTERNALREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
999 |
template <typename ValueType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1000 |
RegexType* CreatePattern(const ValueType& value) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1001 |
if (value.IsString()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1002 |
RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1003 |
if (!r->IsValid()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1004 |
r->~RegexType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1005 |
AllocatorType::Free(r); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1006 |
r = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1007 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1008 |
return r; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1009 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1010 |
return 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1011 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1012 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1013 |
static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1014 |
return pattern->Search(str); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1015 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1016 |
#elif CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1017 |
template <typename ValueType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1018 |
RegexType* CreatePattern(const ValueType& value) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1019 |
if (value.IsString()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1020 |
try { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1021 |
return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1022 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1023 |
catch (const std::regex_error&) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1024 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1025 |
return 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1026 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1027 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1028 |
static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1029 |
std::match_results<const Ch*> r; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1030 |
return std::regex_search(str, str + length, r, *pattern); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1031 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1032 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1033 |
template <typename ValueType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1034 |
RegexType* CreatePattern(const ValueType&) { return 0; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1035 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1036 |
static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1037 |
#endif // CEREAL_RAPIDJSON_SCHEMA_USE_STDREGEX |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1038 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1039 |
void AddType(const ValueType& type) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1040 |
if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1041 |
else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1042 |
else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1043 |
else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1044 |
else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1045 |
else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1046 |
else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1047 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1048 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1049 |
bool CreateParallelValidator(Context& context) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1050 |
if (enum_ || context.arrayUniqueness) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1051 |
context.hasher = context.factory.CreateHasher(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1052 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1053 |
if (validatorCount_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1054 |
CEREAL_RAPIDJSON_ASSERT(context.validators == 0); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1055 |
context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1056 |
context.validatorCount = validatorCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1057 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1058 |
if (allOf_.schemas) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1059 |
CreateSchemaValidators(context, allOf_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1060 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1061 |
if (anyOf_.schemas) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1062 |
CreateSchemaValidators(context, anyOf_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1063 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1064 |
if (oneOf_.schemas) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1065 |
CreateSchemaValidators(context, oneOf_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1066 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1067 |
if (not_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1068 |
context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1069 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1070 |
if (hasSchemaDependencies_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1071 |
for (SizeType i = 0; i < propertyCount_; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1072 |
if (properties_[i].dependenciesSchema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1073 |
context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1074 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1075 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1076 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1077 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1078 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1079 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1080 |
void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1081 |
for (SizeType i = 0; i < schemas.count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1082 |
context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1083 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1084 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1085 |
// O(n) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1086 |
bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1087 |
SizeType len = name.GetStringLength(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1088 |
const Ch* str = name.GetString(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1089 |
for (SizeType index = 0; index < propertyCount_; index++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1090 |
if (properties_[index].name.GetStringLength() == len && |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1091 |
(std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1092 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1093 |
*outIndex = index; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1094 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1095 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1096 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1097 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1098 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1099 |
bool CheckInt(Context& context, int64_t i) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1100 |
if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1101 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1102 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1103 |
if (!minimum_.IsNull()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1104 |
if (minimum_.IsInt64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1105 |
if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1106 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1107 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1108 |
else if (minimum_.IsUint64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1109 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1110 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1111 |
else if (!CheckDoubleMinimum(context, static_cast<double>(i))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1112 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1113 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1114 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1115 |
if (!maximum_.IsNull()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1116 |
if (maximum_.IsInt64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1117 |
if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1118 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1119 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1120 |
else if (maximum_.IsUint64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1121 |
/* do nothing */; // i <= max(int64_t) < maximum_.GetUint64() |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1122 |
else if (!CheckDoubleMaximum(context, static_cast<double>(i))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1123 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1124 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1125 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1126 |
if (!multipleOf_.IsNull()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1127 |
if (multipleOf_.IsUint64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1128 |
if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1129 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1130 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1131 |
else if (!CheckDoubleMultipleOf(context, static_cast<double>(i))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1132 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1133 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1134 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1135 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1136 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1137 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1138 |
bool CheckUint(Context& context, uint64_t i) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1139 |
if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1140 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1141 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1142 |
if (!minimum_.IsNull()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1143 |
if (minimum_.IsUint64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1144 |
if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1145 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1146 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1147 |
else if (minimum_.IsInt64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1148 |
/* do nothing */; // i >= 0 > minimum.Getint64() |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1149 |
else if (!CheckDoubleMinimum(context, static_cast<double>(i))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1150 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1151 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1152 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1153 |
if (!maximum_.IsNull()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1154 |
if (maximum_.IsUint64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1155 |
if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1156 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1157 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1158 |
else if (maximum_.IsInt64()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1159 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1160 |
else if (!CheckDoubleMaximum(context, static_cast<double>(i))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1161 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1162 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1163 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1164 |
if (!multipleOf_.IsNull()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1165 |
if (multipleOf_.IsUint64()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1166 |
if (i % multipleOf_.GetUint64() != 0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1167 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1168 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1169 |
else if (!CheckDoubleMultipleOf(context, static_cast<double>(i))) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1170 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1171 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1172 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1173 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1174 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1175 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1176 |
bool CheckDoubleMinimum(Context& context, double d) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1177 |
if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1178 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1179 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1180 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1181 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1182 |
bool CheckDoubleMaximum(Context& context, double d) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1183 |
if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1184 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1185 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1186 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1187 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1188 |
bool CheckDoubleMultipleOf(Context& context, double d) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1189 |
double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1190 |
double q = std::floor(a / b); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1191 |
double r = a - q * b; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1192 |
if (r > 0.0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1193 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1194 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1195 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1196 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1197 |
struct Property { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1198 |
Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1199 |
~Property() { AllocatorType::Free(dependencies); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1200 |
SValue name; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1201 |
const SchemaType* schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1202 |
const SchemaType* dependenciesSchema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1203 |
SizeType dependenciesValidatorIndex; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1204 |
bool* dependencies; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1205 |
bool required; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1206 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1207 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1208 |
struct PatternProperty { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1209 |
PatternProperty() : schema(), pattern() {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1210 |
~PatternProperty() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1211 |
if (pattern) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1212 |
pattern->~RegexType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1213 |
AllocatorType::Free(pattern); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1214 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1215 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1216 |
const SchemaType* schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1217 |
RegexType* pattern; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1218 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1219 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1220 |
AllocatorType* allocator_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1221 |
uint64_t* enum_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1222 |
SizeType enumCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1223 |
SchemaArray allOf_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1224 |
SchemaArray anyOf_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1225 |
SchemaArray oneOf_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1226 |
const SchemaType* not_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1227 |
unsigned type_; // bitmask of kSchemaType |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1228 |
SizeType validatorCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1229 |
SizeType notValidatorIndex_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1230 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1231 |
Property* properties_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1232 |
const SchemaType* additionalPropertiesSchema_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1233 |
PatternProperty* patternProperties_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1234 |
SizeType patternPropertyCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1235 |
SizeType propertyCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1236 |
SizeType minProperties_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1237 |
SizeType maxProperties_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1238 |
bool additionalProperties_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1239 |
bool hasDependencies_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1240 |
bool hasRequired_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1241 |
bool hasSchemaDependencies_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1242 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1243 |
const SchemaType* additionalItemsSchema_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1244 |
const SchemaType* itemsList_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1245 |
const SchemaType** itemsTuple_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1246 |
SizeType itemsTupleCount_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1247 |
SizeType minItems_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1248 |
SizeType maxItems_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1249 |
bool additionalItems_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1250 |
bool uniqueItems_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1251 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1252 |
RegexType* pattern_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1253 |
SizeType minLength_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1254 |
SizeType maxLength_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1255 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1256 |
SValue minimum_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1257 |
SValue maximum_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1258 |
SValue multipleOf_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1259 |
bool exclusiveMinimum_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1260 |
bool exclusiveMaximum_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1261 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1262 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1263 |
template<typename Stack, typename Ch> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1264 |
struct TokenHelper { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1265 |
CEREAL_RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1266 |
*documentStack.template Push<Ch>() = '/'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1267 |
char buffer[21]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1268 |
size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1269 |
for (size_t i = 0; i < length; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1270 |
*documentStack.template Push<Ch>() = buffer[i]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1271 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1272 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1273 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1274 |
// Partial specialized version for char to prevent buffer copying. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1275 |
template <typename Stack> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1276 |
struct TokenHelper<Stack, char> { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1277 |
CEREAL_RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1278 |
if (sizeof(SizeType) == 4) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1279 |
char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1280 |
*buffer++ = '/'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1281 |
const char* end = internal::u32toa(index, buffer); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1282 |
documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1283 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1284 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1285 |
char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1286 |
*buffer++ = '/'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1287 |
const char* end = internal::u64toa(index, buffer); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1288 |
documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer))); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1289 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1290 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1291 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1292 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1293 |
} // namespace internal |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1294 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1295 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1296 |
// IGenericRemoteSchemaDocumentProvider |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1297 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1298 |
template <typename SchemaDocumentType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1299 |
class IGenericRemoteSchemaDocumentProvider { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1300 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1301 |
typedef typename SchemaDocumentType::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1302 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1303 |
virtual ~IGenericRemoteSchemaDocumentProvider() {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1304 |
virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1305 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1306 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1307 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1308 |
// GenericSchemaDocument |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1309 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1310 |
//! JSON schema document. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1311 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1312 |
A JSON schema document is a compiled version of a JSON schema. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1313 |
It is basically a tree of internal::Schema. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1314 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1315 |
\note This is an immutable class (i.e. its instance cannot be modified after construction). |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1316 |
\tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1317 |
\tparam Allocator Allocator type for allocating memory of this document. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1318 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1319 |
template <typename ValueT, typename Allocator = CrtAllocator> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1320 |
class GenericSchemaDocument { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1321 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1322 |
typedef ValueT ValueType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1323 |
typedef IGenericRemoteSchemaDocumentProvider<GenericSchemaDocument> IRemoteSchemaDocumentProviderType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1324 |
typedef Allocator AllocatorType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1325 |
typedef typename ValueType::EncodingType EncodingType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1326 |
typedef typename EncodingType::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1327 |
typedef internal::Schema<GenericSchemaDocument> SchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1328 |
typedef GenericPointer<ValueType, Allocator> PointerType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1329 |
friend class internal::Schema<GenericSchemaDocument>; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1330 |
template <typename, typename, typename> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1331 |
friend class GenericSchemaValidator; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1332 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1333 |
//! Constructor. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1334 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1335 |
Compile a JSON document into schema document. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1336 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1337 |
\param document A JSON document as source. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1338 |
\param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1339 |
\param allocator An optional allocator instance for allocating memory. Can be null. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1340 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1341 |
explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1342 |
remoteProvider_(remoteProvider), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1343 |
allocator_(allocator), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1344 |
ownAllocator_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1345 |
root_(), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1346 |
schemaMap_(allocator, kInitialSchemaMapSize), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1347 |
schemaRef_(allocator, kInitialSchemaRefSize) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1348 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1349 |
if (!allocator_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1350 |
ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1351 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1352 |
// Generate root schema, it will call CreateSchema() to create sub-schemas, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1353 |
// And call AddRefSchema() if there are $ref. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1354 |
CreateSchemaRecursive(&root_, PointerType(), document, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1355 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1356 |
// Resolve $ref |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1357 |
while (!schemaRef_.Empty()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1358 |
SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1359 |
if (const SchemaType* s = GetSchema(refEntry->target)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1360 |
if (refEntry->schema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1361 |
*refEntry->schema = s; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1362 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1363 |
// Create entry in map if not exist |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1364 |
if (!GetSchema(refEntry->source)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1365 |
new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1366 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1367 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1368 |
refEntry->~SchemaRefEntry(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1369 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1370 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1371 |
CEREAL_RAPIDJSON_ASSERT(root_ != 0); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1372 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1373 |
schemaRef_.ShrinkToFit(); // Deallocate all memory for ref |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1374 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1375 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1376 |
#if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1377 |
//! Move constructor in C++11 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1378 |
GenericSchemaDocument(GenericSchemaDocument&& rhs) CEREAL_RAPIDJSON_NOEXCEPT : |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1379 |
remoteProvider_(rhs.remoteProvider_), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1380 |
allocator_(rhs.allocator_), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1381 |
ownAllocator_(rhs.ownAllocator_), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1382 |
root_(rhs.root_), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1383 |
schemaMap_(std::move(rhs.schemaMap_)), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1384 |
schemaRef_(std::move(rhs.schemaRef_)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1385 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1386 |
rhs.remoteProvider_ = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1387 |
rhs.allocator_ = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1388 |
rhs.ownAllocator_ = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1389 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1390 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1391 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1392 |
//! Destructor |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1393 |
~GenericSchemaDocument() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1394 |
while (!schemaMap_.Empty()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1395 |
schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1396 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1397 |
CEREAL_RAPIDJSON_DELETE(ownAllocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1398 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1399 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1400 |
//! Get the root schema. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1401 |
const SchemaType& GetRoot() const { return *root_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1402 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1403 |
private: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1404 |
//! Prohibit copying |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1405 |
GenericSchemaDocument(const GenericSchemaDocument&); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1406 |
//! Prohibit assignment |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1407 |
GenericSchemaDocument& operator=(const GenericSchemaDocument&); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1408 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1409 |
struct SchemaRefEntry { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1410 |
SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1411 |
PointerType source; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1412 |
PointerType target; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1413 |
const SchemaType** schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1414 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1415 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1416 |
struct SchemaEntry { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1417 |
SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1418 |
~SchemaEntry() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1419 |
if (owned) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1420 |
schema->~SchemaType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1421 |
Allocator::Free(schema); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1422 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1423 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1424 |
PointerType pointer; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1425 |
SchemaType* schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1426 |
bool owned; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1427 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1428 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1429 |
void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1430 |
if (schema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1431 |
*schema = SchemaType::GetTypeless(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1432 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1433 |
if (v.GetType() == kObjectType) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1434 |
const SchemaType* s = GetSchema(pointer); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1435 |
if (!s) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1436 |
CreateSchema(schema, pointer, v, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1437 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1438 |
for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1439 |
CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1440 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1441 |
else if (v.GetType() == kArrayType) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1442 |
for (SizeType i = 0; i < v.Size(); i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1443 |
CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1444 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1445 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1446 |
void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1447 |
CEREAL_RAPIDJSON_ASSERT(pointer.IsValid()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1448 |
if (v.IsObject()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1449 |
if (!HandleRefSchema(pointer, schema, v, document)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1450 |
SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1451 |
new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1452 |
if (schema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1453 |
*schema = s; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1454 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1455 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1456 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1457 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1458 |
bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1459 |
static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' }; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1460 |
static const ValueType kRefValue(kRefString, 4); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1461 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1462 |
typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1463 |
if (itr == v.MemberEnd()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1464 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1465 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1466 |
if (itr->value.IsString()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1467 |
SizeType len = itr->value.GetStringLength(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1468 |
if (len > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1469 |
const Ch* s = itr->value.GetString(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1470 |
SizeType i = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1471 |
while (i < len && s[i] != '#') // Find the first # |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1472 |
i++; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1473 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1474 |
if (i > 0) { // Remote reference, resolve immediately |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1475 |
if (remoteProvider_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1476 |
if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1477 |
PointerType pointer(&s[i], len - i, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1478 |
if (pointer.IsValid()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1479 |
if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1480 |
if (schema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1481 |
*schema = sc; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1482 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1483 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1484 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1485 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1486 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1487 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1488 |
else if (s[i] == '#') { // Local reference, defer resolution |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1489 |
PointerType pointer(&s[i], len - i, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1490 |
if (pointer.IsValid()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1491 |
if (const ValueType* nv = pointer.Get(document)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1492 |
if (HandleRefSchema(source, schema, *nv, document)) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1493 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1494 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1495 |
new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1496 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1497 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1498 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1499 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1500 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1501 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1502 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1503 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1504 |
const SchemaType* GetSchema(const PointerType& pointer) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1505 |
for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1506 |
if (pointer == target->pointer) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1507 |
return target->schema; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1508 |
return 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1509 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1510 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1511 |
PointerType GetPointer(const SchemaType* schema) const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1512 |
for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1513 |
if (schema == target->schema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1514 |
return target->pointer; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1515 |
return PointerType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1516 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1517 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1518 |
static const size_t kInitialSchemaMapSize = 64; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1519 |
static const size_t kInitialSchemaRefSize = 64; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1520 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1521 |
IRemoteSchemaDocumentProviderType* remoteProvider_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1522 |
Allocator *allocator_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1523 |
Allocator *ownAllocator_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1524 |
const SchemaType* root_; //!< Root schema. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1525 |
internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1526 |
internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1527 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1528 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1529 |
//! GenericSchemaDocument using Value type. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1530 |
typedef GenericSchemaDocument<Value> SchemaDocument; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1531 |
//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1532 |
typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1533 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1534 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1535 |
// GenericSchemaValidator |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1536 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1537 |
//! JSON Schema Validator. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1538 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1539 |
A SAX style JSON schema validator. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1540 |
It uses a \c GenericSchemaDocument to validate SAX events. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1541 |
It delegates the incoming SAX events to an output handler. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1542 |
The default output handler does nothing. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1543 |
It can be reused multiple times by calling \c Reset(). |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1544 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1545 |
\tparam SchemaDocumentType Type of schema document. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1546 |
\tparam OutputHandler Type of output handler. Default handler does nothing. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1547 |
\tparam StateAllocator Allocator for storing the internal validation states. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1548 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1549 |
template < |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1550 |
typename SchemaDocumentType, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1551 |
typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1552 |
typename StateAllocator = CrtAllocator> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1553 |
class GenericSchemaValidator : |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1554 |
public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1555 |
public internal::ISchemaValidator |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1556 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1557 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1558 |
typedef typename SchemaDocumentType::SchemaType SchemaType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1559 |
typedef typename SchemaDocumentType::PointerType PointerType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1560 |
typedef typename SchemaType::EncodingType EncodingType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1561 |
typedef typename EncodingType::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1562 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1563 |
//! Constructor without output handler. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1564 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1565 |
\param schemaDocument The schema document to conform to. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1566 |
\param allocator Optional allocator for storing internal validation states. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1567 |
\param schemaStackCapacity Optional initial capacity of schema path stack. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1568 |
\param documentStackCapacity Optional initial capacity of document path stack. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1569 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1570 |
GenericSchemaValidator( |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1571 |
const SchemaDocumentType& schemaDocument, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1572 |
StateAllocator* allocator = 0, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1573 |
size_t schemaStackCapacity = kDefaultSchemaStackCapacity, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1574 |
size_t documentStackCapacity = kDefaultDocumentStackCapacity) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1575 |
: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1576 |
schemaDocument_(&schemaDocument), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1577 |
root_(schemaDocument.GetRoot()), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1578 |
outputHandler_(GetNullHandler()), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1579 |
stateAllocator_(allocator), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1580 |
ownStateAllocator_(0), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1581 |
schemaStack_(allocator, schemaStackCapacity), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1582 |
documentStack_(allocator, documentStackCapacity), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1583 |
valid_(true) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1584 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1585 |
, depth_(0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1586 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1587 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1588 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1589 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1590 |
//! Constructor with output handler. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1591 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1592 |
\param schemaDocument The schema document to conform to. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1593 |
\param allocator Optional allocator for storing internal validation states. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1594 |
\param schemaStackCapacity Optional initial capacity of schema path stack. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1595 |
\param documentStackCapacity Optional initial capacity of document path stack. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1596 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1597 |
GenericSchemaValidator( |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1598 |
const SchemaDocumentType& schemaDocument, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1599 |
OutputHandler& outputHandler, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1600 |
StateAllocator* allocator = 0, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1601 |
size_t schemaStackCapacity = kDefaultSchemaStackCapacity, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1602 |
size_t documentStackCapacity = kDefaultDocumentStackCapacity) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1603 |
: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1604 |
schemaDocument_(&schemaDocument), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1605 |
root_(schemaDocument.GetRoot()), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1606 |
outputHandler_(outputHandler), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1607 |
stateAllocator_(allocator), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1608 |
ownStateAllocator_(0), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1609 |
schemaStack_(allocator, schemaStackCapacity), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1610 |
documentStack_(allocator, documentStackCapacity), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1611 |
valid_(true) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1612 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1613 |
, depth_(0) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1614 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1615 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1616 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1617 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1618 |
//! Destructor. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1619 |
~GenericSchemaValidator() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1620 |
Reset(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1621 |
CEREAL_RAPIDJSON_DELETE(ownStateAllocator_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1622 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1623 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1624 |
//! Reset the internal states. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1625 |
void Reset() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1626 |
while (!schemaStack_.Empty()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1627 |
PopSchema(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1628 |
documentStack_.Clear(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1629 |
valid_ = true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1630 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1631 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1632 |
//! Checks whether the current state is valid. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1633 |
// Implementation of ISchemaValidator |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1634 |
virtual bool IsValid() const { return valid_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1635 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1636 |
//! Gets the JSON pointer pointed to the invalid schema. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1637 |
PointerType GetInvalidSchemaPointer() const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1638 |
return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1639 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1640 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1641 |
//! Gets the keyword of invalid schema. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1642 |
const Ch* GetInvalidSchemaKeyword() const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1643 |
return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1644 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1645 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1646 |
//! Gets the JSON pointer pointed to the invalid value. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1647 |
PointerType GetInvalidDocumentPointer() const { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1648 |
return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1649 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1650 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1651 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1652 |
#define CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1653 |
CEREAL_RAPIDJSON_MULTILINEMACRO_BEGIN\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1654 |
*documentStack_.template Push<Ch>() = '\0';\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1655 |
documentStack_.template Pop<Ch>(1);\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1656 |
internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1657 |
CEREAL_RAPIDJSON_MULTILINEMACRO_END |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1658 |
#else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1659 |
#define CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1660 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1661 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1662 |
#define CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1663 |
if (!valid_) return false; \ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1664 |
if (!BeginValue() || !CurrentSchema().method arg1) {\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1665 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1666 |
return valid_ = false;\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1667 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1668 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1669 |
#define CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1670 |
for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1671 |
if (context->hasher)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1672 |
static_cast<HasherType*>(context->hasher)->method arg2;\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1673 |
if (context->validators)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1674 |
for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1675 |
static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1676 |
if (context->patternPropertiesValidators)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1677 |
for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1678 |
static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1679 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1680 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1681 |
#define CEREAL_RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1682 |
return valid_ = EndValue() && outputHandler_.method arg2 |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1683 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1684 |
#define CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1685 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1686 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1687 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1688 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1689 |
bool Null() { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext() ), ( )); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1690 |
bool Bool(bool b) { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1691 |
bool Int(int i) { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1692 |
bool Uint(unsigned u) { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1693 |
bool Int64(int64_t i) { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1694 |
bool Uint64(uint64_t u) { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1695 |
bool Double(double d) { CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1696 |
bool RawNumber(const Ch* str, SizeType length, bool copy) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1697 |
{ CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1698 |
bool String(const Ch* str, SizeType length, bool copy) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1699 |
{ CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1700 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1701 |
bool StartObject() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1702 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1703 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1704 |
return valid_ = outputHandler_.StartObject(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1705 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1706 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1707 |
bool Key(const Ch* str, SizeType len, bool copy) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1708 |
if (!valid_) return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1709 |
AppendToken(str, len); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1710 |
if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1711 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1712 |
return valid_ = outputHandler_.Key(str, len, copy); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1713 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1714 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1715 |
bool EndObject(SizeType memberCount) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1716 |
if (!valid_) return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1717 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1718 |
if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1719 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1720 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1721 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1722 |
bool StartArray() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1723 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1724 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1725 |
return valid_ = outputHandler_.StartArray(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1726 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1727 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1728 |
bool EndArray(SizeType elementCount) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1729 |
if (!valid_) return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1730 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1731 |
if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1732 |
CEREAL_RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1733 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1734 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1735 |
#undef CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1736 |
#undef CEREAL_RAPIDJSON_SCHEMA_HANDLE_BEGIN_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1737 |
#undef CEREAL_RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1738 |
#undef CEREAL_RAPIDJSON_SCHEMA_HANDLE_VALUE_ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1739 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1740 |
// Implementation of ISchemaStateFactory<SchemaType> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1741 |
virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1742 |
return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1743 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1744 |
depth_ + 1, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1745 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1746 |
&GetStateAllocator()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1747 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1748 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1749 |
virtual void DestroySchemaValidator(ISchemaValidator* validator) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1750 |
GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1751 |
v->~GenericSchemaValidator(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1752 |
StateAllocator::Free(v); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1753 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1754 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1755 |
virtual void* CreateHasher() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1756 |
return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1757 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1758 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1759 |
virtual uint64_t GetHashCode(void* hasher) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1760 |
return static_cast<HasherType*>(hasher)->GetHashCode(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1761 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1762 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1763 |
virtual void DestroryHasher(void* hasher) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1764 |
HasherType* h = static_cast<HasherType*>(hasher); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1765 |
h->~HasherType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1766 |
StateAllocator::Free(h); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1767 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1768 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1769 |
virtual void* MallocState(size_t size) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1770 |
return GetStateAllocator().Malloc(size); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1771 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1772 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1773 |
virtual void FreeState(void* p) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1774 |
return StateAllocator::Free(p); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1775 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1776 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1777 |
private: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1778 |
typedef typename SchemaType::Context Context; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1779 |
typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1780 |
typedef internal::Hasher<EncodingType, StateAllocator> HasherType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1781 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1782 |
GenericSchemaValidator( |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1783 |
const SchemaDocumentType& schemaDocument, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1784 |
const SchemaType& root, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1785 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1786 |
unsigned depth, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1787 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1788 |
StateAllocator* allocator = 0, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1789 |
size_t schemaStackCapacity = kDefaultSchemaStackCapacity, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1790 |
size_t documentStackCapacity = kDefaultDocumentStackCapacity) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1791 |
: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1792 |
schemaDocument_(&schemaDocument), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1793 |
root_(root), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1794 |
outputHandler_(GetNullHandler()), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1795 |
stateAllocator_(allocator), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1796 |
ownStateAllocator_(0), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1797 |
schemaStack_(allocator, schemaStackCapacity), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1798 |
documentStack_(allocator, documentStackCapacity), |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1799 |
valid_(true) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1800 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1801 |
, depth_(depth) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1802 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1803 |
{ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1804 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1805 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1806 |
StateAllocator& GetStateAllocator() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1807 |
if (!stateAllocator_) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1808 |
stateAllocator_ = ownStateAllocator_ = CEREAL_RAPIDJSON_NEW(StateAllocator()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1809 |
return *stateAllocator_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1810 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1811 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1812 |
bool BeginValue() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1813 |
if (schemaStack_.Empty()) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1814 |
PushSchema(root_); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1815 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1816 |
if (CurrentContext().inArray) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1817 |
internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1818 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1819 |
if (!CurrentSchema().BeginValue(CurrentContext())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1820 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1821 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1822 |
SizeType count = CurrentContext().patternPropertiesSchemaCount; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1823 |
const SchemaType** sa = CurrentContext().patternPropertiesSchemas; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1824 |
typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1825 |
bool valueUniqueness = CurrentContext().valueUniqueness; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1826 |
if (CurrentContext().valueSchema) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1827 |
PushSchema(*CurrentContext().valueSchema); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1828 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1829 |
if (count > 0) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1830 |
CurrentContext().objectPatternValidatorType = patternValidatorType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1831 |
ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1832 |
SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1833 |
va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count)); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1834 |
for (SizeType i = 0; i < count; i++) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1835 |
va[validatorCount++] = CreateSchemaValidator(*sa[i]); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1836 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1837 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1838 |
CurrentContext().arrayUniqueness = valueUniqueness; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1839 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1840 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1841 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1842 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1843 |
bool EndValue() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1844 |
if (!CurrentSchema().EndValue(CurrentContext())) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1845 |
return false; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1846 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1847 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1848 |
GenericStringBuffer<EncodingType> sb; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1849 |
schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1850 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1851 |
*documentStack_.template Push<Ch>() = '\0'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1852 |
documentStack_.template Pop<Ch>(1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1853 |
internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1854 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1855 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1856 |
uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1857 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1858 |
PopSchema(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1859 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1860 |
if (!schemaStack_.Empty()) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1861 |
Context& context = CurrentContext(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1862 |
if (context.valueUniqueness) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1863 |
HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1864 |
if (!a) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1865 |
CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1866 |
for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1867 |
if (itr->GetUint64() == h) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1868 |
CEREAL_RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1869 |
a->PushBack(h, GetStateAllocator()); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1870 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1871 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1872 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1873 |
// Remove the last token of document pointer |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1874 |
while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/') |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1875 |
; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1876 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1877 |
return true; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1878 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1879 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1880 |
void AppendToken(const Ch* str, SizeType len) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1881 |
documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1882 |
*documentStack_.template PushUnsafe<Ch>() = '/'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1883 |
for (SizeType i = 0; i < len; i++) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1884 |
if (str[i] == '~') { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1885 |
*documentStack_.template PushUnsafe<Ch>() = '~'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1886 |
*documentStack_.template PushUnsafe<Ch>() = '0'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1887 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1888 |
else if (str[i] == '/') { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1889 |
*documentStack_.template PushUnsafe<Ch>() = '~'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1890 |
*documentStack_.template PushUnsafe<Ch>() = '1'; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1891 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1892 |
else |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1893 |
*documentStack_.template PushUnsafe<Ch>() = str[i]; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1894 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1895 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1896 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1897 |
CEREAL_RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1898 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1899 |
CEREAL_RAPIDJSON_FORCEINLINE void PopSchema() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1900 |
Context* c = schemaStack_.template Pop<Context>(1); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1901 |
if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1902 |
a->~HashCodeArray(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1903 |
StateAllocator::Free(a); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1904 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1905 |
c->~Context(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1906 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1907 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1908 |
const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1909 |
Context& CurrentContext() { return *schemaStack_.template Top<Context>(); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1910 |
const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1911 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1912 |
static OutputHandler& GetNullHandler() { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1913 |
static OutputHandler nullHandler; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1914 |
return nullHandler; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1915 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1916 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1917 |
static const size_t kDefaultSchemaStackCapacity = 1024; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1918 |
static const size_t kDefaultDocumentStackCapacity = 256; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1919 |
const SchemaDocumentType* schemaDocument_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1920 |
const SchemaType& root_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1921 |
OutputHandler& outputHandler_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1922 |
StateAllocator* stateAllocator_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1923 |
StateAllocator* ownStateAllocator_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1924 |
internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1925 |
internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch) |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1926 |
bool valid_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1927 |
#if CEREAL_RAPIDJSON_SCHEMA_VERBOSE |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1928 |
unsigned depth_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1929 |
#endif |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1930 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1931 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1932 |
typedef GenericSchemaValidator<SchemaDocument> SchemaValidator; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1933 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1934 |
/////////////////////////////////////////////////////////////////////////////// |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1935 |
// SchemaValidatingReader |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1936 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1937 |
//! A helper class for parsing with validation. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1938 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1939 |
This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1940 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1941 |
\tparam parseFlags Combination of \ref ParseFlag. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1942 |
\tparam InputStream Type of input stream, implementing Stream concept. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1943 |
\tparam SourceEncoding Encoding of the input stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1944 |
\tparam SchemaDocumentType Type of schema document. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1945 |
\tparam StackAllocator Allocator type for stack. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1946 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1947 |
template < |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1948 |
unsigned parseFlags, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1949 |
typename InputStream, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1950 |
typename SourceEncoding, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1951 |
typename SchemaDocumentType = SchemaDocument, |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1952 |
typename StackAllocator = CrtAllocator> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1953 |
class SchemaValidatingReader { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1954 |
public: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1955 |
typedef typename SchemaDocumentType::PointerType PointerType; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1956 |
typedef typename InputStream::Ch Ch; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1957 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1958 |
//! Constructor |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1959 |
/*! |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1960 |
\param is Input stream. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1961 |
\param sd Schema document. |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1962 |
*/ |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1963 |
SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1964 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1965 |
template <typename Handler> |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1966 |
bool operator()(Handler& handler) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1967 |
GenericReader<SourceEncoding, typename SchemaDocumentType::EncodingType, StackAllocator> reader; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1968 |
GenericSchemaValidator<SchemaDocumentType, Handler> validator(sd_, handler); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1969 |
parseResult_ = reader.template Parse<parseFlags>(is_, validator); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1970 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1971 |
isValid_ = validator.IsValid(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1972 |
if (isValid_) { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1973 |
invalidSchemaPointer_ = PointerType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1974 |
invalidSchemaKeyword_ = 0; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1975 |
invalidDocumentPointer_ = PointerType(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1976 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1977 |
else { |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1978 |
invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1979 |
invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1980 |
invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1981 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1982 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1983 |
return parseResult_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1984 |
} |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1985 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1986 |
const ParseResult& GetParseResult() const { return parseResult_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1987 |
bool IsValid() const { return isValid_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1988 |
const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1989 |
const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1990 |
const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1991 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1992 |
private: |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1993 |
InputStream& is_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1994 |
const SchemaDocumentType& sd_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1995 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1996 |
ParseResult parseResult_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1997 |
PointerType invalidSchemaPointer_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1998 |
const Ch* invalidSchemaKeyword_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
1999 |
PointerType invalidDocumentPointer_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2000 |
bool isValid_; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2001 |
}; |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2002 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2003 |
CEREAL_RAPIDJSON_NAMESPACE_END |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2004 |
CEREAL_RAPIDJSON_DIAG_POP |
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2005 |
|
| 6c5f2c01 |
sago007 |
2017-03-15 17:56 |
2006 |
#endif // CEREAL_RAPIDJSON_SCHEMA_H_ |
|
|
1970-01-01 00:00 |
2007 |
|