Skip to content

Commit

Permalink
Update FfiBuf data type and improve buffer reading
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
xorza committed Jun 9, 2024
1 parent f8da612 commit 984644a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 57 deletions.
20 changes: 3 additions & 17 deletions ScenariumEditor.QML/src/BufferStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,17 @@


BufferStream::~BufferStream() {
delete[] data;
}


template<>
[[maybe_unused]] std::string BufferStream::read<std::string>() {
uint32_t str_len = read<uint32_t>();
if (pos + str_len > len) {
if (_pos + str_len > _len) {
throw std::runtime_error("BufferStream: out of bounds");
}

std::string str(reinterpret_cast<char *>(data + pos), str_len);
pos += str_len;
return str;
}

std::string BufferStream::read_cstr() {
std::string str;
while (pos < len) {
char c = *reinterpret_cast<char *>(data + pos);
pos += 1;
if (c == '\0') {
break;
}
str.push_back(c);
}
std::string str(reinterpret_cast<char *>(_data + _pos), str_len);
_pos += str_len;
return str;
}
28 changes: 12 additions & 16 deletions ScenariumEditor.QML/src/BufferStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@
#include <string>



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<uint8_t *>(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<typename T>
[[maybe_unused]] T read() {
static_assert(std::is_trivially_copyable<T>::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<T *>(data + pos);
pos += sizeof(T);
T val = *reinterpret_cast<T *>(_data + _pos);
_pos += sizeof(T);
return val;
}

Expand All @@ -43,7 +43,7 @@ class BufferStream {
template<typename T>
[[maybe_unused]] std::vector<T> read_vec() {
uint32_t vec_len = read<uint32_t>();
if (pos + vec_len * sizeof(T) > len) {
if (_pos + vec_len * sizeof(T) > _len) {
throw std::runtime_error("BufferStream: out of bounds");
}

Expand All @@ -54,10 +54,6 @@ class BufferStream {
}
return vec;
}

std::string read_cstr();

std::string read_str_buf();
};


Expand Down
85 changes: 61 additions & 24 deletions ScenariumEditor.QML/src/CoreContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

extern "C" {
struct FfiBuf {
uint8_t *data;
void *data;
uint32_t len;
uint32_t cap;

Expand All @@ -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<char *>(data()), len());
}


template<class T>
[[nodiscard]] std::vector<T> 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 <T *>(ffi_buf.data);

std::vector<T> result;
result.reserve(len);
for (uint32_t i = 0; i < len; i++) {
result.push_back(data[i]);
}
return result;
}
};

template<>
std::vector<std::string> Buf::read_vec<std::string>() const {
if (len() == 0) {
return {};
}

BufferStream stream{data(), len()};
auto len = stream.read<uint32_t>();

std::vector<std::string> result{};
result.reserve(len);
for (uint32_t i = 0; i < len; i++) {
result.push_back(stream.read<std::string>());
}

return result;
}

struct FfiFunc {
Buf id;
Buf name;
Expand All @@ -70,31 +108,30 @@ Ctx::~Ctx() {
std::vector<Func> 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 <FfiFunc *>( static_cast <void *>(buf.data()));
auto funcs = buf.read_vec<FfiFunc>();

std::vector<Func> 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<std::string>();
auto outputs = ffi_func->outputs.read_vec<std::string>();
auto events = ffi_func->events.read_vec<std::string>();

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;
}

0 comments on commit 984644a

Please sign in to comment.