Return error_code from beast::http::basic_parser:

This changes the HTTP parser interface to return an error_code instead
of a bool. This eliminates the need for the error() member function and
simplifies calling code.
This commit is contained in:
Vinnie Falco
2014-10-12 19:10:33 -07:00
parent 88cb0a1f7a
commit 3cd391daa6
3 changed files with 41 additions and 43 deletions

View File

@@ -111,16 +111,12 @@ public:
return complete_; return complete_;
} }
/** Returns the error if write or write_eof returned false. */
error_code
error() const noexcept;
/** Write data to the parser. /** Write data to the parser.
@param data A buffer containing the data to write @param data A buffer containing the data to write
@param bytes The size of the buffer pointed to by data. @param bytes The size of the buffer pointed to by data.
@return A pair with bool success, and the number of bytes consumed. @return A pair with bool success, and the number of bytes consumed.
*/ */
std::pair <bool, std::size_t> std::pair <error_code, std::size_t>
write (void const* data, std::size_t bytes); write (void const* data, std::size_t bytes);
/** Write a set of buffer data to the parser. /** Write a set of buffer data to the parser.
@@ -131,24 +127,8 @@ public:
@return A pair with bool success, and the number of bytes consumed. @return A pair with bool success, and the number of bytes consumed.
*/ */
template <class ConstBufferSequence> template <class ConstBufferSequence>
std::pair <bool, std::size_t> std::pair <error_code, std::size_t>
write (ConstBufferSequence const& buffers) write (ConstBufferSequence const& buffers);
{
std::pair <bool, std::size_t> result (true, 0);
for (auto const& buffer : buffers)
{
std::size_t bytes_consumed;
std::tie (result.first, bytes_consumed) =
write (boost::asio::buffer_cast <void const*> (buffer),
boost::asio::buffer_size (buffer));
if (! result.first)
break;
result.second += bytes_consumed;
if (complete())
break;
}
return result;
}
/** Called to indicate the end of file. /** Called to indicate the end of file.
HTTP needs to know where the end of the stream is. For example, HTTP needs to know where the end of the stream is. For example,
@@ -158,7 +138,7 @@ public:
@note This is typically called when a socket read returns eof. @note This is typically called when a socket read returns eof.
@return `true` if the message is complete. @return `true` if the message is complete.
*/ */
bool error_code
write_eof(); write_eof();
protected: protected:
@@ -253,6 +233,27 @@ private:
static int cb_message_complete (joyent::http_parser*); static int cb_message_complete (joyent::http_parser*);
}; };
template <class ConstBufferSequence>
auto
basic_parser::write (ConstBufferSequence const& buffers) ->
std::pair <error_code, std::size_t>
{
std::pair <error_code, std::size_t> result ({}, 0);
for (auto const& buffer : buffers)
{
std::size_t bytes_consumed;
std::tie (result.first, bytes_consumed) =
write (boost::asio::buffer_cast <void const*> (buffer),
boost::asio::buffer_size (buffer));
if (result.first)
break;
result.second += bytes_consumed;
if (complete())
break;
}
return result;
}
} // http } // http
} // beast } // beast

View File

@@ -114,32 +114,29 @@ basic_parser::operator= (basic_parser&& other)
return *this; return *this;
} }
basic_parser::error_code auto
basic_parser::error() const noexcept basic_parser::write (void const* data, std::size_t bytes) ->
std::pair <error_code, std::size_t>
{ {
auto s (reinterpret_cast <joyent::http_parser const*> (&state_)); std::pair <error_code, std::size_t> result ({}, 0);
return error_code{static_cast<int>(s->http_errno), message_category()};
}
std::pair <bool, std::size_t>
basic_parser::write (void const* data, std::size_t bytes)
{
std::pair <bool, std::size_t> result (false, 0);
auto s (reinterpret_cast <joyent::http_parser*> (&state_)); auto s (reinterpret_cast <joyent::http_parser*> (&state_));
auto h (reinterpret_cast <joyent::http_parser_settings const*> (&hooks_)); auto h (reinterpret_cast <joyent::http_parser_settings const*> (&hooks_));
result.second = joyent::http_parser_execute (s, h, result.second = joyent::http_parser_execute (s, h,
static_cast <const char*> (data), bytes); static_cast <const char*> (data), bytes);
result.first = s->http_errno == 0; result.first = error_code{static_cast<int>(s->http_errno),
message_category()};
return result; return result;
} }
bool auto
basic_parser::write_eof() basic_parser::write_eof() ->
error_code
{ {
auto s (reinterpret_cast <joyent::http_parser*> (&state_)); auto s (reinterpret_cast <joyent::http_parser*> (&state_));
auto h (reinterpret_cast <joyent::http_parser_settings const*> (&hooks_)); auto h (reinterpret_cast <joyent::http_parser_settings const*> (&hooks_));
joyent::http_parser_execute (s, h, nullptr, 0); joyent::http_parser_execute (s, h, nullptr, 0);
return s->http_errno == 0; return error_code{static_cast<int>(s->http_errno),
message_category()};
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@@ -67,9 +67,9 @@ public:
message m; message m;
parser p (m, true); parser p (m, true);
auto result (p.write (boost::asio::buffer(text))); auto result (p.write (boost::asio::buffer(text)));
expect (result.first); expect (! result.first);
auto result2 (p.write_eof()); auto result2 (p.write_eof());
expect (result2); expect (! result2);
expect (p.complete()); expect (p.complete());
} }
@@ -81,9 +81,9 @@ public:
; ;
message m; message m;
parser p (m, true); parser p (m, true);
auto result (p.write (boost::asio::buffer(text))); auto result = p.write (boost::asio::buffer(text));
if (expect (! result.first)) if (expect (result.first))
expect (p.error().message() == "invalid HTTP method"); expect (result.first.message() == "invalid HTTP method");
} }
} }
}; };