c2a7473b36
(synced from 9ee6cfbbfd)
156 lines
4.1 KiB
C++
156 lines
4.1 KiB
C++
/*
|
|
* Copyright 2015 - 2022 gary@drinkingtea.net
|
|
*
|
|
* 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/.
|
|
*/
|
|
|
|
#include <ox/std/assert.hpp>
|
|
#include <ox/std/byteswap.hpp>
|
|
#include <ox/std/memops.hpp>
|
|
|
|
#include "read.hpp"
|
|
|
|
namespace ox {
|
|
|
|
MetalClawReader::MetalClawReader(const uint8_t *buff, std::size_t buffLen, int unionIdx, MetalClawReader *parent) noexcept:
|
|
m_fieldPresence(buff, buffLen),
|
|
m_unionIdx(unionIdx),
|
|
m_buffLen(buffLen),
|
|
m_buff(buff),
|
|
m_parent(parent) {
|
|
}
|
|
|
|
MetalClawReader::~MetalClawReader() noexcept {
|
|
if (m_parent) {
|
|
m_parent->m_buffIt += m_buffIt;
|
|
}
|
|
if (m_field != m_fields) {
|
|
oxTrace("ox::mc::MetalClawReader::error") << "MetalClawReader: incorrect fields number given";
|
|
}
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, int8_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, int16_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, int32_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, int64_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
|
|
Error MetalClawReader::field(const char*, uint8_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, uint16_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, uint32_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, uint64_t *val) noexcept {
|
|
return readInteger(val);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, bool *val) noexcept {
|
|
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
|
auto valErr = m_fieldPresence.get(static_cast<std::size_t>(m_field));
|
|
*val = valErr.value;
|
|
oxReturnError(valErr.error);
|
|
}
|
|
++m_field;
|
|
return OxError(0);
|
|
}
|
|
|
|
Error MetalClawReader::field(const char*, SerStr val) noexcept {
|
|
if (m_unionIdx == -1 || m_unionIdx == m_field) {
|
|
if (m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
|
|
// read the length
|
|
if (m_buffIt >= m_buffLen) {
|
|
return OxError(MC_BUFFENDED);
|
|
}
|
|
std::size_t bytesRead = 0;
|
|
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(data, &m_buff[m_buffIt], size);
|
|
data[size] = 0;
|
|
m_buffIt += size;
|
|
} else {
|
|
return OxError(MC_BUFFENDED);
|
|
}
|
|
} else {
|
|
return OxError(MC_OUTBUFFENDED);
|
|
}
|
|
} else {
|
|
auto data = val.data();
|
|
if (data) {
|
|
data[0] = 0;
|
|
}
|
|
}
|
|
}
|
|
++m_field;
|
|
return OxError(0);
|
|
}
|
|
|
|
Result<ArrayLength> MetalClawReader::arrayLength(const char*, bool pass) noexcept {
|
|
if ((m_unionIdx == -1 || m_unionIdx == m_field) && m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
|
|
// read the length
|
|
if (m_buffIt >= m_buffLen) {
|
|
return OxError(MC_BUFFENDED);
|
|
}
|
|
std::size_t bytesRead = 0;
|
|
auto out = mc::decodeInteger<ArrayLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead).value;
|
|
if (pass) {
|
|
m_buffIt += bytesRead;
|
|
}
|
|
return out;
|
|
}
|
|
return OxError(1);
|
|
}
|
|
|
|
[[nodiscard]]
|
|
StringLength MetalClawReader::stringLength(const char*) noexcept {
|
|
if ((m_unionIdx == -1 || m_unionIdx == m_field) && m_fieldPresence.get(static_cast<std::size_t>(m_field))) {
|
|
// read the length
|
|
std::size_t bytesRead = 0;
|
|
auto len = mc::decodeInteger<StringLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead);
|
|
return len.value;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
MetalClawReader MetalClawReader::child(const char*, int unionIdx) noexcept {
|
|
return MetalClawReader(m_buff + m_buffIt, m_buffLen - m_buffIt, unionIdx, this);
|
|
}
|
|
|
|
bool MetalClawReader::fieldPresent(const char*) const noexcept {
|
|
return m_fieldPresence.get(static_cast<std::size_t>(m_field)).value;
|
|
}
|
|
|
|
bool MetalClawReader::fieldPresent(int fieldNo) const noexcept {
|
|
return m_fieldPresence.get(static_cast<std::size_t>(fieldNo)).value;
|
|
}
|
|
|
|
void MetalClawReader::nextField() noexcept {
|
|
++m_field;
|
|
}
|
|
|
|
}
|