[ox/mc] Add McStr to wrap C style strings to distinguish them from arrays
This commit is contained in:
		
							
								
								
									
										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 {
 | 
			
		||||
 | 
			
		||||
using String = const char*;
 | 
			
		||||
using String = BString<100>;
 | 
			
		||||
 | 
			
		||||
enum class PrimitiveType: uint8_t {
 | 
			
		||||
	UnsignedInteger = 0,
 | 
			
		||||
@@ -26,38 +26,35 @@ enum class PrimitiveType: uint8_t {
 | 
			
		||||
	Struct = 6,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
using FieldName = String;
 | 
			
		||||
 | 
			
		||||
struct Field {
 | 
			
		||||
	// order of fields matters
 | 
			
		||||
 | 
			
		||||
	// only serialize type name if type has already been serialized
 | 
			
		||||
	const struct Type *type = nullptr;
 | 
			
		||||
	FieldName fieldName;
 | 
			
		||||
	String fieldName;
 | 
			
		||||
	int subscriptLevels = 0;
 | 
			
		||||
 | 
			
		||||
	// do not serialize the following
 | 
			
		||||
	bool serializeType = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
using TypeName = String;
 | 
			
		||||
using FieldList = Vector<Field>;
 | 
			
		||||
 | 
			
		||||
struct Type {
 | 
			
		||||
	TypeName typeName;
 | 
			
		||||
	String typeName;
 | 
			
		||||
	PrimitiveType primitiveType;
 | 
			
		||||
	// fieldList only applies to structs
 | 
			
		||||
	FieldList fieldList;
 | 
			
		||||
	Vector<Field> fieldList;
 | 
			
		||||
	// - number of bytes for integer and float types
 | 
			
		||||
	// - number of fields for structs and lists
 | 
			
		||||
	int64_t length = 0;
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 auto TypeName = "B: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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr mc::Type *MetalClawDefWriter::type(const char*, 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) {
 | 
			
		||||
constexpr mc::Type *MetalClawDefWriter::getPrimitive(mc::String tn, mc::PrimitiveType pt, int b, bool *alreadyExisted) {
 | 
			
		||||
	if (m_typeStore->contains(tn)) {
 | 
			
		||||
		*alreadyExisted = true;
 | 
			
		||||
		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 "err.hpp"
 | 
			
		||||
#include "optype.hpp"
 | 
			
		||||
#include "types.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ox {
 | 
			
		||||
 | 
			
		||||
@@ -31,6 +32,11 @@ static constexpr int indirectionLevels(T *t) {
 | 
			
		||||
	return 1 + indirectionLevels(*t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static_assert([] {
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	return indirectionLevels(i) == 0;
 | 
			
		||||
}(), "indirectionLevels broken: indirectionLevels(int)");
 | 
			
		||||
 | 
			
		||||
static_assert([] {
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	return indirectionLevels(&i) == 1;
 | 
			
		||||
@@ -93,13 +99,15 @@ class MetalClawDefWriter {
 | 
			
		||||
 | 
			
		||||
		constexpr mc::Type *type(const char *val, bool *alreadyExisted);
 | 
			
		||||
 | 
			
		||||
		mc::Type *type(McStr val, bool *alreadyExisted);
 | 
			
		||||
 | 
			
		||||
		template<std::size_t L>
 | 
			
		||||
		constexpr mc::Type *type(ox::BString<L> *val, bool *alreadyExisted);
 | 
			
		||||
 | 
			
		||||
		template<typename T>
 | 
			
		||||
		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
 | 
			
		||||
@@ -145,8 +153,10 @@ mc::Type *MetalClawDefWriter::type(T *val, bool *alreadyExisted) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<std::size_t L>
 | 
			
		||||
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L> *val, bool *alreadyExisted) {
 | 
			
		||||
	return type(val->c_str(), alreadyExisted);
 | 
			
		||||
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L>*, bool *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 "defwriter.hpp"
 | 
			
		||||
#include "read.hpp"
 | 
			
		||||
#include "types.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 len = 0;
 | 
			
		||||
	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 "optype.hpp"
 | 
			
		||||
#include "presencemask.hpp"
 | 
			
		||||
#include "types.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ox {
 | 
			
		||||
 | 
			
		||||
@@ -59,6 +60,8 @@ class MetalClawReader {
 | 
			
		||||
		template<std::size_t L>
 | 
			
		||||
		int op(const char*, ox::BString<L> *val);
 | 
			
		||||
 | 
			
		||||
		Error op(const char*, McStr val);
 | 
			
		||||
 | 
			
		||||
		std::size_t arrayLength(const char*);
 | 
			
		||||
 | 
			
		||||
		// stringLength returns the length of the string, including the null terminator.
 | 
			
		||||
@@ -66,7 +69,7 @@ class MetalClawReader {
 | 
			
		||||
 | 
			
		||||
		void setTypeInfo(const char *name, int fields);
 | 
			
		||||
 | 
			
		||||
      OpType opType() {
 | 
			
		||||
      constexpr OpType opType() {
 | 
			
		||||
          return OpType::Read;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -88,35 +91,9 @@ int MetalClawReader::op(const char*, T *val) {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<std::size_t L>
 | 
			
		||||
int MetalClawReader::op(const char*, ox::BString<L> *val) {
 | 
			
		||||
	int err = 0;
 | 
			
		||||
	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;
 | 
			
		||||
};
 | 
			
		||||
int MetalClawReader::op(const char *name, ox::BString<L> *val) {
 | 
			
		||||
	return op(name, McStr(val->data(), val->cap()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename I>
 | 
			
		||||
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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, int8_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, int8_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, int16_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, int16_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, int32_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, int32_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, int64_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, int64_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, uint8_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, uint8_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, uint16_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, uint16_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, uint32_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, uint32_t *val) {
 | 
			
		||||
	return appendInteger(*val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MetalClawWriter::op(const char*, uint64_t *val) {
 | 
			
		||||
Error MetalClawWriter::op(const char*, uint64_t *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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
	m_fields = fields;
 | 
			
		||||
	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 "optype.hpp"
 | 
			
		||||
#include "presencemask.hpp"
 | 
			
		||||
#include "types.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ox {
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +23,6 @@ class MetalClawWriter {
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		FieldPresenseMask m_fieldPresence;
 | 
			
		||||
		const char *m_typeName = nullptr;
 | 
			
		||||
		int m_fields = 0;
 | 
			
		||||
		int m_field = 0;
 | 
			
		||||
		std::size_t m_buffIt = 0;
 | 
			
		||||
@@ -34,29 +34,28 @@ class MetalClawWriter {
 | 
			
		||||
 | 
			
		||||
		~MetalClawWriter() noexcept;
 | 
			
		||||
 | 
			
		||||
		int op(const char*, int8_t *val);
 | 
			
		||||
		int op(const char*, int16_t *val);
 | 
			
		||||
		int op(const char*, int32_t *val);
 | 
			
		||||
		int op(const char*, int64_t *val);
 | 
			
		||||
		Error op(const char*, int8_t *val);
 | 
			
		||||
		Error op(const char*, int16_t *val);
 | 
			
		||||
		Error op(const char*, int32_t *val);
 | 
			
		||||
		Error op(const char*, int64_t *val);
 | 
			
		||||
 | 
			
		||||
		int op(const char*, uint8_t *val);
 | 
			
		||||
		int op(const char*, uint16_t *val);
 | 
			
		||||
		int op(const char*, uint32_t *val);
 | 
			
		||||
		int op(const char*, uint64_t *val);
 | 
			
		||||
		Error op(const char*, uint8_t *val);
 | 
			
		||||
		Error op(const char*, uint16_t *val);
 | 
			
		||||
		Error op(const char*, uint32_t *val);
 | 
			
		||||
		Error op(const char*, uint64_t *val);
 | 
			
		||||
 | 
			
		||||
		int op(const char*, bool *val);
 | 
			
		||||
		Error op(const char*, bool *val);
 | 
			
		||||
 | 
			
		||||
		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>
 | 
			
		||||
		int op(const char*, ox::Vector<T> *val);
 | 
			
		||||
		Error op(const char*, ox::Vector<T> *val);
 | 
			
		||||
 | 
			
		||||
		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>
 | 
			
		||||
		int op(const char*, ox::BString<L> *val);
 | 
			
		||||
		Error op(const char*, McStr val);
 | 
			
		||||
 | 
			
		||||
		template<typename T>
 | 
			
		||||
		int op(const char*, T *val);
 | 
			
		||||
@@ -65,37 +64,18 @@ class MetalClawWriter {
 | 
			
		||||
 | 
			
		||||
		std::size_t size();
 | 
			
		||||
 | 
			
		||||
      OpType opType() {
 | 
			
		||||
      constexpr OpType opType() {
 | 
			
		||||
          return OpType::Write;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		template<typename I>
 | 
			
		||||
		int appendInteger(I val);
 | 
			
		||||
		Error appendInteger(I val);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<std::size_t L>
 | 
			
		||||
int MetalClawWriter::op(const char*, ox::BString<L> *val) {
 | 
			
		||||
	int err = 0;
 | 
			
		||||
	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;
 | 
			
		||||
Error MetalClawWriter::op(const char *name, ox::BString<L> *val) {
 | 
			
		||||
	return op(name, McStr(val->data(), val->cap()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
@@ -116,12 +96,12 @@ int MetalClawWriter::op(const char*, T *val) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename I>
 | 
			
		||||
int MetalClawWriter::appendInteger(I val) {
 | 
			
		||||
Error MetalClawWriter::appendInteger(I val) {
 | 
			
		||||
	int err = 0;
 | 
			
		||||
	bool fieldSet = false;
 | 
			
		||||
	if (val) {
 | 
			
		||||
@@ -139,7 +119,7 @@ int MetalClawWriter::appendInteger(I val) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
	bool fieldSet = false;
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +151,7 @@ int MetalClawWriter::op(const char*, T *val, std::size_t len) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
	auto err = ioOp(&writer, val);
 | 
			
		||||
	if (sizeOut) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user