rename StructMapping to StructLayout

This commit is contained in:
MihailRis 2024-08-29 18:56:26 +03:00
parent d0bc679815
commit bcd6f40ddb
5 changed files with 63 additions and 60 deletions

View File

@ -1,4 +1,4 @@
#include "StructMapper.hpp"
#include "StructLayout.hpp"
#include <cstring>
#include <string.h>
@ -13,7 +13,7 @@ using namespace data;
static_assert(sizeof(float) == sizeof(int32_t));
static_assert(sizeof(double) == sizeof(int64_t));
StructMapping StructMapping::create(const std::vector<Field>& fields) {
StructLayout StructLayout::create(const std::vector<Field>& fields) {
std::vector<Field> builtFields = fields;
std::unordered_map<std::string, int> indices;
@ -32,11 +32,11 @@ StructMapping StructMapping::create(const std::vector<Field>& fields) {
indices[field.name] = i;
offset += field.size;
}
return StructMapping(
return StructLayout(
offset, std::move(builtFields), std::move(indices));
}
const Field& StructMapping::requreField(const std::string& name) const {
const Field& StructLayout::requreField(const std::string& name) const {
auto found = indices.find(name);
if (found == indices.end()) {
throw std::runtime_error("field '"+name+"' does not exist");
@ -52,7 +52,7 @@ static void set_int(ubyte* dst, integer_t value) {
*reinterpret_cast<T*>(dst) = out_value;
}
void StructMapping::setInteger(
void StructLayout::setInteger(
ubyte* dst, integer_t value, const std::string& name, int index
) {
const auto& field = requreField(name);
@ -76,7 +76,7 @@ void StructMapping::setInteger(
}
}
void StructMapping::setNumber(
void StructLayout::setNumber(
ubyte* dst, number_t value, const std::string& name, int index
) {
const auto& field = requreField(name);
@ -105,7 +105,7 @@ void StructMapping::setNumber(
}
}
size_t StructMapping::setChars(
size_t StructLayout::setChars(
ubyte* dst, std::string_view value, const std::string& name
) {
const auto& field = requreField(name);
@ -118,7 +118,7 @@ size_t StructMapping::setChars(
return size;
}
size_t StructMapping::setUnicode(
size_t StructLayout::setUnicode(
ubyte* dst, std::string_view value, const std::string& name
) {
const auto& field = requreField(name);
@ -137,7 +137,7 @@ static T get_int(const ubyte* src) {
return dataio::le2h(*reinterpret_cast<const T*>(src));
}
integer_t StructMapping::getInteger(
integer_t StructLayout::getInteger(
const ubyte* src, const std::string& name, int index
) const {
const auto& field = requreField(name);
@ -157,7 +157,7 @@ integer_t StructMapping::getInteger(
}
}
number_t StructMapping::getNumber(
number_t StructLayout::getNumber(
const ubyte* src, const std::string& name, int index
) const {
const auto& field = requreField(name);
@ -190,7 +190,7 @@ number_t StructMapping::getNumber(
throw std::runtime_error("type error");
}
std::string_view StructMapping::getChars(
std::string_view StructLayout::getChars(
const ubyte* src, const std::string& name
) const {
const auto& field = requreField(name);

View File

@ -30,12 +30,12 @@ namespace data {
int size;
};
class StructMapping {
class StructLayout {
int totalSize;
std::vector<Field> fields;
std::unordered_map<std::string, int> indices;
public:
StructMapping(
StructLayout(
int totalSize,
std::vector<Field> fields,
std::unordered_map<std::string, int> indices
@ -47,6 +47,7 @@ namespace data {
/// @brief Get field by name. Returns nullptr if field not found.
/// @param name field name
/// @return nullable field pointer
[[nodiscard]]
const Field* getField(const std::string& name) const {
auto found = indices.find(name);
if (found == indices.end()) {
@ -128,18 +129,19 @@ namespace data {
size_t setUnicode(ubyte* dst, std::string_view value, const std::string& name);
/// @return total structure size (bytes)
int size() const {
[[nodiscard]] size_t size() const {
return totalSize;
}
static StructMapping create(const std::vector<Field>& fields);
[[nodiscard]]
static StructLayout create(const std::vector<Field>& fields);
};
class StructAccess {
const StructMapping& mapping;
const StructLayout& mapping;
uint8_t* buffer;
public:
StructAccess(const StructMapping& mapping, uint8_t* buffer)
StructAccess(const StructLayout& mapping, uint8_t* buffer)
: mapping(mapping), buffer(buffer) {
}
};

View File

@ -22,7 +22,8 @@ namespace util {
/// @brief Find current entry address by index
/// @param index entry index
/// @return nullptr if entry does not exists
/// @return temporary raw pointer or nullptr if entry does not exists
/// @attention pointer becomes invalid after allocate(...) or free(...)
uint8_t* find(Tindex index) {
auto data = buffer.data();
for (size_t i = 0; i < entriesCount; i++) {
@ -60,7 +61,7 @@ namespace util {
/// @param index entry index
/// @param size entry size
/// @return temporary entry pointer
/// (invalid after next allocate(...) or free(...))
/// @attention pointer becomes invalid after allocate(...) or free(...)
uint8_t* allocate(Tindex index, Tsize size) {
if (size == 0) {
throw std::runtime_error("size is 0");

View File

@ -0,0 +1,41 @@
#include "data/StructLayout.hpp"
#include <gtest/gtest.h>
using namespace data;
TEST(StructLayout, ReadWrite) {
ubyte buffer[16] {};
std::vector<Field> fields {
Field {FieldType::I8, "a", 1},
Field {FieldType::CHAR, "s", 4},
Field {FieldType::F32, "f", 1},
};
auto layout = StructLayout::create(fields);
EXPECT_EQ(layout.size(), 9);
layout.setInteger(buffer, 42, "a");
EXPECT_EQ(layout.getInteger(buffer, "a"), 42);
layout.setNumber(buffer, 3.141592f, "f");
EXPECT_FLOAT_EQ(layout.getNumber(buffer, "f"), 3.141592f);
layout.setChars(buffer, "hello", "s");
EXPECT_EQ(layout.getChars(buffer, "s"), "hell");
}
TEST(StructLayout, Unicode) {
ubyte buffer[8] {};
std::vector<Field> fields {
Field {FieldType::CHAR, "text", 5},
};
auto layout = StructLayout::create(fields);
EXPECT_EQ(layout.size(), 5);
layout.setUnicode(buffer, u8"テキストデモ", "text");
EXPECT_EQ(layout.getChars(buffer, "text"), std::string(u8""));
layout.setUnicode(buffer, u8"пример", "text");
EXPECT_EQ(layout.getChars(buffer, "text"), std::string(u8"пр"));
}

View File

@ -1,41 +0,0 @@
#include "data/StructMapper.hpp"
#include <gtest/gtest.h>
using namespace data;
TEST(StructMapper, ReadWrite) {
ubyte buffer[16] {};
std::vector<Field> fields {
Field {FieldType::I8, "a", 1},
Field {FieldType::CHAR, "s", 4},
Field {FieldType::F32, "f", 1},
};
auto mapping = StructMapping::create(fields);
EXPECT_EQ(mapping.size(), 9);
mapping.setInteger(buffer, 42, "a");
EXPECT_EQ(mapping.getInteger(buffer, "a"), 42);
mapping.setNumber(buffer, 3.141592f, "f");
EXPECT_FLOAT_EQ(mapping.getNumber(buffer, "f"), 3.141592f);
mapping.setChars(buffer, "hello", "s");
EXPECT_EQ(mapping.getChars(buffer, "s"), "hell");
}
TEST(StructMapper, Unicode) {
ubyte buffer[8] {};
std::vector<Field> fields {
Field {FieldType::CHAR, "text", 5},
};
auto mapping = StructMapping::create(fields);
EXPECT_EQ(mapping.size(), 5);
mapping.setUnicode(buffer, u8"テキストデモ", "text");
EXPECT_EQ(mapping.getChars(buffer, "text"), std::string(u8""));
mapping.setUnicode(buffer, u8"пример", "text");
EXPECT_EQ(mapping.getChars(buffer, "text"), std::string(u8"пр"));
}