From c3388c58f9559e49cde943697b31d9ab8378c0be Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sun, 30 Apr 2017 20:25:37 -0500 Subject: [PATCH] Fix issue with writing setting field presence mask for empty arrays --- src/ox/mc/presencemask.cpp | 10 ++++++++-- src/ox/mc/write.hpp | 41 ++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/ox/mc/presencemask.cpp b/src/ox/mc/presencemask.cpp index c6e28d144..0860efdb7 100644 --- a/src/ox/mc/presencemask.cpp +++ b/src/ox/mc/presencemask.cpp @@ -10,6 +10,9 @@ #include "err.hpp" #include "presencemask.hpp" +#include +using namespace std; + namespace ox { FieldPresenseMask::FieldPresenseMask(uint8_t *mask, size_t maxLen) { @@ -26,9 +29,12 @@ bool FieldPresenseMask::get(int i) { } int FieldPresenseMask::set(int i, bool on) { - uint8_t val = on ? 1 : 0; // normalize to 0 or 1 if (i / 8 < m_maxLen) { - m_mask[i / 8] |= val << (i % 8); + if (on) { + m_mask[i / 8] |= 1 << (i % 8); + } else { + m_mask[i / 8] &= ~(1 << (i % 8)); + } return 0; } else { return MC_PRESENCEMASKOUTBOUNDS; diff --git a/src/ox/mc/write.hpp b/src/ox/mc/write.hpp index 577a148e8..c3b5b9f42 100644 --- a/src/ox/mc/write.hpp +++ b/src/ox/mc/write.hpp @@ -70,7 +70,7 @@ int MetalClawWriter::op(const char*, ox::bstring *val) { m_buffIt += val->size(); fieldSet = true; } else { - err = 1; + err = MC_BUFFENDED; } } err |= m_fieldPresence.set(m_field, fieldSet); @@ -84,6 +84,7 @@ int MetalClawWriter::op(const char*, T *val) { MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); err |= ioOp(&writer, val); m_buffIt += writer.m_buffIt; + m_field++; return err; }; @@ -110,26 +111,28 @@ int MetalClawWriter::op(const char*, T *val, size_t len) { int err = 0; bool fieldSet = false; - // write the length - typedef uint32_t ArrayLength; - if (m_buffIt + sizeof(ArrayLength) < m_buffLen) { - *((T*) &m_buff[m_buffIt]) = ox::std::bigEndianAdapt((ArrayLength) len); - m_buffIt += sizeof(ArrayLength); - } else { - err = MC_BUFFENDED; + if (len) { + // write the length + typedef uint32_t ArrayLength; + if (m_buffIt + sizeof(ArrayLength) < m_buffLen) { + *((T*) &m_buff[m_buffIt]) = ox::std::bigEndianAdapt((ArrayLength) len); + m_buffIt += sizeof(ArrayLength); + } else { + err = MC_BUFFENDED; + } + + MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); + writer.setFields(len); + + // write the array + for (size_t i = 0; i < len; i++) { + err |= writer.op("", &val[i]); + } + + m_buffIt += writer.m_buffIt; + fieldSet = true; } - MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); - writer.setFields(len); - - // write the string - for (size_t i = 0; i < len; i++) { - err |= writer.op("", &val[i]); - } - - m_buffIt += writer.m_buffIt; - fieldSet = true; - err |= m_fieldPresence.set(m_field, fieldSet); m_field++; return err;