OpenTTD Source 20260421-master-gc2fbc6fdeb
packet.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef NETWORK_CORE_PACKET_H
11#define NETWORK_CORE_PACKET_H
12
13#include "os_abstraction.h"
14#include "config.h"
15#include "core.h"
17#include "../../string_type.h"
18
19typedef uint16_t PacketSize;
20typedef uint8_t PacketType;
21
32template <typename enum_type>
34 static constexpr bool value = false;
35};
36
56struct Packet {
57 static constexpr size_t ENCODED_LENGTH_OF_PACKET_SIZE = sizeof(PacketSize);
58 static constexpr size_t ENCODED_LENGTH_OF_PACKET_TYPE = sizeof(PacketType);
59private:
63 std::vector<uint8_t> buffer;
65 size_t limit;
66
69
70public:
71 Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = Packet::ENCODED_LENGTH_OF_PACKET_SIZE);
73
83 template <typename E, typename = std::enable_if_t<IsEnumPacketType<E>::value>>
85
86 /* Sending/writing of packets */
87 void PrepareToSend();
88
89 bool CanWriteToPacket(size_t bytes_to_write);
90 void Send_bool (bool data);
91 void Send_uint8 (uint8_t data);
93 void Send_uint8 (const ConvertibleThroughBase auto &data) { this->Send_uint8(data.base()); }
94 void Send_uint16(uint16_t data);
95 void Send_uint32(uint32_t data);
96 void Send_uint64(uint64_t data);
97 void Send_string(std::string_view data);
98 void Send_buffer(const std::vector<uint8_t> &data);
99 std::span<const uint8_t> Send_bytes(const std::span<const uint8_t> span);
100
101 /* Reading/receiving of packets */
102 bool HasPacketSizeData() const;
103 bool ParsePacketSize();
104 size_t Size() const;
105 [[nodiscard]] bool PrepareToRead();
107
108 bool CanReadFromPacket(size_t bytes_to_read, bool close_connection = false);
109 bool Recv_bool ();
110 uint8_t Recv_uint8 ();
111 uint16_t Recv_uint16();
112 uint32_t Recv_uint32();
113 uint64_t Recv_uint64();
114 std::vector<uint8_t> Recv_buffer();
115 size_t Recv_bytes(std::span<uint8_t> span);
116 std::string Recv_string(size_t length, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark);
117
118 size_t RemainingBytesToTransfer() const;
119
130 template <typename F>
131 ssize_t TransferOutWithLimit(F transfer_function, size_t limit)
132 {
133 size_t amount = std::min(this->RemainingBytesToTransfer(), limit);
134 if (amount == 0) return 0;
135
136 assert(this->pos < this->buffer.size());
137 assert(this->pos + amount <= this->buffer.size());
138 auto output_buffer = std::span<const uint8_t>(this->buffer.data() + this->pos, amount);
139 ssize_t bytes = transfer_function(output_buffer);
140 if (bytes > 0) this->pos += bytes;
141 return bytes;
142 }
143
153 template <typename F>
154 ssize_t TransferOut(F transfer_function)
155 {
156 return TransferOutWithLimit(transfer_function, std::numeric_limits<size_t>::max());
157 }
158
182 template <typename F>
183 ssize_t TransferIn(F transfer_function)
184 {
185 size_t amount = this->RemainingBytesToTransfer();
186 if (amount == 0) return 0;
187
188 assert(this->pos < this->buffer.size());
189 assert(this->pos + amount <= this->buffer.size());
190 auto input_buffer = std::span<uint8_t>(this->buffer.data() + this->pos, amount);
191 ssize_t bytes = transfer_function(input_buffer);
192 if (bytes > 0) this->pos += bytes;
193 return bytes;
194 }
195};
196
197#endif /* NETWORK_CORE_PACKET_H */
SocketHandler for all network sockets in OpenTTD.
Definition core.h:41
A type is considered 'convertible through base()' when it has a 'base()' function that returns someth...
Configuration options of the network stuff.
static const size_t COMPAT_MTU
Number of bytes we can pack in a single packet for backward compatibility.
Definition config.h:44
Concept for unifying the convert through 'base()' behaviour of several 'strong' types.
Base for all network types (UDP and TCP).
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
fluid_settings_t * settings
FluidSynth settings handle.
Includes and/or implementations for the network stuff.
uint8_t PacketType
Identifier for the packet.
Definition packet.h:20
uint16_t PacketSize
Size of the whole packet.
Definition packet.h:19
Types for strings.
@ ReplaceWithQuestionMark
Replace the unknown/bad bits with question marks.
Definition string_type.h:45
Trait to mark an enumeration as a PacketType.
Definition packet.h:33
static constexpr bool value
True iff a PacketType.
Definition packet.h:34
size_t Size() const
Get the number of bytes in the packet.
Definition packet.cpp:248
static constexpr size_t ENCODED_LENGTH_OF_PACKET_TYPE
The length of the packet type in the byte stream once it's encoded.
Definition packet.h:58
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition packet.cpp:330
size_t Recv_bytes(std::span< uint8_t > span)
Extract at most the length of the span bytes from the packet into the span.
Definition packet.cpp:401
uint64_t Recv_uint64()
Read a 64 bits integer from the packet.
Definition packet.cpp:362
bool Recv_bool()
Read a boolean from the packet.
Definition packet.cpp:307
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
Definition packet.cpp:345
NetworkSocketHandler * cs
Socket we're associated with.
Definition packet.h:68
ssize_t TransferOutWithLimit(F transfer_function, size_t limit)
Transfer data from the packet to the given function.
Definition packet.h:131
void Send_string(std::string_view data)
Sends a string over the network.
Definition packet.cpp:170
std::string Recv_string(size_t length, StringValidationSettings settings=StringValidationSetting::ReplaceWithQuestionMark)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition packet.cpp:423
void Send_bool(bool data)
Package a boolean in the packet.
Definition packet.cpp:109
bool PrepareToRead()
Prepares the packet so it can be read.
Definition packet.cpp:276
PacketType GetPacketType() const
Get the PacketType from this packet.
Definition packet.cpp:296
ssize_t TransferIn(F transfer_function)
Transfer data from the given function into the packet.
Definition packet.h:183
PacketSize pos
The current read/write position in the packet.
Definition packet.h:61
std::span< const uint8_t > Send_bytes(const std::span< const uint8_t > span)
Send as many of the bytes as possible in the packet.
Definition packet.cpp:195
size_t limit
The limit for the packet size.
Definition packet.h:65
bool HasPacketSizeData() const
Check whether the packet, given the position of the "write" pointer, has read enough of the packet to...
Definition packet.cpp:236
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition packet.cpp:316
bool ParsePacketSize()
Reads the packet size from the raw packet and stores it in the packet->size.
Definition packet.cpp:257
std::vector< uint8_t > buffer
The buffer of this packet.
Definition packet.h:63
void PrepareToSend()
Writes the packet size from the raw packet from packet->size.
Definition packet.cpp:64
Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size=Packet::ENCODED_LENGTH_OF_PACKET_SIZE)
Create a packet that is used to read from a network socket.
Definition packet.cpp:29
void Send_uint8(uint8_t data)
Package a 8 bits integer in the packet.
Definition packet.cpp:118
size_t RemainingBytesToTransfer() const
Get the amount of bytes that are still available for the Transfer functions.
Definition packet.cpp:445
void Send_uint32(uint32_t data)
Package a 32 bits integer in the packet.
Definition packet.cpp:139
void Send_buffer(const std::vector< uint8_t > &data)
Copy a sized byte buffer into the packet.
Definition packet.cpp:181
void Send_uint8(const ConvertibleThroughBase auto &data)
Package a 8 bits integer in the packet.
Definition packet.h:93
std::vector< uint8_t > Recv_buffer()
Extract a sized byte buffer from the packet.
Definition packet.cpp:383
Packet(NetworkSocketHandler *cs, E type, size_t limit=COMPAT_MTU)
Creates a packet to send.
Definition packet.h:84
void Send_uint16(uint16_t data)
Package a 16 bits integer in the packet.
Definition packet.cpp:128
bool CanReadFromPacket(size_t bytes_to_read, bool close_connection=false)
Is it safe to read from the packet, i.e.
Definition packet.cpp:217
bool CanWriteToPacket(size_t bytes_to_write)
Is it safe to write to the packet, i.e.
Definition packet.cpp:88
static constexpr size_t ENCODED_LENGTH_OF_PACKET_SIZE
The length of the packet size in the byte stream once it's encoded.
Definition packet.h:57
void Send_uint64(uint64_t data)
Package a 64 bits integer in the packet.
Definition packet.cpp:152
ssize_t TransferOut(F transfer_function)
Transfer data from the packet to the given function.
Definition packet.h:154