[ox/mc] Fix read to resize Vectors before writing to them

This commit is contained in:
Gary Talent 2019-10-25 21:48:43 -05:00
parent 37009a7923
commit 4ca4c31539
4 changed files with 22 additions and 18 deletions

View File

@ -125,12 +125,12 @@ template<typename I>
if (bytes == 9) { if (bytes == 9) {
*bytesRead = bytes; *bytesRead = bytes;
I out = 0; I out = 0;
ox_memcpy(&out, &buff[1], sizeof(I)); memcpy(&out, &buff[1], sizeof(I));
return {LittleEndian<I>(out), OxError(0)}; return {LittleEndian<I>(out), OxError(0)};
} else if (buffLen >= bytes) { } else if (buffLen >= bytes) {
*bytesRead = bytes; *bytesRead = bytes;
uint64_t decoded = 0; uint64_t decoded = 0;
ox_memcpy(&decoded, &buff[0], bytes); memcpy(&decoded, &buff[0], bytes);
decoded >>= bytes; decoded >>= bytes;
auto out = static_cast<I>(decoded); auto out = static_cast<I>(decoded);
// move sign bit // move sign bit
@ -142,7 +142,7 @@ template<typename I>
decoded &= uint64_t(~0) ^ (uint64_t(1) << valBits); decoded &= uint64_t(~0) ^ (uint64_t(1) << valBits);
// set sign // set sign
decoded |= sign << (Bits<I> - 1); decoded |= sign << (Bits<I> - 1);
ox_memcpy(&out, &decoded, sizeof(out)); memcpy(&out, &decoded, sizeof(out));
} }
return {out, OxError(0)}; return {out, OxError(0)};
} }

View File

@ -63,7 +63,7 @@ Error MetalClawReader::field(const char*, uint64_t *val) {
Error MetalClawReader::field(const char*, bool *val) { Error MetalClawReader::field(const char*, bool *val) {
auto valErr = m_fieldPresence.get(m_field++); auto valErr = m_fieldPresence.get(m_field++);
*val = valErr.value; *val = valErr.value;
return OxError(valErr.error); return valErr.error;
} }
Error MetalClawReader::field(const char*, SerStr val) { Error MetalClawReader::field(const char*, SerStr val) {
@ -94,7 +94,7 @@ Error MetalClawReader::field(const char*, SerStr val) {
return OxError(0); return OxError(0);
} }
[[nodiscard]] ArrayLength MetalClawReader::arrayLength(bool pass) { [[nodiscard]] ValErr<ArrayLength> MetalClawReader::arrayLength(bool pass) {
std::size_t len = 0; std::size_t len = 0;
if (m_fieldPresence.get(m_field)) { if (m_fieldPresence.get(m_field)) {
// read the length // read the length
@ -102,7 +102,7 @@ Error MetalClawReader::field(const char*, SerStr val) {
return OxError(MC_BUFFENDED); return OxError(MC_BUFFENDED);
} }
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
len = mc::decodeInteger<StringLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead).value; len = mc::decodeInteger<ArrayLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead).value;
if (pass) { if (pass) {
m_buffIt += sizeof(ArrayLength); m_buffIt += sizeof(ArrayLength);
} }

View File

@ -12,6 +12,7 @@
#include <ox/model/types.hpp> #include <ox/model/types.hpp>
#include <ox/std/byteswap.hpp> #include <ox/std/byteswap.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/trace.hpp>
#include <ox/std/vector.hpp> #include <ox/std/vector.hpp>
#include "err.hpp" #include "err.hpp"
@ -68,7 +69,7 @@ class MetalClawReader {
* Reads an array length from the current location in the buffer. * Reads an array length from the current location in the buffer.
* @param pass indicates that the parsing should iterate past the array length * @param pass indicates that the parsing should iterate past the array length
*/ */
[[nodiscard]] ArrayLength arrayLength(bool pass = true); [[nodiscard]] ValErr<ArrayLength> arrayLength(bool pass = true);
/** /**
* Reads an string length from the current location in the buffer. * Reads an string length from the current location in the buffer.
@ -106,12 +107,11 @@ class MetalClawReader {
template<typename T> template<typename T>
Error MetalClawReader::field(const char*, T *val) { Error MetalClawReader::field(const char*, T *val) {
auto err = OxError(0);
if (val && m_fieldPresence.get(m_field++)) { if (val && m_fieldPresence.get(m_field++)) {
auto reader = child(); auto reader = child();
err |= model(&reader, val); oxReturnError(model(&reader, val));
} }
return err; return OxError(0);
} }
template<std::size_t L> template<std::size_t L>
@ -138,8 +138,7 @@ Error MetalClawReader::readInteger(I *val) {
// array handler // array handler
template<typename T> template<typename T>
Error MetalClawReader::field(const char*, T *val, std::size_t valLen) { Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) {
auto err = OxError(0);
if (m_fieldPresence.get(m_field++)) { if (m_fieldPresence.get(m_field++)) {
// read the length // read the length
if (m_buffIt >= m_buffLen) { if (m_buffIt >= m_buffLen) {
@ -155,18 +154,22 @@ Error MetalClawReader::field(const char*, T *val, std::size_t valLen) {
auto reader = child(); auto reader = child();
reader.setTypeInfo("List", len.value); reader.setTypeInfo("List", len.value);
for (std::size_t i = 0; i < len.value; i++) { for (std::size_t i = 0; i < len.value; i++) {
err |= reader.field("", &val[i]); oxReturnError(reader.field("", &val[i]));
} }
} else { } else {
err = OxError(MC_OUTBUFFENDED); oxTrace("ox::mc::read::field(T)") << name << ", size:" << valLen;
return OxError(MC_OUTBUFFENDED);
} }
} }
return err; return OxError(0);
} }
template<typename T> template<typename T>
Error MetalClawReader::field(const char*, ox::Vector<T> *val) { Error MetalClawReader::field(const char* name, ox::Vector<T> *val) {
return field(nullptr, val->data(), val->size()); const auto [len, err] = arrayLength(false);
oxReturnError(err);
val->resize(len);
return field(name, val->data(), val->size());
} }
template<typename T> template<typename T>

View File

@ -86,7 +86,8 @@ static ox::Error parseField(const DescriptorField &field, Reader *rdr, DataWalke
walker->pushNamePath(field.fieldName); walker->pushNamePath(field.fieldName);
if (field.subscriptLevels) { if (field.subscriptLevels) {
// add array handling // add array handling
const auto arrayLen = rdr->arrayLength(true); const auto [arrayLen, err] = rdr->arrayLength(true);
oxReturnError(err);
auto child = rdr->child(); auto child = rdr->child();
child.setTypeInfo(field.fieldName.c_str(), arrayLen); child.setTypeInfo(field.fieldName.c_str(), arrayLen);
DescriptorField f(field); // create mutable copy DescriptorField f(field); // create mutable copy