-
-
Notifications
You must be signed in to change notification settings - Fork 177
/
Copy pathupdate_json_in_place_examples.cpp
112 lines (93 loc) · 2.71 KB
/
update_json_in_place_examples.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2013-2025 Daniel Parker
// Distributed under Boost license
#include <jsoncons/json.hpp>
#include <iostream>
using namespace jsoncons;
class string_locator : public jsoncons::default_json_visitor
{
char* data_;
std::size_t length_;
std::vector<std::string> path_;
std::string from_;
std::vector<std::string> current_;
std::vector<std::size_t> positions_;
public:
using jsoncons::default_json_visitor::string_view_type;
string_locator(char* data, std::size_t length,
const std::vector<std::string>& path,
const std::string& from)
: data_(data), length_(length),
path_(path), from_(from)
{
}
const std::vector<std::size_t>& positions() const
{
return positions_;
}
private:
bool visit_begin_object(semantic_tag, const ser_context&, std::error_code&) override
{
current_.emplace_back();
return true;
}
bool visit_end_object(const ser_context&, std::error_code&) override
{
current_.pop_back();
return true;
}
bool visit_key(const string_view_type& key, const ser_context&, std::error_code&) override
{
current_.back() = std::string(key);
return true;
}
bool visit_string(const string_view_type& value,
jsoncons::semantic_tag,
const jsoncons::ser_context& context,
std::error_code&) override
{
if (path_.size() <= current_.size() && std::equal(path_.rbegin(), path_.rend(), current_.rbegin()))
{
if (value == from_)
{
positions_.push_back(context.position()+1); // one past quote character
}
}
return true;
}
};
void update_json_in_place(std::string& input,
const std::vector<std::string>& path,
const std::string& from,
const std::string& to)
{
if (input.size() > 0)
{
string_locator locator(&input[0], input.size(), path, from);
jsoncons::json_string_reader reader(input, locator);
reader.read();
for (auto it = locator.positions().rbegin(); it != locator.positions().rend(); ++it)
{
input.replace(*it, from.size(), to);
}
}
}
int main()
{
std::cout << "\njson update in place examples\n\n";
std::string input = R"(
{
"Cola" : {"Type":"Drink", "Price": 10.99},"Water" : {"Type":"Drink"}, "Extra" : {"Cola" : {"Type":"Drink", "Price": 8.99}}
}
)";
try
{
std::cout << "(original)\n" << input << "\n";
update_json_in_place(input, {"Cola", "Type"}, "Drink", "SoftDrink");
std::cout << "(updated)\n" << input << "\n";
}
catch (std::exception& e)
{
std::cout << e.what() << "\n";
}
std::cout << '\n';
}