diff --git a/include/rapidjson/pointer.h b/include/rapidjson/pointer.h index c0b7ba1..bc2795f 100644 --- a/include/rapidjson/pointer.h +++ b/include/rapidjson/pointer.h @@ -166,27 +166,30 @@ public: ValueType* v = &root; bool exist = true; for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { - if (v->GetType() != kObjectType && v->GetType() != kArrayType) { - if (t->index == kPointerInvalidIndex) - v->SetObject(); - else - v->SetArray(); - } - - if (t->index == kPointerInvalidIndex) { - if (!v->IsObject()) - v->SetObject(); // Change to Object - - typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); - if (m == v->MemberEnd()) { - v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator); - v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end + if (t->index == kPointerInvalidIndex) { // object name + // Handling of '-' for last element of array + if (t->name[0] == '-' && t->length == 1) { + if (!v->IsArray()) + v->SetArray(); // Change to Array + v->PushBack(Value().Move(), allocator); + v = &((*v)[v->Size() - 1]); exist = false; } - else - v = &m->value; + else { + if (!v->IsObject()) + v->SetObject(); // Change to Object + + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) { + v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator); + v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end + exist = false; + } + else + v = &m->value; + } } - else { + else { // array index if (!v->IsArray()) v->SetArray(); // Change to Array diff --git a/test/unittest/pointertest.cpp b/test/unittest/pointertest.cpp index c58b858..887a7f8 100644 --- a/test/unittest/pointertest.cpp +++ b/test/unittest/pointertest.cpp @@ -280,6 +280,14 @@ TEST(Pointer, Create) { Value* v = &Pointer("/foo/0").Create(d, d.GetAllocator()); EXPECT_EQ(&d["foo"][0], v); } + { + Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator()); + EXPECT_EQ(&d["foo"][1], v); + } + { + Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator()); + EXPECT_EQ(&d["foo"][2][0], v); + } } TEST(Pointer, Get) { @@ -310,6 +318,8 @@ TEST(Pointer, GetWithDefault) { EXPECT_TRUE(Value("bar") == Pointer("/foo/0").GetWithDefault(d, v, a)); EXPECT_TRUE(Value("baz") == Pointer("/foo/1").GetWithDefault(d, v, a)); EXPECT_TRUE(Value("qux") == Pointer("/foo/2").GetWithDefault(d, v, a)); + EXPECT_TRUE(Value("last") == Pointer("/foo/-").GetWithDefault(d, Value("last").Move(), a)); + EXPECT_STREQ("last", d["foo"][3].GetString()); } TEST(Pointer, Set) { @@ -321,6 +331,9 @@ TEST(Pointer, Set) { Pointer("/foo/0").Set(d, Value(123).Move(), a); EXPECT_EQ(123, d["foo"][0].GetInt()); + Pointer("/foo/-").Set(d, Value(456).Move(), a); + EXPECT_EQ(456, d["foo"][2].GetInt()); + Pointer("/foo/null").Set(d, Value().Move(), a); EXPECT_TRUE(GetValueByPointer(d, "/foo/null")->IsNull());