mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 15:45:38 +00:00
Squashed 'external/rapidjson/' changes from 2e8f5d897..a95e013b9
a95e013b9 Stringify NaN, Inf as null if needs 973dc9c06 Avoid ptrdiff between pointers to different allocations 2a1f586ba Check for __GNUC__ definition 0e88d5e40 Eliminate missing prototypes warning 949c771b0 Resolve conflict with Windows header about max macro 083f359f5 CMakeLists: fix optflags for ppc 012be8528 Use passed in allocator. 1ce516e50 Suppress uritest 778dc8b03 fix #1 76281ff38 fix a typo in error.h: literial -> literal a98e99992 do not define operator!= in C++20 b08672d46 review comment updates 55eca66f3 code & tests for openapi 2.0 & 3.0 suppprt 80b6d1c83 small corrections for schema.h 97fd83017 attempt to fix SEH 7cad78e23 tidy up after merge from master 794248ee6 fix build break 2d87923e9 remove unnecessary templating from schema tests aa1f22251 correct address.json so tests pass ecb8d9e3a add dump of unexpected schema errors in schematest.cpp 89f6717f0 corrections 338d8defd initial 06d58b9e8 Update dtoa.h 22a62fcc2 Update allocators.h 27c3a8dc0 docs: fix simple typo, perecent -> percent 232389d4f delete unused variable 64faab2e9 gate definition of symmetric equality operators on impl, not lib 719304b11 fixes for natvis dd3f730d7 Make schema dtor robust against exceptions 781a4e667 Try to fix MSVC build. 88f8ddd70 Include conceptual change from PR 2001. 469595356 Avoid exit-time destructors. 0390b1ad5 Avoid exit-time destructors. 2b2c80450 encdedstreamtest: fix use-after-free compile error with gcc-12 1f59c69cd valuetest: fix potential write of terminating nul past the end of the destination fcb23c2db Merge pull request #2008 from agate-pris/access-to-allocator-types bdc49ad80 Merge pull request #2014 from lazydroid/dev/lenik/fix_shadowed_variables 6b500986c fix shadowed variable, take 2 3988c5e25 fix shadowed variable 386d31ab6 Allow access to the template parameter StackAllocator in the GenericDocument 79d7a448e Allow the macro RAPIDJSON_DEFAULT_STACK_ALLOCATOR to be used in any namespace 9965ab37f Allow the macro RAPIDJSON_DEFAULT_ALLOCATOR to be used in any namespace 8261c1ddf Merge pull request #1969 from MalcolmTyrrell/MalcolmTyrrell/sanitizeSchemaCode 0d78b1ce9 Merge pull request #1989 from adamcalhoon/really-fix-placement-new-alignment 1dff2abff Fix the alignment of placement new buffer for GenericValue. e4bde9774 Merge pull request #1988 from Tencent/revert-1987-fix-placement-new-alignment 88bbd87dd Revert "Fix the alignment of placement new buffer for GenericValue." bf8ca5da8 Merge pull request #1987 from adamcalhoon/fix-placement-new-alignment 5b242b6b2 Fix the alignment of placement new buffer for GenericValue. fd3dc29a5 Merge pull request #1944 from ilelann/patch-1 53602ec6b Sanitize the code in schema.h 0d4517f15 Merge pull request #1961 from jedwardsol/issue1960_arm64ec_intrinsic 060c348ea use softintrin on arm64ec 4d6cb0818 Merge pull request #1949 from ardb-uk/master 033bef3c6 Merge pull request #1 from ardb-uk/ardb-uk-patch-1 befba39af Merge pull request #2 from ardb-uk/ardb-uk-patch-1-1 4bbaf28ff Add files via upload 14f1e37f8 Resolve issue 1948 e6736d1ba Support CMake none targets git-subtree-dir: external/rapidjson git-subtree-split: a95e013b97ca6523f32da23f5095fcc9dd6067e5
This commit is contained in:
parent
6e7ab511db
commit
11e98042f4
|
@ -1,4 +1,4 @@
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
|
||||||
if(POLICY CMP0025)
|
if(POLICY CMP0025)
|
||||||
# detect Apple's Clang
|
# detect Apple's Clang
|
||||||
cmake_policy(SET CMP0025 NEW)
|
cmake_policy(SET CMP0025 NEW)
|
||||||
|
@ -68,7 +68,7 @@ endif(CCACHE_FOUND)
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
if(RAPIDJSON_ENABLE_INSTRUMENTATION_OPT AND NOT CMAKE_CROSSCOMPILING)
|
if(RAPIDJSON_ENABLE_INSTRUMENTATION_OPT AND NOT CMAKE_CROSSCOMPILING)
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
|
||||||
else()
|
else()
|
||||||
#FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
|
#FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
|
||||||
|
@ -102,7 +102,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
if(NOT CMAKE_CROSSCOMPILING)
|
if(NOT CMAKE_CROSSCOMPILING)
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "powerpc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=native")
|
||||||
else()
|
else()
|
||||||
#FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
|
#FIXME: x86 is -march=native, but doesn't mean every arch is this option. To keep original project's compatibility, I leave this except POWER.
|
||||||
|
@ -128,6 +128,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
|
||||||
|
add_definitions(-DNOMINMAX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
||||||
# CMake >= 3.10 should handle the above CMAKE_CXX_STANDARD fine, otherwise use /std:c++XX with MSVC >= 19.10
|
# CMake >= 3.10 should handle the above CMAKE_CXX_STANDARD fine, otherwise use /std:c++XX with MSVC >= 19.10
|
||||||
if (RAPIDJSON_BUILD_CXX11 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")
|
if (RAPIDJSON_BUILD_CXX11 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")
|
||||||
|
@ -241,8 +242,10 @@ INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${PROJECT_NAM
|
||||||
DESTINATION ${CMAKECONFIG_INSTALL_DIR} )
|
DESTINATION ${CMAKECONFIG_INSTALL_DIR} )
|
||||||
|
|
||||||
# Install files
|
# Install files
|
||||||
INSTALL(FILES
|
IF(CMAKE_INSTALL_DIR)
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
INSTALL(FILES
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
||||||
DESTINATION "${CMAKE_INSTALL_DIR}"
|
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
||||||
COMPONENT dev)
|
DESTINATION "${CMAKE_INSTALL_DIR}"
|
||||||
|
COMPONENT dev)
|
||||||
|
ENDIF()
|
||||||
|
|
|
@ -97,11 +97,11 @@
|
||||||
},
|
},
|
||||||
"county_type": {
|
"county_type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["Sussex", "Surrey", "Kent"]
|
"enum": ["Sussex", "Surrey", "Kent", "Narnia"]
|
||||||
},
|
},
|
||||||
"province_type": {
|
"province_type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["Quebec", "BC", "Alberta"]
|
"enum": ["Quebec", "Narnia", "BC", "Alberta"]
|
||||||
},
|
},
|
||||||
"date_type": {
|
"date_type": {
|
||||||
"pattern": "^([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?$",
|
"pattern": "^([0-9]([0-9]([0-9][1-9]|[1-9]0)|[1-9]00)|[1-9]000)(-(0[1-9]|1[0-2])(-(0[1-9]|[1-2][0-9]|3[0-1]))?)?$",
|
||||||
|
@ -132,7 +132,6 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"url_type": {
|
"url_type": {
|
||||||
"pattern": "^\\S*$",
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,30 +2,30 @@
|
||||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||||
<!-- rapidjson::GenericValue - basic support -->
|
<!-- rapidjson::GenericValue - basic support -->
|
||||||
<Type Name="rapidjson::GenericValue<*,*>">
|
<Type Name="rapidjson::GenericValue<*,*>">
|
||||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == kNullType">null</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kTypeMask) == rapidjson::kNullType">null</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kTrueFlag">true</DisplayString>
|
<DisplayString Condition="data_.f.flags == kTrueFlag">true</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kFalseFlag">false</DisplayString>
|
<DisplayString Condition="data_.f.flags == kFalseFlag">false</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kShortStringFlag">{(const Ch*)data_.ss.str,na}</DisplayString>
|
<DisplayString Condition="data_.f.flags == kShortStringFlag">{(const Ch*)data_.ss.str,na}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kTypeMask) == kStringType">{(const Ch*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF),na}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kTypeMask) == rapidjson::kStringType">{(const Ch*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF),[data_.s.length]na}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberIntFlag) == kNumberIntFlag">{data_.n.i.i}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberIntFlag) == kNumberIntFlag">{data_.n.i.i}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberUintFlag) == kNumberUintFlag">{data_.n.u.u}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberUintFlag) == kNumberUintFlag">{data_.n.u.u}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberInt64Flag) == kNumberInt64Flag">{data_.n.i64}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberInt64Flag) == kNumberInt64Flag">{data_.n.i64}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberUint64Flag) == kNumberUint64Flag">{data_.n.u64}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberUint64Flag) == kNumberUint64Flag">{data_.n.u64}</DisplayString>
|
||||||
<DisplayString Condition="(data_.f.flags & kNumberDoubleFlag) == kNumberDoubleFlag">{data_.n.d}</DisplayString>
|
<DisplayString Condition="(data_.f.flags & kNumberDoubleFlag) == kNumberDoubleFlag">{data_.n.d}</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kObjectType">Object members={data_.o.size}</DisplayString>
|
<DisplayString Condition="data_.f.flags == rapidjson::kObjectType">Object members={data_.o.size}</DisplayString>
|
||||||
<DisplayString Condition="data_.f.flags == kArrayType">Array members={data_.a.size}</DisplayString>
|
<DisplayString Condition="data_.f.flags == rapidjson::kArrayType">Array members={data_.a.size}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Condition="data_.f.flags == kObjectType" Name="[size]">data_.o.size</Item>
|
<Item Condition="data_.f.flags == rapidjson::kObjectType" Name="[size]">data_.o.size</Item>
|
||||||
<Item Condition="data_.f.flags == kObjectType" Name="[capacity]">data_.o.capacity</Item>
|
<Item Condition="data_.f.flags == rapidjson::kObjectType" Name="[capacity]">data_.o.capacity</Item>
|
||||||
<ArrayItems Condition="data_.f.flags == kObjectType">
|
<ArrayItems Condition="data_.f.flags == rapidjson::kObjectType">
|
||||||
<Size>data_.o.size</Size>
|
<Size>data_.o.size</Size>
|
||||||
<!-- NOTE: Rapidjson stores some extra data in the high bits of pointers, which is why the mask -->
|
<!-- NOTE: Rapidjson stores some extra data in the high bits of pointers, which is why the mask -->
|
||||||
<ValuePointer>(rapidjson::GenericMember<$T1,$T2>*)(((size_t)data_.o.members) & 0x0000FFFFFFFFFFFF)</ValuePointer>
|
<ValuePointer>(rapidjson::GenericMember<$T1,$T2>*)(((size_t)data_.o.members) & 0x0000FFFFFFFFFFFF)</ValuePointer>
|
||||||
</ArrayItems>
|
</ArrayItems>
|
||||||
|
|
||||||
<Item Condition="data_.f.flags == kArrayType" Name="[size]">data_.a.size</Item>
|
<Item Condition="data_.f.flags == rapidjson::kArrayType" Name="[size]">data_.a.size</Item>
|
||||||
<Item Condition="data_.f.flags == kArrayType" Name="[capacity]">data_.a.capacity</Item>
|
<Item Condition="data_.f.flags == rapidjson::kArrayType" Name="[capacity]">data_.a.capacity</Item>
|
||||||
<ArrayItems Condition="data_.f.flags == kArrayType">
|
<ArrayItems Condition="data_.f.flags == rapidjson::kArrayType">
|
||||||
<Size>data_.a.size</Size>
|
<Size>data_.a.size</Size>
|
||||||
<!-- NOTE: Rapidjson stores some extra data in the high bits of pointers, which is why the mask -->
|
<!-- NOTE: Rapidjson stores some extra data in the high bits of pointers, which is why the mask -->
|
||||||
<ValuePointer>(rapidjson::GenericValue<$T1,$T2>*)(((size_t)data_.a.elements) & 0x0000FFFFFFFFFFFF)</ValuePointer>
|
<ValuePointer>(rapidjson::GenericValue<$T1,$T2>*)(((size_t)data_.a.elements) & 0x0000FFFFFFFFFFFF)</ValuePointer>
|
||||||
|
|
|
@ -22,13 +22,15 @@
|
||||||
* RapidJSON should be fully RFC4627/ECMA-404 compliance.
|
* RapidJSON should be fully RFC4627/ECMA-404 compliance.
|
||||||
* Support JSON Pointer (RFC6901).
|
* Support JSON Pointer (RFC6901).
|
||||||
* Support JSON Schema Draft v4.
|
* Support JSON Schema Draft v4.
|
||||||
|
* Support Swagger v2 schema.
|
||||||
|
* Support OpenAPI v3.0.x schema.
|
||||||
* Support Unicode surrogate.
|
* Support Unicode surrogate.
|
||||||
* Support null character (`"\u0000"`)
|
* Support null character (`"\u0000"`)
|
||||||
* For example, `["Hello\u0000World"]` can be parsed and handled gracefully. There is API for getting/setting lengths of string.
|
* For example, `["Hello\u0000World"]` can be parsed and handled gracefully. There is API for getting/setting lengths of string.
|
||||||
* Support optional relaxed syntax.
|
* Support optional relaxed syntax.
|
||||||
* Single line (`// ...`) and multiple line (`/* ... */`) comments (`kParseCommentsFlag`).
|
* Single line (`// ...`) and multiple line (`/* ... */`) comments (`kParseCommentsFlag`).
|
||||||
* Trailing commas at the end of objects and arrays (`kParseTrailingCommasFlag`).
|
* Trailing commas at the end of objects and arrays (`kParseTrailingCommasFlag`).
|
||||||
* `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (`kParseNanAndInfFlag`)
|
* `NaN`, `Inf`, `Infinity`, `-Inf` and `-Infinity` as `double` values (`kParseNanAndInfFlag`)
|
||||||
* [NPM compliant](http://github.com/Tencent/rapidjson/blob/master/doc/npm.md).
|
* [NPM compliant](http://github.com/Tencent/rapidjson/blob/master/doc/npm.md).
|
||||||
|
|
||||||
## Unicode
|
## Unicode
|
||||||
|
|
|
@ -24,7 +24,15 @@ if (sd.Parse(schemaJson).HasParseError()) {
|
||||||
// the schema is not a valid JSON.
|
// the schema is not a valid JSON.
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
SchemaDocument schema(sd); // Compile a Document to SchemaDocument
|
SchemaDocument schema(sd); // Compile a Document to SchemaDocument
|
||||||
|
if (!schema.GetError().ObjectEmpty()) {
|
||||||
|
// there was a problem compiling the schema
|
||||||
|
StringBuffer sb;
|
||||||
|
Writer<StringBuffer> w(sb);
|
||||||
|
schema.GetError().Accept(w);
|
||||||
|
printf("Invalid schema: %s\n", sb.GetString());
|
||||||
|
}
|
||||||
// sd is no longer needed here.
|
// sd is no longer needed here.
|
||||||
|
|
||||||
Document d;
|
Document d;
|
||||||
|
|
|
@ -41,7 +41,8 @@ static std::string GetString(const ValueType& val) {
|
||||||
s << "false";
|
s << "false";
|
||||||
else if (val.IsFloat())
|
else if (val.IsFloat())
|
||||||
s << val.GetFloat();
|
s << val.GetFloat();
|
||||||
return s.str();}
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
// Create the error message for a named error
|
// Create the error message for a named error
|
||||||
// The error object can either be empty or contain at least member properties:
|
// The error object can either be empty or contain at least member properties:
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "internal/meta.h"
|
#include "internal/meta.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_CXX11
|
#if RAPIDJSON_HAS_CXX11
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
@ -433,7 +434,7 @@ namespace internal {
|
||||||
template<typename T, typename A>
|
template<typename T, typename A>
|
||||||
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
|
inline T* Realloc(A& a, T* old_p, size_t old_n, size_t new_n)
|
||||||
{
|
{
|
||||||
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= SIZE_MAX / sizeof(T) && new_n <= SIZE_MAX / sizeof(T));
|
RAPIDJSON_NOEXCEPT_ASSERT(old_n <= (std::numeric_limits<size_t>::max)() / sizeof(T) && new_n <= (std::numeric_limits<size_t>::max)() / sizeof(T));
|
||||||
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
|
return static_cast<T*>(a.Realloc(old_p, old_n * sizeof(T), new_n * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ class GenericDocument;
|
||||||
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||||
*/
|
*/
|
||||||
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
|
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
|
||||||
#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
|
#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||||
|
@ -85,7 +85,7 @@ class GenericDocument;
|
||||||
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
User can define this to use CrtAllocator or MemoryPoolAllocator.
|
||||||
*/
|
*/
|
||||||
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
|
||||||
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
|
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
|
||||||
|
@ -1078,6 +1078,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
|
||||||
|
|
||||||
|
#ifndef __cpp_impl_three_way_comparison
|
||||||
//! Not-equal-to operator
|
//! Not-equal-to operator
|
||||||
/*! \return !(*this == rhs)
|
/*! \return !(*this == rhs)
|
||||||
*/
|
*/
|
||||||
|
@ -1092,7 +1093,6 @@ public:
|
||||||
*/
|
*/
|
||||||
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
|
||||||
|
|
||||||
#ifndef __cpp_lib_three_way_comparison
|
|
||||||
//! Equal-to operator with arbitrary types (symmetric version)
|
//! Equal-to operator with arbitrary types (symmetric version)
|
||||||
/*! \return (rhs == lhs)
|
/*! \return (rhs == lhs)
|
||||||
*/
|
*/
|
||||||
|
@ -1230,13 +1230,28 @@ public:
|
||||||
else {
|
else {
|
||||||
RAPIDJSON_ASSERT(false); // see above note
|
RAPIDJSON_ASSERT(false); // see above note
|
||||||
|
|
||||||
// This will generate -Wexit-time-destructors in clang
|
#if RAPIDJSON_HAS_CXX11
|
||||||
// static GenericValue NullValue;
|
// Use thread-local storage to prevent races between threads.
|
||||||
// return NullValue;
|
// Use static buffer and placement-new to prevent destruction, with
|
||||||
|
// alignas() to ensure proper alignment.
|
||||||
// Use static buffer and placement-new to prevent destruction
|
alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
|
||||||
static char buffer[sizeof(GenericValue)];
|
|
||||||
return *new (buffer) GenericValue();
|
return *new (buffer) GenericValue();
|
||||||
|
#elif defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
|
// There's no way to solve both thread locality and proper alignment
|
||||||
|
// simultaneously.
|
||||||
|
__declspec(thread) static char buffer[sizeof(GenericValue)];
|
||||||
|
return *new (buffer) GenericValue();
|
||||||
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
// This will generate -Wexit-time-destructors in clang, but that's
|
||||||
|
// better than having under-alignment.
|
||||||
|
__thread static GenericValue buffer;
|
||||||
|
return buffer;
|
||||||
|
#else
|
||||||
|
// Don't know what compiler this is, so don't know how to ensure
|
||||||
|
// thread-locality.
|
||||||
|
static GenericValue buffer;
|
||||||
|
return buffer;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template <typename SourceAllocator>
|
template <typename SourceAllocator>
|
||||||
|
@ -2486,6 +2501,7 @@ public:
|
||||||
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
|
||||||
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
|
typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
|
||||||
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
||||||
|
typedef StackAllocator StackAllocatorType; //!< StackAllocator type from template parameter.
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
/*! Creates an empty document of specified type.
|
/*! Creates an empty document of specified type.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
@ -7,9 +7,9 @@
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ERROR_EN_H_
|
#ifndef RAPIDJSON_ERROR_EN_H_
|
||||||
|
@ -39,13 +39,13 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro
|
||||||
|
|
||||||
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
|
||||||
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
|
||||||
|
|
||||||
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
|
||||||
|
|
||||||
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
|
||||||
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
|
||||||
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
|
||||||
|
|
||||||
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
|
||||||
|
|
||||||
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
|
||||||
|
@ -104,15 +104,69 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetValidateError_En(ValidateErrorCode val
|
||||||
case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
|
case kValidateErrorType: return RAPIDJSON_ERROR_STRING("Property has a type '%actual' that is not in the following list: '%expected'.");
|
||||||
|
|
||||||
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
|
case kValidateErrorOneOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'oneOf', refer to following errors.");
|
||||||
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf'.");
|
case kValidateErrorOneOfMatch: return RAPIDJSON_ERROR_STRING("Property matched more than one of the sub-schemas specified by 'oneOf', indices '%matches'.");
|
||||||
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
|
case kValidateErrorAllOf: return RAPIDJSON_ERROR_STRING("Property did not match all of the sub-schemas specified by 'allOf', refer to following errors.");
|
||||||
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
|
case kValidateErrorAnyOf: return RAPIDJSON_ERROR_STRING("Property did not match any of the sub-schemas specified by 'anyOf', refer to following errors.");
|
||||||
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
|
case kValidateErrorNot: return RAPIDJSON_ERROR_STRING("Property matched the sub-schema specified by 'not'.");
|
||||||
|
|
||||||
|
case kValidateErrorReadOnly: return RAPIDJSON_ERROR_STRING("Property is read-only but has been provided when validation is for writing.");
|
||||||
|
case kValidateErrorWriteOnly: return RAPIDJSON_ERROR_STRING("Property is write-only but has been provided when validation is for reading.");
|
||||||
|
|
||||||
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Maps error code of schema document compilation into error message.
|
||||||
|
/*!
|
||||||
|
\ingroup RAPIDJSON_ERRORS
|
||||||
|
\param schemaErrorCode Error code obtained from compiling the schema document.
|
||||||
|
\return the error message.
|
||||||
|
\note User can make a copy of this function for localization.
|
||||||
|
Using switch-case is safer for future modification of error codes.
|
||||||
|
*/
|
||||||
|
inline const RAPIDJSON_ERROR_CHARTYPE* GetSchemaError_En(SchemaErrorCode schemaErrorCode) {
|
||||||
|
switch (schemaErrorCode) {
|
||||||
|
case kSchemaErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||||
|
|
||||||
|
case kSchemaErrorStartUnknown: return RAPIDJSON_ERROR_STRING("Pointer '%value' to start of schema does not resolve to a location in the document.");
|
||||||
|
case kSchemaErrorRefPlainName: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' must be a JSON pointer.");
|
||||||
|
case kSchemaErrorRefInvalid: return RAPIDJSON_ERROR_STRING("$ref must not be an empty string.");
|
||||||
|
case kSchemaErrorRefPointerInvalid: return RAPIDJSON_ERROR_STRING("$ref fragment '%value' is not a valid JSON pointer at offset '%offset'.");
|
||||||
|
case kSchemaErrorRefUnknown: return RAPIDJSON_ERROR_STRING("$ref '%value' does not resolve to a location in the target document.");
|
||||||
|
case kSchemaErrorRefCyclical: return RAPIDJSON_ERROR_STRING("$ref '%value' is cyclical.");
|
||||||
|
case kSchemaErrorRefNoRemoteProvider: return RAPIDJSON_ERROR_STRING("$ref is remote but there is no remote provider.");
|
||||||
|
case kSchemaErrorRefNoRemoteSchema: return RAPIDJSON_ERROR_STRING("$ref '%value' is remote but the remote provider did not return a schema.");
|
||||||
|
case kSchemaErrorRegexInvalid: return RAPIDJSON_ERROR_STRING("Invalid regular expression '%value' in 'pattern' or 'patternProperties'.");
|
||||||
|
case kSchemaErrorSpecUnknown: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not recognized.");
|
||||||
|
case kSchemaErrorSpecUnsupported: return RAPIDJSON_ERROR_STRING("JSON schema draft or OpenAPI version is not supported.");
|
||||||
|
case kSchemaErrorSpecIllegal: return RAPIDJSON_ERROR_STRING("Both JSON schema draft and OpenAPI version found in document.");
|
||||||
|
case kSchemaErrorReadOnlyAndWriteOnly: return RAPIDJSON_ERROR_STRING("Property must not be both 'readOnly' and 'writeOnly'.");
|
||||||
|
|
||||||
|
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Maps error code of pointer parse into error message.
|
||||||
|
/*!
|
||||||
|
\ingroup RAPIDJSON_ERRORS
|
||||||
|
\param pointerParseErrorCode Error code obtained from pointer parse.
|
||||||
|
\return the error message.
|
||||||
|
\note User can make a copy of this function for localization.
|
||||||
|
Using switch-case is safer for future modification of error codes.
|
||||||
|
*/
|
||||||
|
inline const RAPIDJSON_ERROR_CHARTYPE* GetPointerParseError_En(PointerParseErrorCode pointerParseErrorCode) {
|
||||||
|
switch (pointerParseErrorCode) {
|
||||||
|
case kPointerParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
|
||||||
|
|
||||||
|
case kPointerParseErrorTokenMustBeginWithSolidus: return RAPIDJSON_ERROR_STRING("A token must begin with a '/'.");
|
||||||
|
case kPointerParseErrorInvalidEscape: return RAPIDJSON_ERROR_STRING("Invalid escape.");
|
||||||
|
case kPointerParseErrorInvalidPercentEncoding: return RAPIDJSON_ERROR_STRING("Invalid percent encoding in URI fragment.");
|
||||||
|
case kPointerParseErrorCharacterMustPercentEncode: return RAPIDJSON_ERROR_STRING("A character must be percent encoded in a URI fragment.");
|
||||||
|
|
||||||
|
default: return RAPIDJSON_ERROR_STRING("Unknown error.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
@ -7,9 +7,9 @@
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_ERROR_ERROR_H_
|
#ifndef RAPIDJSON_ERROR_ERROR_H_
|
||||||
|
@ -42,7 +42,7 @@ RAPIDJSON_DIAG_OFF(padded)
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// RAPIDJSON_ERROR_STRING
|
// RAPIDJSON_ERROR_STRING
|
||||||
|
|
||||||
//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
//! Macro for converting string literal to \ref RAPIDJSON_ERROR_CHARTYPE[].
|
||||||
/*! \ingroup RAPIDJSON_ERRORS
|
/*! \ingroup RAPIDJSON_ERRORS
|
||||||
By default this conversion macro does nothing.
|
By default this conversion macro does nothing.
|
||||||
On Windows, user can define this macro as \c _T(x) for supporting both
|
On Windows, user can define this macro as \c _T(x) for supporting both
|
||||||
|
@ -185,14 +185,17 @@ enum ValidateErrorCode {
|
||||||
kValidateErrorPatternProperties, //!< See other errors.
|
kValidateErrorPatternProperties, //!< See other errors.
|
||||||
kValidateErrorDependencies, //!< Object has missing property or schema dependencies.
|
kValidateErrorDependencies, //!< Object has missing property or schema dependencies.
|
||||||
|
|
||||||
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values
|
kValidateErrorEnum, //!< Property has a value that is not one of its allowed enumerated values.
|
||||||
kValidateErrorType, //!< Property has a type that is not allowed by the schema..
|
kValidateErrorType, //!< Property has a type that is not allowed by the schema.
|
||||||
|
|
||||||
kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'.
|
kValidateErrorOneOf, //!< Property did not match any of the sub-schemas specified by 'oneOf'.
|
||||||
kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
|
kValidateErrorOneOfMatch, //!< Property matched more than one of the sub-schemas specified by 'oneOf'.
|
||||||
kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'.
|
kValidateErrorAllOf, //!< Property did not match all of the sub-schemas specified by 'allOf'.
|
||||||
kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'.
|
kValidateErrorAnyOf, //!< Property did not match any of the sub-schemas specified by 'anyOf'.
|
||||||
kValidateErrorNot //!< Property matched the sub-schema specified by 'not'.
|
kValidateErrorNot, //!< Property matched the sub-schema specified by 'not'.
|
||||||
|
|
||||||
|
kValidateErrorReadOnly, //!< Property is read-only but has been provided when validation is for writing
|
||||||
|
kValidateErrorWriteOnly //!< Property is write-only but has been provided when validation is for reading
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Function pointer type of GetValidateError().
|
//! Function pointer type of GetValidateError().
|
||||||
|
@ -207,6 +210,72 @@ enum ValidateErrorCode {
|
||||||
*/
|
*/
|
||||||
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
|
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetValidateErrorFunc)(ValidateErrorCode);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// SchemaErrorCode
|
||||||
|
|
||||||
|
//! Error codes when validating.
|
||||||
|
/*! \ingroup RAPIDJSON_ERRORS
|
||||||
|
\see GenericSchemaValidator
|
||||||
|
*/
|
||||||
|
enum SchemaErrorCode {
|
||||||
|
kSchemaErrorNone = 0, //!< No error.
|
||||||
|
|
||||||
|
kSchemaErrorStartUnknown, //!< Pointer to start of schema does not resolve to a location in the document
|
||||||
|
kSchemaErrorRefPlainName, //!< $ref fragment must be a JSON pointer
|
||||||
|
kSchemaErrorRefInvalid, //!< $ref must not be an empty string
|
||||||
|
kSchemaErrorRefPointerInvalid, //!< $ref fragment is not a valid JSON pointer at offset
|
||||||
|
kSchemaErrorRefUnknown, //!< $ref does not resolve to a location in the target document
|
||||||
|
kSchemaErrorRefCyclical, //!< $ref is cyclical
|
||||||
|
kSchemaErrorRefNoRemoteProvider, //!< $ref is remote but there is no remote provider
|
||||||
|
kSchemaErrorRefNoRemoteSchema, //!< $ref is remote but the remote provider did not return a schema
|
||||||
|
kSchemaErrorRegexInvalid, //!< Invalid regular expression in 'pattern' or 'patternProperties'
|
||||||
|
kSchemaErrorSpecUnknown, //!< JSON schema draft or OpenAPI version is not recognized
|
||||||
|
kSchemaErrorSpecUnsupported, //!< JSON schema draft or OpenAPI version is not supported
|
||||||
|
kSchemaErrorSpecIllegal, //!< Both JSON schema draft and OpenAPI version found in document
|
||||||
|
kSchemaErrorReadOnlyAndWriteOnly //!< Property must not be both 'readOnly' and 'writeOnly'
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Function pointer type of GetSchemaError().
|
||||||
|
/*! \ingroup RAPIDJSON_ERRORS
|
||||||
|
|
||||||
|
This is the prototype for \c GetSchemaError_X(), where \c X is a locale.
|
||||||
|
User can dynamically change locale in runtime, e.g.:
|
||||||
|
\code
|
||||||
|
GetSchemaErrorFunc GetSchemaError = GetSchemaError_En; // or whatever
|
||||||
|
const RAPIDJSON_ERROR_CHARTYPE* s = GetSchemaError(validator.GetInvalidSchemaCode());
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetSchemaErrorFunc)(SchemaErrorCode);
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PointerParseErrorCode
|
||||||
|
|
||||||
|
//! Error code of JSON pointer parsing.
|
||||||
|
/*! \ingroup RAPIDJSON_ERRORS
|
||||||
|
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
|
||||||
|
*/
|
||||||
|
enum PointerParseErrorCode {
|
||||||
|
kPointerParseErrorNone = 0, //!< The parse is successful
|
||||||
|
|
||||||
|
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
|
||||||
|
kPointerParseErrorInvalidEscape, //!< Invalid escape
|
||||||
|
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
|
||||||
|
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Function pointer type of GetPointerParseError().
|
||||||
|
/*! \ingroup RAPIDJSON_ERRORS
|
||||||
|
|
||||||
|
This is the prototype for \c GetPointerParseError_X(), where \c X is a locale.
|
||||||
|
User can dynamically change locale in runtime, e.g.:
|
||||||
|
\code
|
||||||
|
GetPointerParseErrorFunc GetPointerParseError = GetPointerParseError_En; // or whatever
|
||||||
|
const RAPIDJSON_ERROR_CHARTYPE* s = GetPointerParseError(pointer.GetParseErrorCode());
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetPointerParseErrorFunc)(PointerParseErrorCode);
|
||||||
|
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_END
|
RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_M_AMD64)
|
||||||
#include <intrin.h> // for _umul128
|
#include <intrin.h> // for _umul128
|
||||||
|
#if !defined(_ARM64EC_)
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
|
#else
|
||||||
|
#pragma comment(lib,"softintrin")
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
@ -255,7 +259,7 @@ private:
|
||||||
if (low < k)
|
if (low < k)
|
||||||
(*outHigh)++;
|
(*outHigh)++;
|
||||||
return low;
|
return low;
|
||||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||||
__extension__ typedef unsigned __int128 uint128;
|
__extension__ typedef unsigned __int128 uint128;
|
||||||
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
|
uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
|
||||||
p += k;
|
p += k;
|
||||||
|
|
|
@ -25,7 +25,11 @@
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
#if !defined(_ARM64EC_)
|
||||||
#pragma intrinsic(_umul128)
|
#pragma intrinsic(_umul128)
|
||||||
|
#else
|
||||||
|
#pragma comment(lib,"softintrin")
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RAPIDJSON_NAMESPACE_BEGIN
|
RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
@ -75,7 +79,7 @@ struct DiyFp {
|
||||||
if (l & (uint64_t(1) << 63)) // rounding
|
if (l & (uint64_t(1) << 63)) // rounding
|
||||||
h++;
|
h++;
|
||||||
return DiyFp(h, e + rhs.e + 64);
|
return DiyFp(h, e + rhs.e + 64);
|
||||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||||
__extension__ typedef unsigned __int128 uint128;
|
__extension__ typedef unsigned __int128 uint128;
|
||||||
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
|
uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
|
||||||
uint64_t h = static_cast<uint64_t>(p >> 64);
|
uint64_t h = static_cast<uint64_t>(p >> 64);
|
||||||
|
|
|
@ -58,11 +58,11 @@ inline int CountDecimalDigit32(uint32_t n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
||||||
static const uint64_t kPow10[] = { 1U, 10U, 100U, 1000U, 10000U, 100000U, 1000000U, 10000000U, 100000000U,
|
static const uint64_t kPow10[] = { 1ULL, 10ULL, 100ULL, 1000ULL, 10000ULL, 100000ULL, 1000000ULL, 10000000ULL, 100000000ULL,
|
||||||
1000000000U, 10000000000U, 100000000000U, 1000000000000U,
|
1000000000ULL, 10000000000ULL, 100000000000ULL, 1000000000000ULL,
|
||||||
10000000000000U, 100000000000000U, 1000000000000000U,
|
10000000000000ULL, 100000000000000ULL, 1000000000000000ULL,
|
||||||
10000000000000000U, 100000000000000000U, 1000000000000000000U,
|
10000000000000000ULL, 100000000000000000ULL, 1000000000000000000ULL,
|
||||||
10000000000000000000U };
|
10000000000000000000ULL };
|
||||||
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
||||||
const DiyFp wp_w = Mp - W;
|
const DiyFp wp_w = Mp - W;
|
||||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "document.h"
|
#include "document.h"
|
||||||
#include "uri.h"
|
#include "uri.h"
|
||||||
#include "internal/itoa.h"
|
#include "internal/itoa.h"
|
||||||
|
#include "error/error.h" // PointerParseErrorCode
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
RAPIDJSON_DIAG_PUSH
|
RAPIDJSON_DIAG_PUSH
|
||||||
|
@ -31,19 +32,6 @@ RAPIDJSON_NAMESPACE_BEGIN
|
||||||
|
|
||||||
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
|
||||||
|
|
||||||
//! Error code of parsing.
|
|
||||||
/*! \ingroup RAPIDJSON_ERRORS
|
|
||||||
\see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
|
|
||||||
*/
|
|
||||||
enum PointerParseErrorCode {
|
|
||||||
kPointerParseErrorNone = 0, //!< The parse is successful
|
|
||||||
|
|
||||||
kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
|
|
||||||
kPointerParseErrorInvalidEscape, //!< Invalid escape
|
|
||||||
kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
|
|
||||||
kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// GenericPointer
|
// GenericPointer
|
||||||
|
|
||||||
|
@ -69,10 +57,10 @@ enum PointerParseErrorCode {
|
||||||
supplied tokens eliminates these.
|
supplied tokens eliminates these.
|
||||||
|
|
||||||
GenericPointer depends on GenericDocument and GenericValue.
|
GenericPointer depends on GenericDocument and GenericValue.
|
||||||
|
|
||||||
\tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
|
\tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
|
||||||
\tparam Allocator The allocator type for allocating memory for internal representation.
|
\tparam Allocator The allocator type for allocating memory for internal representation.
|
||||||
|
|
||||||
\note GenericPointer uses same encoding of ValueType.
|
\note GenericPointer uses same encoding of ValueType.
|
||||||
However, Allocator of GenericPointer is independent of Allocator of Value.
|
However, Allocator of GenericPointer is independent of Allocator of Value.
|
||||||
*/
|
*/
|
||||||
|
@ -84,7 +72,7 @@ public:
|
||||||
typedef GenericUri<ValueType, Allocator> UriType;
|
typedef GenericUri<ValueType, Allocator> UriType;
|
||||||
|
|
||||||
|
|
||||||
//! A token is the basic units of internal representation.
|
//! A token is the basic units of internal representation.
|
||||||
/*!
|
/*!
|
||||||
A JSON pointer string representation "/foo/123" is parsed to two tokens:
|
A JSON pointer string representation "/foo/123" is parsed to two tokens:
|
||||||
"foo" and 123. 123 will be represented in both numeric form and string form.
|
"foo" and 123. 123 will be represented in both numeric form and string form.
|
||||||
|
@ -701,7 +689,7 @@ public:
|
||||||
ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
|
ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
|
||||||
return GetWithDefault(document, defaultValue, document.GetAllocator());
|
return GetWithDefault(document, defaultValue, document.GetAllocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
//! Query a value in a document with default std::basic_string.
|
//! Query a value in a document with default std::basic_string.
|
||||||
template <typename stackAllocator>
|
template <typename stackAllocator>
|
||||||
|
@ -902,10 +890,16 @@ private:
|
||||||
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
|
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust pointers to name buffer
|
// The names of each token point to a string in the nameBuffer_. The
|
||||||
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
|
// previous memcpy copied over string pointers into the rhs.nameBuffer_,
|
||||||
for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
|
// but they should point to the strings in the new nameBuffer_.
|
||||||
t->name += diff;
|
for (size_t i = 0; i < rhs.tokenCount_; ++i) {
|
||||||
|
// The offset between the string address and the name buffer should
|
||||||
|
// still be constant, so we can just get this offset and set each new
|
||||||
|
// token name according the new buffer start + the known offset.
|
||||||
|
std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_;
|
||||||
|
tokens_[i].name = nameBuffer_ + name_offset;
|
||||||
|
}
|
||||||
|
|
||||||
return nameBuffer_ + nameBufferSize;
|
return nameBuffer_ + nameBufferSize;
|
||||||
}
|
}
|
||||||
|
@ -995,7 +989,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
// Escaping "~0" -> '~', "~1" -> '/'
|
// Escaping "~0" -> '~', "~1" -> '/'
|
||||||
if (c == '~') {
|
if (c == '~') {
|
||||||
if (i < length) {
|
if (i < length) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Tencent is pleased to support the open source community by making RapidJSON available.
|
// Tencent is pleased to support the open source community by making RapidJSON available.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
|
||||||
//
|
//
|
||||||
// Licensed under the MIT License (the "License"); you may not use this file except
|
// Licensed under the MIT License (the "License"); you may not use this file except
|
||||||
|
@ -7,9 +7,9 @@
|
||||||
//
|
//
|
||||||
// http://opensource.org/licenses/MIT
|
// http://opensource.org/licenses/MIT
|
||||||
//
|
//
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
#ifndef RAPIDJSON_RAPIDJSON_H_
|
#ifndef RAPIDJSON_RAPIDJSON_H_
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
/*!\file rapidjson.h
|
/*!\file rapidjson.h
|
||||||
\brief common definitions and configuration
|
\brief common definitions and configuration
|
||||||
|
|
||||||
\see RAPIDJSON_CONFIG
|
\see RAPIDJSON_CONFIG
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef RAPIDJSON_NO_INT64DEFINE
|
#ifndef RAPIDJSON_NO_INT64DEFINE
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||||
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
|
#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
|
||||||
#include "msinttypes/stdint.h"
|
#include "msinttypes/stdint.h"
|
||||||
#include "msinttypes/inttypes.h"
|
#include "msinttypes/inttypes.h"
|
||||||
#else
|
#else
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
|
||||||
# define RAPIDJSON_ENDIAN
|
# define RAPIDJSON_ENDIAN
|
||||||
# else
|
# else
|
||||||
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
# error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN.
|
||||||
# endif
|
# endif
|
||||||
#endif // RAPIDJSON_ENDIAN
|
#endif // RAPIDJSON_ENDIAN
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ RAPIDJSON_NAMESPACE_END
|
||||||
|
|
||||||
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
|
||||||
|
|
||||||
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
|
||||||
#define RAPIDJSON_MULTILINEMACRO_END \
|
#define RAPIDJSON_MULTILINEMACRO_END \
|
||||||
} while((void)0, 0)
|
} while((void)0, 0)
|
||||||
|
|
||||||
|
@ -731,7 +731,7 @@ enum Type {
|
||||||
kFalseType = 1, //!< false
|
kFalseType = 1, //!< false
|
||||||
kTrueType = 2, //!< true
|
kTrueType = 2, //!< true
|
||||||
kObjectType = 3, //!< object
|
kObjectType = 3, //!< object
|
||||||
kArrayType = 4, //!< array
|
kArrayType = 4, //!< array
|
||||||
kStringType = 5, //!< string
|
kStringType = 5, //!< string
|
||||||
kNumberType = 6 //!< number
|
kNumberType = 6 //!< number
|
||||||
};
|
};
|
||||||
|
|
|
@ -1433,7 +1433,7 @@ private:
|
||||||
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
|
class NumberStream<InputStream, StackCharacter, true, false> : public NumberStream<InputStream, StackCharacter, false, false> {
|
||||||
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
|
typedef NumberStream<InputStream, StackCharacter, false, false> Base;
|
||||||
public:
|
public:
|
||||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
|
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s), stackStream(reader.stack_) {}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE Ch TakePush() {
|
RAPIDJSON_FORCEINLINE Ch TakePush() {
|
||||||
stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
|
stackStream.Put(static_cast<StackCharacter>(Base::is.Peek()));
|
||||||
|
@ -1459,7 +1459,7 @@ private:
|
||||||
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
|
class NumberStream<InputStream, StackCharacter, true, true> : public NumberStream<InputStream, StackCharacter, true, false> {
|
||||||
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
|
typedef NumberStream<InputStream, StackCharacter, true, false> Base;
|
||||||
public:
|
public:
|
||||||
NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
|
NumberStream(GenericReader& reader, InputStream& s) : Base(reader, s) {}
|
||||||
|
|
||||||
RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
|
RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
|
||||||
};
|
};
|
||||||
|
@ -1694,7 +1694,7 @@ private:
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
|
SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
|
||||||
GenericStringStream<UTF8<NumberCharacter>> srcStream(s.Pop());
|
GenericStringStream<UTF8<NumberCharacter> > srcStream(s.Pop());
|
||||||
StackStream<typename TargetEncoding::Ch> dstStream(stack_);
|
StackStream<typename TargetEncoding::Ch> dstStream(stack_);
|
||||||
while (numCharsToCopy--) {
|
while (numCharsToCopy--) {
|
||||||
Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
|
Transcoder<UTF8<typename TargetEncoding::Ch>, TargetEncoding>::Transcode(srcStream, dstStream);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,6 +67,7 @@ enum WriteFlag {
|
||||||
kWriteNoFlags = 0, //!< No flags are set.
|
kWriteNoFlags = 0, //!< No flags are set.
|
||||||
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
|
kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
|
||||||
kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
|
kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
|
||||||
|
kWriteNanAndInfNullFlag = 4, //!< Allow writing of Infinity, -Infinity and NaN as null.
|
||||||
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
|
kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -350,6 +351,11 @@ protected:
|
||||||
if (internal::Double(d).IsNanOrInf()) {
|
if (internal::Double(d).IsNanOrInf()) {
|
||||||
if (!(writeFlags & kWriteNanAndInfFlag))
|
if (!(writeFlags & kWriteNanAndInfFlag))
|
||||||
return false;
|
return false;
|
||||||
|
if (writeFlags & kWriteNanAndInfNullFlag) {
|
||||||
|
PutReserve(*os_, 4);
|
||||||
|
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (internal::Double(d).IsNan()) {
|
if (internal::Double(d).IsNan()) {
|
||||||
PutReserve(*os_, 3);
|
PutReserve(*os_, 3);
|
||||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||||
|
@ -548,6 +554,11 @@ inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
||||||
// Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
|
// Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
|
||||||
if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
|
if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
|
||||||
return false;
|
return false;
|
||||||
|
if (kWriteDefaultFlags & kWriteNanAndInfNullFlag) {
|
||||||
|
PutReserve(*os_, 4);
|
||||||
|
PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (internal::Double(d).IsNan()) {
|
if (internal::Double(d).IsNan()) {
|
||||||
PutReserve(*os_, 3);
|
PutReserve(*os_, 3);
|
||||||
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
|
||||||
|
|
|
@ -20,7 +20,7 @@ using namespace rapidjson;
|
||||||
|
|
||||||
// static const char json[] = "{\"string\"\n\n:\"my string\",\"array\"\n:[\"1\", \"2\", \"3\"]}";
|
// static const char json[] = "{\"string\"\n\n:\"my string\",\"array\"\n:[\"1\", \"2\", \"3\"]}";
|
||||||
|
|
||||||
bool testJson(const char *json, size_t &line, size_t &col) {
|
static bool testJson(const char *json, size_t &line, size_t &col) {
|
||||||
StringStream ss(json);
|
StringStream ss(json);
|
||||||
CursorStreamWrapper<StringStream> csw(ss);
|
CursorStreamWrapper<StringStream> csw(ss);
|
||||||
Document document;
|
Document document;
|
||||||
|
|
|
@ -113,8 +113,8 @@ protected:
|
||||||
EXPECT_EQ(expected, actual);
|
EXPECT_EQ(expected, actual);
|
||||||
}
|
}
|
||||||
EXPECT_EQ('\0', s.Peek());
|
EXPECT_EQ('\0', s.Peek());
|
||||||
free(data);
|
|
||||||
EXPECT_EQ(size, eis.Tell());
|
EXPECT_EQ(size, eis.Tell());
|
||||||
|
free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void TestFileStream() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(filename, "r");
|
fp = fopen(filename, "r");
|
||||||
ASSERT_TRUE( fp != NULL );
|
ASSERT_TRUE( fp != NULL );
|
||||||
for (const char* p = s; *p; p++)
|
for (const char* p = s; *p; p++)
|
||||||
EXPECT_EQ(*p, static_cast<char>(fgetc(fp)));
|
EXPECT_EQ(*p, static_cast<char>(fgetc(fp)));
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
|
@ -303,7 +303,7 @@ TEST(Pointer, Parse_URIFragment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Decode UTF-8 perecent encoding to UTF-8
|
// Decode UTF-8 percent encoding to UTF-8
|
||||||
Pointer p("#/%C2%A2");
|
Pointer p("#/%C2%A2");
|
||||||
EXPECT_TRUE(p.IsValid());
|
EXPECT_TRUE(p.IsValid());
|
||||||
EXPECT_EQ(1u, p.GetTokenCount());
|
EXPECT_EQ(1u, p.GetTokenCount());
|
||||||
|
@ -311,7 +311,7 @@ TEST(Pointer, Parse_URIFragment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Decode UTF-8 perecent encoding to UTF-16
|
// Decode UTF-8 percent encoding to UTF-16
|
||||||
GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
|
GenericPointer<GenericValue<UTF16<> > > p(L"#/%C2%A2");
|
||||||
EXPECT_TRUE(p.IsValid());
|
EXPECT_TRUE(p.IsValid());
|
||||||
EXPECT_EQ(1u, p.GetTokenCount());
|
EXPECT_EQ(1u, p.GetTokenCount());
|
||||||
|
@ -320,7 +320,7 @@ TEST(Pointer, Parse_URIFragment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Decode UTF-8 perecent encoding to UTF-16
|
// Decode UTF-8 percent encoding to UTF-16
|
||||||
GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
|
GenericPointer<GenericValue<UTF16<> > > p(L"#/%E2%82%AC");
|
||||||
EXPECT_TRUE(p.IsValid());
|
EXPECT_TRUE(p.IsValid());
|
||||||
EXPECT_EQ(1u, p.GetTokenCount());
|
EXPECT_EQ(1u, p.GetTokenCount());
|
||||||
|
@ -475,7 +475,7 @@ TEST(Pointer, CopyConstructor) {
|
||||||
EXPECT_EQ(1u, q.GetTokens()[1].length);
|
EXPECT_EQ(1u, q.GetTokens()[1].length);
|
||||||
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
||||||
EXPECT_EQ(0u, q.GetTokens()[1].index);
|
EXPECT_EQ(0u, q.GetTokens()[1].index);
|
||||||
|
|
||||||
// Copied pointer needs to have its own allocator
|
// Copied pointer needs to have its own allocator
|
||||||
EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
|
EXPECT_NE(&p.GetAllocator(), &q.GetAllocator());
|
||||||
}
|
}
|
||||||
|
@ -1727,4 +1727,4 @@ TEST(Pointer, Issue1899) {
|
||||||
EXPECT_TRUE(PointerType("/foo/1234") == q);
|
EXPECT_TRUE(PointerType("/foo/1234") == q);
|
||||||
q = q.Append("");
|
q = q.Append("");
|
||||||
EXPECT_TRUE(PointerType("/foo/1234/") == q);
|
EXPECT_TRUE(PointerType("/foo/1234/") == q);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2054,61 +2054,61 @@ struct NumbersAsStringsHandlerWChar_t {
|
||||||
TEST(Reader, NumbersAsStringsWChar_t) {
|
TEST(Reader, NumbersAsStringsWChar_t) {
|
||||||
{
|
{
|
||||||
const wchar_t* json = L"{ \"pi\": 3.1416 } ";
|
const wchar_t* json = L"{ \"pi\": 3.1416 } ";
|
||||||
GenericStringStream<UTF16<>> s(json);
|
GenericStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"3.1416");
|
NumbersAsStringsHandlerWChar_t h(L"3.1416");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
wchar_t* json = StrDup(L"{ \"pi\": 3.1416 } ");
|
wchar_t* json = StrDup(L"{ \"pi\": 3.1416 } ");
|
||||||
GenericInsituStringStream<UTF16<>> s(json);
|
GenericInsituStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"3.1416");
|
NumbersAsStringsHandlerWChar_t h(L"3.1416");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||||
free(json);
|
free(json);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const wchar_t* json = L"{ \"gigabyte\": 1.0e9 } ";
|
const wchar_t* json = L"{ \"gigabyte\": 1.0e9 } ";
|
||||||
GenericStringStream<UTF16<>> s(json);
|
GenericStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"1.0e9");
|
NumbersAsStringsHandlerWChar_t h(L"1.0e9");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
wchar_t* json = StrDup(L"{ \"gigabyte\": 1.0e9 } ");
|
wchar_t* json = StrDup(L"{ \"gigabyte\": 1.0e9 } ");
|
||||||
GenericInsituStringStream<UTF16<>> s(json);
|
GenericInsituStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"1.0e9");
|
NumbersAsStringsHandlerWChar_t h(L"1.0e9");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||||
free(json);
|
free(json);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const wchar_t* json = L"{ \"pi\": 314.159e-2 } ";
|
const wchar_t* json = L"{ \"pi\": 314.159e-2 } ";
|
||||||
GenericStringStream<UTF16<>> s(json);
|
GenericStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
wchar_t* json = StrDup(L"{ \"gigabyte\": 314.159e-2 } ");
|
wchar_t* json = StrDup(L"{ \"gigabyte\": 314.159e-2 } ");
|
||||||
GenericInsituStringStream<UTF16<>> s(json);
|
GenericInsituStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||||
free(json);
|
free(json);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const wchar_t* json = L"{ \"negative\": -1.54321 } ";
|
const wchar_t* json = L"{ \"negative\": -1.54321 } ";
|
||||||
GenericStringStream<UTF16<>> s(json);
|
GenericStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"-1.54321");
|
NumbersAsStringsHandlerWChar_t h(L"-1.54321");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
wchar_t* json = StrDup(L"{ \"negative\": -1.54321 } ");
|
wchar_t* json = StrDup(L"{ \"negative\": -1.54321 } ");
|
||||||
GenericInsituStringStream<UTF16<>> s(json);
|
GenericInsituStringStream<UTF16<> > s(json);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"-1.54321");
|
NumbersAsStringsHandlerWChar_t h(L"-1.54321");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseInsituFlag | kParseNumbersAsStringsFlag>(s, h));
|
||||||
free(json);
|
free(json);
|
||||||
}
|
}
|
||||||
|
@ -2117,7 +2117,7 @@ TEST(Reader, NumbersAsStringsWChar_t) {
|
||||||
std::wstringstream ss(json);
|
std::wstringstream ss(json);
|
||||||
WIStreamWrapper s(ss);
|
WIStreamWrapper s(ss);
|
||||||
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
NumbersAsStringsHandlerWChar_t h(L"314.159e-2");
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -2126,9 +2126,9 @@ TEST(Reader, NumbersAsStringsWChar_t) {
|
||||||
for(int i = 1; i < 320; i++)
|
for(int i = 1; i < 320; i++)
|
||||||
n1e319[i] = L'0';
|
n1e319[i] = L'0';
|
||||||
n1e319[320] = L'\0';
|
n1e319[320] = L'\0';
|
||||||
GenericStringStream<UTF16<>> s(n1e319);
|
GenericStringStream<UTF16<> > s(n1e319);
|
||||||
NumbersAsStringsHandlerWChar_t h(n1e319);
|
NumbersAsStringsHandlerWChar_t h(n1e319);
|
||||||
GenericReader<UTF16<>, UTF16<>> reader;
|
GenericReader<UTF16<>, UTF16<> > reader;
|
||||||
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,13 @@ TEST(SchemaValidator, Hasher) {
|
||||||
|
|
||||||
#define VALIDATE(schema, json, expected) \
|
#define VALIDATE(schema, json, expected) \
|
||||||
{\
|
{\
|
||||||
|
VALIDATE_(schema, json, expected, true) \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VALIDATE_(schema, json, expected, expected2) \
|
||||||
|
{\
|
||||||
|
EXPECT_TRUE(expected2 == schema.GetError().ObjectEmpty());\
|
||||||
|
EXPECT_TRUE(schema.IsSupportedSpecification());\
|
||||||
SchemaValidator validator(schema);\
|
SchemaValidator validator(schema);\
|
||||||
Document d;\
|
Document d;\
|
||||||
/*printf("\n%s\n", json);*/\
|
/*printf("\n%s\n", json);*/\
|
||||||
|
@ -149,6 +156,8 @@ TEST(SchemaValidator, Hasher) {
|
||||||
#define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
|
#define INVALIDATE_(schema, json, invalidSchemaPointer, invalidSchemaKeyword, invalidDocumentPointer, error, \
|
||||||
flags, SchemaValidatorType, PointerType) \
|
flags, SchemaValidatorType, PointerType) \
|
||||||
{\
|
{\
|
||||||
|
EXPECT_TRUE(schema.GetError().ObjectEmpty());\
|
||||||
|
EXPECT_TRUE(schema.IsSupportedSpecification());\
|
||||||
SchemaValidatorType validator(schema);\
|
SchemaValidatorType validator(schema);\
|
||||||
validator.SetValidateFlags(flags);\
|
validator.SetValidateFlags(flags);\
|
||||||
Document d;\
|
Document d;\
|
||||||
|
@ -188,6 +197,20 @@ TEST(SchemaValidator, Hasher) {
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use for checking whether a compiled schema document contains errors
|
||||||
|
#define SCHEMAERROR(schema, error) \
|
||||||
|
{\
|
||||||
|
Document e;\
|
||||||
|
e.Parse(error);\
|
||||||
|
if (schema.GetError() != e) {\
|
||||||
|
StringBuffer sb;\
|
||||||
|
Writer<StringBuffer> w(sb);\
|
||||||
|
schema.GetError().Accept(w);\
|
||||||
|
printf("GetError() Expected: %s Actual: %s\n", error, sb.GetString());\
|
||||||
|
ADD_FAILURE();\
|
||||||
|
}\
|
||||||
|
}
|
||||||
|
|
||||||
TEST(SchemaValidator, Typeless) {
|
TEST(SchemaValidator, Typeless) {
|
||||||
Document sd;
|
Document sd;
|
||||||
sd.Parse("{}");
|
sd.Parse("{}");
|
||||||
|
@ -223,7 +246,7 @@ TEST(SchemaValidator, Enum_Typed) {
|
||||||
"{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
|
"{ \"enum\": { \"errorCode\": 19, \"instanceRef\": \"#\", \"schemaRef\": \"#\" }}");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SchemaValidator, Enum_Typless) {
|
TEST(SchemaValidator, Enum_Typeless) {
|
||||||
Document sd;
|
Document sd;
|
||||||
sd.Parse("{ \"enum\": [\"red\", \"amber\", \"green\", null, 42] }");
|
sd.Parse("{ \"enum\": [\"red\", \"amber\", \"green\", null, 42] }");
|
||||||
SchemaDocument s(sd);
|
SchemaDocument s(sd);
|
||||||
|
@ -333,7 +356,7 @@ TEST(SchemaValidator, OneOf) {
|
||||||
" ]"
|
" ]"
|
||||||
"}}");
|
"}}");
|
||||||
INVALIDATE(s, "15", "", "oneOf", "",
|
INVALIDATE(s, "15", "", "oneOf", "",
|
||||||
"{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"errors\": [{}, {}]}}");
|
"{ \"oneOf\": { \"errorCode\": 22, \"instanceRef\": \"#\", \"schemaRef\": \"#\", \"matches\": [0,1]}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SchemaValidator, Not) {
|
TEST(SchemaValidator, Not) {
|
||||||
|
@ -502,12 +525,13 @@ TEST(SchemaValidator, String_Pattern) {
|
||||||
|
|
||||||
TEST(SchemaValidator, String_Pattern_Invalid) {
|
TEST(SchemaValidator, String_Pattern_Invalid) {
|
||||||
Document sd;
|
Document sd;
|
||||||
sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}"); // TODO: report regex is invalid somehow
|
sd.Parse("{\"type\":\"string\",\"pattern\":\"a{0}\"}");
|
||||||
SchemaDocument s(sd);
|
SchemaDocument s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RegexInvalid\":{\"errorCode\":9,\"instanceRef\":\"#/pattern\",\"value\":\"a{0}\"}}");
|
||||||
|
|
||||||
VALIDATE(s, "\"\"", true);
|
VALIDATE_(s, "\"\"", true, false);
|
||||||
VALIDATE(s, "\"a\"", true);
|
VALIDATE_(s, "\"a\"", true, false);
|
||||||
VALIDATE(s, "\"aa\"", true);
|
VALIDATE_(s, "\"aa\"", true, false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1886,12 +1910,6 @@ TEST(SchemaValidator, SchemaPointer) {
|
||||||
" },"
|
" },"
|
||||||
" \"f\": {"
|
" \"f\": {"
|
||||||
" \"type\": \"boolean\""
|
" \"type\": \"boolean\""
|
||||||
" },"
|
|
||||||
" \"cyclic_source\": {"
|
|
||||||
" \"$ref\": \"#/definitions/Resp_200/properties/cyclic_target\""
|
|
||||||
" },"
|
|
||||||
" \"cyclic_target\": {"
|
|
||||||
" \"$ref\": \"#/definitions/Resp_200/properties/cyclic_source\""
|
|
||||||
" }"
|
" }"
|
||||||
" },"
|
" },"
|
||||||
" \"type\": \"object\""
|
" \"type\": \"object\""
|
||||||
|
@ -2135,9 +2153,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const SchemaDocumentType* GetRemoteDocument(const char* uri, SizeType length) {
|
virtual const SchemaDocumentType* GetRemoteDocument(const char* uri, SizeType length) {
|
||||||
|
//printf("GetRemoteDocument : %s\n", uri);
|
||||||
for (size_t i = 0; i < kCount; i++)
|
for (size_t i = 0; i < kCount; i++)
|
||||||
if (typename SchemaDocumentType::SValue(uri, length) == sd_[i]->GetURI())
|
if (typename SchemaDocumentType::GValue(uri, length) == sd_[i]->GetURI()) {
|
||||||
|
//printf("Matched document");
|
||||||
return sd_[i];
|
return sd_[i];
|
||||||
|
}
|
||||||
|
//printf("No matched document");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2390,7 +2412,9 @@ TEST(SchemaValidator, Issue728_AllOfRef) {
|
||||||
Document sd;
|
Document sd;
|
||||||
sd.Parse("{\"allOf\": [{\"$ref\": \"#/abc\"}]}");
|
sd.Parse("{\"allOf\": [{\"$ref\": \"#/abc\"}]}");
|
||||||
SchemaDocument s(sd);
|
SchemaDocument s(sd);
|
||||||
VALIDATE(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true);
|
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/allOf/0\",\"value\":\"#/abc\"}}");
|
||||||
|
|
||||||
|
VALIDATE_(s, "{\"key1\": \"abc\", \"key2\": \"def\"}", true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SchemaValidator, Issue1017_allOfHandler) {
|
TEST(SchemaValidator, Issue1017_allOfHandler) {
|
||||||
|
@ -2625,7 +2649,7 @@ TEST(SchemaValidator, Ref_remote_issue1210) {
|
||||||
SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { }
|
SchemaDocumentProvider(SchemaDocument** collection) : collection(collection) { }
|
||||||
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
|
virtual const SchemaDocument* GetRemoteDocument(const char* uri, SizeType length) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (collection[i] && SchemaDocument::SValue(uri, length) != collection[i]->GetURI()) ++i;
|
while (collection[i] && SchemaDocument::GValue(uri, length) != collection[i]->GetURI()) ++i;
|
||||||
return collection[i];
|
return collection[i];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2656,7 +2680,7 @@ TEST(SchemaValidator, ContinueOnErrors) {
|
||||||
ASSERT_FALSE(sd.HasParseError());
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
SchemaDocument s(sd);
|
SchemaDocument s(sd);
|
||||||
VALIDATE(s, "{\"version\": 1.0, \"address\": {\"number\": 24, \"street1\": \"The Woodlands\", \"street3\": \"Ham\", \"city\": \"Romsey\", \"area\": \"Kent\", \"country\": \"UK\", \"postcode\": \"SO51 0GP\"}, \"phones\": [\"0111-222333\", \"0777-666888\"], \"names\": [\"Fred\", \"Bloggs\"]}", true);
|
VALIDATE(s, "{\"version\": 1.0, \"address\": {\"number\": 24, \"street1\": \"The Woodlands\", \"street3\": \"Ham\", \"city\": \"Romsey\", \"area\": \"Kent\", \"country\": \"UK\", \"postcode\": \"SO51 0GP\"}, \"phones\": [\"0111-222333\", \"0777-666888\"], \"names\": [\"Fred\", \"Bloggs\"]}", true);
|
||||||
INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false, \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"BC\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#",
|
INVALIDATE_(s, "{\"version\": 1.01, \"address\": {\"number\": 0, \"street2\": false, \"street3\": \"Ham\", \"city\": \"RomseyTownFC\", \"area\": \"Narnia\", \"country\": \"USA\", \"postcode\": \"999ABC\"}, \"phones\": [], \"planet\": \"Earth\", \"extra\": {\"S_xxx\": 123}}", "#", "errors", "#",
|
||||||
"{ \"multipleOf\": {"
|
"{ \"multipleOf\": {"
|
||||||
" \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01"
|
" \"errorCode\": 1, \"instanceRef\": \"#/version\", \"schemaRef\": \"#/definitions/decimal_type\", \"expected\": 1.0, \"actual\": 1.01"
|
||||||
" },"
|
" },"
|
||||||
|
@ -2691,6 +2715,9 @@ TEST(SchemaValidator, ContinueOnErrors) {
|
||||||
" },"
|
" },"
|
||||||
" \"required\": {"
|
" \"required\": {"
|
||||||
" \"missing\": [\"street1\"], \"errorCode\": 15, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\""
|
" \"missing\": [\"street1\"], \"errorCode\": 15, \"instanceRef\": \"#/address\", \"schemaRef\": \"#/definitions/address_type\""
|
||||||
|
" },"
|
||||||
|
" \"oneOf\": {"
|
||||||
|
" \"matches\": [0, 1], \"errorCode\": 22, \"instanceRef\": \"#/address/area\", \"schemaRef\": \"#/definitions/address_type/properties/area\""
|
||||||
" }"
|
" }"
|
||||||
"}",
|
"}",
|
||||||
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
|
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
|
||||||
|
@ -2917,7 +2944,7 @@ TEST(SchemaValidator, ContinueOnErrors_RogueString) {
|
||||||
|
|
||||||
// Test that when kValidateContinueOnErrorFlag is set, an incorrect simple type with a sub-schema is handled correctly.
|
// Test that when kValidateContinueOnErrorFlag is set, an incorrect simple type with a sub-schema is handled correctly.
|
||||||
// This tests that we don't blow up when there is a type mismatch but there is a sub-schema present
|
// This tests that we don't blow up when there is a type mismatch but there is a sub-schema present
|
||||||
TEST(SchemaValidator, ContinueOnErrors_Issue2) {
|
TEST(SchemaValidator, ContinueOnErrors_BadSimpleType) {
|
||||||
Document sd;
|
Document sd;
|
||||||
sd.Parse("{\"type\":\"string\", \"anyOf\":[{\"maxLength\":2}]}");
|
sd.Parse("{\"type\":\"string\", \"anyOf\":[{\"maxLength\":2}]}");
|
||||||
ASSERT_FALSE(sd.HasParseError());
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
@ -2943,10 +2970,606 @@ TEST(SchemaValidator, ContinueOnErrors_Issue2) {
|
||||||
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
|
kValidateDefaultFlags | kValidateContinueOnErrorFlag, SchemaValidator, Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SchemaValidator, Schema_UnknownError) {
|
|
||||||
|
TEST(SchemaValidator, UnknownValidationError) {
|
||||||
ASSERT_TRUE(SchemaValidator::SchemaType::GetValidateErrorKeyword(kValidateErrors).GetString() == std::string("null"));
|
ASSERT_TRUE(SchemaValidator::SchemaType::GetValidateErrorKeyword(kValidateErrors).GetString() == std::string("null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The first occurrence of a duplicate keyword is taken
|
||||||
|
TEST(SchemaValidator, DuplicateKeyword) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{ \"title\": \"test\",\"type\": \"number\", \"type\": \"string\" }");
|
||||||
|
EXPECT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
VALIDATE(s, "42", true);
|
||||||
|
INVALIDATE(s, "\"Life, the universe, and everything\"", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"number\"], \"actual\": \"string\""
|
||||||
|
"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SchemaDocument tests
|
||||||
|
|
||||||
|
// Specification (schema draft, open api version)
|
||||||
|
TEST(SchemaValidator, Schema_SupportedNotObject) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("true");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedNoSpec) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedNoSpecStatic) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
Specification spec = SchemaDocumentType::GetSpecification(sd);
|
||||||
|
ASSERT_FALSE(spec.IsSupported());
|
||||||
|
ASSERT_TRUE(spec.draft == kDraftNone);
|
||||||
|
ASSERT_TRUE(spec.oapi == kVersionNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedDraft5Static) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
Specification spec = SchemaDocumentType::GetSpecification(sd);
|
||||||
|
ASSERT_TRUE(spec.IsSupported());
|
||||||
|
ASSERT_TRUE(spec.draft == kDraft05);
|
||||||
|
ASSERT_TRUE(spec.oapi == kVersionNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedDraft4) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-04/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedDraft4NoFrag) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-04/schema\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedDraft5) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft05);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedDraft5NoFrag) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-05/schema\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft05);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_IgnoreDraftEmbedded) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"root\": {\"$schema\":\"http://json-schema.org/draft-05/schema#\", \"type\": \"integer\"}}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, SchemaDocument::PointerType("/root"));
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedDraftOverride) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraft04));
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownDraftOverride) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraftUnknown));
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedDraftOverride) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kDraft03));
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft03);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownDraft) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-xxx/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownDraftNotString) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\": 4, \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraftUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedDraft3) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-03/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft03);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedDraft6) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-06/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft06);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedDraft7) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"http://json-schema.org/draft-07/schema#\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft07);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedDraft2019_09) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"https://json-schema.org/draft/2019-09/schema\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft2019_09);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedDraft2020_12) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"$schema\":\"https://json-schema.org/draft/2020-12/schema\", \"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionNone);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedVersion20Static) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"swagger\":\"2.0\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
Specification spec = SchemaDocumentType::GetSpecification(sd);
|
||||||
|
ASSERT_TRUE(spec.IsSupported());
|
||||||
|
ASSERT_TRUE(spec.draft == kDraft04);
|
||||||
|
ASSERT_TRUE(spec.oapi == kVersion20);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedVersion20) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"swagger\":\"2.0\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersion20);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedVersion30x) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"openapi\":\"3.0.0\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersion30);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft05);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_SupportedVersionOverride) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion20));
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersion20);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
EXPECT_TRUE(s.GetError().ObjectEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownVersionOverride) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersionUnknown));
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedVersionOverride) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion31));
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersion31);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownVersion) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"openapi\":\"1.0\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownVersionShort) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"openapi\":\"3.0.\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnknownVersionNotString) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"swagger\": 2}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersionUnknown);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft04);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnknown\":{\"errorCode\":10,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_UnsupportedVersion31) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"openapi\":\"3.1.0\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_FALSE(s.IsSupportedSpecification());
|
||||||
|
ASSERT_TRUE(s.GetSpecification().oapi == kVersion31);
|
||||||
|
ASSERT_TRUE(s.GetSpecification().draft == kDraft2020_12);
|
||||||
|
SCHEMAERROR(s, "{\"SpecUnsupported\":{\"errorCode\":11,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_DraftAndVersion) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"swagger\": \"2.0\", \"$schema\": \"http://json-schema.org/draft-04/schema#\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
ASSERT_TRUE(s.IsSupportedSpecification());
|
||||||
|
SCHEMAERROR(s, "{\"SpecIllegal\":{\"errorCode\":12,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_StartUnknown) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, SchemaDocument::PointerType("/nowhere"));
|
||||||
|
SCHEMAERROR(s, "{\"StartUnknown\":{\"errorCode\":1,\"instanceRef\":\"#\", \"value\":\"#/nowhere\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_MultipleErrors) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"swagger\": \"foo\", \"$schema\": \"bar\"}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s(sd);
|
||||||
|
SCHEMAERROR(s, "{ \"SpecUnknown\": {\"errorCode\":10,\"instanceRef\":\"#\"},"
|
||||||
|
" \"SpecIllegal\": {\"errorCode\":12,\"instanceRef\":\"#\"}"
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is a non-JSON pointer fragment - not allowed when OpenAPI
|
||||||
|
TEST(SchemaValidator, Schema_RefPlainNameOpenApi) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"swagger\": \"2.0\", \"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"#myId\"}, \"myStr\": {\"type\": \"string\", \"id\": \"#myStrId\"}, \"myInt2\": {\"type\": \"integer\", \"id\": \"#myId\"}}}");
|
||||||
|
SchemaDocumentType s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RefPlainName\":{\"errorCode\":2,\"instanceRef\":\"#/properties/myInt1\",\"value\":\"#myId\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is a non-JSON pointer fragment - not allowed when remote document
|
||||||
|
TEST(SchemaValidator, Schema_RefPlainNameRemote) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#plainname\"}}}");
|
||||||
|
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
|
||||||
|
SCHEMAERROR(s, "{\"RefPlainName\":{\"errorCode\":2,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#plainname\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is an empty string
|
||||||
|
TEST(SchemaValidator, Schema_RefEmptyString) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt1\": {\"$ref\": \"\"}}}");
|
||||||
|
SchemaDocumentType s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RefInvalid\":{\"errorCode\":3,\"instanceRef\":\"#/properties/myInt1\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is remote but no provider
|
||||||
|
TEST(SchemaValidator, Schema_RefNoRemoteProvider) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#plainname\"}}}");
|
||||||
|
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, 0);
|
||||||
|
SCHEMAERROR(s, "{\"RefNoRemoteProvider\":{\"errorCode\":7,\"instanceRef\":\"#/properties/myInt\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is remote but no schema returned
|
||||||
|
TEST(SchemaValidator, Schema_RefNoRemoteSchema) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/will-not-resolve.json\"}}}");
|
||||||
|
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
|
||||||
|
SCHEMAERROR(s, "{\"RefNoRemoteSchema\":{\"errorCode\":8,\"instanceRef\":\"#/properties/myInt\",\"value\":\"http://localhost:1234/will-not-resolve.json\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref pointer is invalid
|
||||||
|
TEST(SchemaValidator, Schema_RefPointerInvalid) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#/&&&&&\"}}}");
|
||||||
|
SchemaDocumentType s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RefPointerInvalid\":{\"errorCode\":4,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/&&&&&\",\"offset\":2}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is remote and pointer is invalid
|
||||||
|
TEST(SchemaValidator, Schema_RefPointerInvalidRemote) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/abc&&&&&\"}}}");
|
||||||
|
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
|
||||||
|
SCHEMAERROR(s, "{\"RefPointerInvalid\":{\"errorCode\":4,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/abc&&&&&\",\"offset\":5}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is unknown non-pointer
|
||||||
|
TEST(SchemaValidator, Schema_RefUnknownPlainName) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#plainname\"}}}");
|
||||||
|
SchemaDocumentType s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#plainname\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// $ref is unknown pointer
|
||||||
|
TEST(SchemaValidator, Schema_RefUnknownPointer) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"#/a/b\"}}}");
|
||||||
|
SchemaDocumentType s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"#/a/b\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is remote and unknown pointer
|
||||||
|
TEST(SchemaValidator, Schema_RefUnknownPointerRemote) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
RemoteSchemaDocumentProvider<SchemaDocumentType> provider;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {\"myInt\": {\"$ref\": \"/subSchemas.json#/a/b\"}}}");
|
||||||
|
SchemaDocumentType s(sd, "http://localhost:1234/xxxx", 26, &provider);
|
||||||
|
SCHEMAERROR(s, "{\"RefUnknown\":{\"errorCode\":5,\"instanceRef\":\"#/properties/myInt\",\"value\":\"http://localhost:1234/subSchemas.json#/a/b\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// $ref is cyclical
|
||||||
|
TEST(SchemaValidator, Schema_RefCyclical) {
|
||||||
|
typedef GenericSchemaDocument<Value, MemoryPoolAllocator<> > SchemaDocumentType;
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"object\", \"properties\": {"
|
||||||
|
" \"cyclic_source\": {"
|
||||||
|
" \"$ref\": \"#/properties/cyclic_target\""
|
||||||
|
" },"
|
||||||
|
" \"cyclic_target\": {"
|
||||||
|
" \"$ref\": \"#/properties/cyclic_source\""
|
||||||
|
" }"
|
||||||
|
"}}");
|
||||||
|
SchemaDocumentType s(sd);
|
||||||
|
SCHEMAERROR(s, "{\"RefCyclical\":{\"errorCode\":6,\"instanceRef\":\"#/properties/cyclic_target\",\"value\":\"#/properties/cyclic_source\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, Schema_ReadOnlyAndWriteOnly) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"integer\", \"readOnly\": true, \"writeOnly\": true}");
|
||||||
|
ASSERT_FALSE(sd.HasParseError());
|
||||||
|
SchemaDocument s1(sd, 0, 0, 0, 0, 0, Specification(kDraft04));
|
||||||
|
EXPECT_TRUE(s1.GetError().ObjectEmpty());
|
||||||
|
SchemaDocument s2(sd, 0, 0, 0, 0, 0, Specification(kVersion30));
|
||||||
|
SCHEMAERROR(s2, "{\"ReadOnlyAndWriteOnly\":{\"errorCode\":13,\"instanceRef\":\"#\"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, ReadOnlyWhenWriting) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse(
|
||||||
|
"{"
|
||||||
|
" \"type\":\"object\","
|
||||||
|
" \"properties\": {"
|
||||||
|
" \"rprop\" : {"
|
||||||
|
" \"type\": \"string\","
|
||||||
|
" \"readOnly\": true"
|
||||||
|
" }"
|
||||||
|
" }"
|
||||||
|
"}");
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion20));
|
||||||
|
VALIDATE(s, "{ \"rprop\": \"hello\" }", true);
|
||||||
|
INVALIDATE_(s, "{ \"rprop\": \"hello\" }", "/properties/rprop", "readOnly", "/rprop",
|
||||||
|
"{ \"readOnly\": {"
|
||||||
|
" \"errorCode\": 26, \"instanceRef\": \"#/rprop\", \"schemaRef\": \"#/properties/rprop\""
|
||||||
|
" }"
|
||||||
|
"}",
|
||||||
|
kValidateDefaultFlags | kValidateWriteFlag, SchemaValidator, Pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, WriteOnlyWhenReading) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse(
|
||||||
|
"{"
|
||||||
|
" \"type\":\"object\","
|
||||||
|
" \"properties\": {"
|
||||||
|
" \"wprop\" : {"
|
||||||
|
" \"type\": \"boolean\","
|
||||||
|
" \"writeOnly\": true"
|
||||||
|
" }"
|
||||||
|
" }"
|
||||||
|
"}");
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, Specification(kVersion30));
|
||||||
|
VALIDATE(s, "{ \"wprop\": true }", true);
|
||||||
|
INVALIDATE_(s, "{ \"wprop\": true }", "/properties/wprop", "writeOnly", "/wprop",
|
||||||
|
"{ \"writeOnly\": {"
|
||||||
|
" \"errorCode\": 27, \"instanceRef\": \"#/wprop\", \"schemaRef\": \"#/properties/wprop\""
|
||||||
|
" }"
|
||||||
|
"}",
|
||||||
|
kValidateDefaultFlags | kValidateReadFlag, SchemaValidator, Pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, NullableTrue) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"string\", \"nullable\": true}");
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, kVersion20);
|
||||||
|
|
||||||
|
VALIDATE(s, "\"hello\"", true);
|
||||||
|
INVALIDATE(s, "null", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"string\"], \"actual\": \"null\""
|
||||||
|
"}}");
|
||||||
|
INVALIDATE(s, "false", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"string\"], \"actual\": \"boolean\""
|
||||||
|
"}}");
|
||||||
|
|
||||||
|
SchemaDocument s30(sd, 0, 0, 0, 0, 0, kVersion30);
|
||||||
|
|
||||||
|
VALIDATE(s30, "\"hello\"", true);
|
||||||
|
VALIDATE(s30, "null", true);
|
||||||
|
INVALIDATE(s30, "false", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"null\", \"string\"], \"actual\": \"boolean\""
|
||||||
|
"}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchemaValidator, NullableFalse) {
|
||||||
|
Document sd;
|
||||||
|
sd.Parse("{\"type\": \"string\", \"nullable\": false}");
|
||||||
|
SchemaDocument s(sd, 0, 0, 0, 0, 0, kVersion20);
|
||||||
|
|
||||||
|
VALIDATE(s, "\"hello\"", true);
|
||||||
|
INVALIDATE(s, "null", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"string\"], \"actual\": \"null\""
|
||||||
|
"}}");
|
||||||
|
INVALIDATE(s, "false", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"string\"], \"actual\": \"boolean\""
|
||||||
|
"}}");
|
||||||
|
|
||||||
|
SchemaDocument s30(sd, 0, 0, 0, 0, 0, kVersion30);
|
||||||
|
|
||||||
|
VALIDATE(s30, "\"hello\"", true);
|
||||||
|
INVALIDATE(s, "null", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"string\"], \"actual\": \"null\""
|
||||||
|
"}}");
|
||||||
|
INVALIDATE(s30, "false", "", "type", "",
|
||||||
|
"{ \"type\": {"
|
||||||
|
" \"errorCode\": 20,"
|
||||||
|
" \"instanceRef\": \"#\", \"schemaRef\": \"#\","
|
||||||
|
" \"expected\": [\"string\"], \"actual\": \"boolean\""
|
||||||
|
"}}");
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__clang__)
|
#if defined(_MSC_VER) || defined(__clang__)
|
||||||
RAPIDJSON_DIAG_POP
|
RAPIDJSON_DIAG_POP
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,10 +49,12 @@ using namespace rapidjson_simd;
|
||||||
#define SIMD_SUFFIX(name) name
|
#define SIMD_SUFFIX(name) name
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SIMD_SIZE_ALIGN(n) ((size_t(n) + 15) & ~size_t(15))
|
||||||
|
|
||||||
template <typename StreamType>
|
template <typename StreamType>
|
||||||
void TestSkipWhitespace() {
|
void TestSkipWhitespace() {
|
||||||
for (size_t step = 1; step < 32; step++) {
|
for (size_t step = 1; step < 32; step++) {
|
||||||
char buffer[1025];
|
char buffer[SIMD_SIZE_ALIGN(1025)];
|
||||||
for (size_t i = 0; i < 1024; i++)
|
for (size_t i = 0; i < 1024; i++)
|
||||||
buffer[i] = " \t\r\n"[i % 4];
|
buffer[i] = " \t\r\n"[i % 4];
|
||||||
for (size_t i = 0; i < 1024; i += step)
|
for (size_t i = 0; i < 1024; i += step)
|
||||||
|
@ -79,7 +81,7 @@ TEST(SIMD, SIMD_SUFFIX(SkipWhitespace)) {
|
||||||
|
|
||||||
TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) {
|
TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) {
|
||||||
for (size_t step = 1; step < 32; step++) {
|
for (size_t step = 1; step < 32; step++) {
|
||||||
char buffer[1024];
|
char buffer[SIMD_SIZE_ALIGN(1024)];
|
||||||
for (size_t i = 0; i < 1024; i++)
|
for (size_t i = 0; i < 1024; i++)
|
||||||
buffer[i] = " \t\r\n"[i % 4];
|
buffer[i] = " \t\r\n"[i % 4];
|
||||||
for (size_t i = 0; i < 1024; i += step)
|
for (size_t i = 0; i < 1024; i += step)
|
||||||
|
@ -87,14 +89,12 @@ TEST(SIMD, SIMD_SUFFIX(SkipWhitespace_EncodedMemoryStream)) {
|
||||||
|
|
||||||
MemoryStream ms(buffer, 1024);
|
MemoryStream ms(buffer, 1024);
|
||||||
EncodedInputStream<UTF8<>, MemoryStream> s(ms);
|
EncodedInputStream<UTF8<>, MemoryStream> s(ms);
|
||||||
size_t i = 0;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
SkipWhitespace(s);
|
SkipWhitespace(s);
|
||||||
if (s.Peek() == '\0')
|
if (s.Peek() == '\0')
|
||||||
break;
|
break;
|
||||||
//EXPECT_EQ(i, s.Tell());
|
//EXPECT_EQ(i, s.Tell());
|
||||||
EXPECT_EQ('X', s.Take());
|
EXPECT_EQ('X', s.Take());
|
||||||
i += step;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,8 @@ struct ScanCopyUnescapedStringHandler : BaseReaderHandler<UTF8<>, ScanCopyUnesca
|
||||||
|
|
||||||
template <unsigned parseFlags, typename StreamType>
|
template <unsigned parseFlags, typename StreamType>
|
||||||
void TestScanCopyUnescapedString() {
|
void TestScanCopyUnescapedString() {
|
||||||
char buffer[1024u + 5 + 32];
|
char buffer[SIMD_SIZE_ALIGN(1024u + 5 + 32)];
|
||||||
char backup[1024u + 5 + 32];
|
char backup[SIMD_SIZE_ALIGN(1024u + 5 + 32)];
|
||||||
|
|
||||||
// Test "ABCDABCD...\\"
|
// Test "ABCDABCD...\\"
|
||||||
for (size_t offset = 0; offset < 32; offset++) {
|
for (size_t offset = 0; offset < 32; offset++) {
|
||||||
|
@ -167,7 +167,7 @@ TEST(SIMD, SIMD_SUFFIX(ScanCopyUnescapedString)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SIMD, SIMD_SUFFIX(ScanWriteUnescapedString)) {
|
TEST(SIMD, SIMD_SUFFIX(ScanWriteUnescapedString)) {
|
||||||
char buffer[2048 + 1 + 32];
|
char buffer[SIMD_SIZE_ALIGN(2048 + 1 + 32)];
|
||||||
for (size_t offset = 0; offset < 32; offset++) {
|
for (size_t offset = 0; offset < 32; offset++) {
|
||||||
for (size_t step = 0; step < 1024; step++) {
|
for (size_t step = 0; step < 1024; step++) {
|
||||||
char* s = buffer + offset;
|
char* s = buffer + offset;
|
||||||
|
|
|
@ -48,7 +48,6 @@ TEST(Uri, DefaultConstructor) {
|
||||||
EXPECT_TRUE(u.GetStringLength() == 0);
|
EXPECT_TRUE(u.GetStringLength() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(Uri, Parse) {
|
TEST(Uri, Parse) {
|
||||||
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
||||||
MemoryPoolAllocator<CrtAllocator> allocator;
|
MemoryPoolAllocator<CrtAllocator> allocator;
|
||||||
|
@ -66,21 +65,8 @@ TEST(Uri, Parse) {
|
||||||
u.Get(w, allocator);
|
u.Get(w, allocator);
|
||||||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
typedef std::basic_string<Value::Ch> String;
|
|
||||||
String str = "http://auth/path/xxx?query#frag";
|
|
||||||
const UriType uri = UriType(str);
|
|
||||||
EXPECT_TRUE(UriType::GetScheme(uri) == "http:");
|
|
||||||
EXPECT_TRUE(UriType::GetAuth(uri) == "//auth");
|
|
||||||
EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx");
|
|
||||||
EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query");
|
|
||||||
EXPECT_TRUE(UriType::GetQuery(uri) == "?query");
|
|
||||||
EXPECT_TRUE(UriType::GetFrag(uri) == "#frag");
|
|
||||||
EXPECT_TRUE(UriType::Get(uri) == str);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
v.SetString("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
v.SetString("urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
||||||
u = UriType(v);
|
u = UriType(v, &allocator);
|
||||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "urn:") == 0);
|
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "urn:") == 0);
|
||||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||||
EXPECT_TRUE(StrCmp(u.GetPathString(), "uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
EXPECT_TRUE(StrCmp(u.GetPathString(), "uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
||||||
|
@ -91,7 +77,7 @@ TEST(Uri, Parse) {
|
||||||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||||
|
|
||||||
v.SetString("", allocator);
|
v.SetString("", allocator);
|
||||||
u = UriType(v);
|
u = UriType(v, &allocator);
|
||||||
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
||||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||||
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
||||||
|
@ -100,7 +86,7 @@ TEST(Uri, Parse) {
|
||||||
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
||||||
|
|
||||||
v.SetString("http://auth/", allocator);
|
v.SetString("http://auth/", allocator);
|
||||||
u = UriType(v);
|
u = UriType(v, &allocator);
|
||||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0);
|
EXPECT_TRUE(StrCmp(u.GetAuthString(), "//auth") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0);
|
EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0);
|
||||||
|
@ -162,12 +148,11 @@ TEST(Uri, Parse) {
|
||||||
EXPECT_TRUE(u.GetFragStringLength() == len);
|
EXPECT_TRUE(u.GetFragStringLength() == len);
|
||||||
|
|
||||||
// Incomplete auth treated as path
|
// Incomplete auth treated as path
|
||||||
str = "http:/";
|
u = UriType("http:/");
|
||||||
const UriType u2 = UriType(str);
|
EXPECT_TRUE(StrCmp(u.GetSchemeString(), "http:") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u2.GetSchemeString(), "http:") == 0);
|
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||||
EXPECT_TRUE(u2.GetAuthStringLength() == 0);
|
EXPECT_TRUE(StrCmp(u.GetPathString(), "/") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u2.GetPathString(), "/") == 0);
|
EXPECT_TRUE(StrCmp(u.GetBaseString(), "http:/") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u2.GetBaseString(), "http:/") == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Uri, Parse_UTF16) {
|
TEST(Uri, Parse_UTF16) {
|
||||||
|
@ -188,21 +173,8 @@ TEST(Uri, Parse_UTF16) {
|
||||||
u.Get(w, allocator);
|
u.Get(w, allocator);
|
||||||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||||
|
|
||||||
#if RAPIDJSON_HAS_STDSTRING
|
|
||||||
typedef std::basic_string<Value16::Ch> String;
|
|
||||||
String str = L"http://auth/path/xxx?query#frag";
|
|
||||||
const UriType uri = UriType(str);
|
|
||||||
EXPECT_TRUE(UriType::GetScheme(uri) == L"http:");
|
|
||||||
EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth");
|
|
||||||
EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx");
|
|
||||||
EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query");
|
|
||||||
EXPECT_TRUE(UriType::GetQuery(uri) == L"?query");
|
|
||||||
EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag");
|
|
||||||
EXPECT_TRUE(UriType::Get(uri) == str);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
v.SetString(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
v.SetString(L"urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", allocator);
|
||||||
u = UriType(v);
|
u = UriType(v, &allocator);
|
||||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"urn:") == 0);
|
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"urn:") == 0);
|
||||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||||
EXPECT_TRUE(StrCmp(u.GetPathString(), L"uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
EXPECT_TRUE(StrCmp(u.GetPathString(), L"uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f") == 0);
|
||||||
|
@ -213,7 +185,7 @@ TEST(Uri, Parse_UTF16) {
|
||||||
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
EXPECT_TRUE(*w.GetString() == *v.GetString());
|
||||||
|
|
||||||
v.SetString(L"", allocator);
|
v.SetString(L"", allocator);
|
||||||
u = UriType(v);
|
u = UriType(v, &allocator);
|
||||||
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
EXPECT_TRUE(u.GetSchemeStringLength() == 0);
|
||||||
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
EXPECT_TRUE(u.GetAuthStringLength() == 0);
|
||||||
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
EXPECT_TRUE(u.GetPathStringLength() == 0);
|
||||||
|
@ -222,7 +194,7 @@ TEST(Uri, Parse_UTF16) {
|
||||||
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
EXPECT_TRUE(u.GetFragStringLength() == 0);
|
||||||
|
|
||||||
v.SetString(L"http://auth/", allocator);
|
v.SetString(L"http://auth/", allocator);
|
||||||
u = UriType(v);
|
u = UriType(v, &allocator);
|
||||||
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
EXPECT_TRUE(StrCmp(u.GetSchemeString(), L"http:") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0);
|
EXPECT_TRUE(StrCmp(u.GetAuthString(), L"//auth") == 0);
|
||||||
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0);
|
EXPECT_TRUE(StrCmp(u.GetPathString(), L"/") == 0);
|
||||||
|
@ -291,6 +263,41 @@ TEST(Uri, Parse_UTF16) {
|
||||||
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http:/") == 0);
|
EXPECT_TRUE(StrCmp(u.GetBaseString(), L"http:/") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if RAPIDJSON_HAS_STDSTRING
|
||||||
|
TEST(Uri, Parse_Std) {
|
||||||
|
typedef GenericUri<Value, MemoryPoolAllocator<> > UriType;
|
||||||
|
MemoryPoolAllocator<CrtAllocator> allocator;
|
||||||
|
typedef std::basic_string<Value::Ch> String;
|
||||||
|
|
||||||
|
String str = "http://auth/path/xxx?query#frag";
|
||||||
|
const UriType uri = UriType(str, &allocator);
|
||||||
|
EXPECT_TRUE(UriType::GetScheme(uri) == "http:");
|
||||||
|
EXPECT_TRUE(UriType::GetAuth(uri) == "//auth");
|
||||||
|
EXPECT_TRUE(UriType::GetPath(uri) == "/path/xxx");
|
||||||
|
EXPECT_TRUE(UriType::GetBase(uri) == "http://auth/path/xxx?query");
|
||||||
|
EXPECT_TRUE(UriType::GetQuery(uri) == "?query");
|
||||||
|
EXPECT_TRUE(UriType::GetFrag(uri) == "#frag");
|
||||||
|
EXPECT_TRUE(UriType::Get(uri) == str);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Uri, Parse_UTF16_Std) {
|
||||||
|
typedef GenericValue<UTF16<> > Value16;
|
||||||
|
typedef GenericUri<Value16, MemoryPoolAllocator<> > UriType;
|
||||||
|
MemoryPoolAllocator<CrtAllocator> allocator;
|
||||||
|
typedef std::basic_string<Value16::Ch> String;
|
||||||
|
|
||||||
|
String str = L"http://auth/path/xxx?query#frag";
|
||||||
|
const UriType uri = UriType(str, &allocator);
|
||||||
|
EXPECT_TRUE(UriType::GetScheme(uri) == L"http:");
|
||||||
|
EXPECT_TRUE(UriType::GetAuth(uri) == L"//auth");
|
||||||
|
EXPECT_TRUE(UriType::GetPath(uri) == L"/path/xxx");
|
||||||
|
EXPECT_TRUE(UriType::GetBase(uri) == L"http://auth/path/xxx?query");
|
||||||
|
EXPECT_TRUE(UriType::GetQuery(uri) == L"?query");
|
||||||
|
EXPECT_TRUE(UriType::GetFrag(uri) == L"#frag");
|
||||||
|
EXPECT_TRUE(UriType::Get(uri) == str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(Uri, CopyConstructor) {
|
TEST(Uri, CopyConstructor) {
|
||||||
typedef GenericUri<Value> UriType;
|
typedef GenericUri<Value> UriType;
|
||||||
CrtAllocator allocator;
|
CrtAllocator allocator;
|
||||||
|
|
|
@ -1060,7 +1060,7 @@ static void TestArray(T& x, Allocator& allocator) {
|
||||||
x.Clear();
|
x.Clear();
|
||||||
for (unsigned i = 0; i < n; i++)
|
for (unsigned i = 0; i < n; i++)
|
||||||
x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
|
x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
|
||||||
|
|
||||||
itr = x.Erase(x.Begin() + first, x.Begin() + last);
|
itr = x.Erase(x.Begin() + first, x.Begin() + last);
|
||||||
if (last == n)
|
if (last == n)
|
||||||
EXPECT_EQ(x.End(), itr);
|
EXPECT_EQ(x.End(), itr);
|
||||||
|
@ -1556,7 +1556,7 @@ TEST(Value, ObjectHelper) {
|
||||||
EXPECT_STREQ("apple", y["a"].GetString());
|
EXPECT_STREQ("apple", y["a"].GetString());
|
||||||
EXPECT_TRUE(x.IsObject()); // Invariant
|
EXPECT_TRUE(x.IsObject()); // Invariant
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Value x(kObjectType);
|
Value x(kObjectType);
|
||||||
x.AddMember("a", "apple", allocator);
|
x.AddMember("a", "apple", allocator);
|
||||||
|
@ -1581,7 +1581,7 @@ TEST(Value, ObjectHelperRangeFor) {
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (auto& m : x.GetObject()) {
|
for (auto& m : x.GetObject()) {
|
||||||
char name[10];
|
char name[11];
|
||||||
sprintf(name, "%d", i);
|
sprintf(name, "%d", i);
|
||||||
EXPECT_STREQ(name, m.name.GetString());
|
EXPECT_STREQ(name, m.name.GetString());
|
||||||
EXPECT_EQ(i, m.value.GetInt());
|
EXPECT_EQ(i, m.value.GetInt());
|
||||||
|
@ -1592,7 +1592,7 @@ TEST(Value, ObjectHelperRangeFor) {
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto& m : const_cast<const Value&>(x).GetObject()) {
|
for (const auto& m : const_cast<const Value&>(x).GetObject()) {
|
||||||
char name[10];
|
char name[11];
|
||||||
sprintf(name, "%d", i);
|
sprintf(name, "%d", i);
|
||||||
EXPECT_STREQ(name, m.name.GetString());
|
EXPECT_STREQ(name, m.name.GetString());
|
||||||
EXPECT_EQ(i, m.value.GetInt());
|
EXPECT_EQ(i, m.value.GetInt());
|
||||||
|
@ -1674,7 +1674,7 @@ TEST(Value, BigNestedObject) {
|
||||||
for (SizeType i = 0; i < n; i++) {
|
for (SizeType i = 0; i < n; i++) {
|
||||||
char name1[10];
|
char name1[10];
|
||||||
sprintf(name1, "%d", i);
|
sprintf(name1, "%d", i);
|
||||||
|
|
||||||
for (SizeType j = 0; j < n; j++) {
|
for (SizeType j = 0; j < n; j++) {
|
||||||
char name2[10];
|
char name2[10];
|
||||||
sprintf(name2, "%d", j);
|
sprintf(name2, "%d", j);
|
||||||
|
@ -1689,8 +1689,8 @@ TEST(Value, BigNestedObject) {
|
||||||
TEST(Value, RemoveLastElement) {
|
TEST(Value, RemoveLastElement) {
|
||||||
rapidjson::Document doc;
|
rapidjson::Document doc;
|
||||||
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
|
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
|
||||||
rapidjson::Value objVal(rapidjson::kObjectType);
|
rapidjson::Value objVal(rapidjson::kObjectType);
|
||||||
objVal.AddMember("var1", 123, allocator);
|
objVal.AddMember("var1", 123, allocator);
|
||||||
objVal.AddMember("var2", "444", allocator);
|
objVal.AddMember("var2", "444", allocator);
|
||||||
objVal.AddMember("var3", 555, allocator);
|
objVal.AddMember("var3", 555, allocator);
|
||||||
EXPECT_TRUE(objVal.HasMember("var3"));
|
EXPECT_TRUE(objVal.HasMember("var3"));
|
||||||
|
@ -1712,22 +1712,22 @@ TEST(Document, CrtAllocator) {
|
||||||
|
|
||||||
static void TestShortStringOptimization(const char* str) {
|
static void TestShortStringOptimization(const char* str) {
|
||||||
const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
|
const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str));
|
||||||
|
|
||||||
rapidjson::Document doc;
|
rapidjson::Document doc;
|
||||||
rapidjson::Value val;
|
rapidjson::Value val;
|
||||||
val.SetString(str, len, doc.GetAllocator());
|
val.SetString(str, len, doc.GetAllocator());
|
||||||
|
|
||||||
EXPECT_EQ(val.GetStringLength(), len);
|
EXPECT_EQ(val.GetStringLength(), len);
|
||||||
EXPECT_STREQ(val.GetString(), str);
|
EXPECT_STREQ(val.GetString(), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Value, AllocateShortString) {
|
TEST(Value, AllocateShortString) {
|
||||||
TestShortStringOptimization(""); // edge case: empty string
|
TestShortStringOptimization(""); // edge case: empty string
|
||||||
TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
|
TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars
|
||||||
TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
|
TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string)
|
||||||
TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
|
TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string)
|
||||||
TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
|
TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string)
|
||||||
TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
|
TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <int e>
|
template <int e>
|
||||||
|
@ -1802,7 +1802,7 @@ static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
|
||||||
// Convert all key:value into key:[value]
|
// Convert all key:value into key:[value]
|
||||||
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
|
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
|
||||||
itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
|
itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
|
||||||
|
|
||||||
// Merge arrays if key is duplicated
|
// Merge arrays if key is duplicated
|
||||||
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
|
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();) {
|
||||||
Value::MemberIterator itr2 = v.FindMember(itr->name);
|
Value::MemberIterator itr2 = v.FindMember(itr->name);
|
||||||
|
|
|
@ -15,3 +15,12 @@
|
||||||
Memcheck:Value8
|
Memcheck:Value8
|
||||||
fun:__wcslen_sse2
|
fun:__wcslen_sse2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Suppress wmemcmp valgrind report 4
|
||||||
|
Memcheck:Addr32
|
||||||
|
fun:__wmemcmp_avx2_movbe
|
||||||
|
...
|
||||||
|
fun:*Uri*Parse_UTF16_Std*
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue