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. \para
| 538 | Use unresolvedTokenIndex to retrieve the token index. |
| 539 | */ |
| 540 | UriType GetUri(ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { |
| 541 | static const Ch kIdString[] = { 'i', 'd', '\0' }; |
| 542 | static const ValueType kIdValue(kIdString, 2); |
| 543 | UriType base = UriType(rootUri, allocator); |
| 544 | RAPIDJSON_ASSERT(IsValid()); |
| 545 | ValueType* v = &root; |
| 546 | for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { |
| 547 | switch (v->GetType()) { |
| 548 | case kObjectType: |
| 549 | { |
| 550 | // See if we have an id, and if so resolve with the current base |
| 551 | typename ValueType::MemberIterator m = v->FindMember(kIdValue); |
| 552 | if (m != v->MemberEnd() && (m->value).IsString()) { |
| 553 | UriType here = UriType(m->value, allocator).Resolve(base, allocator); |
| 554 | base = here; |
| 555 | } |
| 556 | m = v->FindMember(GenericValue<EncodingType>(GenericStringRef<Ch>(t->name, t->length))); |
| 557 | if (m == v->MemberEnd()) |
| 558 | break; |
| 559 | v = &m->value; |
| 560 | } |
| 561 | continue; |
| 562 | case kArrayType: |
| 563 | if (t->index == kPointerInvalidIndex || t->index >= v->Size()) |
| 564 | break; |
| 565 | v = &((*v)[t->index]); |
| 566 | continue; |
| 567 | default: |
| 568 | break; |
| 569 | } |
| 570 | |
| 571 | // Error: unresolved token |
| 572 | if (unresolvedTokenIndex) |
| 573 | *unresolvedTokenIndex = static_cast<size_t>(t - tokens_); |
| 574 | return UriType(allocator); |
| 575 | } |
| 576 | return base; |
| 577 | } |
| 578 | |
| 579 | UriType GetUri(const ValueType& root, const UriType& rootUri, size_t* unresolvedTokenIndex = 0, Allocator* allocator = 0) const { |
| 580 | return GetUri(const_cast<ValueType&>(root), rootUri, unresolvedTokenIndex, allocator); |