Skip to content

Commit

Permalink
Merge 6d253c1 into 17aa824
Browse files Browse the repository at this point in the history
  • Loading branch information
smhdfdl committed Jun 8, 2021
2 parents 17aa824 + 6d253c1 commit eee0e85
Show file tree
Hide file tree
Showing 11 changed files with 1,933 additions and 108 deletions.
69 changes: 69 additions & 0 deletions bin/unittestschema/idandref.json
@@ -0,0 +1,69 @@
{
"id": "http://example.com/root.json",
"definitions": {
"A": {
"id": "#foo",
"type": "integer"
},
"B": {
"id": "other.json",
"definitions": {
"X": {
"id": "#bar",
"type": "boolean"
},
"Y": {
"$ref": "#/definitions/X"
},
"W": {
"$ref": "#/definitions/Y"
},
"Z": {
"$ref": "#bar"
},
"N": {
"properties": {
"NX": {
"$ref": "#/definitions/X"
}
}
}
}
}
},
"properties": {
"PA1": {
"$ref": "http://example.com/root.json#/definitions/A"
},
"PA2": {
"$ref": "#/definitions/A"
},
"PA3": {
"$ref": "#foo"
},
"PX1": {
"$ref": "#/definitions/B/definitions/X"
},
"PX2Y": {
"$ref": "#/definitions/B/definitions/Y"
},
"PX3Z": {
"$ref": "#/definitions/B/definitions/Z"
},
"PX4": {
"$ref": "http://example.com/other.json#/definitions/X"
},
"PX5": {
"$ref": "other.json#/definitions/X"
},
"PX6": {
"$ref": "other.json#bar"
},
"PX7W": {
"$ref": "#/definitions/B/definitions/W"
},
"PX8N": {
"$ref": "#/definitions/B/definitions/N"
}
}
}
2 changes: 2 additions & 0 deletions example/schemavalidator/schemavalidator.cpp
Expand Up @@ -2,6 +2,8 @@

// The example validates JSON text from stdin with a JSON schema specified in the argument.

#define RAPIDJSON_HAS_STDSTRING 1

#include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/schema.h"
Expand Down
2 changes: 1 addition & 1 deletion include/rapidjson/document.h
Expand Up @@ -1951,7 +1951,7 @@ class GenericValue {
case kArrayType:
if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
return false;
for (const GenericValue* v = Begin(); v != End(); ++v)
for (ConstValueIterator v = Begin(); v != End(); ++v)
if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
return false;
return handler.EndArray(data_.a.size);
Expand Down
14 changes: 14 additions & 0 deletions include/rapidjson/internal/strfunc.h
Expand Up @@ -45,6 +45,20 @@ inline SizeType StrLen(const wchar_t* s) {
return SizeType(std::wcslen(s));
}

//! Custom strcmpn() which works on different character types.
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
\param s1 Null-terminated input string.
\param s2 Null-terminated input string.
\return 0 if equal
*/
template<typename Ch>
inline int StrCmp(const Ch* s1, const Ch* s2) {
RAPIDJSON_ASSERT(s1 != 0);
RAPIDJSON_ASSERT(s2 != 0);
while(*s1 && (*s1 == *s2)) { s1++; s2++; }
return static_cast<unsigned>(*s1) < static_cast<unsigned>(*s2) ? -1 : static_cast<unsigned>(*s1) > static_cast<unsigned>(*s2);
}

//! Returns number of code points in a encoded string.
template<typename Encoding>
bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
Expand Down
65 changes: 65 additions & 0 deletions include/rapidjson/pointer.h
Expand Up @@ -16,6 +16,7 @@
#define RAPIDJSON_POINTER_H_

#include "document.h"
#include "uri.h"
#include "internal/itoa.h"

#ifdef __clang__
Expand Down Expand Up @@ -80,6 +81,8 @@ class GenericPointer {
public:
typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value
typedef typename ValueType::Ch Ch; //!< Character type from Value
typedef GenericUri<ValueType, Allocator> UriType;


//! A token is the basic units of internal representation.
/*!
Expand Down Expand Up @@ -520,6 +523,68 @@ class GenericPointer {

//@}

//!@name Compute URI
//@{

//! Compute the in-scope URI for a subtree.
// For use with JSON pointers into JSON schema documents.
/*!
\param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
\param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
\return Uri if it can be resolved. Otherwise null.
\note
There are only 3 situations when a URI cannot be resolved:
1. A value in the path is not an array nor object.
2. An object value does not contain the token.
3. A token is out of range of an array value.
Use unresolvedTokenIndex to retrieve the token index.
*/
UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0) const {
static const Ch kIdString[] = { 'i', 'd', '\0' };
static const ValueType kIdValue(kIdString, 2);
UriType base = rootUri;
RAPIDJSON_ASSERT(IsValid());
ValueType* v = &root;
for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
switch (v->GetType()) {
case kObjectType:
{
// See if we have an id, and if so resolve with the current base
typename ValueType::MemberIterator m = v->FindMember(kIdValue);
if (m != v->MemberEnd() && (m->value).IsString()) {
UriType here = UriType(m->value, allocator_).Resolve(base, allocator_);
base = here;
}
m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length)));
if (m == v->MemberEnd())
break;
v = &m->value;
}
continue;
case kArrayType:
if (t->index == kPointerInvalidIndex || t->index >= v->Size())
break;
v = &((*v)[t->index]);
continue;
default:
break;
}

// Error: unresolved token
if (unresolvedTokenIndex)
*unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
return UriType(allocator_);
}
return base;
}

UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0) const {
return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex);
}


//!@name Query value
//@{

Expand Down

0 comments on commit eee0e85

Please sign in to comment.