ext/rj_schema/rapidjson/include/rapidjson/pointer.h in rj_schema-1.0.0 vs ext/rj_schema/rapidjson/include/rapidjson/pointer.h in rj_schema-1.0.1
- old
+ new
@@ -14,10 +14,11 @@
#ifndef RAPIDJSON_POINTER_H_
#define RAPIDJSON_POINTER_H_
#include "document.h"
+#include "uri.h"
#include "internal/itoa.h"
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(switch-enum)
@@ -78,11 +79,13 @@
template <typename ValueType, typename Allocator = CrtAllocator>
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.
/*!
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.
They are resolved according to the actual value type (object or array).
@@ -161,11 +164,11 @@
\endcode
*/
GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
//! Copy constructor.
- GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
+ GenericPointer(const GenericPointer& rhs) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
*this = rhs;
}
//! Copy constructor.
GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
@@ -517,9 +520,73 @@
ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
return Create(document, document.GetAllocator(), alreadyExist);
}
//@}
+
+ //!@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 rootUri Root URI
+ \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
+ \param allocator Allocator for Uris
+ \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, Allocator* allocator = 0) const {
+ static const Ch kIdString[] = { 'i', 'd', '\0' };
+ static const ValueType kIdValue(kIdString, 2);
+ UriType base = UriType(rootUri, allocator);
+ 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, Allocator* allocator = 0) const {
+ return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator);
+ }
+
//!@name Query value
//@{
//! Query a value in a subtree.