[ox/mc] Add support for individual element readers for arrays

This commit is contained in:
Gary Talent 2019-11-01 01:28:29 -05:00
parent 9da47f75c0
commit 0825c9869a

View File

@ -54,6 +54,14 @@ class MetalClawReader {
template<typename T> template<typename T>
Error field(const char*, T *val, std::size_t len); Error field(const char*, T *val, std::size_t len);
// array handler, with callback to allow handling individual elements
template<typename T, typename Handler>
Error field(const char*, Handler *val);
// array handler, with callback to allow handling individual elements
template<typename T, typename Handler>
Error field(const char*, Handler *val, ArrayLength len);
template<typename T> template<typename T>
Error field(const char*, ox::Vector<T> *val); Error field(const char*, ox::Vector<T> *val);
@ -145,7 +153,7 @@ Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) {
return OxError(MC_BUFFENDED); return OxError(MC_BUFFENDED);
} }
std::size_t bytesRead = 0; std::size_t bytesRead = 0;
auto len = mc::decodeInteger<StringLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead); auto len = mc::decodeInteger<ArrayLength>(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead);
m_buffIt += bytesRead; m_buffIt += bytesRead;
oxReturnError(len.error); oxReturnError(len.error);
@ -164,6 +172,32 @@ Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) {
return OxError(0); return OxError(0);
} }
template<typename T, typename Handler>
Error MetalClawReader::field(const char *name, Handler *handler) {
auto [arrayLen, err] = arrayLength(true);
oxReturnError(err);
return field(name, handler, arrayLen);
}
template<typename T, typename Handler>
Error MetalClawReader::field(const char*, Handler *handler, ArrayLength len) {
if (m_fieldPresence.get(m_field++)) {
// read the length
if (m_buffIt >= m_buffLen) {
return OxError(MC_BUFFENDED);
}
// read the list
auto reader = child();
reader.setTypeInfo("List", len);
for (std::size_t i = 0; i < len; i++) {
T val;
oxReturnError(reader.field("", &val));
oxReturnError(handler(i, &val));
}
}
return OxError(0);
}
template<typename T> template<typename T>
Error MetalClawReader::field(const char* name, ox::Vector<T> *val) { Error MetalClawReader::field(const char* name, ox::Vector<T> *val) {
const auto [len, err] = arrayLength(false); const auto [len, err] = arrayLength(false);