diff --git a/src/ox/mc/read.hpp b/src/ox/mc/read.hpp index 501f9dfa3..6b25c2676 100644 --- a/src/ox/mc/read.hpp +++ b/src/ox/mc/read.hpp @@ -54,6 +54,14 @@ class MetalClawReader { template Error field(const char*, T *val, std::size_t len); + // array handler, with callback to allow handling individual elements + template + Error field(const char*, Handler *val); + + // array handler, with callback to allow handling individual elements + template + Error field(const char*, Handler *val, ArrayLength len); + template Error field(const char*, ox::Vector *val); @@ -145,7 +153,7 @@ Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) { return OxError(MC_BUFFENDED); } std::size_t bytesRead = 0; - auto len = mc::decodeInteger(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead); + auto len = mc::decodeInteger(&m_buff[m_buffIt], m_buffLen - m_buffIt, &bytesRead); m_buffIt += bytesRead; oxReturnError(len.error); @@ -164,6 +172,32 @@ Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) { return OxError(0); } +template +Error MetalClawReader::field(const char *name, Handler *handler) { + auto [arrayLen, err] = arrayLength(true); + oxReturnError(err); + return field(name, handler, arrayLen); +} + +template +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 Error MetalClawReader::field(const char* name, ox::Vector *val) { const auto [len, err] = arrayLength(false);