Skip to content

Commit

Permalink
Add index flag to serialize oneof types, like variants
Browse files Browse the repository at this point in the history
  • Loading branch information
beckdave committed Jan 17, 2024
1 parent e2cda00 commit f6997a5
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 186 deletions.
3 changes: 2 additions & 1 deletion inc/finalmq/metadataserialize/metadata.fmq
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down
2 changes: 1 addition & 1 deletion inc/finalmq/metadataserialize/variant.fmq
Original file line number Diff line number Diff line change
Expand Up @@ -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":[]},
Expand Down
9 changes: 9 additions & 0 deletions inc/finalmq/serializeqt/ParserQt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 16 additions & 5 deletions inc/finalmq/serializeqt/SerializerQt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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;
Expand Down
57 changes: 47 additions & 10 deletions src/serializeqt/ParserQt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);

Expand All @@ -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;
}
Expand All @@ -151,6 +157,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterInt8(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -166,6 +173,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterUInt8(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -181,6 +189,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterInt16(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -196,6 +205,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterUInt16(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -211,6 +221,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterInt32(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -226,6 +237,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterUInt32(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -241,6 +253,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterInt64(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand All @@ -256,6 +269,7 @@ namespace finalmq {
if (ok)
{
m_visitor.enterUInt64(*field, value);
index = checkIndex(*field, value);
}
}
break;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -644,6 +658,11 @@ namespace finalmq {
assert(false);
break;
}

if ((index == INDEX_ABORTSTRUCT) || (index >= numberOfFields))
{
abortStruct = true;
}
}

return ok;
Expand Down Expand Up @@ -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
Loading

0 comments on commit f6997a5

Please sign in to comment.