From a81a7a1b4e4c6a947604982ec2da3e0753627c51 Mon Sep 17 00:00:00 2001 From: Kevin Cheng Date: Wed, 10 Nov 2021 14:07:34 -0800 Subject: Parse and check schema version when LoadSchemaFile() - This is useful if user has two different copies of serialization_lib code, an incorrectly load the incompatible one. Signed-off-by: Kevin Cheng Change-Id: I0f241d2ddbb7188df030cc5dddaa6a0b5dad7a45 --- include/tosa_serialization_handler.h | 1 + src/tosa_serialization_handler.cpp | 68 ++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/include/tosa_serialization_handler.h b/include/tosa_serialization_handler.h index b07fa3b..b588fa0 100644 --- a/include/tosa_serialization_handler.h +++ b/include/tosa_serialization_handler.h @@ -377,6 +377,7 @@ protected: tosa_err_t Clear(); tosa_err_t Deserialize(const uint8_t* buf); tosa_err_t Serialize(); + TosaVersion ParseTosaSchemaVersion(std::string schema); private: TosaVersion _version; /* version struct */ diff --git a/src/tosa_serialization_handler.cpp b/src/tosa_serialization_handler.cpp index 547c3db..12d55c6 100644 --- a/src/tosa_serialization_handler.cpp +++ b/src/tosa_serialization_handler.cpp @@ -189,6 +189,56 @@ TosaSerializationHandler::~TosaSerializationHandler() Clear(); // deallocate all basic blocks } +TosaVersion TosaSerializationHandler::ParseTosaSchemaVersion(std::string schema) +{ + // Parse all 4 version fields in schema file + static const char* keywords[4] = { "major: int32 = ", "minor: int32 = ", "patch: int32 = ", "draft: bool = " }; + string keyword_str[4]; + size_t search_pos = 0; + size_t keyword_pos; + size_t semicolon_pos; + // parse integer field first + for (int32_t i = 0; i < 4; i++) + { + keyword_pos = schema.find(keywords[i], search_pos); + if (keyword_pos == std::string::npos) + { + printf("ERROR: can't find keyword \"%s\" in schema\n", keywords[i]); + assert(0); + } + semicolon_pos = schema.find(';', keyword_pos); + if (keyword_pos == std::string::npos) + { + printf("ERROR: can't find ';' in schema\n"); + assert(0); + } + keyword_str[i] = + schema.substr(keyword_pos + strlen(keywords[i]), semicolon_pos - keyword_pos - strlen(keywords[i])); + search_pos = semicolon_pos; + } + + int32_t schema_major = 0; + int32_t schema_minor = 0; + int32_t schema_patch = 0; + bool schema_draft = false; + try + { + schema_major = stoi(keyword_str[0]); + schema_minor = stoi(keyword_str[1]); + schema_patch = stoi(keyword_str[2]); + schema_draft = (keyword_str[3] == "true") ? true : false; + } + catch (std::invalid_argument& e) + { + printf("ERROR: fail at stoi(): %s\n", e.what()); + assert(0); + } + + TosaVersion schema_version(schema_major, schema_minor, schema_patch, schema_draft); + + return schema_version; +} + tosa_err_t TosaSerializationHandler::LoadFileSchema(const char* schema_filename) { std::string schema; @@ -202,6 +252,24 @@ tosa_err_t TosaSerializationHandler::LoadFileSchema(const char* schema_filename) } ok = _parser.Parse(schema.c_str()); + + TosaVersion schema_version = ParseTosaSchemaVersion(schema); + + TosaVersion::compat_t is_compat = schema_version.is_compatible(GetVersion()); + switch (is_compat) + { + case TosaVersion::compat_t::COMPLETELY_COMPATIBLE: + break; + case TosaVersion::compat_t::PARTIALLY_COMPATIBLE: + printf("WARNING: Schema flatbuffer version %s is partially compatible with serializer version %s\n", + schema_version.to_string().c_str(), GetVersion().to_string().c_str()); + break; + case TosaVersion::compat_t::NOT_COMPATIBLE: + printf("ERROR: Schema flatbuffer version %s is not compatible with serializer version %s\n", + schema_version.to_string().c_str(), GetVersion().to_string().c_str()); + return TOSA_VERSION_MISMATCH; + } + if (!ok) { printf("Error parsing ISA schema file: %s\n", schema_filename); -- cgit v1.2.1