From 984644a05c4db717c7763544ffeaacbd2c8b0390 Mon Sep 17 00:00:00 2001 From: xxorza Date: Sun, 9 Jun 2024 07:56:37 +0300 Subject: [PATCH] Update FfiBuf data type and improve buffer reading FfiBuf's 'data' field type has been changed from 'uint8_t' to 'void' to make it more generic. Improvements were made to the buffer reading operations by adding a 'read_vec' function to the BufferStream class, reducing code duplication while enhancing the code readability. Also, the deprecated 'read_cstr' function was removed. --- ScenariumEditor.QML/src/BufferStream.cpp | 20 +----- ScenariumEditor.QML/src/BufferStream.hpp | 28 ++++---- ScenariumEditor.QML/src/CoreContext.cpp | 85 +++++++++++++++++------- 3 files changed, 76 insertions(+), 57 deletions(-) diff --git a/ScenariumEditor.QML/src/BufferStream.cpp b/ScenariumEditor.QML/src/BufferStream.cpp index be0b5c5..d3deb3d 100644 --- a/ScenariumEditor.QML/src/BufferStream.cpp +++ b/ScenariumEditor.QML/src/BufferStream.cpp @@ -4,31 +4,17 @@ BufferStream::~BufferStream() { - delete[] data; } template<> [[maybe_unused]] std::string BufferStream::read() { uint32_t str_len = read(); - if (pos + str_len > len) { + if (_pos + str_len > _len) { throw std::runtime_error("BufferStream: out of bounds"); } - std::string str(reinterpret_cast(data + pos), str_len); - pos += str_len; - return str; -} - -std::string BufferStream::read_cstr() { - std::string str; - while (pos < len) { - char c = *reinterpret_cast(data + pos); - pos += 1; - if (c == '\0') { - break; - } - str.push_back(c); - } + std::string str(reinterpret_cast(_data + _pos), str_len); + _pos += str_len; return str; } diff --git a/ScenariumEditor.QML/src/BufferStream.hpp b/ScenariumEditor.QML/src/BufferStream.hpp index a473a87..e207e95 100644 --- a/ScenariumEditor.QML/src/BufferStream.hpp +++ b/ScenariumEditor.QML/src/BufferStream.hpp @@ -7,34 +7,34 @@ #include - class BufferStream { private: - uint8_t *data = nullptr; - uint32_t len = 0; - uint32_t pos = 0; + uint8_t *_data = nullptr; + uint32_t _len = 0; + uint32_t _pos = 0; public: + BufferStream(void *data, uint32_t len) : _data(static_cast(data)), _len(len) {} ~BufferStream(); - [[nodiscard]] uint32_t get_len() const { - return len; + [[nodiscard]] uint32_t len() const { + return _len; } - [[nodiscard]] void *get_data() const { - return data; + [[nodiscard]] void *data() const { + return _data; } template [[maybe_unused]] T read() { static_assert(std::is_trivially_copyable::value, "T must be trivially copyable"); - if (pos + sizeof(T) > len) { + if (_pos + sizeof(T) > _len) { throw std::runtime_error("BufferStream: out of bounds"); } - T val = *reinterpret_cast(data + pos); - pos += sizeof(T); + T val = *reinterpret_cast(_data + _pos); + _pos += sizeof(T); return val; } @@ -43,7 +43,7 @@ class BufferStream { template [[maybe_unused]] std::vector read_vec() { uint32_t vec_len = read(); - if (pos + vec_len * sizeof(T) > len) { + if (_pos + vec_len * sizeof(T) > _len) { throw std::runtime_error("BufferStream: out of bounds"); } @@ -54,10 +54,6 @@ class BufferStream { } return vec; } - - std::string read_cstr(); - - std::string read_str_buf(); }; diff --git a/ScenariumEditor.QML/src/CoreContext.cpp b/ScenariumEditor.QML/src/CoreContext.cpp index 697b7cf..5a06c67 100644 --- a/ScenariumEditor.QML/src/CoreContext.cpp +++ b/ScenariumEditor.QML/src/CoreContext.cpp @@ -6,7 +6,7 @@ extern "C" { struct FfiBuf { - uint8_t *data; + void *data; uint32_t len; uint32_t cap; @@ -29,23 +29,61 @@ struct Buf { destroy_ffi_buf(ffi_buf); } -// Buf(const Buf &other) = delete; -// -// Buf &operator=(const Buf &other) = delete; - [[nodiscard]] uint32_t len() const { return ffi_buf.len; } - [[nodiscard]] uint8_t *data() const { + [[nodiscard]] void *data() const { return ffi_buf.data; } [[nodiscard]] std::string to_string() const { + if (len() == 0) { + return {}; + } + return std::string(reinterpret_cast(data()), len()); } + + + template + [[nodiscard]] std::vector read_vec() const { + if (len() == 0) { + return {}; + } + + assert(ffi_buf.len % sizeof(T) == 0); // check that the buffer is a multiple of the size of T + + auto len = ffi_buf.len / sizeof(T); + auto data = static_cast (ffi_buf.data); + + std::vector result; + result.reserve(len); + for (uint32_t i = 0; i < len; i++) { + result.push_back(data[i]); + } + return result; + } }; +template<> +std::vector Buf::read_vec() const { + if (len() == 0) { + return {}; + } + + BufferStream stream{data(), len()}; + auto len = stream.read(); + + std::vector result{}; + result.reserve(len); + for (uint32_t i = 0; i < len; i++) { + result.push_back(stream.read()); + } + + return result; +} + struct FfiFunc { Buf id; Buf name; @@ -70,31 +108,30 @@ Ctx::~Ctx() { std::vector Ctx::get_funcs() const { Buf buf = Buf{::get_funcs(this->ctx)}; - assert(buf.len() % sizeof(FfiFunc) == 0); // check that the buffer is a multiple of the size of FfiFunc - auto len = buf.len() / sizeof(FfiFunc); - auto funcs = static_cast ( static_cast (buf.data())); + auto funcs = buf.read_vec(); std::vector result; - result.reserve(len); + result.reserve(funcs.size()); + + for (uint32_t i = 0; i < funcs.size(); i++) { + auto ffi_func = &funcs[i]; + + auto inputs = ffi_func->inputs.read_vec(); + auto outputs = ffi_func->outputs.read_vec(); + auto events = ffi_func->events.read_vec(); - for (uint32_t i = 0; i < len; i++) { - auto ffi_func = funcs[i]; Func func{ - ffi_func.id.to_string(), - ffi_func.name.to_string(), - ffi_func.category.to_string(), - ffi_func.behaviour, - ffi_func.output, - {}, - {}, - {} -// BufferStream{ffi_func->inputs.data(), ffi_func->inputs.len()}.read_strings(), -// BufferStream{ffi_func->outputs.data(), ffi_func->outputs.len()}.read_strings(), -// BufferStream{ffi_func->events.data(), ffi_func->events.len()}.read_strings() + ffi_func->id.to_string(), + ffi_func->name.to_string(), + ffi_func->category.to_string(), + ffi_func->behaviour, + ffi_func->output, + inputs, + outputs, + events, }; result.push_back(func); } - return result; }