Fix ambiguous cases in Pointer::Create()
This commit is contained in:
parent
b6a54f7244
commit
436625f83c
@ -305,19 +305,31 @@ public:
|
|||||||
ValueType* v = &root;
|
ValueType* v = &root;
|
||||||
bool exist = true;
|
bool exist = true;
|
||||||
for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
|
||||||
if (t->index == kPointerInvalidIndex) { // object name
|
if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
|
||||||
// Handling of '-' for last element of array
|
v->PushBack(Value().Move(), allocator);
|
||||||
if (t->name[0] == '-' && t->length == 1) {
|
v = &((*v)[v->Size() - 1]);
|
||||||
if (!v->IsArray())
|
exist = false;
|
||||||
v->SetArray(); // Change to Array
|
}
|
||||||
v->PushBack(Value().Move(), allocator);
|
else {
|
||||||
v = &((*v)[v->Size() - 1]);
|
if (t->index == kPointerInvalidIndex) { // must be object name
|
||||||
exist = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!v->IsObject())
|
if (!v->IsObject())
|
||||||
v->SetObject(); // Change to Object
|
v->SetObject(); // Change to Object
|
||||||
|
}
|
||||||
|
else { // object name or array index
|
||||||
|
if (!v->IsArray() && !v->IsObject())
|
||||||
|
v->SetArray(); // Change to Array
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v->IsArray()) {
|
||||||
|
if (t->index >= v->Size()) {
|
||||||
|
v->Reserve(t->index + 1, allocator);
|
||||||
|
while (t->index >= v->Size())
|
||||||
|
v->PushBack(Value().Move(), allocator);
|
||||||
|
exist = false;
|
||||||
|
}
|
||||||
|
v = &((*v)[t->index]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
|
||||||
if (m == v->MemberEnd()) {
|
if (m == v->MemberEnd()) {
|
||||||
v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator);
|
v->AddMember(Value(t->name, t->length, allocator).Move(), Value().Move(), allocator);
|
||||||
@ -328,18 +340,6 @@ public:
|
|||||||
v = &m->value;
|
v = &m->value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // array index
|
|
||||||
if (!v->IsArray())
|
|
||||||
v->SetArray(); // Change to Array
|
|
||||||
|
|
||||||
if (t->index >= v->Size()) {
|
|
||||||
v->Reserve(t->index + 1, allocator);
|
|
||||||
while (t->index >= v->Size())
|
|
||||||
v->PushBack(Value().Move(), allocator);
|
|
||||||
exist = false;
|
|
||||||
}
|
|
||||||
v = &((*v)[t->index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alreadyExist)
|
if (alreadyExist)
|
||||||
|
@ -532,9 +532,13 @@ TEST(Pointer, Create) {
|
|||||||
Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
|
Value* v = &Pointer("/foo/-").Create(d, d.GetAllocator());
|
||||||
EXPECT_EQ(&d["foo"][1], v);
|
EXPECT_EQ(&d["foo"][1], v);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
|
Value* v = &Pointer("/foo/-/-").Create(d, d.GetAllocator());
|
||||||
EXPECT_EQ(&d["foo"][2][0], v);
|
// "foo/-" is a newly created null value x.
|
||||||
|
// "foo/-/-" finds that x is not an array, it converts x to empty object
|
||||||
|
// and treats - as "-" member name
|
||||||
|
EXPECT_EQ(&d["foo"][2]["-"], v);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1314,3 +1318,22 @@ TEST(Pointer, SwapValueByPointer_NoAllocator) {
|
|||||||
EXPECT_STREQ("bar", d["foo"][0].GetString());
|
EXPECT_STREQ("bar", d["foo"][0].GetString());
|
||||||
EXPECT_STREQ("baz", d["foo"][1].GetString());
|
EXPECT_STREQ("baz", d["foo"][1].GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Pointer, Ambiguity) {
|
||||||
|
{
|
||||||
|
Document d;
|
||||||
|
d.Parse("{\"0\" : [123]}");
|
||||||
|
EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
|
||||||
|
Pointer("/0/a").Set(d, 456); // Change array [123] to object {456}
|
||||||
|
EXPECT_EQ(456, Pointer("/0/a").Get(d)->GetInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Document d;
|
||||||
|
EXPECT_FALSE(d.Parse("[{\"0\": 123}]").HasParseError());
|
||||||
|
EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
|
||||||
|
Pointer("/0/1").Set(d, 456); // 1 is treated as "1" to index object
|
||||||
|
EXPECT_EQ(123, Pointer("/0/0").Get(d)->GetInt());
|
||||||
|
EXPECT_EQ(456, Pointer("/0/1").Get(d)->GetInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user