bool is_obj{false}; /* either obj field or array entity */
string name; /* if obj */
int index{0}; /* if array */
+ bool append{false};
field_entity() {}
field_entity(const string& n) : is_obj(true), name(n) {}
ofs = end_arr + 1;
- result->push_back(field_entity(atoi(index_str.c_str())));
+ if (!index_str.empty()) {
+ result->push_back(field_entity(atoi(index_str.c_str())));
+ } else {
+ field_entity f;
+ f.append = true;
+ result->push_back(f);
+ }
}
return 0;
}
if (vi.is_obj) {
return -EINVAL;
}
- if ((size_t)vi.index >= f->arr.size()) {
- f->arr.resize(vi.index + 1);
+ int index = vi.index;
+ if (vi.append) {
+ index = f->arr.size();
+ } else if (index < 0) {
+ index = f->arr.size() + index;
+ if (index < 0) {
+ return -EINVAL; /* out of bounds */
+ }
}
- f = &f->arr[vi.index];
+ if ((size_t)index >= f->arr.size()) {
+ f->arr.resize(index + 1);
+ }
+ f = &f->arr[index];
}
}
}
parent = f;
- last_entity = vi;
-
if (f->type == FMT_OBJ) {
if (!vi.is_obj) {
return -EINVAL;
if (vi.is_obj) {
return -EINVAL;
}
+ if (vi.index < 0) {
+ vi.index = f->arr.size() + vi.index;
+ if (vi.index < 0) { /* out of bounds, nothing to remove */
+ return 0;
+ }
+ }
if ((size_t)vi.index >= f->arr.size()) {
return 0; /* index beyond array boundaries */
}
f = &f->arr[vi.index];
}
+ last_entity = vi;
}
}
ASSERT_EQ(f["bbb"][0].array().size(), 2);
ASSERT_EQ((int)f["bbb"][0][1], 25);
+ f.set("bbb[0][]", "26"); /* append operation */
+ ASSERT_EQ((int)f["bbb"][0][2], 26);
+ f.set("bbb[0][-1]", "27"); /* replace last */
+ ASSERT_EQ((int)f["bbb"][0][2], 27);
+ ASSERT_EQ(f["bbb"][0].array().size(), 3);
+
f.set("foo.asd[0][0]", "{ \"field\": \"xyz\"}");
ASSERT_EQ((string)f["foo"]["asd"][0][0]["field"], "xyz");
f.erase("asd");
ASSERT_FALSE(f["asd"].exists(0));
ASSERT_FALSE(f.exists("asd"));
+
+ f.set("bbb[]", "10");
+ f.set("bbb[]", "20");
+ f.set("bbb[]", "30");
+ ASSERT_EQ((int)f["bbb"][0], 10);
+ ASSERT_EQ((int)f["bbb"][1], 20);
+ ASSERT_EQ((int)f["bbb"][2], 30);
+ f.erase("bbb[-2]");
+ ASSERT_FALSE(f.exists("bbb[2]"));
+
+ ASSERT_EQ((int)f["bbb"][0], 10);
+ ASSERT_EQ((int)f["bbb"][1], 30);
+
+ if (0) { /* for debugging when needed */
+ dumpf(f);
+ }
}