5 #ifndef PACKIO_NL_JSON_RPC_INCREMENTAL_BUFFERS_H
6 #define PACKIO_NL_JSON_RPC_INCREMENTAL_BUFFERS_H
12 #include <string_view>
16 namespace nl_json_rpc {
18 class incremental_buffers {
20 std::size_t available_buffers()
const
22 return serialized_objects_.size();
25 std::optional<std::string> get_parsed_buffer()
27 if (serialized_objects_.empty()) {
31 auto buffer = std::move(serialized_objects_.front());
32 serialized_objects_.pop_front();
36 void feed(std::string_view data)
38 reserve_in_place_buffer(data.size());
39 std::copy(begin(data), end(data), in_place_buffer());
40 in_place_buffer_consumed(data.size());
43 char* in_place_buffer()
45 return raw_buffer_.data() + buffer_.size();
48 std::size_t in_place_buffer_capacity()
const
50 return raw_buffer_.size() - buffer_.size();
53 void in_place_buffer_consumed(std::size_t bytes)
58 incremental_parse(bytes);
61 void reserve_in_place_buffer(std::size_t bytes)
63 if (in_place_buffer_capacity() >= bytes) {
66 raw_buffer_.resize(buffer_.size() + bytes);
70 void incremental_parse(std::size_t bytes)
76 if (buffer_.empty()) {
77 std::string_view new_data{in_place_buffer(), bytes};
78 auto first_pos = new_data.find_first_of(
"{[");
79 if (first_pos == std::string::npos) {
83 initialize(new_data[first_pos]);
86 std::size_t search_pos = buffer_.size();
87 buffer_ = std::string_view{raw_buffer_.data(), buffer_.size() + bytes};
90 auto token_pos = buffer_.find_first_of(tokens_, search_pos);
91 if (token_pos == std::string::npos) {
94 search_pos = token_pos + 1;
96 char token = buffer_[token_pos];
97 if (token ==
'"' && !is_escaped(token_pos)) {
98 in_string_ = !in_string_;
106 if (token == last_char_) {
109 std::size_t object_size = token_pos + 1;
110 serialized_objects_.emplace_back(
111 raw_buffer_.data(), object_size);
112 std::size_t bytes_left = buffer_.size() - object_size;
114 raw_buffer_.begin() + object_size,
115 raw_buffer_.begin() + object_size + bytes_left,
116 raw_buffer_.begin());
117 buffer_ = std::string_view{raw_buffer_.data(), bytes_left};
118 token_pos -= object_size;
119 search_pos -= object_size;
123 assert(token == first_char_);
129 bool is_escaped(std::size_t pos)
131 bool escaped =
false;
133 if (buffer_[pos] ==
'\\') {
143 void initialize(
char first_char)
145 first_char_ = first_char;
146 if (first_char_ ==
'{') {
151 assert(first_char_ ==
'[');
165 std::string_view buffer_;
166 std::vector<char> raw_buffer_;
168 std::deque<std::string> serialized_objects_;
The packio namespace.
Definition: arg.h:14