HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
packet_buffer.hpp
1// Copyright Take Vos 2020-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../macros.hpp"
8
9hi_export_module(hikogui.net.packet_buffer);
10
11hi_export namespace hi::inline v1 {
12
14 std::list<packet> packets;
15 ssize_t _totalNrBytes;
16 bool _closed;
17
18public:
22 bool closed() const noexcept
23 {
24 return _closed;
25 }
26
29 ssize_t nrBytes() const noexcept
30 {
31 return _totalNrBytes;
32 }
33
39 ssize_t nrpackets() const noexcept
40 {
41 return packets.size();
42 }
43
46 void close() noexcept
47 {
48 _closed = true;
49 }
50
54 std::span<std::byte> getNewpacket(ssize_t nrBytes) noexcept
55 {
56 hi_assert(!closed());
57 packets.emplace_back(nrBytes);
58 return {packets.back().end(), nrBytes};
59 }
60
64 std::span<std::byte> getpacket(ssize_t nrBytes) noexcept
65 {
66 hi_assert(!closed());
67 if (packets.empty() || (packets.back().writeSize() < nrBytes)) {
68 packets.emplace_back(nrBytes);
69 }
70 return {packets.back().end(), nrBytes};
71 }
72
80 void write(ssize_t nrBytes, bool push = true) noexcept
81 {
82 hi_assert(!closed());
83 packets.back().write(nrBytes);
84 if (push) {
85 packets.back().push();
86 }
87 _totalNrBytes += nrBytes;
88 }
89
96 std::span<std::byte const> peek(ssize_t nrBytes)
97 {
98 if (packets.empty() || size() < nrBytes) {
99 return {};
100 }
101
102 while (true) {
103 if (packets.front().readSize() >= nrBytes) {
104 return {packets.front().readSize(), ssize(packets)};
105 }
106
107 // Check if we can merge packets.
108 hi_assert(packets.front().size() >= nrBytes);
109
110 // Merge data from next packet.
111 }
112 }
113
121 std::string_view peekLine(ssize_t nrBytes = 1024)
122 {
123 ssize_t packetNr = 0;
124 ssize_t byteNr = 0;
125 ssize_t i = 0;
126 while (packetNr < nrpackets()) {
127 hi_check(byteNr < nrBytes, "New-line not found within {} bytes", nrBytes);
128
129 if (i == ssize(packets[packetNr])) {
130 // Advance to next packet.
131 ++packetNr;
132 i = 0;
133 }
134
135 auto const c = packets[packetNr][i] if (c == '\n' || c == '\0')
136 {
137 // Found end-of-line
138 auto const bspan = peek(byteNr + 1);
139 return {reinterpret_cast<char *>(bspan.data()), byteNr + 1};
140 }
141 ++i;
142 ++byteNr;
143 }
144
145 // Not enough bytes read yet.
146 return {}
147 }
148
155 void read(ssize_t nrBytes) noexcept
156 {
157 peekBuffer.clear();
158
159 while (nrBytes) {
160 auto const packet_size = ssize(packets.front());
161 if (nrBytes >= packet_size) {
162 packets.pop_front();
163 } else {
164 packets.front().read(nrBytes);
165 hi_assert(ssize(packets.front()) > 0);
166 }
167 nrBytes -= ssize(packets_size);
168 }
169 }
170};
171
172} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Definition packet_buffer.hpp:13
void read(ssize_t nrBytes) noexcept
Consume the data from the buffer.
Definition packet_buffer.hpp:155
std::span< std::byte > getNewpacket(ssize_t nrBytes) noexcept
Get a new packet to write a message into.
Definition packet_buffer.hpp:54
std::string_view peekLine(ssize_t nrBytes=1024)
Peek into the data a single text-line without consuming.
Definition packet_buffer.hpp:121
std::span< std::byte const > peek(ssize_t nrBytes)
Peek into the data without consuming.
Definition packet_buffer.hpp:96
bool closed() const noexcept
Connection is closed.
Definition packet_buffer.hpp:22
std::span< std::byte > getpacket(ssize_t nrBytes) noexcept
Get a packet to write a stream of bytes into.
Definition packet_buffer.hpp:64
void close() noexcept
Close the connection on this side.
Definition packet_buffer.hpp:46
void write(ssize_t nrBytes, bool push=true) noexcept
Write the data added to the packet.
Definition packet_buffer.hpp:80
ssize_t nrBytes() const noexcept
Total number of bytes in the buffer.
Definition packet_buffer.hpp:29
ssize_t nrpackets() const noexcept
Total number of packets in the buffer.
Definition packet_buffer.hpp:39
T back(T... args)
T emplace_back(T... args)
T empty(T... args)
T front(T... args)
T pop_front(T... args)
T size(T... args)