OpenTTD Source  20241125-master-g5b02f51e17
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 <http://www.gnu.org/licenses/>.
6  */
7 
12 #ifndef NETWORK_CORE_PACKET_H
13 #define NETWORK_CORE_PACKET_H
14 
15 #include "os_abstraction.h"
16 #include "config.h"
17 #include "core.h"
18 #include "../../string_type.h"
19 
20 typedef uint16_t PacketSize;
21 typedef uint8_t PacketType;
22 
42 struct Packet {
43  static constexpr size_t EncodedLengthOfPacketSize() { return sizeof(PacketSize); }
44  static constexpr size_t EncodedLengthOfPacketType() { return sizeof(PacketType); }
45 private:
49  std::vector<uint8_t> buffer;
51  size_t limit;
52 
55 
56 public:
57  Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size = EncodedLengthOfPacketSize());
59 
60  /* Sending/writing of packets */
61  void PrepareToSend();
62 
63  bool CanWriteToPacket(size_t bytes_to_write);
64  void Send_bool (bool data);
65  void Send_uint8 (uint8_t data);
66  void Send_uint16(uint16_t data);
67  void Send_uint32(uint32_t data);
68  void Send_uint64(uint64_t data);
69  void Send_string(const std::string_view data);
70  void Send_buffer(const std::vector<uint8_t> &data);
71  std::span<const uint8_t> Send_bytes(const std::span<const uint8_t> span);
72 
73  /* Reading/receiving of packets */
74  bool HasPacketSizeData() const;
75  bool ParsePacketSize();
76  size_t Size() const;
77  [[nodiscard]] bool PrepareToRead();
78  PacketType GetPacketType() const;
79 
80  bool CanReadFromPacket(size_t bytes_to_read, bool close_connection = false);
81  bool Recv_bool ();
82  uint8_t Recv_uint8 ();
83  uint16_t Recv_uint16();
84  uint32_t Recv_uint32();
85  uint64_t Recv_uint64();
86  std::vector<uint8_t> Recv_buffer();
87  size_t Recv_bytes(std::span<uint8_t> span);
89 
90  size_t RemainingBytesToTransfer() const;
91 
104  template <
105  typename A = size_t,
106  typename F,
107  typename D,
108  typename ... Args>
109  ssize_t TransferOutWithLimit(F transfer_function, size_t limit, D destination, Args&& ... args)
110  {
111  size_t amount = std::min(this->RemainingBytesToTransfer(), limit);
112  if (amount == 0) return 0;
113 
114  assert(this->pos < this->buffer.size());
115  assert(this->pos + amount <= this->buffer.size());
116  /* Making buffer a char means casting a lot in the Recv/Send functions. */
117  const char *output_buffer = reinterpret_cast<const char*>(this->buffer.data() + this->pos);
118  ssize_t bytes = transfer_function(destination, output_buffer, static_cast<A>(amount), std::forward<Args>(args)...);
119  if (bytes > 0) this->pos += bytes;
120  return bytes;
121  }
122 
138  template <typename A = size_t, typename F, typename D, typename ... Args>
139  ssize_t TransferOut(F transfer_function, D destination, Args&& ... args)
140  {
141  return TransferOutWithLimit<A>(transfer_function, std::numeric_limits<size_t>::max(), destination, std::forward<Args>(args)...);
142  }
143 
173  template <typename A = size_t, typename F, typename S, typename ... Args>
174  ssize_t TransferIn(F transfer_function, S source, Args&& ... args)
175  {
176  size_t amount = this->RemainingBytesToTransfer();
177  if (amount == 0) return 0;
178 
179  assert(this->pos < this->buffer.size());
180  assert(this->pos + amount <= this->buffer.size());
181  /* Making buffer a char means casting a lot in the Recv/Send functions. */
182  char *input_buffer = reinterpret_cast<char*>(this->buffer.data() + this->pos);
183  ssize_t bytes = transfer_function(source, input_buffer, static_cast<A>(amount), std::forward<Args>(args)...);
184  if (bytes > 0) this->pos += bytes;
185  return bytes;
186  }
187 };
188 
189 #endif /* NETWORK_CORE_PACKET_H */
SocketHandler for all network sockets in OpenTTD.
Definition: core.h:43
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:46
Base for all network types (UDP and TCP)
fluid_settings_t * settings
FluidSynth settings handle.
Definition: fluidsynth.cpp:21
Network stuff has many things that needs to be included and/or implemented by default.
uint8_t PacketType
Identifier for the packet.
Definition: packet.h:21
uint16_t PacketSize
Size of the whole packet.
Definition: packet.h:20
StringValidationSettings
Settings for the string validation.
Definition: string_type.h:44
@ SVS_REPLACE_WITH_QUESTION_MARK
Replace the unknown/bad bits with question marks.
Definition: string_type.h:46
Internal entity of a packet.
Definition: packet.h:42
size_t Size() const
Get the number of bytes in the packet.
Definition: packet.cpp:250
uint16_t Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:332
ssize_t TransferOutWithLimit(F transfer_function, size_t limit, D destination, Args &&... args)
Transfer data from the packet to the given function.
Definition: packet.h:109
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:403
uint64_t Recv_uint64()
Read a 64 bits integer from the packet.
Definition: packet.cpp:364
bool Recv_bool()
Read a boolean from the packet.
Definition: packet.cpp:309
uint32_t Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:347
NetworkSocketHandler * cs
Socket we're associated with.
Definition: packet.h:54
void Send_bool(bool data)
Package a boolean in the packet.
Definition: packet.cpp:111
bool PrepareToRead()
Prepares the packet so it can be read.
Definition: packet.cpp:278
PacketType GetPacketType() const
Get the PacketType from this packet.
Definition: packet.cpp:297
PacketSize pos
The current read/write position in the packet.
Definition: packet.h:47
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:197
size_t limit
The limit for the packet size.
Definition: packet.h:51
bool HasPacketSizeData() const
Check whether the packet, given the position of the "write" pointer, has read enough of the packet to...
Definition: packet.cpp:238
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:318
bool ParsePacketSize()
Reads the packet size from the raw packet and stores it in the packet->size.
Definition: packet.cpp:259
std::vector< uint8_t > buffer
The buffer of this packet.
Definition: packet.h:49
ssize_t TransferIn(F transfer_function, S source, Args &&... args)
Transfer data from the given function into the packet.
Definition: packet.h:174
void PrepareToSend()
Writes the packet size from the raw packet from packet->size.
Definition: packet.cpp:66
void Send_uint8(uint8_t data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:120
size_t RemainingBytesToTransfer() const
Get the amount of bytes that are still available for the Transfer functions.
Definition: packet.cpp:447
void Send_uint32(uint32_t data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:141
ssize_t TransferOut(F transfer_function, D destination, Args &&... args)
Transfer data from the packet to the given function.
Definition: packet.h:139
void Send_buffer(const std::vector< uint8_t > &data)
Copy a sized byte buffer into the packet.
Definition: packet.cpp:183
std::vector< uint8_t > Recv_buffer()
Extract a sized byte buffer from the packet.
Definition: packet.cpp:385
Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size=EncodedLengthOfPacketSize())
Create a packet that is used to read from a network socket.
Definition: packet.cpp:31
void Send_uint16(uint16_t data)
Package a 16 bits integer in the packet.
Definition: packet.cpp:130
bool CanReadFromPacket(size_t bytes_to_read, bool close_connection=false)
Is it safe to read from the packet, i.e.
Definition: packet.cpp:219
bool CanWriteToPacket(size_t bytes_to_write)
Is it safe to write to the packet, i.e.
Definition: packet.cpp:90
std::string Recv_string(size_t length, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads characters (bytes) from the packet until it finds a '\0', or reaches a maximum of length charac...
Definition: packet.cpp:425
void Send_string(const std::string_view data)
Sends a string over the network.
Definition: packet.cpp:172
void Send_uint64(uint64_t data)
Package a 64 bits integer in the packet.
Definition: packet.cpp:154