From 0244d5958a549aad491d9ddf4f41513876e60e28 Mon Sep 17 00:00:00 2001 From: Roy Bellingan Date: Sat, 15 Feb 2025 01:50:33 +0000 Subject: [PATCH 1/4] delete_at_pointer --- include/boost/json/impl/pointer.ipp | 102 ++++++++++++++++++++++++++++ include/boost/json/value.hpp | 7 ++ 2 files changed, 109 insertions(+) diff --git a/include/boost/json/impl/pointer.ipp b/include/boost/json/impl/pointer.ipp index d07c48082..57da07c78 100644 --- a/include/boost/json/impl/pointer.ipp +++ b/include/boost/json/impl/pointer.ipp @@ -415,6 +415,108 @@ value::find_pointer(string_view ptr, std::error_code& ec) noexcept return const_cast(self.find_pointer(ptr, ec)); } +std::pair +value::delete_at_pointer( + string_view sv, + system::error_code& ec) +{ + ec.clear(); + + + string_view previous_segment; + string_view sv_copy = sv; + string_view err_position; + string_view segment = detail::next_segment(sv, ec); + size_t shift = 0; + + auto result = this; + auto previous_result = this; + + while (true) + { + if (ec.failed()) + return {false, err_position}; + + if (!result) + { + BOOST_JSON_FAIL(ec, error::not_found); + return {false, err_position}; + } + + if( segment.empty() ) + break; + + shift += segment.size(); + err_position = sv_copy.substr(0, shift); + + previous_segment = segment; + previous_result = result; + + switch (result->kind()) + { + case kind::object: { + auto& obj = result->get_object(); + + detail::pointer_token const token(segment); + segment = detail::next_segment(sv, ec); + + result = detail::if_contains_token(obj, token); + if( !result ) + { + BOOST_JSON_FAIL(ec, error::not_found); + return {false, err_position}; + } + break; + } + case kind::array: { + auto const index = detail::parse_number_token(segment, ec); + segment = detail::next_segment(sv, ec); + + auto& arr = result->get_array(); + result = arr.if_contains(index); + if( !result ) + { + BOOST_JSON_FAIL(ec, error::past_the_end); + return {false, err_position}; + } + break; + } + default: { + BOOST_JSON_FAIL(ec, error::value_is_scalar); + return {false, err_position}; + } + } + } + + err_position = {}; + + switch (previous_result->kind()) + { + case kind::object: { + auto& obj = previous_result->get_object(); + detail::pointer_token const token(previous_segment); + key_value_pair* kv = detail::find_in_object(obj, token).first; + if (kv) { + obj.erase(kv); + return {true, err_position}; + } + } + case kind::array: { + auto const index = detail::parse_number_token(previous_segment, ec); + auto& arr = previous_result->get_array(); + if (arr.if_contains(index)){ + arr.erase(arr.begin() + index); + return {true, err_position}; + } + } + default: { + BOOST_JSON_FAIL(ec, error::value_is_scalar); + return {false, err_position}; + } + } + return {false, err_position}; +} + value* value::set_at_pointer( string_view sv, diff --git a/include/boost/json/value.hpp b/include/boost/json/value.hpp index 151b8e3e2..13b8650d5 100644 --- a/include/boost/json/value.hpp +++ b/include/boost/json/value.hpp @@ -3996,6 +3996,13 @@ class value set_pointer_options const& opts = {} ); /** @} */ + /** Remove an element via JSON Pointer. + */ + BOOST_JSON_DECL + std::pair + delete_at_pointer( + string_view sv, + system::error_code& ec); //------------------------------------------------------ /** Return `true` if two values are equal. From 21582608d293ee2ecd4b9b6ea6437580873f168c Mon Sep 17 00:00:00 2001 From: Roy Date: Sat, 15 Feb 2025 13:50:15 +0000 Subject: [PATCH 2/4] forget the falltrought --- include/boost/json/impl/pointer.ipp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/json/impl/pointer.ipp b/include/boost/json/impl/pointer.ipp index 57da07c78..c97a8c97a 100644 --- a/include/boost/json/impl/pointer.ipp +++ b/include/boost/json/impl/pointer.ipp @@ -500,6 +500,7 @@ value::delete_at_pointer( obj.erase(kv); return {true, err_position}; } + return {false,err_position}; } case kind::array: { auto const index = detail::parse_number_token(previous_segment, ec); @@ -508,6 +509,7 @@ value::delete_at_pointer( arr.erase(arr.begin() + index); return {true, err_position}; } + return {false,err_position}; } default: { BOOST_JSON_FAIL(ec, error::value_is_scalar); From 231143c0a19fe851fabb3d6d4ecd6dae21a591b4 Mon Sep 17 00:00:00 2001 From: Roy Date: Sat, 15 Feb 2025 15:09:36 +0000 Subject: [PATCH 3/4] build was failing on old gcc4 and 5, https://drone.cpp.al/boostorg/json/1791/15/2 ./boost/json/impl/pointer.ipp:457:18: error: 'kind' is not a class, namespace, or enumeration --- include/boost/json/impl/pointer.ipp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/json/impl/pointer.ipp b/include/boost/json/impl/pointer.ipp index c97a8c97a..aa17947f0 100644 --- a/include/boost/json/impl/pointer.ipp +++ b/include/boost/json/impl/pointer.ipp @@ -454,7 +454,7 @@ value::delete_at_pointer( switch (result->kind()) { - case kind::object: { + case boost::json::kind::object: { auto& obj = result->get_object(); detail::pointer_token const token(segment); @@ -468,7 +468,7 @@ value::delete_at_pointer( } break; } - case kind::array: { + case boost::json::kind::array: { auto const index = detail::parse_number_token(segment, ec); segment = detail::next_segment(sv, ec); @@ -492,7 +492,7 @@ value::delete_at_pointer( switch (previous_result->kind()) { - case kind::object: { + case boost::json::kind::object: { auto& obj = previous_result->get_object(); detail::pointer_token const token(previous_segment); key_value_pair* kv = detail::find_in_object(obj, token).first; @@ -502,7 +502,7 @@ value::delete_at_pointer( } return {false,err_position}; } - case kind::array: { + case boost::json::kind::array: { auto const index = detail::parse_number_token(previous_segment, ec); auto& arr = previous_result->get_array(); if (arr.if_contains(index)){ From c829369210d768d139fa37bfb015f65d5dc62262 Mon Sep 17 00:00:00 2001 From: Roy Bellingan Date: Sat, 15 Feb 2025 22:17:33 +0000 Subject: [PATCH 4/4] Update pointer.ipp Unreachable code removed. --- include/boost/json/impl/pointer.ipp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/boost/json/impl/pointer.ipp b/include/boost/json/impl/pointer.ipp index aa17947f0..65d6e340a 100644 --- a/include/boost/json/impl/pointer.ipp +++ b/include/boost/json/impl/pointer.ipp @@ -516,7 +516,6 @@ value::delete_at_pointer( return {false, err_position}; } } - return {false, err_position}; } value*