Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/bitcoin/network/net/socket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,12 @@ class BCT_API socket

typedef std::function<void(const code&, const socket::ptr&)> socket_handler;

// TODO: reimplement as template.
#define VARIANT_DISPATCH_METHOD(object, method) \
std::visit([&](auto&& value) NOEXCEPT \
{ \
value.get().method; \
}, object)

// TODO: reimplement as template.
#define VARIANT_DISPATCH_FUNCTION(function, object, ...) \
std::visit([&](auto&& value) NOEXCEPT \
{ \
Expand Down
244 changes: 122 additions & 122 deletions src/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,45 +534,44 @@ code asio_to_error_code(const boost_code& ec) NOEXCEPT
// includes json codes
code http_to_error_code(const boost_code& ec) NOEXCEPT
{
static const auto& category = to_http_code(
boost::beast::http::error::end_of_stream).category();

if (!ec)
return error::success;

if (ec.category() != category)
return json_to_error_code(ec);

switch (static_cast<http_error_t>(ec.value()))
if (ec.category() == to_http_code(http_error_t::end_of_stream).category())
{
case http_error_t::end_of_stream: return error::end_of_stream;
case http_error_t::partial_message: return error::partial_message;
case http_error_t::need_more: return error::need_more;
case http_error_t::unexpected_body: return error::unexpected_body;
case http_error_t::need_buffer: return error::need_buffer;
case http_error_t::end_of_chunk: return error::end_of_chunk;
case http_error_t::buffer_overflow: return error::buffer_overflow;
case http_error_t::header_limit: return error::header_limit;
case http_error_t::body_limit: return error::body_limit;
case http_error_t::bad_alloc: return error::bad_alloc;
case http_error_t::bad_line_ending: return error::bad_line_ending;
case http_error_t::bad_method: return error::bad_method;
case http_error_t::bad_target: return error::bad_target;
case http_error_t::bad_version: return error::bad_version;
case http_error_t::bad_status: return error::bad_status;
case http_error_t::bad_reason: return error::bad_reason;
case http_error_t::bad_field: return error::bad_field;
case http_error_t::bad_value: return error::bad_value;
case http_error_t::bad_content_length: return error::bad_content_length;
case http_error_t::bad_transfer_encoding: return error::bad_transfer_encoding;
case http_error_t::bad_chunk: return error::bad_chunk;
case http_error_t::bad_chunk_extension: return error::bad_chunk_extension;
case http_error_t::bad_obs_fold: return error::bad_obs_fold;
case http_error_t::multiple_content_length: return error::multiple_content_length;
case http_error_t::stale_parser: return error::stale_parser;
case http_error_t::short_read: return error::short_read;
default: return error::http_unknown;
switch (static_cast<http_error_t>(ec.value()))
{
case http_error_t::end_of_stream: return error::end_of_stream;
case http_error_t::partial_message: return error::partial_message;
case http_error_t::need_more: return error::need_more;
case http_error_t::unexpected_body: return error::unexpected_body;
case http_error_t::need_buffer: return error::need_buffer;
case http_error_t::end_of_chunk: return error::end_of_chunk;
case http_error_t::buffer_overflow: return error::buffer_overflow;
case http_error_t::header_limit: return error::header_limit;
case http_error_t::body_limit: return error::body_limit;
case http_error_t::bad_alloc: return error::bad_alloc;
case http_error_t::bad_line_ending: return error::bad_line_ending;
case http_error_t::bad_method: return error::bad_method;
case http_error_t::bad_target: return error::bad_target;
case http_error_t::bad_version: return error::bad_version;
case http_error_t::bad_status: return error::bad_status;
case http_error_t::bad_reason: return error::bad_reason;
case http_error_t::bad_field: return error::bad_field;
case http_error_t::bad_value: return error::bad_value;
case http_error_t::bad_content_length: return error::bad_content_length;
case http_error_t::bad_transfer_encoding: return error::bad_transfer_encoding;
case http_error_t::bad_chunk: return error::bad_chunk;
case http_error_t::bad_chunk_extension: return error::bad_chunk_extension;
case http_error_t::bad_obs_fold: return error::bad_obs_fold;
case http_error_t::multiple_content_length: return error::multiple_content_length;
case http_error_t::stale_parser: return error::stale_parser;
case http_error_t::short_read: return error::short_read;
default: return error::http_unknown;
}
}

return json_to_error_code(ec);
}

// includes asio codes
Expand All @@ -581,8 +580,7 @@ code ssl_to_error_code(const boost_code& ec) NOEXCEPT
if (!ec)
return error::success;

namespace stream = boost::asio::ssl::error;
if (ec.category() == stream::get_stream_category())
if (ec.category() == boost::asio::ssl::error::get_stream_category())
{
switch (static_cast<asio_ssl_stream_error_t>(ec.value()))
{
Expand Down Expand Up @@ -619,50 +617,49 @@ code ssl_to_error_code(const boost_code& ec) NOEXCEPT
// includes json codes
code ws_to_error_code(const boost_code& ec) NOEXCEPT
{
static const auto& category = to_websocket_code(
boost::beast::websocket::error::closed).category();

if (!ec)
return error::success;

if (ec.category() != category)
return http_to_error_code(ec);

switch (static_cast<ws_error_t>(ec.value()))
if (ec.category() == to_websocket_code(ws_error_t::closed).category())
{
case ws_error_t::closed: return error::websocket_closed;
case ws_error_t::buffer_overflow: return error::websocket_buffer_overflow;
case ws_error_t::partial_deflate_block: return error::partial_deflate_block;
case ws_error_t::message_too_big: return error::message_too_big;
case ws_error_t::bad_http_version: return error::bad_http_version;
case ws_error_t::bad_method: return error::websocket_bad_method;
case ws_error_t::no_host: return error::no_host;
case ws_error_t::no_connection: return error::no_connection;
case ws_error_t::no_connection_upgrade: return error::no_connection_upgrade;
case ws_error_t::no_upgrade: return error::no_upgrade;
case ws_error_t::no_upgrade_websocket: return error::no_upgrade_websocket;
case ws_error_t::no_sec_key: return error::no_sec_key;
case ws_error_t::bad_sec_key: return error::bad_sec_key;
case ws_error_t::no_sec_version: return error::no_sec_version;
case ws_error_t::bad_sec_version: return error::bad_sec_version;
case ws_error_t::no_sec_accept: return error::no_sec_accept;
case ws_error_t::bad_sec_accept: return error::bad_sec_accept;
case ws_error_t::upgrade_declined: return error::upgrade_declined;
case ws_error_t::bad_opcode: return error::bad_opcode;
case ws_error_t::bad_data_frame: return error::bad_data_frame;
case ws_error_t::bad_continuation: return error::bad_continuation;
case ws_error_t::bad_reserved_bits: return error::bad_reserved_bits;
case ws_error_t::bad_control_fragment: return error::bad_control_fragment;
case ws_error_t::bad_control_size: return error::bad_control_size;
case ws_error_t::bad_unmasked_frame: return error::bad_unmasked_frame;
case ws_error_t::bad_masked_frame: return error::bad_masked_frame;
case ws_error_t::bad_size: return error::bad_size;
case ws_error_t::bad_frame_payload: return error::bad_frame_payload;
case ws_error_t::bad_close_code: return error::bad_close_code;
case ws_error_t::bad_close_size: return error::bad_close_size;
case ws_error_t::bad_close_payload: return error::bad_close_payload;
default: return error::websocket_unknown;
switch (static_cast<ws_error_t>(ec.value()))
{
case ws_error_t::closed: return error::websocket_closed;
case ws_error_t::buffer_overflow: return error::websocket_buffer_overflow;
case ws_error_t::partial_deflate_block: return error::partial_deflate_block;
case ws_error_t::message_too_big: return error::message_too_big;
case ws_error_t::bad_http_version: return error::bad_http_version;
case ws_error_t::bad_method: return error::websocket_bad_method;
case ws_error_t::no_host: return error::no_host;
case ws_error_t::no_connection: return error::no_connection;
case ws_error_t::no_connection_upgrade: return error::no_connection_upgrade;
case ws_error_t::no_upgrade: return error::no_upgrade;
case ws_error_t::no_upgrade_websocket: return error::no_upgrade_websocket;
case ws_error_t::no_sec_key: return error::no_sec_key;
case ws_error_t::bad_sec_key: return error::bad_sec_key;
case ws_error_t::no_sec_version: return error::no_sec_version;
case ws_error_t::bad_sec_version: return error::bad_sec_version;
case ws_error_t::no_sec_accept: return error::no_sec_accept;
case ws_error_t::bad_sec_accept: return error::bad_sec_accept;
case ws_error_t::upgrade_declined: return error::upgrade_declined;
case ws_error_t::bad_opcode: return error::bad_opcode;
case ws_error_t::bad_data_frame: return error::bad_data_frame;
case ws_error_t::bad_continuation: return error::bad_continuation;
case ws_error_t::bad_reserved_bits: return error::bad_reserved_bits;
case ws_error_t::bad_control_fragment: return error::bad_control_fragment;
case ws_error_t::bad_control_size: return error::bad_control_size;
case ws_error_t::bad_unmasked_frame: return error::bad_unmasked_frame;
case ws_error_t::bad_masked_frame: return error::bad_masked_frame;
case ws_error_t::bad_size: return error::bad_size;
case ws_error_t::bad_frame_payload: return error::bad_frame_payload;
case ws_error_t::bad_close_code: return error::bad_close_code;
case ws_error_t::bad_close_size: return error::bad_close_size;
case ws_error_t::bad_close_payload: return error::bad_close_payload;
default: return error::websocket_unknown;
}
}

return http_to_error_code(ec);
}

// includes asio codes
Expand All @@ -671,52 +668,54 @@ code json_to_error_code(const boost_code& ec) NOEXCEPT
if (!ec)
return error::success;

if (ec.category() != boost::json::detail::error_code_category)
return asio_to_error_code(ec);

switch (static_cast<json_error_t>(ec.value()))
if (ec.category() == boost::json::detail::error_code_category)
{
case json_error_t::syntax: return error::syntax;
case json_error_t::extra_data: return error::extra_data;
case json_error_t::incomplete: return error::incomplete;
case json_error_t::exponent_overflow: return error::exponent_overflow;
case json_error_t::too_deep: return error::too_deep;
case json_error_t::illegal_leading_surrogate: return error::illegal_leading_surrogate;
case json_error_t::illegal_trailing_surrogate: return error::illegal_trailing_surrogate;
case json_error_t::expected_hex_digit: return error::expected_hex_digit;
case json_error_t::expected_utf16_escape: return error::expected_utf16_escape;
case json_error_t::object_too_large: return error::object_too_large;
case json_error_t::array_too_large: return error::array_too_large;
case json_error_t::key_too_large: return error::key_too_large;
case json_error_t::string_too_large: return error::string_too_large;
case json_error_t::number_too_large: return error::number_too_large;
case json_error_t::input_error: return error::input_error;
case json_error_t::exception: return error::exception;
case json_error_t::out_of_range: return error::out_of_range;
case json_error_t::test_failure: return error::test_failure;
case json_error_t::missing_slash: return error::missing_slash;
case json_error_t::invalid_escape: return error::invalid_escape;
case json_error_t::token_not_number: return error::token_not_number;
case json_error_t::value_is_scalar: return error::value_is_scalar;
case json_error_t::not_found: return error::not_found;
case json_error_t::token_overflow: return error::token_overflow;
case json_error_t::past_the_end: return error::past_the_end;
case json_error_t::not_number: return error::not_number;
case json_error_t::not_exact: return error::not_exact;
case json_error_t::not_null: return error::not_null;
case json_error_t::not_bool: return error::not_bool;
case json_error_t::not_array: return error::not_array;
case json_error_t::not_object: return error::not_object;
case json_error_t::not_string: return error::not_string;
case json_error_t::not_int64: return error::not_int64;
case json_error_t::not_uint64: return error::not_uint64;
case json_error_t::not_double: return error::not_double;
case json_error_t::not_integer: return error::not_integer;
case json_error_t::size_mismatch: return error::size_mismatch;
case json_error_t::exhausted_variants: return error::exhausted_variants;
case json_error_t::unknown_name: return error::unknown_name;
default: return error::json_unknown;
switch (static_cast<json_error_t>(ec.value()))
{
case json_error_t::syntax: return error::syntax;
case json_error_t::extra_data: return error::extra_data;
case json_error_t::incomplete: return error::incomplete;
case json_error_t::exponent_overflow: return error::exponent_overflow;
case json_error_t::too_deep: return error::too_deep;
case json_error_t::illegal_leading_surrogate: return error::illegal_leading_surrogate;
case json_error_t::illegal_trailing_surrogate: return error::illegal_trailing_surrogate;
case json_error_t::expected_hex_digit: return error::expected_hex_digit;
case json_error_t::expected_utf16_escape: return error::expected_utf16_escape;
case json_error_t::object_too_large: return error::object_too_large;
case json_error_t::array_too_large: return error::array_too_large;
case json_error_t::key_too_large: return error::key_too_large;
case json_error_t::string_too_large: return error::string_too_large;
case json_error_t::number_too_large: return error::number_too_large;
case json_error_t::input_error: return error::input_error;
case json_error_t::exception: return error::exception;
case json_error_t::out_of_range: return error::out_of_range;
case json_error_t::test_failure: return error::test_failure;
case json_error_t::missing_slash: return error::missing_slash;
case json_error_t::invalid_escape: return error::invalid_escape;
case json_error_t::token_not_number: return error::token_not_number;
case json_error_t::value_is_scalar: return error::value_is_scalar;
case json_error_t::not_found: return error::not_found;
case json_error_t::token_overflow: return error::token_overflow;
case json_error_t::past_the_end: return error::past_the_end;
case json_error_t::not_number: return error::not_number;
case json_error_t::not_exact: return error::not_exact;
case json_error_t::not_null: return error::not_null;
case json_error_t::not_bool: return error::not_bool;
case json_error_t::not_array: return error::not_array;
case json_error_t::not_object: return error::not_object;
case json_error_t::not_string: return error::not_string;
case json_error_t::not_int64: return error::not_int64;
case json_error_t::not_uint64: return error::not_uint64;
case json_error_t::not_double: return error::not_double;
case json_error_t::not_integer: return error::not_integer;
case json_error_t::size_mismatch: return error::size_mismatch;
case json_error_t::exhausted_variants: return error::exhausted_variants;
case json_error_t::unknown_name: return error::unknown_name;
default: return error::json_unknown;
}
}

return asio_to_error_code(ec);
}

// includes http codes
Expand All @@ -725,9 +724,10 @@ code rpc_to_error_code(const boost_code& ec) NOEXCEPT
if (!ec)
return error::success;

// These are libbitcoin-category-in-boost codes, for simplified transport.
if (ec.category() == network::error::error_category::singleton)
return { static_cast<error_t>(ec.value()) };
// libbitcoin-category-in-boost codes, for portability via boost_code.
if (const auto portable = static_cast<code>(ec);
portable.category() == network::error::error_category::singleton)
return portable;

return http_to_error_code(ec);
}
Expand Down
12 changes: 9 additions & 3 deletions src/net/socket_rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ void socket::do_rpc_read(boost_code ec, size_t total, const read_rpc::ptr& in,
return;
}

// async_read_some allows variable sized or empty reads into fixed buffer.
VARIANT_DISPATCH_METHOD(get_tcp(),
async_read_some(in->buffer.prepare(size),
std::bind(&socket::handle_rpc_read,
Expand Down Expand Up @@ -110,6 +111,7 @@ void socket::handle_rpc_read(boost_code ec, size_t size, size_t total,
}
}

// Handle error condition or incomplete message.
do_rpc_read(ec, total, in, handler);
}

Expand Down Expand Up @@ -145,10 +147,13 @@ void socket::do_rpc_write(boost_code ec, size_t total,
}

BC_ASSERT(buffer.has_value());
VARIANT_DISPATCH_METHOD(get_tcp(),
async_write_some(buffer.value().first,

// Internally this may compose multiple async_write_some to consume buffer.
// Writes one buffer from writer, must still iterator until writer is done.
VARIANT_DISPATCH_FUNCTION(boost::asio::async_write, get_tcp(),
buffer.value().first,
std::bind(&socket::handle_rpc_write,
shared_from_this(), _1, _2, total, out, handler)));
shared_from_this(), _1, _2, total, out, handler));
}

void socket::handle_rpc_write(boost_code ec, size_t size, size_t total,
Expand All @@ -169,6 +174,7 @@ void socket::handle_rpc_write(boost_code ec, size_t size, size_t total,
return;
}

// Handle error condition or incomplete message.
do_rpc_write(ec, total, out, handler);
}

Expand Down
Loading