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