MySQL 8.4.0
Source Code Documentation
classic_protocol_codec_frame.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQL_ROUTER_CLASSIC_PROTOCOL_CODEC_FRAME_H_
27#define MYSQL_ROUTER_CLASSIC_PROTOCOL_CODEC_FRAME_H_
28
29#include <cstddef> // size_t
30#include <cstdint> // uint8_t
31#include <memory>
32#include <system_error> // error_code
33#include <utility> // move
34
41
42namespace classic_protocol {
43
44/**
45 * Codec of a Frame Header.
46 */
47template <>
48class Codec<frame::Header> : public impl::EncodeBase<Codec<frame::Header>> {
49 template <class Accumulator>
50 constexpr auto accumulate_fields(Accumulator &&accu) const {
51 return accu.step(wire::FixedInt<3>(v_.payload_size()))
52 .step(wire::FixedInt<1>(v_.seq_id()))
53 .result();
54 }
55
56 public:
59
60 friend __base;
61
63 : __base(caps), v_{std::move(v)} {}
64
65 static constexpr size_t max_size() noexcept { return 4; }
66
70
71 auto payload_size_res = accu.template step<wire::FixedInt<3>>();
72 auto seq_id_res = accu.template step<wire::FixedInt<1>>();
73
74 if (!accu.result()) return stdx::unexpected(accu.result().error());
75
76 return std::make_pair(
77 accu.result().value(),
78 value_type(payload_size_res->value(), seq_id_res->value()));
79 }
80
81 private:
83};
84
85/**
86 * Codec of Compressed Header.
87 */
88template <>
89class Codec<frame::CompressedHeader>
90 : public impl::EncodeBase<Codec<frame::CompressedHeader>> {
91 template <class Accumulator>
92 auto accumulate_fields(Accumulator &&accu) const {
93 return accu.step(wire::FixedInt<3>(v_.payload_size()))
94 .step(wire::FixedInt<1>(v_.seq_id()))
95 .step(wire::FixedInt<3>(v_.uncompressed_size()))
96 .result();
97 }
98
99 public:
102
103 friend __base;
104
106 : __base(caps), v_{std::move(v)} {}
107
108 static size_t max_size() noexcept { return 7; }
109
113
114 auto payload_size_res = accu.template step<wire::FixedInt<3>>();
115 auto seq_id_res = accu.template step<wire::FixedInt<1>>();
116 auto uncompressed_size_res = accu.template step<wire::FixedInt<3>>();
117
118 if (!accu.result()) return stdx::unexpected(accu.result().error());
119
120 return std::make_pair(
121 accu.result().value(),
122 value_type(payload_size_res->value(), seq_id_res->value(),
123 uncompressed_size_res->value()));
124 }
125
126 private:
128};
129
130/**
131 * Codec for a Frame.
132 *
133 * Frame is
134 *
135 * - header
136 * - payload
137 */
138template <class PayloadType>
139class Codec<frame::Frame<PayloadType>>
140 : public impl::EncodeBase<Codec<frame::Frame<PayloadType>>> {
141 template <class Accumulator>
142 constexpr auto accumulate_fields(Accumulator &&accu) const {
143 return accu
144 .step(frame::Header(
145 Codec<PayloadType>(v_.payload(), this->caps()).size(), v_.seq_id()))
146 .step(PayloadType(v_.payload()))
147 .result();
148 }
149
150 public:
153
154 friend __base;
155
157 : __base(caps), v_{std::move(v)} {}
158
162
163 auto header_res = accu.template step<frame::Header>();
164 if (!accu.result()) return stdx::unexpected(accu.result().error());
165
166 constexpr const size_t header_size{Codec<frame::Header>::max_size()};
167
168 // check the payload is at least what we expect.
169 if (buffer.size() < header_size + header_res->payload_size()) {
170 return stdx::unexpected(
172 }
173
174 auto payload_res =
175 accu.template step<PayloadType>(header_res->payload_size());
176
177 if (!accu.result()) return stdx::unexpected(accu.result().error());
178
179 return std::make_pair(
180 accu.result().value(),
181 value_type(header_res->seq_id(), payload_res.value()));
182 }
183
184 private:
186};
187} // namespace classic_protocol
188
189#endif
const value_type v_
Definition: classic_protocol_codec_frame.h:127
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_frame.h:105
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_frame.h:110
auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_frame.h:92
friend __base
Definition: classic_protocol_codec_frame.h:103
static size_t max_size() noexcept
Definition: classic_protocol_codec_frame.h:108
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_frame.h:156
friend __base
Definition: classic_protocol_codec_frame.h:154
const value_type v_
Definition: classic_protocol_codec_frame.h:185
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(net::const_buffer buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_frame.h:159
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_frame.h:142
const value_type v_
Definition: classic_protocol_codec_frame.h:82
constexpr Codec(value_type v, capabilities::value_type caps)
Definition: classic_protocol_codec_frame.h:62
constexpr auto accumulate_fields(Accumulator &&accu) const
Definition: classic_protocol_codec_frame.h:50
friend __base
Definition: classic_protocol_codec_frame.h:60
static constexpr size_t max_size() noexcept
Definition: classic_protocol_codec_frame.h:65
static stdx::expected< std::pair< size_t, value_type >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
Definition: classic_protocol_codec_frame.h:67
Codec for a type.
Definition: classic_protocol_codec_base.h:72
Definition: classic_protocol_wire.h:103
header of a compressed frame.
Definition: classic_protocol_frame.h:58
Definition: classic_protocol_frame.h:85
Definition: classic_protocol_frame.h:36
Generator of decoded Types of a buffer.
Definition: classic_protocol_codec_base.h:153
result_type result() const
get result of the step().
Definition: classic_protocol_codec_base.h:219
CRTP base for the Codec's encode part.
Definition: classic_protocol_codec_base.h:374
Definition: buffer.h:135
size_t size() const noexcept
Definition: buffer.h:120
Definition: expected.h:284
constexpr const error_type & error() const &
Definition: expected.h:751
constexpr value_type & value() &
Definition: expected.h:636
Definition: expected.h:112
std::bitset< 32 > value_type
Definition: classic_protocol_constants.h:73
Definition: classic_protocol_binary.h:39
std::error_code make_error_code(codec_errc e) noexcept
Definition: classic_protocol_codec_error.h:86
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
Definition: gcs_xcom_synode.h:64
unexpected(E) -> unexpected< E >