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

View File

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

View File

@ -22,7 +22,8 @@ namespace util {
/// @brief Find current entry address by index /// @brief Find current entry address by index
/// @param index entry 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) { uint8_t* find(Tindex index) {
auto data = buffer.data(); auto data = buffer.data();
for (size_t i = 0; i < entriesCount; i++) { for (size_t i = 0; i < entriesCount; i++) {
@ -60,7 +61,7 @@ namespace util {
/// @param index entry index /// @param index entry index
/// @param size entry size /// @param size entry size
/// @return temporary entry pointer /// @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) { uint8_t* allocate(Tindex index, Tsize size) {
if (size == 0) { if (size == 0) {
throw std::runtime_error("size is 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"пр"));
}