String serialization.

This commit is contained in:
2025-01-23 14:57:00 -05:00
parent 71b95b2615
commit 0e8f6600a0
2 changed files with 78 additions and 21 deletions

View File

@@ -2,6 +2,7 @@
#include <cstdint>
#include <cstddef>
#include <string>
namespace CaveGame::Core
{
@@ -9,9 +10,9 @@ namespace CaveGame::Core
/// A data container structure which keeps track of the current position.
struct Buffer {
uint8_t* data;
size_t size;
size_t index;
uint8_t* data;
};
/// Writes a 1-byte unsigned int to the buffer, in network-byte-order, and advances the index by 1.
@@ -60,4 +61,10 @@ namespace CaveGame::Core
/// Reads a 8-byte float from the buffer, via reinterpreting from uint64_t, and advances the index by 8.
double read_f64(Buffer& buffer);
void write_string(Buffer& buffer, const char* value, uint length);
void write_string(Buffer& buffer, std::string value);
std::string read_string(Buffer& buffer);
}

View File

@@ -3,37 +3,64 @@
#include <cassert>
#include <netinet/in.h>
#include <J3ML/Algorithm/Reinterpret.hpp>
#include <algorithm>
namespace CaveGame::Core
{
/* hton16
ntoh16
hton32
ntoh32
hton64
ntoh64 */
template <typename T>
constexpr T host_to_network(T value) noexcept
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
char* ptr = reinterpret_cast<char*>(&value);
std::reverse(ptr, ptr + sizeof(T));
#endif
return value;
}
template <typename T>
constexpr T network_to_host(T value) noexcept
{
return host_to_network(value);
}
void write_u8(Buffer &buffer, uint8_t value) {
assert(buffer.index + 1 <= buffer.size);
*((uint8_t*)(buffer.data + buffer.index)) = (value);
*(buffer.data + buffer.index) = (value);
//*((uint8_t*)(buffer.data + buffer.index)) = (value);
buffer.index += 1;
}
void write_u16(Buffer &buffer, uint16_t value) {
assert(buffer.index + 2 <= buffer.size);
*((uint16_t*)(buffer.data + buffer.index)) = htons(value);
*((uint16_t*)(buffer.data + buffer.index)) = host_to_network(value);
buffer.index += 2;
}
void write_u32(Buffer &buffer, uint32_t value) {
assert(buffer.index + 4 <= buffer.size);
*((uint32_t*)(buffer.data + buffer.index)) = htonl(value);
*((uint32_t*)(buffer.data + buffer.index)) = host_to_network(value);
buffer.index += 4;
}
void write_u64(Buffer &buffer, uint64_t value) {
assert(buffer.index + 8 <= buffer.size);
*((uint64_t*)(buffer.data + buffer.index)) = htonl(value);
*((uint64_t*)(buffer.data + buffer.index)) = host_to_network(value);
buffer.index += 8;
}
uint8_t read_u8(Buffer &buffer) {
assert(buffer.index + 1 <= buffer.size);
uint8_t value;
value = (*((uint8_t*)(buffer.data + buffer.index)));
value = (*((buffer.data + buffer.index)));
buffer.index += 1;
return value;
}
@@ -41,7 +68,7 @@ namespace CaveGame::Core
uint16_t read_u16(Buffer &buffer) {
assert(buffer.index + 2 <= buffer.size);
uint16_t value;
value = ntohs(*((uint16_t*)(buffer.data + buffer.index)));
value = network_to_host(*((uint16_t*)(buffer.data + buffer.index)));
buffer.index += 2;
return value;
}
@@ -49,15 +76,17 @@ namespace CaveGame::Core
uint32_t read_u32(Buffer &buffer) {
assert(buffer.index + 4 <= buffer.size);
uint32_t value;
value = ntohl(*((uint32_t*)(buffer.data + buffer.index)));
value = network_to_host(*((uint32_t*)(buffer.data + buffer.index)));
buffer.index += 4;
return value;
}
uint64_t read_u64(Buffer &buffer) {
assert(buffer.index + 8 <= buffer.size);
uint64_t value;
value = ntohl(*((uint64_t*)(buffer.data + buffer.index)));
value = network_to_host(*((uint64_t*)(buffer.data + buffer.index)));
buffer.index += 8;
return value;
}
@@ -66,36 +95,36 @@ namespace CaveGame::Core
void write_s8(Buffer& buffer, int8_t value)
{
assert(buffer.index + 1 <= buffer.size);
*((int8_t*)(buffer.data + buffer.index)) = (value);
*((buffer.data + buffer.index)) = (value);
buffer.index += 1;
}
void write_s16(Buffer& buffer, int16_t value)
{
assert(buffer.index + 2 <= buffer.size);
*((int16_t*)(buffer.data + buffer.index)) = htons(value);
*((int16_t*)(buffer.data + buffer.index)) = host_to_network(value);
buffer.index += 2;
}
void write_s32(Buffer& buffer, int32_t value)
{
assert(buffer.index + 3 <= buffer.size);
*((int32_t*)(buffer.data + buffer.index)) = htons(value);
buffer.index += 3;
assert(buffer.index + 4 <= buffer.size);
*((int32_t*)(buffer.data + buffer.index)) = host_to_network(value);
buffer.index += 4;
}
void write_s64(Buffer& buffer, int64_t value)
{
assert(buffer.index + 4 <= buffer.size);
*((int64_t*)(buffer.data + buffer.index)) = htons(value);
buffer.index += 3;
assert(buffer.index + 8 <= buffer.size);
*((int64_t*)(buffer.data + buffer.index)) = host_to_network(value);
buffer.index += 8;
}
int8_t read_s8(Buffer& buffer)
{
assert(buffer.index + 1 <= buffer.size);
int8_t value;
value = (*((int8_t*)(buffer.data + buffer.index)));
value = (*((buffer.data + buffer.index)));
buffer.index += 1;
return value;
}
@@ -103,7 +132,7 @@ namespace CaveGame::Core
{
assert(buffer.index + 2 <= buffer.size);
int16_t value;
value = ntohs(*((int16_t*)(buffer.data + buffer.index)));
value = network_to_host(*((int16_t*)(buffer.data + buffer.index)));
buffer.index += 2;
return value;
}
@@ -111,7 +140,7 @@ namespace CaveGame::Core
{
assert(buffer.index + 4 <= buffer.size);
int32_t value;
value = ntohs(*((int32_t*)(buffer.data + buffer.index)));
value = network_to_host(*((int32_t*)(buffer.data + buffer.index)));
buffer.index += 4;
return value;
}
@@ -120,7 +149,7 @@ namespace CaveGame::Core
{
assert(buffer.index + 8 <= buffer.size);
int64_t value;
value = ntohs(*((int64_t*)(buffer.data + buffer.index)));
value = network_to_host(*((int64_t*)(buffer.data + buffer.index)));
buffer.index += 8;
return value;
}
@@ -142,4 +171,25 @@ namespace CaveGame::Core
double read_f64(Buffer &buffer) {
return ReinterpretAs<float>(read_u64(buffer));
}
void write_string(Buffer &buffer, std::string value) {
uint16_t length = value.length();
write_u16(buffer, length);
for (size_t i = 0; i < length; i++)
{
write_u8(buffer, (uint8_t)value[i]);
}
}
std::string read_string(Buffer &buffer) {
uint16_t str_size = read_u16(buffer);
std::string result;
for (size_t i = 0; i < str_size; i++)
{
result += (char)read_u8(buffer);
}
return result;
}
}