Boost.Redis: include/boost/redis/resp3/parser.hpp Source File

Boost.Redis 1.84.0 A redis client library

Loading...
Searching...
No Matches
parser.hpp
1/* Copyright (c) 2018-2024 Marcelo Zimbres Silva (mzimbres@gmail.com)
2 *
3 * Distributed under the Boost Software License, Version 1.0. (See
4 * accompanying file LICENSE.txt)
5 */
6
7#ifndef BOOST_REDIS_RESP3_PARSER_HPP
8#define BOOST_REDIS_RESP3_PARSER_HPP
9
10#include <boost/redis/resp3/node.hpp>
11#include <boost/system/error_code.hpp>
12#include <array>
13#include <string_view>
14#include <cstdint>
15#include <optional>
16
17namespace boost::redis::resp3 {
18
19class parser {
20public:
21 using node_type = basic_node<std::string_view>;
22 using result = std::optional<node_type>;
23
24 static constexpr std::size_t max_embedded_depth = 5;
25 static constexpr std::string_view sep = "\r\n";
26
27private:
28 // The current depth. Simple data types will have depth 0, whereas
29 // the elements of aggregates will have depth 1. Embedded types
30 // will have increasing depth.
31 std::size_t depth_;
32
33 // The parser supports up to 5 levels of nested structures. The
34 // first element in the sizes stack is a sentinel and must be
35 // different from 1.
36 std::array<std::size_t, max_embedded_depth + 1> sizes_;
37
38 // Contains the length expected in the next bulk read.
39 std::size_t bulk_length_;
40
41 // The type of the next bulk. Contains type::invalid if no bulk is
42 // expected.
43 type bulk_;
44
45 // The number of bytes consumed from the buffer.
46 std::size_t consumed_;
47
48 // Returns the number of bytes that have been consumed.
49 auto consume_impl(type t, std::string_view elem, system::error_code& ec) -> node_type;
50
51 void commit_elem() noexcept;
52
53 // The bulk type expected in the next read. If none is expected
54 // returns type::invalid.
55 [[nodiscard]]
56 auto bulk_expected() const noexcept -> bool
57 { return bulk_ != type::invalid; }
58
59public:
60 parser();
61
62 // Returns true when the parser is done with the current message.
63 [[nodiscard]]
64 auto done() const noexcept -> bool;
65
66 auto get_suggested_buffer_growth(std::size_t hint) const noexcept -> std::size_t;
67
68 auto get_consumed() const noexcept -> std::size_t;
69
70 auto consume(std::string_view view, system::error_code& ec) noexcept -> result;
71
72 void reset();
73};
74
75// Returns false if more data is needed. If true is returned the
76// parser is either done or an error occured, that can be checked on
77// ec.
78template <class Adapter>
79bool
80parse(
81 resp3::parser& p,
82 std::string_view const& msg,
83 Adapter& adapter,
84 system::error_code& ec)
85{
86 while (!p.done()) {
87 auto const res = p.consume(msg, ec);
88 if (ec)
89 return true;
90
91 if (!res)
92 return false;
93
94 adapter(res.value(), ec);
95 if (ec)
96 return true;
97 }
98
99 return true;
100}
101
102} // boost::redis::resp3
103
104#endif // BOOST_REDIS_RESP3_PARSER_HPP
boost::redis::resp3::type
type
RESP3 data types.
Definition type.hpp:23
boost::redis::resp3::type::invalid
@ invalid
Invalid.