[ox/mc] Add McStr to wrap C style strings to distinguish them from arrays
This commit is contained in:
parent
c7e9a95a3f
commit
1c64096c38
17
deps/ox/src/ox/mc/deftypes.hpp
vendored
17
deps/ox/src/ox/mc/deftypes.hpp
vendored
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace ox::mc {
|
namespace ox::mc {
|
||||||
|
|
||||||
using String = const char*;
|
using String = BString<100>;
|
||||||
|
|
||||||
enum class PrimitiveType: uint8_t {
|
enum class PrimitiveType: uint8_t {
|
||||||
UnsignedInteger = 0,
|
UnsignedInteger = 0,
|
||||||
@ -26,38 +26,35 @@ enum class PrimitiveType: uint8_t {
|
|||||||
Struct = 6,
|
Struct = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
using FieldName = String;
|
|
||||||
|
|
||||||
struct Field {
|
struct Field {
|
||||||
// order of fields matters
|
// order of fields matters
|
||||||
|
|
||||||
// only serialize type name if type has already been serialized
|
// only serialize type name if type has already been serialized
|
||||||
const struct Type *type = nullptr;
|
const struct Type *type = nullptr;
|
||||||
FieldName fieldName;
|
String fieldName;
|
||||||
int subscriptLevels = 0;
|
int subscriptLevels = 0;
|
||||||
|
|
||||||
// do not serialize the following
|
// do not serialize the following
|
||||||
bool serializeType = false;
|
bool serializeType = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
using TypeName = String;
|
|
||||||
using FieldList = Vector<Field>;
|
using FieldList = Vector<Field>;
|
||||||
|
|
||||||
struct Type {
|
struct Type {
|
||||||
TypeName typeName;
|
String typeName;
|
||||||
PrimitiveType primitiveType;
|
PrimitiveType primitiveType;
|
||||||
// fieldList only applies to structs
|
// fieldList only applies to structs
|
||||||
FieldList fieldList;
|
Vector<Field> fieldList;
|
||||||
// - number of bytes for integer and float types
|
// - number of bytes for integer and float types
|
||||||
// - number of fields for structs and lists
|
// - number of fields for structs and lists
|
||||||
int64_t length = 0;
|
int64_t length = 0;
|
||||||
|
|
||||||
Type() = default;
|
Type() = default;
|
||||||
|
|
||||||
Type(TypeName tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) {
|
Type(String tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type(TypeName tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) {
|
Type(String tn, PrimitiveType t, FieldList fl): typeName(tn), primitiveType(t), fieldList(fl) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,6 +87,6 @@ int ioOp(T *io, Type *type) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
using TypeStore = ox::HashMap<mc::TypeName, mc::Type>;
|
using TypeStore = ox::HashMap<mc::String, mc::Type>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
14
deps/ox/src/ox/mc/defwriter.cpp
vendored
14
deps/ox/src/ox/mc/defwriter.cpp
vendored
@ -82,6 +82,12 @@ constexpr mc::Type *MetalClawDefWriter::type(uint64_t*, bool *alreadyExisted) {
|
|||||||
return getPrimitive(TypeName, PT, Bytes, alreadyExisted);
|
return getPrimitive(TypeName, PT, Bytes, alreadyExisted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mc::Type *MetalClawDefWriter::type(McStr, bool *alreadyExisted) {
|
||||||
|
constexpr auto TypeName = "B:string";
|
||||||
|
constexpr auto PT = mc::PrimitiveType::String;
|
||||||
|
return getPrimitive(TypeName, PT, 0, alreadyExisted);
|
||||||
|
}
|
||||||
|
|
||||||
constexpr mc::Type *MetalClawDefWriter::type(bool*, bool *alreadyExisted) {
|
constexpr mc::Type *MetalClawDefWriter::type(bool*, bool *alreadyExisted) {
|
||||||
constexpr auto TypeName = "B:bool";
|
constexpr auto TypeName = "B:bool";
|
||||||
constexpr auto PT = mc::PrimitiveType::Bool;
|
constexpr auto PT = mc::PrimitiveType::Bool;
|
||||||
@ -95,13 +101,7 @@ constexpr void MetalClawDefWriter::setTypeInfo(const char *name, int) {
|
|||||||
m_type->primitiveType = mc::PrimitiveType::Struct;
|
m_type->primitiveType = mc::PrimitiveType::Struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr mc::Type *MetalClawDefWriter::type(const char*, bool *alreadyExisted) {
|
constexpr mc::Type *MetalClawDefWriter::getPrimitive(mc::String tn, mc::PrimitiveType pt, int b, bool *alreadyExisted) {
|
||||||
constexpr auto TypeName = "B:string";
|
|
||||||
constexpr auto PT = mc::PrimitiveType::String;
|
|
||||||
return getPrimitive(TypeName, PT, 0, alreadyExisted);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr mc::Type *MetalClawDefWriter::getPrimitive(mc::TypeName tn, mc::PrimitiveType pt, int b, bool *alreadyExisted) {
|
|
||||||
if (m_typeStore->contains(tn)) {
|
if (m_typeStore->contains(tn)) {
|
||||||
*alreadyExisted = true;
|
*alreadyExisted = true;
|
||||||
return &m_typeStore->at(tn);
|
return &m_typeStore->at(tn);
|
||||||
|
16
deps/ox/src/ox/mc/defwriter.hpp
vendored
16
deps/ox/src/ox/mc/defwriter.hpp
vendored
@ -18,6 +18,7 @@
|
|||||||
#include "deftypes.hpp"
|
#include "deftypes.hpp"
|
||||||
#include "err.hpp"
|
#include "err.hpp"
|
||||||
#include "optype.hpp"
|
#include "optype.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -31,6 +32,11 @@ static constexpr int indirectionLevels(T *t) {
|
|||||||
return 1 + indirectionLevels(*t);
|
return 1 + indirectionLevels(*t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static_assert([] {
|
||||||
|
int i = 0;
|
||||||
|
return indirectionLevels(i) == 0;
|
||||||
|
}(), "indirectionLevels broken: indirectionLevels(int)");
|
||||||
|
|
||||||
static_assert([] {
|
static_assert([] {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
return indirectionLevels(&i) == 1;
|
return indirectionLevels(&i) == 1;
|
||||||
@ -93,13 +99,15 @@ class MetalClawDefWriter {
|
|||||||
|
|
||||||
constexpr mc::Type *type(const char *val, bool *alreadyExisted);
|
constexpr mc::Type *type(const char *val, bool *alreadyExisted);
|
||||||
|
|
||||||
|
mc::Type *type(McStr val, bool *alreadyExisted);
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
constexpr mc::Type *type(ox::BString<L> *val, bool *alreadyExisted);
|
constexpr mc::Type *type(ox::BString<L> *val, bool *alreadyExisted);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
mc::Type *type(T *val, bool *alreadyExisted);
|
mc::Type *type(T *val, bool *alreadyExisted);
|
||||||
|
|
||||||
constexpr mc::Type *getPrimitive(mc::TypeName tn, mc::PrimitiveType t, int b, bool *alreadyExisted);
|
constexpr mc::Type *getPrimitive(mc::String tn, mc::PrimitiveType t, int b, bool *alreadyExisted);
|
||||||
};
|
};
|
||||||
|
|
||||||
// array handler
|
// array handler
|
||||||
@ -145,8 +153,10 @@ mc::Type *MetalClawDefWriter::type(T *val, bool *alreadyExisted) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L> *val, bool *alreadyExisted) {
|
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L>*, bool *alreadyExisted) {
|
||||||
return type(val->c_str(), alreadyExisted);
|
constexpr auto TypeName = "B:string";
|
||||||
|
constexpr auto PT = mc::PrimitiveType::String;
|
||||||
|
return getPrimitive(TypeName, PT, 0, alreadyExisted);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
1
deps/ox/src/ox/mc/mc.hpp
vendored
1
deps/ox/src/ox/mc/mc.hpp
vendored
@ -11,4 +11,5 @@
|
|||||||
#include "deftypes.hpp"
|
#include "deftypes.hpp"
|
||||||
#include "defwriter.hpp"
|
#include "defwriter.hpp"
|
||||||
#include "read.hpp"
|
#include "read.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
#include "write.hpp"
|
#include "write.hpp"
|
||||||
|
30
deps/ox/src/ox/mc/read.cpp
vendored
30
deps/ox/src/ox/mc/read.cpp
vendored
@ -61,6 +61,36 @@ int MetalClawReader::op(const char*, bool *val) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error MetalClawReader::op(const char*, McStr val) {
|
||||||
|
int err = 0;
|
||||||
|
if (m_fieldPresence.get(m_field)) {
|
||||||
|
// read the length
|
||||||
|
int size = 0;
|
||||||
|
if (m_buffIt + sizeof(StringLength) < m_buffLen) {
|
||||||
|
size = *reinterpret_cast<LittleEndian<StringLength>*>(&m_buff[m_buffIt]);
|
||||||
|
m_buffIt += sizeof(StringLength);
|
||||||
|
} else {
|
||||||
|
err |= MC_BUFFENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the string
|
||||||
|
if (val.cap() >= size) {
|
||||||
|
if (m_buffIt + size < m_buffLen) {
|
||||||
|
ox_memcpy(val.data(), &m_buff[m_buffIt], size);
|
||||||
|
m_buffIt += size;
|
||||||
|
} else {
|
||||||
|
err |= MC_BUFFENDED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err |= MC_OUTBUFFENDED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val.data()[0] = 0;
|
||||||
|
}
|
||||||
|
m_field++;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t MetalClawReader::arrayLength(const char*) {
|
std::size_t MetalClawReader::arrayLength(const char*) {
|
||||||
std::size_t len = 0;
|
std::size_t len = 0;
|
||||||
if (m_fieldPresence.get(m_field)) {
|
if (m_fieldPresence.get(m_field)) {
|
||||||
|
37
deps/ox/src/ox/mc/read.hpp
vendored
37
deps/ox/src/ox/mc/read.hpp
vendored
@ -14,6 +14,7 @@
|
|||||||
#include "err.hpp"
|
#include "err.hpp"
|
||||||
#include "optype.hpp"
|
#include "optype.hpp"
|
||||||
#include "presencemask.hpp"
|
#include "presencemask.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -59,6 +60,8 @@ class MetalClawReader {
|
|||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
int op(const char*, ox::BString<L> *val);
|
int op(const char*, ox::BString<L> *val);
|
||||||
|
|
||||||
|
Error op(const char*, McStr val);
|
||||||
|
|
||||||
std::size_t arrayLength(const char*);
|
std::size_t arrayLength(const char*);
|
||||||
|
|
||||||
// stringLength returns the length of the string, including the null terminator.
|
// stringLength returns the length of the string, including the null terminator.
|
||||||
@ -66,7 +69,7 @@ class MetalClawReader {
|
|||||||
|
|
||||||
void setTypeInfo(const char *name, int fields);
|
void setTypeInfo(const char *name, int fields);
|
||||||
|
|
||||||
OpType opType() {
|
constexpr OpType opType() {
|
||||||
return OpType::Read;
|
return OpType::Read;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,35 +91,9 @@ int MetalClawReader::op(const char*, T *val) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
int MetalClawReader::op(const char*, ox::BString<L> *val) {
|
int MetalClawReader::op(const char *name, ox::BString<L> *val) {
|
||||||
int err = 0;
|
return op(name, McStr(val->data(), val->cap()));
|
||||||
if (m_fieldPresence.get(m_field)) {
|
}
|
||||||
// read the length
|
|
||||||
std::size_t size = 0;
|
|
||||||
if (m_buffIt + sizeof(StringLength) < m_buffLen) {
|
|
||||||
size = *reinterpret_cast<LittleEndian<StringLength>*>(&m_buff[m_buffIt]);
|
|
||||||
m_buffIt += sizeof(StringLength);
|
|
||||||
} else {
|
|
||||||
err |= MC_BUFFENDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the string
|
|
||||||
if (val->cap() >= size) {
|
|
||||||
if (m_buffIt + size < m_buffLen) {
|
|
||||||
ox_memcpy(val, &m_buff[m_buffIt], size);
|
|
||||||
m_buffIt += size;
|
|
||||||
} else {
|
|
||||||
err |= MC_BUFFENDED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err |= MC_OUTBUFFENDED;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*val = "";
|
|
||||||
}
|
|
||||||
m_field++;
|
|
||||||
return err;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
int MetalClawReader::readInteger(I *val) {
|
int MetalClawReader::readInteger(I *val) {
|
||||||
|
60
deps/ox/src/ox/mc/types.hpp
vendored
Normal file
60
deps/ox/src/ox/mc/types.hpp
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 - 2018 gtalent2@gmail.com
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ox/std/strops.hpp>
|
||||||
|
#include <ox/std/types.hpp>
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
class McStr {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_cap = -1;
|
||||||
|
char *m_str = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit constexpr McStr(const char *str) noexcept {
|
||||||
|
m_str = const_cast<char*>(str);
|
||||||
|
m_cap = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr McStr(char *str, int cap) noexcept {
|
||||||
|
m_str = str;
|
||||||
|
m_cap = cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const char *c_str() noexcept {
|
||||||
|
return m_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr char *data() noexcept {
|
||||||
|
// do not return a non-const pointer to the const_casted m_str
|
||||||
|
if (m_cap > -1) {
|
||||||
|
return m_str;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int len() noexcept {
|
||||||
|
return ox_strlen(m_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int bytes() noexcept {
|
||||||
|
return ox_strlen(m_str) + 1; // adds 1 for \0
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int cap() noexcept {
|
||||||
|
return m_cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
41
deps/ox/src/ox/mc/write.cpp
vendored
41
deps/ox/src/ox/mc/write.cpp
vendored
@ -23,43 +23,66 @@ MetalClawWriter::~MetalClawWriter() noexcept {
|
|||||||
oxAssert(m_field == m_fields, "MetalClawWriter: incorrect fields number given");
|
oxAssert(m_field == m_fields, "MetalClawWriter: incorrect fields number given");
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, int8_t *val) {
|
Error MetalClawWriter::op(const char*, int8_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, int16_t *val) {
|
Error MetalClawWriter::op(const char*, int16_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, int32_t *val) {
|
Error MetalClawWriter::op(const char*, int32_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, int64_t *val) {
|
Error MetalClawWriter::op(const char*, int64_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, uint8_t *val) {
|
Error MetalClawWriter::op(const char*, uint8_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, uint16_t *val) {
|
Error MetalClawWriter::op(const char*, uint16_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, uint32_t *val) {
|
Error MetalClawWriter::op(const char*, uint32_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, uint64_t *val) {
|
Error MetalClawWriter::op(const char*, uint64_t *val) {
|
||||||
return appendInteger(*val);
|
return appendInteger(*val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MetalClawWriter::op(const char*, bool *val) {
|
Error MetalClawWriter::op(const char*, bool *val) {
|
||||||
return m_fieldPresence.set(m_field++, *val);
|
return m_fieldPresence.set(m_field++, *val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error MetalClawWriter::op(const char*, McStr val) {
|
||||||
|
int err = 0;
|
||||||
|
bool fieldSet = false;
|
||||||
|
if (val.cap()) {
|
||||||
|
// write the length
|
||||||
|
typedef uint32_t StringLength;
|
||||||
|
if (m_buffIt + sizeof(StringLength) + val.bytes() < m_buffLen) {
|
||||||
|
*reinterpret_cast<LittleEndian<StringLength>*>(&m_buff[m_buffIt]) = static_cast<StringLength>(val.bytes());
|
||||||
|
m_buffIt += sizeof(StringLength);
|
||||||
|
|
||||||
|
// write the string
|
||||||
|
ox_memcpy(&m_buff[m_buffIt], val.c_str(), val.bytes());
|
||||||
|
m_buffIt += val.bytes();
|
||||||
|
fieldSet = true;
|
||||||
|
} else {
|
||||||
|
err = MC_BUFFENDED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err |= m_fieldPresence.set(m_field, fieldSet);
|
||||||
|
m_field++;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void MetalClawWriter::setTypeInfo(const char*, int fields) {
|
void MetalClawWriter::setTypeInfo(const char*, int fields) {
|
||||||
m_fields = fields;
|
m_fields = fields;
|
||||||
m_buffIt = (fields / 8 + 1) - (fields % 8 == 0);
|
m_buffIt = (fields / 8 + 1) - (fields % 8 == 0);
|
||||||
|
64
deps/ox/src/ox/mc/write.hpp
vendored
64
deps/ox/src/ox/mc/write.hpp
vendored
@ -15,6 +15,7 @@
|
|||||||
#include "err.hpp"
|
#include "err.hpp"
|
||||||
#include "optype.hpp"
|
#include "optype.hpp"
|
||||||
#include "presencemask.hpp"
|
#include "presencemask.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace ox {
|
namespace ox {
|
||||||
|
|
||||||
@ -22,7 +23,6 @@ class MetalClawWriter {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FieldPresenseMask m_fieldPresence;
|
FieldPresenseMask m_fieldPresence;
|
||||||
const char *m_typeName = nullptr;
|
|
||||||
int m_fields = 0;
|
int m_fields = 0;
|
||||||
int m_field = 0;
|
int m_field = 0;
|
||||||
std::size_t m_buffIt = 0;
|
std::size_t m_buffIt = 0;
|
||||||
@ -34,29 +34,28 @@ class MetalClawWriter {
|
|||||||
|
|
||||||
~MetalClawWriter() noexcept;
|
~MetalClawWriter() noexcept;
|
||||||
|
|
||||||
int op(const char*, int8_t *val);
|
Error op(const char*, int8_t *val);
|
||||||
int op(const char*, int16_t *val);
|
Error op(const char*, int16_t *val);
|
||||||
int op(const char*, int32_t *val);
|
Error op(const char*, int32_t *val);
|
||||||
int op(const char*, int64_t *val);
|
Error op(const char*, int64_t *val);
|
||||||
|
|
||||||
int op(const char*, uint8_t *val);
|
Error op(const char*, uint8_t *val);
|
||||||
int op(const char*, uint16_t *val);
|
Error op(const char*, uint16_t *val);
|
||||||
int op(const char*, uint32_t *val);
|
Error op(const char*, uint32_t *val);
|
||||||
int op(const char*, uint64_t *val);
|
Error op(const char*, uint64_t *val);
|
||||||
|
|
||||||
int op(const char*, bool *val);
|
Error op(const char*, bool *val);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int op(const char*, T *val, std::size_t len);
|
Error op(const char*, T *val, std::size_t len);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int op(const char*, ox::Vector<T> *val);
|
Error op(const char*, ox::Vector<T> *val);
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
int op(const char*, const char *val);
|
Error op(const char*, ox::BString<L> *val);
|
||||||
|
|
||||||
template<std::size_t L>
|
Error op(const char*, McStr val);
|
||||||
int op(const char*, ox::BString<L> *val);
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int op(const char*, T *val);
|
int op(const char*, T *val);
|
||||||
@ -65,37 +64,18 @@ class MetalClawWriter {
|
|||||||
|
|
||||||
std::size_t size();
|
std::size_t size();
|
||||||
|
|
||||||
OpType opType() {
|
constexpr OpType opType() {
|
||||||
return OpType::Write;
|
return OpType::Write;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename I>
|
template<typename I>
|
||||||
int appendInteger(I val);
|
Error appendInteger(I val);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::size_t L>
|
template<std::size_t L>
|
||||||
int MetalClawWriter::op(const char*, ox::BString<L> *val) {
|
Error MetalClawWriter::op(const char *name, ox::BString<L> *val) {
|
||||||
int err = 0;
|
return op(name, McStr(val->data(), val->cap()));
|
||||||
bool fieldSet = false;
|
|
||||||
if (val->len()) {
|
|
||||||
// write the length
|
|
||||||
typedef uint32_t StringLength;
|
|
||||||
if (m_buffIt + sizeof(StringLength) + val->bytes() < m_buffLen) {
|
|
||||||
*reinterpret_cast<LittleEndian<StringLength>*>(&m_buff[m_buffIt]) = static_cast<StringLength>(val->bytes());
|
|
||||||
m_buffIt += sizeof(StringLength);
|
|
||||||
|
|
||||||
// write the string
|
|
||||||
ox_memcpy(&m_buff[m_buffIt], val, val->bytes());
|
|
||||||
m_buffIt += val->bytes();
|
|
||||||
fieldSet = true;
|
|
||||||
} else {
|
|
||||||
err = MC_BUFFENDED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err |= m_fieldPresence.set(m_field, fieldSet);
|
|
||||||
m_field++;
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -116,12 +96,12 @@ int MetalClawWriter::op(const char*, T *val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int MetalClawWriter::op(const char*, ox::Vector<T> *val) {
|
Error MetalClawWriter::op(const char*, ox::Vector<T> *val) {
|
||||||
return op(nullptr, val->data(), val->size());
|
return op(nullptr, val->data(), val->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
int MetalClawWriter::appendInteger(I val) {
|
Error MetalClawWriter::appendInteger(I val) {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
bool fieldSet = false;
|
bool fieldSet = false;
|
||||||
if (val) {
|
if (val) {
|
||||||
@ -139,7 +119,7 @@ int MetalClawWriter::appendInteger(I val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int MetalClawWriter::op(const char*, T *val, std::size_t len) {
|
Error MetalClawWriter::op(const char*, T *val, std::size_t len) {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
bool fieldSet = false;
|
bool fieldSet = false;
|
||||||
|
|
||||||
@ -171,7 +151,7 @@ int MetalClawWriter::op(const char*, T *val, std::size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int writeMC(uint8_t *buff, std::size_t buffLen, T *val, std::size_t *sizeOut = nullptr) {
|
Error writeMC(uint8_t *buff, std::size_t buffLen, T *val, std::size_t *sizeOut = nullptr) {
|
||||||
MetalClawWriter writer(buff, buffLen);
|
MetalClawWriter writer(buff, buffLen);
|
||||||
auto err = ioOp(&writer, val);
|
auto err = ioOp(&writer, val);
|
||||||
if (sizeOut) {
|
if (sizeOut) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user