diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-05-11 20:04:06 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-05-11 20:04:06 +0300 |
commit | 2f575b2beae406eec24a12857a5d7199a108e73c (patch) | |
tree | cd0f53e28ab03e5332f70fc6b9e29a94aaab0b19 /src/ObjectModel | |
parent | f7e1ae6f89316b255a214ec5aa3edc7f2291dd1a (diff) |
Added facility to refer to base class object model
Diffstat (limited to 'src/ObjectModel')
-rw-r--r-- | src/ObjectModel/ObjectModel.cpp | 64 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.h | 36 |
2 files changed, 71 insertions, 29 deletions
diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index 14d6487c..6c4dd0e5 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -288,32 +288,43 @@ void ObjectModel::ReportAsJson(OutputBuffer* buf, ObjectExplorationContext& cont if (context.IncreaseDepth()) { bool added = false; - const uint8_t *descriptor; - const ObjectModelTableEntry *tbl = GetObjectModelTable(descriptor); - if (tableNumber < descriptor[0]) + const ObjectModelClassDescriptor * classDescriptor = GetObjectModelClassDescriptor(); + + if ((tableNumber & 0x80) != 0) // if we want the parent class table { - size_t numEntries = descriptor[tableNumber + 1]; - while (tableNumber != 0) - { - --tableNumber; - tbl += descriptor[tableNumber + 1]; - } + classDescriptor = classDescriptor->parent; + tableNumber &= 0x7F; + } - while (numEntries != 0) + if (classDescriptor != nullptr) + { + const uint8_t * const descriptor = classDescriptor->omd; + if (tableNumber < descriptor[0]) { - if (tbl->Matches(filter, context)) + const ObjectModelTableEntry *tbl = classDescriptor->omt; + size_t numEntries = descriptor[tableNumber + 1]; + while (tableNumber != 0) { - if (tbl->ReportAsJson(buf, context, this, filter, !added)) + --tableNumber; + tbl += descriptor[tableNumber + 1]; + } + + while (numEntries != 0) + { + if (tbl->Matches(filter, context)) { - added = true; + if (tbl->ReportAsJson(buf, context, this, filter, !added)) + { + added = true; + } } + --numEntries; + ++tbl; + } + if (added && *filter == 0) + { + buf->cat('}'); } - --numEntries; - ++tbl; - } - if (added && *filter == 0) - { - buf->cat('}'); } } if (!added) @@ -647,13 +658,24 @@ void ObjectModel::ReportArrayAsJson(OutputBuffer *buf, ObjectExplorationContext& // Find the requested entry const ObjectModelTableEntry* ObjectModel::FindObjectModelTableEntry(uint8_t tableNumber, const char* idString) const noexcept { - const uint8_t *descriptor; - const ObjectModelTableEntry *tbl = GetObjectModelTable(descriptor); + const ObjectModelClassDescriptor * classDescriptor = GetObjectModelClassDescriptor(); + if ((tableNumber & 0x80) != 0) // if we want the parent class table + { + classDescriptor = classDescriptor->parent; + if (classDescriptor == nullptr) + { + return nullptr; // no parent + } + tableNumber &= 0x7F; + } + + const uint8_t * const descriptor = classDescriptor->omd; if (tableNumber >= descriptor[0]) { return nullptr; } + const ObjectModelTableEntry *tbl = classDescriptor->omt; const size_t numEntries = descriptor[tableNumber + 1]; while (tableNumber != 0) { diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h index f6a3c2be..b67617f7 100644 --- a/src/ObjectModel/ObjectModel.h +++ b/src/ObjectModel/ObjectModel.h @@ -27,7 +27,7 @@ enum class TypeCode : uint8_t Char, Uint32, Int32, - Uint64, + Uint64, // only 56 bits actually available Float, Bitmap16, Bitmap32, @@ -211,6 +211,8 @@ public: ExpressionValue (*GetElement)(const ObjectModel*, ObjectExplorationContext&) noexcept; }; +struct ObjectModelClassDescriptor; + // Class from which other classes that represent part of the object model are derived class ObjectModel { @@ -243,7 +245,7 @@ protected: // Get the object model table entry for the current level object in the query const ObjectModelTableEntry *FindObjectModelTableEntry(uint8_t tableNumber, const char *idString) const noexcept; - virtual const ObjectModelTableEntry *GetObjectModelTable(const uint8_t*& descriptor) const noexcept = 0; + virtual const ObjectModelClassDescriptor *GetObjectModelClassDescriptor() const noexcept = 0; private: __attribute__ ((noinline)) static void ReportDateTime(OutputBuffer *buf, ExpressionValue val) noexcept; @@ -309,30 +311,48 @@ public: } }; +struct ObjectModelClassDescriptor +{ + const ObjectModelTableEntry *omt; + const uint8_t *omd; + const ObjectModelClassDescriptor *parent; +}; + // Use this macro to inherit form ObjectModel #define INHERIT_OBJECT_MODEL : public ObjectModel // Use this macro in the 'protected' section of every class declaration that derived from ObjectModel #define DECLARE_OBJECT_MODEL \ - const ObjectModelTableEntry *GetObjectModelTable(const uint8_t*& descriptor) const noexcept override; \ + const ObjectModelClassDescriptor *GetObjectModelClassDescriptor() const noexcept override; \ static const ObjectModelTableEntry objectModelTable[]; \ - static const uint8_t objectModelTableDescriptor[]; + static const uint8_t objectModelTableDescriptor[]; \ + static const ObjectModelClassDescriptor objectModelClassDescriptor; #define DECLARE_OBJECT_MODEL_VIRTUAL \ - virtual const ObjectModelTableEntry *GetObjectModelTable(const uint8_t*& descriptor) const noexcept override = 0; + virtual const ObjectModelClassDescriptor *GetObjectModelClassDescriptor() const noexcept override = 0; #define DESCRIPTOR_OK(_class) (ARRAY_SIZE(_class::objectModelTableDescriptor) == _class::objectModelTableDescriptor[0] + 1) #define OMT_SIZE_OK(_class) (ARRAY_SIZE(_class::objectModelTable) == ArraySum(_class::objectModelTableDescriptor + 1, ARRAY_SIZE(_class::objectModelTableDescriptor) - 1)) #define OMT_ORDERING_OK(_class) (ObjectModelTableEntry::IsOrdered(_class::objectModelTableDescriptor, _class::objectModelTable)) #define DEFINE_GET_OBJECT_MODEL_TABLE(_class) \ - const ObjectModelTableEntry *_class::GetObjectModelTable(const uint8_t*& descriptor) const noexcept \ + const ObjectModelClassDescriptor _class::objectModelClassDescriptor = { _class::objectModelTable, _class::objectModelTableDescriptor, nullptr }; \ + const ObjectModelClassDescriptor *_class::GetObjectModelClassDescriptor() const noexcept \ + { \ + static_assert(DESCRIPTOR_OK(_class), "Bad descriptor length"); \ + static_assert(!DESCRIPTOR_OK(_class) || OMT_SIZE_OK(_class), "Mismatched object model table and descriptor"); \ + static_assert(!DESCRIPTOR_OK(_class) || !OMT_SIZE_OK(_class) || OMT_ORDERING_OK(_class), "Object model table must be ordered"); \ + return &objectModelClassDescriptor; \ + } + +#define DEFINE_GET_OBJECT_MODEL_TABLE_WITH_PARENT(_class, _parent) \ + const ObjectModelClassDescriptor _class::objectModelClassDescriptor = { _class::objectModelTable, _class::objectModelTableDescriptor, &_parent::objectModelClassDescriptor }; \ + const ObjectModelClassDescriptor *_class::GetObjectModelClassDescriptor() const noexcept \ { \ static_assert(DESCRIPTOR_OK(_class), "Bad descriptor length"); \ static_assert(!DESCRIPTOR_OK(_class) || OMT_SIZE_OK(_class), "Mismatched object model table and descriptor"); \ static_assert(!DESCRIPTOR_OK(_class) || !OMT_SIZE_OK(_class) || OMT_ORDERING_OK(_class), "Object model table must be ordered"); \ - descriptor = objectModelTableDescriptor; \ - return objectModelTable; \ + return &objectModelClassDescriptor; \ } #define OBJECT_MODEL_FUNC_BODY(_class,...) [] (const ObjectModel* arg, ObjectExplorationContext& context) noexcept \ |