Skip to content

Commit 5b02aa2

Browse files
committed
Refactor json/rpc body to remove rpc request/response redundancy.
1 parent ae11696 commit 5b02aa2

File tree

5 files changed

+101
-59
lines changed

5 files changed

+101
-59
lines changed

include/bitcoin/network/messages/json/body.hpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,30 @@ namespace libbitcoin {
2727
namespace network {
2828
namespace json {
2929

30+
/// Content passed to/from reader/writer via request/response.
31+
/// `static uint64_t size(const value_type&)` must be defined for beast to
32+
/// produce `content_length`, otherwise the response is chunked. Predeter-
33+
/// mining size would have the effect of eliminating the benefit of
34+
/// streaming serialize.
35+
struct json_value
36+
{
37+
/// JSON document object model to parse/serialize.
38+
boost::json::value model{};
39+
40+
/// Used by channel to resize reusable buffer.
41+
size_t size_hint{};
42+
43+
/// Writer serialization buffer (max size, allocated on write).
44+
mutable http::flat_buffer_ptr buffer{};
45+
};
46+
3047
/// boost::beast::http body for JSON messages.
3148
/// Because of the parser and serializer members, neither the reader nor writer
3249
/// is movable and as such must be in-place contructed (e.g. variant contruct).
50+
template <typename Value = json_value>
3351
struct BCT_API body
3452
{
35-
/// Content passed to/from reader/writer via request/response.
36-
/// `static uint64_t size(const value_type&)` must be defined for beast to
37-
/// produce `content_length`, otherwise the response is chunked. Predeter-
38-
/// mining size would have the effect of eliminating the benefit of
39-
/// streaming serialize.
40-
struct value_type
41-
{
42-
/// JSON DOM.
43-
boost::json::value model{};
44-
45-
/// Used by channel to resize reusable buffer.
46-
size_t size_hint{};
47-
48-
/// Writer serialization buffer (max size, allocated on write).
49-
mutable http::flat_buffer_ptr buffer{};
50-
};
53+
using value_type = Value;
5154

5255
class reader
5356
{
@@ -117,7 +120,7 @@ namespace libbitcoin {
117120
namespace network {
118121
namespace http {
119122

120-
using json_body = json::body;
123+
using json_body = json::body<>;
121124

122125
} // namespace http
123126
} // namespace network

include/bitcoin/network/messages/monad/body.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace network {
3232
namespace monad {
3333

3434
using empty_reader = http::empty_body::reader;
35-
using json_reader = json::body::reader;
35+
using json_reader = http::json_body::reader;
3636
using data_reader = http::chunk_body::reader;
3737
using file_reader = http::file_body::reader;
3838
using span_reader = http::span_body::reader;
@@ -51,7 +51,7 @@ using body_reader = std::variant
5151
>;
5252

5353
using empty_writer = http::empty_body::writer;
54-
using json_writer = json::body::writer;
54+
using json_writer = http::json_body::writer;
5555
using data_writer = http::chunk_body::writer;
5656
using file_writer = http::file_body::writer;
5757
using span_writer = http::span_body::writer;
@@ -69,7 +69,7 @@ using body_writer = std::variant
6969
>;
7070

7171
using empty_value = http::empty_body::value_type;
72-
using json_value = json::body::value_type;
72+
using json_value = http::json_body::value_type;
7373
using data_value = http::chunk_body::value_type;
7474
using file_value = http::file_body::value_type;
7575
using span_value = http::span_body::value_type;

include/bitcoin/network/messages/rpc/body.hpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,56 +27,66 @@ namespace libbitcoin {
2727
namespace network {
2828
namespace rpc {
2929

30+
template <typename Type>
31+
struct value_type
32+
: public json::json_value
33+
{
34+
Type message{};
35+
};
36+
3037
/// Derived boost::beast::http body for JSON-RPC messages.
3138
/// Extends json::body with JSON-RPC validation.
39+
template <typename Message>
3240
struct BCT_API body
33-
: public json::body
41+
: public json::body<value_type<Message>>
3442
{
35-
struct value_type
36-
: json::body::value_type
37-
{
38-
request_t request{};
39-
response_t response{};
40-
};
43+
using message_value = value_type<Message>;
44+
using base = typename json::body<message_value>;
45+
using value_type = base::value_type;
4146

4247
class reader
43-
: public json::body::reader
48+
: public json::body<message_value>::reader
4449
{
4550
public:
51+
using reader_type = base::reader;
52+
using buffer_type = reader_type::buffer_type;
53+
4654
inline explicit reader(value_type& value) NOEXCEPT
47-
: json::body::reader{ value }, terminated_{ true }
55+
: reader_type{ value }, terminated_{ true }
4856
{
4957
}
5058

5159
template <bool IsRequest, class Fields>
5260
inline explicit reader(http::message_header<IsRequest, Fields>& header,
5361
value_type& value) NOEXCEPT
54-
: json::body::reader{ header, value }
62+
: reader_type{ header, value }
5563
{
5664
}
5765

5866
size_t put(const buffer_type& buffer, boost_code& ec) NOEXCEPT override;
5967
void finish(boost_code& ec) NOEXCEPT override;
60-
bool is_done() const NOEXCEPT;
6168

6269
private:
6370
const bool terminated_{};
6471
bool has_terminator_{};
6572
};
6673

6774
class writer
68-
: public json::body::writer
75+
: public json::body<message_value>::writer
6976
{
7077
public:
78+
using writer_type = base::writer;
79+
using out_buffer = writer_type::out_buffer;
80+
7181
inline explicit writer(value_type& value) NOEXCEPT
72-
: json::body::writer{ value }, terminate_{ true }
82+
: writer_type{ value }, terminate_{ true }
7383
{
7484
}
7585

7686
template <bool IsRequest, class Fields>
7787
inline explicit writer(http::message_header<IsRequest, Fields>& header,
7888
value_type& value) NOEXCEPT
79-
: json::body::writer{ header, value }
89+
: writer_type{ header, value }
8090
{
8191
}
8292

@@ -96,9 +106,11 @@ namespace libbitcoin {
96106
namespace network {
97107
namespace http {
98108

99-
using rpc_body = rpc::body;
100-
using rpc_request = boost::beast::http::request<rpc_body>;
101-
using rpc_response = boost::beast::http::response<rpc_body>;
109+
using rpc_request_body = rpc::body<rpc::request_t>;
110+
using rpc_response_body = rpc::body<rpc::response_t>;
111+
112+
using rpc_request = boost::beast::http::request<rpc_request_body>;
113+
using rpc_response = boost::beast::http::response<rpc_response_body>;
102114

103115
} // namespace http
104116
} // namespace network

src/messages/json/body.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ namespace json {
2929
using namespace system;
3030
using namespace network::error;
3131

32-
// json::body::reader
32+
// json::body<>::reader
3333
// ----------------------------------------------------------------------------
3434

35-
void body::reader::init(const http::length_type& length,
35+
void body<>::reader::init(const http::length_type& length,
3636
boost_code& ec) NOEXCEPT
3737
{
3838
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
@@ -54,7 +54,7 @@ void body::reader::init(const http::length_type& length,
5454
ec.clear();
5555
}
5656

57-
size_t body::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
57+
size_t body<>::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
5858
{
5959
try
6060
{
@@ -81,7 +81,7 @@ size_t body::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
8181
return {};
8282
}
8383

84-
void body::reader::finish(boost_code& ec) NOEXCEPT
84+
void body<>::reader::finish(boost_code& ec) NOEXCEPT
8585
{
8686
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
8787
parser_.finish(ec);
@@ -107,10 +107,10 @@ void body::reader::finish(boost_code& ec) NOEXCEPT
107107
parser_.reset();
108108
}
109109

110-
// json::body::writer
110+
// json::body<>::writer
111111
// ----------------------------------------------------------------------------
112112

113-
void body::writer::init(boost_code& ec) NOEXCEPT
113+
void body<>::writer::init(boost_code& ec) NOEXCEPT
114114
{
115115
if (!value_.buffer)
116116
{
@@ -127,7 +127,7 @@ void body::writer::init(boost_code& ec) NOEXCEPT
127127
serializer_.reset(&value_.model);
128128
}
129129

130-
body::writer::out_buffer body::writer::get(boost_code& ec) NOEXCEPT
130+
body<>::writer::out_buffer body<>::writer::get(boost_code& ec) NOEXCEPT
131131
{
132132
ec.clear();
133133
if (serializer_.done())

src/messages/rpc/body.cpp

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include <memory>
2222
#include <utility>
2323
#include <bitcoin/network/define.hpp>
24+
#include <bitcoin/network/messages/json/json.hpp>
25+
#include <bitcoin/network/rpc/rpc.hpp>
2426

2527
namespace libbitcoin {
2628
namespace network {
@@ -36,7 +38,8 @@ BC_PUSH_WARNING(NO_POINTER_ARITHMETIC)
3638
// rpc::body::reader
3739
// ----------------------------------------------------------------------------
3840

39-
size_t body::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
41+
size_t body<rpc::request_t>::reader::
42+
put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
4043
{
4144
const auto size = buffer.size();
4245
if (is_zero(size))
@@ -51,7 +54,7 @@ size_t body::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
5154
return {};
5255
}
5356

54-
const auto parsed = json::body::reader::put(buffer, ec);
57+
const auto parsed = base::reader::put(buffer, ec);
5558
if (ec || !parser_.done())
5659
return parsed;
5760

@@ -87,9 +90,10 @@ size_t body::reader::put(const buffer_type& buffer, boost_code& ec) NOEXCEPT
8790
return parsed;
8891
}
8992

90-
void body::reader::finish(boost_code& ec) NOEXCEPT
93+
void body<rpc::request_t>::reader::
94+
finish(boost_code& ec) NOEXCEPT
9195
{
92-
json::body::reader::finish(ec);
96+
base::reader::finish(ec);
9397
if (ec) return;
9498

9599
if (terminated_ && !has_terminator_)
@@ -98,11 +102,10 @@ void body::reader::finish(boost_code& ec) NOEXCEPT
98102
return;
99103
}
100104

101-
auto& derived = static_cast<body::value_type&>(value_);
102105
try
103106
{
104-
derived.request = value_to<rpc::request_t>(derived.model);
105-
derived.model.emplace_null();
107+
value_.message = value_to<rpc::request_t>(value_.model);
108+
value_.model.emplace_null();
106109
}
107110
catch (const boost::system::system_error& e)
108111
{
@@ -116,23 +119,31 @@ void body::reader::finish(boost_code& ec) NOEXCEPT
116119
}
117120
}
118121

119-
bool body::reader::is_done() const NOEXCEPT
122+
size_t body<rpc::response_t>::reader::
123+
put(const buffer_type&, boost_code&) NOEXCEPT
120124
{
121-
return parser_.done() && has_terminator_;
125+
BC_ASSERT(false);
126+
return {};
127+
}
128+
129+
void body<rpc::response_t>::reader::
130+
finish(boost_code&) NOEXCEPT
131+
{
132+
BC_ASSERT(false);
122133
}
123134

124135
// rpc::body::writer
125136
// ----------------------------------------------------------------------------
126137

127-
void body::writer::init(boost_code& ec) NOEXCEPT
138+
void body<rpc::response_t>::writer::
139+
init(boost_code& ec) NOEXCEPT
128140
{
129-
json::body::writer::init(ec);
141+
base::writer::init(ec);
130142
if (ec) return;
131143

132-
auto& derived = static_cast<body::value_type&>(value_);
133144
try
134145
{
135-
boost::json::value_from(derived.response, value_.model);
146+
boost::json::value_from(value_.message, value_.model);
136147
}
137148
catch (const boost::system::system_error& e)
138149
{
@@ -150,9 +161,11 @@ void body::writer::init(boost_code& ec) NOEXCEPT
150161
serializer_.reset(&value_.model);
151162
}
152163

153-
body::writer::out_buffer body::writer::get(boost_code& ec) NOEXCEPT
164+
body<rpc::response_t>::writer::out_buffer
165+
body<rpc::response_t>::writer::
166+
get(boost_code& ec) NOEXCEPT
154167
{
155-
auto out = json::body::writer::get(ec);
168+
auto out = base::writer::get(ec);
156169
if (ec || !terminate_) return out;
157170

158171
constexpr char more = true;
@@ -167,6 +180,20 @@ body::writer::out_buffer body::writer::get(boost_code& ec) NOEXCEPT
167180
return out_buffer{ std::make_pair(buffer(&line, sizeof(line)), !more) };
168181
}
169182

183+
void body<rpc::request_t>::writer::
184+
init(boost_code&) NOEXCEPT
185+
{
186+
BC_ASSERT(false);
187+
}
188+
189+
body<rpc::request_t>::writer::out_buffer
190+
body<rpc::request_t>::writer::
191+
get(boost_code&) NOEXCEPT
192+
{
193+
BC_ASSERT(false);
194+
return {};
195+
}
196+
170197
BC_POP_WARNING()
171198
BC_POP_WARNING()
172199
BC_POP_WARNING()

0 commit comments

Comments
 (0)