gnss-sim/3rdparty/boost/redis/resp3/parser.hpp

105 lines
2.7 KiB
C++
Raw Normal View History

2024-12-24 16:15:51 +00:00
/* Copyright (c) 2018-2024 Marcelo Zimbres Silva (mzimbres@gmail.com)
*
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE.txt)
*/
#ifndef BOOST_REDIS_RESP3_PARSER_HPP
#define BOOST_REDIS_RESP3_PARSER_HPP
#include <boost/redis/resp3/node.hpp>
#include <boost/system/error_code.hpp>
#include <array>
#include <string_view>
#include <cstdint>
#include <optional>
namespace boost::redis::resp3 {
class parser {
public:
using node_type = basic_node<std::string_view>;
using result = std::optional<node_type>;
static constexpr std::size_t max_embedded_depth = 5;
static constexpr std::string_view sep = "\r\n";
private:
// The current depth. Simple data types will have depth 0, whereas
// the elements of aggregates will have depth 1. Embedded types
// will have increasing depth.
std::size_t depth_;
// The parser supports up to 5 levels of nested structures. The
// first element in the sizes stack is a sentinel and must be
// different from 1.
std::array<std::size_t, max_embedded_depth + 1> sizes_;
// Contains the length expected in the next bulk read.
std::size_t bulk_length_;
// The type of the next bulk. Contains type::invalid if no bulk is
// expected.
type bulk_;
// The number of bytes consumed from the buffer.
std::size_t consumed_;
// Returns the number of bytes that have been consumed.
auto consume_impl(type t, std::string_view elem, system::error_code& ec) -> node_type;
void commit_elem() noexcept;
// The bulk type expected in the next read. If none is expected
// returns type::invalid.
[[nodiscard]]
auto bulk_expected() const noexcept -> bool
{ return bulk_ != type::invalid; }
public:
parser();
// Returns true when the parser is done with the current message.
[[nodiscard]]
auto done() const noexcept -> bool;
auto get_suggested_buffer_growth(std::size_t hint) const noexcept -> std::size_t;
auto get_consumed() const noexcept -> std::size_t;
auto consume(std::string_view view, system::error_code& ec) noexcept -> result;
void reset();
};
// Returns false if more data is needed. If true is returned the
// parser is either done or an error occured, that can be checked on
// ec.
template <class Adapter>
bool
parse(
resp3::parser& p,
std::string_view const& msg,
Adapter& adapter,
system::error_code& ec)
{
while (!p.done()) {
auto const res = p.consume(msg, ec);
if (ec)
return true;
if (!res)
return false;
adapter(res.value(), ec);
if (ec)
return true;
}
return true;
}
} // boost::redis::resp3
#endif // BOOST_REDIS_RESP3_PARSER_HPP