[ox/model] Add support to SerStr for allocating string
This commit is contained in:
parent
8753d39b66
commit
b3fa531aa0
10
deps/ox/src/ox/mc/read.cpp
vendored
10
deps/ox/src/ox/mc/read.cpp
vendored
@ -83,11 +83,12 @@ Error MetalClawReader::field(const char*, SerStr val) {
|
||||
auto [size, err] = mc::decodeInteger<StringLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead);
|
||||
m_buffIt += bytesRead;
|
||||
oxReturnError(err);
|
||||
auto data = val.data(size + 1);
|
||||
// read the string
|
||||
if (val.cap() > -1 && static_cast<StringLength>(val.cap()) >= size) {
|
||||
if (m_buffIt + size <= m_buffLen) {
|
||||
ox_memcpy(val.data(), &m_buff[m_buffIt], size);
|
||||
val.data()[size] = 0;
|
||||
ox_memcpy(data, &m_buff[m_buffIt], size);
|
||||
data[size] = 0;
|
||||
m_buffIt += size;
|
||||
} else {
|
||||
return OxError(MC_BUFFENDED);
|
||||
@ -96,7 +97,10 @@ Error MetalClawReader::field(const char*, SerStr val) {
|
||||
return OxError(MC_OUTBUFFENDED);
|
||||
}
|
||||
} else {
|
||||
val.data()[0] = 0;
|
||||
auto data = val.data();
|
||||
if (data) {
|
||||
data[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
++m_field;
|
||||
|
12
deps/ox/src/ox/mc/test/tests.cpp
vendored
12
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -36,7 +36,7 @@ struct TestStructNest {
|
||||
|
||||
struct TestStruct {
|
||||
static constexpr auto TypeName = "TestStruct";
|
||||
static constexpr auto Fields = 15;
|
||||
static constexpr auto Fields = 16;
|
||||
bool Bool = false;
|
||||
int32_t Int = 0;
|
||||
int32_t Int1 = 0;
|
||||
@ -48,10 +48,16 @@ struct TestStruct {
|
||||
int32_t Int7 = 0;
|
||||
int32_t Int8 = 0;
|
||||
TestUnion Union;
|
||||
char *CString = nullptr;
|
||||
ox::BString<32> String = "";
|
||||
uint32_t List[4] = {0, 0, 0, 0};
|
||||
TestStructNest EmptyStruct;
|
||||
TestStructNest Struct;
|
||||
|
||||
~TestStruct() {
|
||||
delete[] CString;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -86,6 +92,7 @@ ox::Error model(T *io, TestStruct *obj) {
|
||||
oxReturnError(io->field("Int7", &obj->Int7));
|
||||
oxReturnError(io->field("Int8", &obj->Int8));
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 1}));
|
||||
oxReturnError(io->field("CString", ox::SerStr(&obj->CString)));
|
||||
oxReturnError(io->field("String", &obj->String));
|
||||
oxReturnError(io->field("List", obj->List, 4));
|
||||
oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct));
|
||||
@ -120,6 +127,8 @@ std::map<std::string, ox::Error(*)()> tests = {
|
||||
testIn.Int = 42;
|
||||
testIn.Union.Int = 42;
|
||||
testIn.String = "Test String 1";
|
||||
testIn.CString = new char[ox_strlen("c-string") + 1];
|
||||
ox_strcpy(testIn.CString, "c-string");
|
||||
testIn.List[0] = 1;
|
||||
testIn.List[1] = 2;
|
||||
testIn.List[2] = 3;
|
||||
@ -142,6 +151,7 @@ std::map<std::string, ox::Error(*)()> tests = {
|
||||
oxAssert(testIn.Int6 == testOut.Int6, "Int6 value mismatch");
|
||||
oxAssert(testIn.Int7 == testOut.Int7, "Int7 value mismatch");
|
||||
oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch");
|
||||
oxAssert(ox_strcmp(testIn.CString, testOut.CString) == 0, "CString value mismatch");
|
||||
oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch");
|
||||
oxAssert(testIn.String == testOut.String, "String value mismatch");
|
||||
oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch");
|
||||
|
2
deps/ox/src/ox/mc/write.cpp
vendored
2
deps/ox/src/ox/mc/write.cpp
vendored
@ -68,7 +68,7 @@ Error MetalClawWriter::field(const char*, bool *val) noexcept {
|
||||
|
||||
Error MetalClawWriter::field(const char*, SerStr val) noexcept {
|
||||
bool fieldSet = false;
|
||||
if (val.cap() && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
if (val.len() && (m_unionIdx == -1 || m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLen = mc::encodeInteger(val.len());
|
||||
if (m_buffIt + strLen.length + val.len() < m_buffLen) {
|
||||
|
17
deps/ox/src/ox/model/types.hpp
vendored
17
deps/ox/src/ox/model/types.hpp
vendored
@ -20,6 +20,7 @@ class SerStr {
|
||||
protected:
|
||||
int m_cap = 0;
|
||||
char *m_str = nullptr;
|
||||
char **m_tgt = nullptr;
|
||||
|
||||
public:
|
||||
template<std::size_t sz>
|
||||
@ -33,6 +34,12 @@ class SerStr {
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
constexpr SerStr(char **tgt, int cap = -1) noexcept {
|
||||
m_tgt = tgt;
|
||||
m_str = const_cast<char*>(*tgt);
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
template<std::size_t cap>
|
||||
constexpr SerStr(char (&str)[cap]) noexcept {
|
||||
m_str = str;
|
||||
@ -43,13 +50,17 @@ class SerStr {
|
||||
return m_str;
|
||||
}
|
||||
|
||||
constexpr char *data() noexcept {
|
||||
// do not return a non-const pointer to the const_casted m_str
|
||||
constexpr char *data(std::size_t sz = 0) noexcept {
|
||||
if (m_tgt && sz) {
|
||||
*m_tgt = new char[sz];
|
||||
m_str = *m_tgt;
|
||||
m_cap = sz;
|
||||
}
|
||||
return m_str;
|
||||
}
|
||||
|
||||
constexpr int len() noexcept {
|
||||
return ox_strlen(m_str);
|
||||
return m_str ? ox_strlen(m_str) : 0;
|
||||
}
|
||||
|
||||
constexpr int cap() noexcept {
|
||||
|
12
deps/ox/src/ox/std/strops.hpp
vendored
12
deps/ox/src/ox/std/strops.hpp
vendored
@ -12,6 +12,18 @@
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
|
||||
template<typename T1, typename T2>
|
||||
constexpr char *ox_strcpy(T1 dest, T2 src) noexcept {
|
||||
std::size_t i = 0;
|
||||
while (src[i]) {
|
||||
dest[i] = src[i];
|
||||
++i;
|
||||
}
|
||||
// set null terminator
|
||||
dest[i] = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
constexpr char *ox_strncpy(T1 dest, T2 src, std::size_t maxLen) noexcept {
|
||||
std::size_t i = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user