Skip to content

add a new method to insert a new value in an array at specific index. #949

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Oct 16, 2019
Merged
5 changes: 5 additions & 0 deletions include/json/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,12 @@ Json::Value obj_value(Json::objectValue); // {}
///
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value& append(const Value& value);
/// \brief Insert value in array at specific index
bool insert(ArrayIndex index, const Value& newValue);
#if JSON_HAS_RVALUE_REFERENCES
Value& append(Value&& value);
bool insert(ArrayIndex index, Value&& newValue);
#endif

/// Access an object value by name, create a null member if it does not exist.
/// \note Because of our implementation, keys are limited to 2^30 -1 chars.
Expand Down
40 changes: 38 additions & 2 deletions src/lib_json/json_value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,11 +1170,48 @@ Value const& Value::operator[](CppTL::ConstString const& key) const {
#endif

Value& Value::append(const Value& value) { return (*this)[size()] = value; }
/// \brief Insert value in array at specific index
bool Value::insert(ArrayIndex index, const Value& newValue) {
if (type() != arrayValue) {
return false;
}
if (!isValidIndex(index)) {
return false;
}
ArrayIndex oldsize = size();
resize(oldsize + 1);
ArrayIndex length = size();

for (ArrayIndex i = length; i > index; i--) {
CZString key(i);
(*value_.map_)[key] = (*this)[i - 1];
}
(*this)[index] = newValue;
return true;
}
#if JSON_HAS_RVALUE_REFERENCES
Value& Value::append(Value&& value) {
return (*this)[size()] = std::move(value);
}
bool Value::insert(ArrayIndex index, Value&& newValue) {
if (type() != arrayValue) {
return false;
}
if (!isValidIndex(index)) {
return false;
}
ArrayIndex oldsize = size();
resize(oldsize + 1);
ArrayIndex length = size();

for (ArrayIndex i = length; i > index; i--) {
CZString key(i);
(*value_.map_)[key] = std::move((*this)[i - 1]);
}
(*this)[index] = std::move(newValue);
return true;
}
#endif
Value Value::get(char const* begin,
char const* end,
Value const& defaultValue) const {
Expand Down Expand Up @@ -1436,8 +1473,7 @@ bool Value::isObject() const { return type() == objectValue; }
Value::Comments::Comments(const Comments& that)
: ptr_{cloneUnique(that.ptr_)} {}

Value::Comments::Comments(Comments&& that)
: ptr_{std::move(that.ptr_)} {}
Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {}

Value::Comments& Value::Comments::operator=(const Comments& that) {
ptr_ = cloneUnique(that.ptr_);
Expand Down
4 changes: 2 additions & 2 deletions src/test_lib_json/jsontest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,8 @@ void Runner::preventDialogOnCrash() {
_CrtSetReportHook(&msvcrtSilentReportHook);
#endif // if defined(_MSC_VER)

// @todo investigate this handler (for buffer overflow)
// _set_security_error_handler
// @todo investigate this handler (for buffer overflow)
// _set_security_error_handler

#if defined(_WIN32)
// Prevents the system from popping a dialog for debugging if the
Expand Down
41 changes: 36 additions & 5 deletions src/test_lib_json/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,17 @@ JSONTEST_FIXTURE(ValueTest, objects) {
JSONTEST_ASSERT_EQUAL(Json::Value(1234), *foundId);

const char unknownIdKey[] = "unknown id";
const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey));
const Json::Value* foundUnknownId =
object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey));
JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId);

// Access through demand()
const char yetAnotherIdKey[] = "yet another id";
const Json::Value* foundYetAnotherId = object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey));
const Json::Value* foundYetAnotherId =
object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey));
JSONTEST_ASSERT_EQUAL(nullptr, foundYetAnotherId);
Json::Value* demandedYetAnotherId = object1_.demand(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey));
Json::Value* demandedYetAnotherId = object1_.demand(
yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey));
JSONTEST_ASSERT(demandedYetAnotherId != nullptr);
*demandedYetAnotherId = "baz";

Expand Down Expand Up @@ -307,7 +310,34 @@ JSONTEST_FIXTURE(ValueTest, arrayIssue252) {
}
// JSONTEST_ASSERT_EQUAL(5, root["array"].size());
}

JSONTEST_FIXTURE(ValueTest, arrayInsertAtRandomIndex) {
Json::Value array;
JSONCPP_STRING str = "index5";
array.append("index0");
array.append("index1");
array.append("index2");
array.append("index3");

JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]);
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]);
JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[3]);

array.insert(3, "index4"); // rvalue
JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]);
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]);
JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[3]);
JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[4]);

array.insert(4, str); // lvalue
JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]);
JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]);
JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]);
JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[3]);
JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array[4]);
JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[5]);
}
JSONTEST_FIXTURE(ValueTest, null) {
JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type());

Expand Down Expand Up @@ -2495,7 +2525,7 @@ JSONTEST_FIXTURE(IteratorTest, const) {
Json::Value const v;
JSONTEST_ASSERT_THROWS(
Json::Value::iterator it(v.begin()) // Compile, but throw.
);
);

Json::Value value;

Expand Down Expand Up @@ -2535,6 +2565,7 @@ int main(int argc, const char* argv[]) {
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, objects);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrays);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayIssue252);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayInsertAtRandomIndex);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, null);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, strings);
JSONTEST_REGISTER_FIXTURE(runner, ValueTest, bools);
Expand Down