Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Frame.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2023 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_NET_FRAME_HPP
18#define TOOLBOX_NET_FRAME_HPP
19
20#include <toolbox/io/Buffer.hpp>
21
22#include <cassert>
23
24namespace toolbox {
25inline namespace net {
26namespace detail {
27
35template <std::endian Native = std::endian::native>
36constexpr std::uint16_t get_length(const char* buf, std::endian net_byte_order) noexcept
37{
38 // If byte swap required then 1, else 0.
39 // These values provide indices into buffer, which is assumed to be at least 2 bytes long.
40 const int bswap{Native != net_byte_order};
41 return ((buf[!bswap] & 0xff) << 8) | (buf[bswap] & 0xff);
42}
43
51template <std::endian Native = std::endian::native>
52inline void put_length(char* buf, std::uint16_t len, std::endian net_byte_order) noexcept
53{
54 // If byte swap required then 1, else 0.
55 // These values provide indices into buffer, which is assumed to be at least 2 bytes long.
56 const int bswap{Native != net_byte_order};
57 buf[bswap] = 0xff & len;
58 buf[!bswap] = 0xff & (len >> 8);
59}
60
61} // namespace detail
62
68constexpr std::uint16_t get_length(const char* buf, std::endian net_byte_order) noexcept
69{
70 return detail::get_length<>(buf, net_byte_order);
71}
72
78inline std::uint16_t get_length(ConstBuffer buf, std::endian net_byte_order) noexcept
79{
80 assert(buffer_size(buf) >= 2);
82}
83
89inline void put_length(char* buf, std::uint16_t len, std::endian net_byte_order) noexcept
90{
91 detail::put_length<>(buf, len, net_byte_order);
92}
93
99inline void put_length(MutableBuffer buf, std::uint16_t len, std::endian net_byte_order) noexcept
100{
101 assert(buffer_size(buf) >= 2);
103}
104
112template <typename FnT>
113std::size_t parse_frame(ConstBuffer buf, FnT fn, std::endian net_byte_order)
114{
115 std::size_t consumed{0};
116 for (;;) {
117 const auto* data = buffer_cast<const char*>(buf);
118 const std::size_t size = buffer_size(buf);
119 if (size < sizeof(std::uint16_t)) {
120 break;
121 }
122 const auto total = get_length(data, net_byte_order);
123 if (size < total) {
124 break;
125 }
126 fn(ConstBuffer{data + sizeof(std::uint16_t), total - sizeof(std::uint16_t)});
127 buf = advance(buf, total);
128 consumed += total;
129 }
130 return consumed;
131}
132
140template <typename FnT>
141std::size_t parse_frame(std::string_view buf, FnT fn, std::endian net_byte_order)
142{
143 return parse_frame(ConstBuffer{buf.data(), buf.size()}, fn, net_byte_order);
144}
145
146} // namespace net
147} // namespace toolbox
148
149#endif // TOOLBOX_NET_FRAME_HPP
boost::asio::const_buffer ConstBuffer
Definition Buffer.hpp:28
boost::asio::mutable_buffer MutableBuffer
Definition Buffer.hpp:29
const DataT & data(const MsgEvent &ev) noexcept
Definition Event.hpp:54
ConstBuffer advance(ConstBuffer buf, std::size_t n) noexcept
Definition Buffer.cpp:48
void put_length(char *buf, std::uint16_t len, std::endian net_byte_order) noexcept
Definition Frame.hpp:52
constexpr std::uint16_t get_length(const char *buf, std::endian net_byte_order) noexcept
Definition Frame.hpp:36
constexpr std::uint16_t get_length(const char *buf, std::endian net_byte_order) noexcept
Definition Frame.hpp:68
void put_length(char *buf, std::uint16_t len, std::endian net_byte_order) noexcept
Definition Frame.hpp:89
std::size_t parse_frame(ConstBuffer buf, FnT fn, std::endian net_byte_order)
Definition Frame.hpp:113
constexpr std::uint16_t bswap(std::uint16_t n) noexcept
Definition Endian.hpp:27
constexpr std::size_t size(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s)
Definition Struct.hpp:98
constexpr auto bind() noexcept
Definition Slot.hpp:92