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