diff --git a/inc/finalmq/metadataserialize/metadata.fmq b/inc/finalmq/metadataserialize/metadata.fmq index 3872857d..efa97ab8 100644 --- a/inc/finalmq/metadataserialize/metadata.fmq +++ b/inc/finalmq/metadataserialize/metadata.fmq @@ -40,7 +40,8 @@ {"name":"METAFLAG_PROTO_VARINT", "id":1, "desc":"desc"}, {"name":"METAFLAG_PROTO_ZIGZAG", "id":2, "desc":"desc"}, {"name":"METAFLAG_NULLABLE", "id":4, "desc":"desc"}, - {"name":"METAFLAG_ONE_REQUIRED", "id":8, "desc":"desc"} + {"name":"METAFLAG_ONE_REQUIRED", "id":8, "desc":"desc"}, + {"name":"METAFLAG_INDEX", "id":16, "desc":"desc"} ]}, {"type":"SerializeMetaStructFlags","desc":"desc","entries":[ {"name":"METASTRUCTFLAG_NONE", "id":0, "desc":"desc"}, diff --git a/inc/finalmq/metadataserialize/variant.fmq b/inc/finalmq/metadataserialize/variant.fmq index 0eb8e3bc..27eb6ef9 100644 --- a/inc/finalmq/metadataserialize/variant.fmq +++ b/inc/finalmq/metadataserialize/variant.fmq @@ -6,7 +6,7 @@ "structs":[ {"type":"VarValue","desc":"desc","fields":[ {"tid":"TYPE_STRING", "type":"", "name":"name", "desc":"name is only used for elements in valstruct","flags":[]}, - {"tid":"TYPE_INT32", "name":"index", "desc":"","flags":[]}, + {"tid":"TYPE_INT32", "name":"index", "desc":"","flags":["METAFLAG_INDEX"]}, {"tid":"TYPE_BOOL", "type":"", "name":"none", "desc":"","flags":[]}, {"tid":"TYPE_BOOL", "type":"", "name":"valbool", "desc":"","flags":[]}, diff --git a/inc/finalmq/serializeqt/ParserQt.h b/inc/finalmq/serializeqt/ParserQt.h index 062de980..3252c87e 100644 --- a/inc/finalmq/serializeqt/ParserQt.h +++ b/inc/finalmq/serializeqt/ParserQt.h @@ -70,11 +70,20 @@ namespace finalmq { bool parseArrayStruct(const MetaField& field); bool parseQVariantHeader(const MetaField& field); + std::int64_t checkIndex(const MetaField& field, std::int64_t value); const std::uint8_t* m_ptr = nullptr; ssize_t m_size = 0; IParserVisitor& m_visitor; const Mode m_mode = Mode::NONE; + + enum IndexStatus + { + INDEX_NOT_AVAILABLE = -1, + INDEX_ABORTSTRUCT = -2 + }; + + std::int64_t m_index = INDEX_NOT_AVAILABLE; }; } // namespace finalmq diff --git a/inc/finalmq/serializeqt/SerializerQt.h b/inc/finalmq/serializeqt/SerializerQt.h index be8da551..3ae4186a 100644 --- a/inc/finalmq/serializeqt/SerializerQt.h +++ b/inc/finalmq/serializeqt/SerializerQt.h @@ -137,6 +137,8 @@ namespace finalmq { static std::uint32_t getTypeIdByName(const std::string& typeName); static void getQVariantType(const MetaField& field, std::uint32_t& typeId, std::string& typeName); + void checkIndex(const MetaField& field, std::int64_t value); + void reserveSpace(ssize_t space); void resizeBuffer(); @@ -146,13 +148,22 @@ namespace finalmq { char* m_buffer = nullptr; char* m_bufferEnd = nullptr; - char* m_arrayStructCounterBuffer = nullptr; - std::int32_t m_arrayStructCounter = -1; - - int m_levelStruct = 0; const Mode m_mode = Mode::NONE; - int m_abortStruct = -1; + enum IndexStatus + { + INDEX_NOT_AVAILABLE = -1, + }; + + struct LevelState + { + bool abortStruct = false; + std::int64_t index = INDEX_NOT_AVAILABLE; + char* arrayStructCounterBuffer = nullptr; + std::int32_t arrayStructCounter = -1; + }; + + std::deque<LevelState> m_levelState; }; Internal m_internal; diff --git a/src/serializeqt/ParserQt.cpp b/src/serializeqt/ParserQt.cpp index 497dd939..d1a2d0c3 100644 --- a/src/serializeqt/ParserQt.cpp +++ b/src/serializeqt/ParserQt.cpp @@ -83,14 +83,14 @@ namespace finalmq { return res; } - static const std::string QT_ENUM_BITS = "qtenumbits"; + static const std::string ENUM_BITS = "enumbits"; static const std::string BITS_8 = "8"; static const std::string BITS_16 = "16"; static const std::string BITS_32 = "32"; - static const std::string QT_ABORTSTRUCT = "qtabortstruct"; - static const std::string QT_FALSE = "false"; - static const std::string QT_TRUE = "true"; + static const std::string ABORTSTRUCT = "abortstruct"; + static const std::string ABORT_FALSE = "false"; + static const std::string ABORT_TRUE = "true"; bool ParserQt::parseStructIntern(const MetaStruct& stru, bool wrappedByQVariant) { @@ -102,10 +102,16 @@ namespace finalmq { bool ok = true; bool abortStruct = false; + std::int64_t index = INDEX_NOT_AVAILABLE; const ssize_t numberOfFields = stru.getFieldsSize(); for (ssize_t i = 0; i < numberOfFields && ok && !abortStruct; ++i) { + if (index >= 0) + { + i = index; + index = INDEX_ABORTSTRUCT; + } const MetaField* field = stru.getFieldByIndex(i); assert(field); @@ -127,11 +133,11 @@ namespace finalmq { m_visitor.enterBool(*field, static_cast<bool>(value)); // check abort - const std::string& valueAbort = field->getProperty(QT_ABORTSTRUCT); + const std::string& valueAbort = field->getProperty(ABORTSTRUCT); if (!valueAbort.empty()) { - if (((valueAbort == QT_TRUE) && value) || - ((valueAbort == QT_FALSE) && !value)) + if (((valueAbort == ABORT_TRUE) && value) || + ((valueAbort == ABORT_FALSE) && !value)) { abortStruct = true; } @@ -151,6 +157,7 @@ namespace finalmq { if (ok) { m_visitor.enterInt8(*field, value); + index = checkIndex(*field, value); } } break; @@ -166,6 +173,7 @@ namespace finalmq { if (ok) { m_visitor.enterUInt8(*field, value); + index = checkIndex(*field, value); } } break; @@ -181,6 +189,7 @@ namespace finalmq { if (ok) { m_visitor.enterInt16(*field, value); + index = checkIndex(*field, value); } } break; @@ -196,6 +205,7 @@ namespace finalmq { if (ok) { m_visitor.enterUInt16(*field, value); + index = checkIndex(*field, value); } } break; @@ -211,6 +221,7 @@ namespace finalmq { if (ok) { m_visitor.enterInt32(*field, value); + index = checkIndex(*field, value); } } break; @@ -226,6 +237,7 @@ namespace finalmq { if (ok) { m_visitor.enterUInt32(*field, value); + index = checkIndex(*field, value); } } break; @@ -241,6 +253,7 @@ namespace finalmq { if (ok) { m_visitor.enterInt64(*field, value); + index = checkIndex(*field, value); } } break; @@ -256,6 +269,7 @@ namespace finalmq { if (ok) { m_visitor.enterUInt64(*field, value); + index = checkIndex(*field, value); } } break; @@ -352,7 +366,7 @@ namespace finalmq { const MetaEnum* en = MetaDataGlobal::instance().getEnum(*field); if (en) { - const std::string& bits = en->getProperty(QT_ENUM_BITS, BITS_32); + const std::string& bits = en->getProperty(ENUM_BITS, BITS_32); std::int32_t value = 0; if (bits == BITS_32) { @@ -379,7 +393,7 @@ namespace finalmq { m_visitor.enterEnum(*field, value); // check abort - const std::string& valueAbort = field->getProperty(QT_ABORTSTRUCT); + const std::string& valueAbort = field->getProperty(ABORTSTRUCT); if (!valueAbort.empty()) { std::string strValue = en->getNameByValue(value); @@ -600,7 +614,7 @@ namespace finalmq { const MetaEnum* en = MetaDataGlobal::instance().getEnum(*field); if (en) { - const std::string& bits = en->getProperty(QT_ENUM_BITS, BITS_32); + const std::string& bits = en->getProperty(ENUM_BITS, BITS_32); std::vector<std::int32_t> value; if (bits == BITS_32) { @@ -644,6 +658,11 @@ namespace finalmq { assert(false); break; } + + if ((index == INDEX_ABORTSTRUCT) || (index >= numberOfFields)) + { + abortStruct = true; + } } return ok; @@ -1025,4 +1044,22 @@ namespace finalmq { return ok; } + std::int64_t ParserQt::checkIndex(const MetaField& field, std::int64_t value) + { + std::int64_t index = INDEX_NOT_AVAILABLE; + if ((field.flags & MetaFieldFlags::METAFLAG_INDEX) != 0) + { + if (value < 0) + { + index = INDEX_ABORTSTRUCT; + } + else + { + index = field.index + 1 + value; + } + } + return index; + } + + } // namespace finalmq diff --git a/src/serializeqt/SerializerQt.cpp b/src/serializeqt/SerializerQt.cpp index 85969c80..95cf5bde 100644 --- a/src/serializeqt/SerializerQt.cpp +++ b/src/serializeqt/SerializerQt.cpp @@ -65,103 +65,121 @@ namespace finalmq { void SerializerQt::Internal::startStruct(const MetaStruct& stru) { - m_abortStruct = -1; if (m_mode == Mode::WRAPPED_BY_QVARIANTLIST) { reserveSpace(sizeof(std::uint32_t)); const std::uint32_t count = static_cast<std::uint32_t>(stru.getFieldsSize()); serialize(count); } + + m_levelState.push_back(LevelState()); } void SerializerQt::Internal::finished() { resizeBuffer(); + m_levelState.pop_back(); } void SerializerQt::Internal::enterStruct(const MetaField& field) { - if (m_abortStruct == -1) + assert(!m_levelState.empty()); + bool abortStruct = m_levelState.back().abortStruct; + std::int64_t index = m_levelState.back().index; + m_levelState.push_back(LevelState()); + m_levelState.back().abortStruct = abortStruct; + + if (abortStruct || (index != INDEX_NOT_AVAILABLE && index != field.index)) { - assert(field.typeId == MetaTypeId::TYPE_STRUCT); - if (isWrappedByQVariant()) - { - serializeQVariantHeader(field); - } + return; + } - if (m_arrayStructCounter >= 0) - { - ++m_arrayStructCounter; - } + LevelState& levelState = m_levelState.back(); + + assert(field.typeId == MetaTypeId::TYPE_STRUCT); + if (isWrappedByQVariant()) + { + serializeQVariantHeader(field); } - ++m_levelStruct; + if (levelState.arrayStructCounter >= 0) + { + ++levelState.arrayStructCounter; + } } void SerializerQt::Internal::exitStruct(const MetaField& /*field*/) { - if (m_abortStruct == m_levelStruct) - { - m_abortStruct = -1; - } - --m_levelStruct; + m_levelState.pop_back(); } void SerializerQt::Internal::enterStructNull(const MetaField& /*field*/) { - if (m_abortStruct != -1) - { - return; - } } void SerializerQt::Internal::enterArrayStruct(const MetaField& field) { - if (m_abortStruct == -1) + assert(!m_levelState.empty()); + bool abortStruct = m_levelState.back().abortStruct; + std::int64_t index = m_levelState.back().index; + m_levelState.push_back(LevelState()); + m_levelState.back().abortStruct = abortStruct; + + if (abortStruct || (index != INDEX_NOT_AVAILABLE && index != field.index)) { - assert(field.typeId == MetaTypeId::TYPE_ARRAY_STRUCT); - if (isWrappedByQVariant()) - { - serializeQVariantHeader(field); - } + return; + } - reserveSpace(sizeof(std::uint32_t)); - m_arrayStructCounterBuffer = m_buffer; - m_arrayStructCounter = 0; - serialize(m_arrayStructCounter); - m_arrayStructCounter = 0; + LevelState& levelState = m_levelState.back(); + + assert(field.typeId == MetaTypeId::TYPE_ARRAY_STRUCT); + if (isWrappedByQVariant()) + { + serializeQVariantHeader(field); } - ++m_levelStruct; + reserveSpace(sizeof(std::uint32_t)); + levelState.arrayStructCounterBuffer = m_buffer; + levelState.arrayStructCounter = 0; + serialize(levelState.arrayStructCounter); + levelState.arrayStructCounter = 0; } void SerializerQt::Internal::exitArrayStruct(const MetaField& /*field*/) { - if (m_abortStruct == -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + + if (levelState.abortStruct) { - if (m_arrayStructCounterBuffer) - { - char* buffer = m_buffer; - m_buffer = m_arrayStructCounterBuffer; - serialize(m_arrayStructCounter); - m_buffer = buffer; - m_arrayStructCounter = -1; - } + m_levelState.pop_back(); + return; + } + + if (levelState.arrayStructCounterBuffer) + { + char* buffer = m_buffer; + m_buffer = levelState.arrayStructCounterBuffer; + serialize(levelState.arrayStructCounter); + m_buffer = buffer; + levelState.arrayStructCounter = -1; } - --m_levelStruct; + m_levelState.pop_back(); } - static const std::string QT_ABORTSTRUCT = "qtabortstruct"; - static const std::string QT_FALSE = "false"; - static const std::string QT_TRUE = "true"; + static const std::string ABORTSTRUCT = "abortstruct"; + static const std::string ABORT_FALSE = "false"; + static const std::string ABORT_TRUE = "true"; void SerializerQt::Internal::enterBool(const MetaField& field, bool value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -175,20 +193,22 @@ namespace finalmq { serialize(static_cast<std::uint8_t>(value ? 1 : 0)); // check abort - const std::string& valueAbort = field.getProperty(QT_ABORTSTRUCT); + const std::string& valueAbort = field.getProperty(ABORTSTRUCT); if (!valueAbort.empty()) { - if (((valueAbort == QT_TRUE) && value) || - ((valueAbort == QT_FALSE) && !value)) + if (((valueAbort == ABORT_TRUE) && value) || + ((valueAbort == ABORT_FALSE) && !value)) { - m_abortStruct = m_abortStruct; + levelState.abortStruct = true; } } } void SerializerQt::Internal::enterInt8(const MetaField& field, std::int8_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -200,11 +220,14 @@ namespace finalmq { } reserveSpace(sizeof(std::int8_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterUInt8(const MetaField& field, std::uint8_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -216,11 +239,14 @@ namespace finalmq { } reserveSpace(sizeof(std::uint8_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterInt16(const MetaField& field, std::int16_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -232,11 +258,14 @@ namespace finalmq { } reserveSpace(sizeof(std::int16_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterUInt16(const MetaField& field, std::uint16_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -248,11 +277,14 @@ namespace finalmq { } reserveSpace(sizeof(std::uint16_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterInt32(const MetaField& field, std::int32_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -264,11 +296,14 @@ namespace finalmq { } reserveSpace(sizeof(std::int32_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterUInt32(const MetaField& field, std::uint32_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -280,11 +315,14 @@ namespace finalmq { } reserveSpace(sizeof(std::uint32_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterInt64(const MetaField& field, std::int64_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -296,11 +334,14 @@ namespace finalmq { } reserveSpace(sizeof(std::int64_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterUInt64(const MetaField& field, std::uint64_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -312,11 +353,14 @@ namespace finalmq { } reserveSpace(sizeof(std::uint64_t)); serialize(value); + checkIndex(field, value); } void SerializerQt::Internal::enterFloat(const MetaField& field, float value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -332,7 +376,9 @@ namespace finalmq { void SerializerQt::Internal::enterDouble(const MetaField& field, double value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -348,7 +394,9 @@ namespace finalmq { void SerializerQt::Internal::enterString(const MetaField& field, std::string&& value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -364,7 +412,9 @@ namespace finalmq { void SerializerQt::Internal::enterString(const MetaField& field, const char* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -380,18 +430,15 @@ namespace finalmq { void SerializerQt::Internal::enterBytes(const MetaField& field, Bytes&& value) { - if (m_abortStruct != -1) - { - return; - } - assert(field.typeId == MetaTypeId::TYPE_BYTES); enterBytes(field, value.data(), value.size()); } void SerializerQt::Internal::enterBytes(const MetaField& field, const BytesElement* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -405,14 +452,16 @@ namespace finalmq { serialize(value, size); } - static const std::string QT_ENUM_BITS = "qtenumbits"; + static const std::string QT_ENUM_BITS = "enumbits"; static const std::string BITS_8 = "8"; static const std::string BITS_16 = "16"; static const std::string BITS_32 = "32"; void SerializerQt::Internal::enterEnum(const MetaField& field, std::int32_t value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -450,7 +499,7 @@ namespace finalmq { } // check abort - const std::string& valueAbort = field.getProperty(QT_ABORTSTRUCT); + const std::string& valueAbort = field.getProperty(ABORTSTRUCT); if (!valueAbort.empty() && en) { std::string strValue = en->getNameByValue(value); @@ -458,14 +507,14 @@ namespace finalmq { Utils::split(valueAbort, 0, valueAbort.size(), '|', valuesAbort); if (std::find(valuesAbort.begin(), valuesAbort.end(), strValue) != valuesAbort.end()) { - m_abortStruct = m_levelStruct; + levelState.abortStruct = true; } else { std::string aliasValue = en->getAliasByValue(value); if (std::find(valuesAbort.begin(), valuesAbort.end(), aliasValue) != valuesAbort.end()) { - m_abortStruct = m_levelStruct; + levelState.abortStruct = true; } } } @@ -473,38 +522,25 @@ namespace finalmq { void SerializerQt::Internal::enterEnum(const MetaField& field, std::string&& value) { - if (m_abortStruct != -1) - { - return; - } - std::int32_t enumValue = MetaDataGlobal::instance().getEnumValueByName(field, value); enterEnum(field, enumValue); } void SerializerQt::Internal::enterEnum(const MetaField& field, const char* value, ssize_t size) { - if (m_abortStruct != -1) - { - return; - } - enterEnum(field, std::string(value, size)); } void SerializerQt::Internal::enterArrayBoolMove(const MetaField& field, std::vector<bool>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayBool(field, value); } void SerializerQt::Internal::enterArrayBool(const MetaField& field, const std::vector<bool>& value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -521,17 +557,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayInt8(const MetaField& field, std::vector<std::int8_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayInt8(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayInt8(const MetaField& field, const std::int8_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -547,17 +580,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayInt16(const MetaField& field, std::vector<std::int16_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayInt16(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayInt16(const MetaField& field, const std::int16_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -573,17 +603,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayUInt16(const MetaField& field, std::vector<std::uint16_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayUInt16(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayUInt16(const MetaField& field, const std::uint16_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -599,17 +626,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayInt32(const MetaField& field, std::vector<std::int32_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayInt32(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayInt32(const MetaField& field, const std::int32_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -625,17 +649,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayUInt32(const MetaField& field, std::vector<std::uint32_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayUInt32(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayUInt32(const MetaField& field, const std::uint32_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -651,17 +672,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayInt64(const MetaField& field, std::vector<std::int64_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayInt64(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayInt64(const MetaField& field, const std::int64_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -677,17 +695,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayUInt64(const MetaField& field, std::vector<std::uint64_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayUInt64(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayUInt64(const MetaField& field, const std::uint64_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -703,17 +718,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayFloat(const MetaField& field, std::vector<float>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayFloat(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayFloat(const MetaField& field, const float* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -729,17 +741,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayDouble(const MetaField& field, std::vector<double>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayDouble(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayDouble(const MetaField& field, const double* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -755,17 +764,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayStringMove(const MetaField& field, std::vector<std::string>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayString(field, value); } void SerializerQt::Internal::enterArrayString(const MetaField& field, const std::vector<std::string>& value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -786,17 +792,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayBytesMove(const MetaField& field, std::vector<Bytes>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayBytes(field, value); } void SerializerQt::Internal::enterArrayBytes(const MetaField& field, const std::vector<Bytes>& value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -817,17 +820,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayEnum(const MetaField& field, std::vector<std::int32_t>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayEnum(field, value.data(), value.size()); } void SerializerQt::Internal::enterArrayEnum(const MetaField& field, const std::int32_t* value, ssize_t size) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -876,17 +876,14 @@ namespace finalmq { void SerializerQt::Internal::enterArrayEnumMove(const MetaField& field, std::vector<std::string>&& value) { - if (m_abortStruct != -1) - { - return; - } - enterArrayEnum(field, value); } void SerializerQt::Internal::enterArrayEnum(const MetaField& field, const std::vector<std::string>& value) { - if (m_abortStruct != -1) + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if ((levelState.abortStruct) || (levelState.index != INDEX_NOT_AVAILABLE && levelState.index != field.index)) { return; } @@ -1088,7 +1085,7 @@ namespace finalmq { bool SerializerQt::Internal::isWrappedByQVariant() const { - return (m_levelStruct == 0 && (m_mode != Mode::NONE)); + return (m_levelState.size() == 1 && (m_mode != Mode::NONE)); } bool SerializerQt::Internal::getQVariantTypeFromMetaTypeId(const MetaField& field, std::uint32_t& typeId, std::string& typeName) @@ -1374,5 +1371,21 @@ namespace finalmq { } } + void SerializerQt::Internal::checkIndex(const MetaField& field, std::int64_t value) + { + if ((field.flags & MetaFieldFlags::METAFLAG_INDEX) != 0) + { + assert(!m_levelState.empty()); + LevelState& levelState = m_levelState.back(); + if (value < 0) + { + levelState.abortStruct = true; + } + else + { + levelState.index = field.index + 1 + value; + } + } + } } // namespace finalmq