enables erase by json_pointer

This commit is contained in:
Timothy Prepscius 2018-10-23 16:41:49 -04:00
parent 9294e25c98
commit 44166ff4d6
2 changed files with 113 additions and 0 deletions

View File

@ -347,6 +347,80 @@ class json_pointer
return *ptr;
}
/*!
@throw parse_error.106 if an array index begins with '0'
@throw parse_error.109 if an array index was not a number
@throw out_of_range.402 if the array index '-' is used
@throw out_of_range.404 if the JSON pointer can not be resolved
*/
void erase_checked(BasicJsonType* ptr) const
{
BasicJsonType* previous = nullptr;
using size_type = typename BasicJsonType::size_type;
for (const auto& reference_token : reference_tokens)
{
previous = ptr;
switch (ptr->m_type)
{
case detail::value_t::object:
{
// note: at performs range check
ptr = &ptr->at(reference_token);
break;
}
case detail::value_t::array:
{
if (JSON_UNLIKELY(reference_token == "-"))
{
// "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402,
"array index '-' (" + std::to_string(ptr->m_value.array->size()) +
") is out of range"));
}
// error condition (cf. RFC 6901, Sect. 4)
if (JSON_UNLIKELY(reference_token.size() > 1 and reference_token[0] == '0'))
{
JSON_THROW(detail::parse_error::create(106, 0,
"array index '" + reference_token +
"' must not begin with '0'"));
}
// note: at performs range check
JSON_TRY
{
ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
}
JSON_CATCH(std::invalid_argument&)
{
JSON_THROW(detail::parse_error::create(109, 0, "array index '" + reference_token + "' is not a number"));
}
break;
}
default:
JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'"));
}
}
// if we get here, it means that no exception was thrown, so therefore the value specified to
// erase exists
// if previous exists, it means that the specified json value was not a root, so, we use the previous
// object and erase from it
if (previous)
{
previous->erase(reference_tokens.back());
}
else
{
// what to do
}
}
/*!
@brief return a const reference to the pointed to value

View File

@ -7085,6 +7085,45 @@ class basic_json
{
return ptr.get_checked(this);
}
/*!
@brief remove element from a JSON tree given a pointer
Removes elements from a JSON tree with the pointer value @ptr
@param[in] pointer value of the elements to remove
@post References and iterators to the erased elements are invalidated.
Other references and iterators are not affected.
@throw parse_error.106 if an array index in the passed JSON pointer @a ptr
begins with '0'. See example below.
@throw parse_error.109 if an array index in the passed JSON pointer @a ptr
is not a number. See example below.
@throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
is out of range. See example below.
@throw out_of_range.402 if the array index '-' is used in the passed JSON
pointer @a ptr. As `at` provides checked access (and no elements are
implicitly inserted), the index '-' is always invalid. See example below.
@throw out_of_range.403 if the JSON pointer describes a key of an object
which cannot be found. See example below.
@throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
See example below.
@complexity
@since version
*/
void erase(const json_pointer& ptr)
{
ptr.erase_checked(this);
}
/*!
@brief return flattened JSON value