diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-03-10 12:11:13 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-03-10 12:11:13 +0300 |
commit | e5ac5b800b1636652836cfab649fb53004188420 (patch) | |
tree | c05f61c57d8768e78717ccb863c8d95ae1e620af /src/ObjectModel | |
parent | c131ba6fb6640f0b8fab1f6da9be0d20e9bb5fe5 (diff) |
Object model changes
Temperature sensors now report their types in the same format as M308
accepts them
Added 'directories' root element to the OM
Refactored type codes in expressions
Diffstat (limited to 'src/ObjectModel')
-rw-r--r-- | src/ObjectModel/ObjectModel.cpp | 141 | ||||
-rw-r--r-- | src/ObjectModel/ObjectModel.h | 111 |
2 files changed, 145 insertions, 107 deletions
diff --git a/src/ObjectModel/ObjectModel.cpp b/src/ObjectModel/ObjectModel.cpp index e7bba1a4..ac885501 100644 --- a/src/ObjectModel/ObjectModel.cpp +++ b/src/ObjectModel/ObjectModel.cpp @@ -9,57 +9,55 @@ #if SUPPORT_OBJECT_MODEL +#include <RepRap.h> +#include <Platform.h> #include <OutputMemory.h> #include <cstring> #include <General/SafeStrtod.h> #include <General/IP4String.h> -ExpressionValue::ExpressionValue(const MacAddress& mac) noexcept : type(TYPE_OF(MacAddress)), param(mac.HighWord()), uVal(mac.LowWord()) +ExpressionValue::ExpressionValue(const MacAddress& mac) noexcept : type((uint32_t)TypeCode::MacAddress), param(mac.HighWord()), uVal(mac.LowWord()) { } // Append a string representation of this value to a string void ExpressionValue::AppendAsString(const StringRef& str) const noexcept { - switch (type) + switch (GetType()) { - case TYPE_OF(char): + case TypeCode::Char: str.cat(cVal); break; - case TYPE_OF(const char*): + case TypeCode::CString: str.cat(sVal); break; - case TYPE_OF(float): + case TypeCode::Float: str.catf(GetFloatFormatString(), (double)fVal); break; - case TYPE_OF(uint32_t): + case TypeCode::Uint32: str.catf("%" PRIu32, uVal); // convert unsigned integer to string break; - case TYPE_OF(int32_t): + case TypeCode::Int32: str.catf("%" PRIi32, uVal); // convert signed integer to string break; - case TYPE_OF(bool): + case TypeCode::Bool: str.cat((bVal) ? "true" : "false"); // convert bool to string break; - case TYPE_OF(IPAddress): + case TypeCode::IPAddress: str.cat(IP4String(uVal).c_str()); break; - case TYPE_OF(const ObjectModel*): - str.cat("{object}"); - break; - - case NoType: + case TypeCode::None: str.cat("null"); break; - case TYPE_OF(DateTime): + case TypeCode::DateTime: { const time_t time = Get56BitValue(); tm timeInfo; @@ -69,7 +67,7 @@ void ExpressionValue::AppendAsString(const StringRef& str) const noexcept } break; - case TYPE_OF(DriverId): + case TypeCode::DriverId: #if SUPPORT_CAN_EXPANSION str.catf("%u.%u", (unsigned int)(uVal >> 8), (unsigned int)(uVal & 0xFF)); #else @@ -77,20 +75,44 @@ void ExpressionValue::AppendAsString(const StringRef& str) const noexcept #endif break; - case TYPE_OF(MacAddress): + case TypeCode::MacAddress: str.catf("%02x:%02x:%02x:%02x:%02x:%02x", (unsigned int)(uVal & 0xFF), (unsigned int)((uVal >> 8) & 0xFF), (unsigned int)((uVal >> 16) & 0xFF), (unsigned int)((uVal >> 24) & 0xFF), (unsigned int)(param & 0xFF), (unsigned int)((param >> 8) & 0xFF)); break; #if SUPPORT_CAN_EXPANSION - case TYPE_OF(CanExpansionBoardDetails): + case TypeCode::CanExpansionBoardDetails: ExtractRequestedPart(str); break; #endif - default: - str.cat("<unknown type>"); + case TypeCode::Special: + switch ((SpecialType)param) + { + case SpecialType::sysDir: + reprap.GetPlatform().AppendSysDir(str); + break; + } + break; + + // We don't fully handle the remaining types + case TypeCode::ObjectModel: + str.cat("{object}"); + break; + + case TypeCode::Array: + str.cat("[array]"); + break; + + case TypeCode::Bitmap16: + case TypeCode::Bitmap32: + case TypeCode::Bitmap64: + str.cat("(Bitmap)"); + break; + + case TypeCode::Enum32: + str.cat("(enumeration)"); break; } } @@ -310,18 +332,18 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& if (context.WantArrayLength() && *filter == 0) { // We have been asked for the length of an array and we have reached the end of the filter, so the value should be an array - switch (val.type) + switch (val.GetType()) { - case TYPE_OF(const ObjectModelArrayDescriptor*): + case TypeCode::Array: buf->catf("%u", val.omadVal->GetNumElements(this, context)); break; - case TYPE_OF(Bitmap<uint16_t>): - case TYPE_OF(Bitmap<uint32_t>): + case TypeCode::Bitmap16: + case TypeCode::Bitmap32: buf->catf("%u", Bitmap<uint32_t>::MakeFromRaw(val.uVal).CountSetBits()); break; - case TYPE_OF(Bitmap<uint64_t>): + case TypeCode::Bitmap64: buf->catf("%u", Bitmap<uint64_t>::MakeFromRaw(val.Get56BitValue()).CountSetBits()); break; @@ -332,9 +354,9 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } else { - switch (val.type) + switch (val.GetType()) { - case TYPE_OF(const ObjectModelArrayDescriptor*): + case TypeCode::Array: if (*filter == '[') { ++filter; @@ -377,7 +399,7 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } break; - case TYPE_OF(const ObjectModel*): + case TypeCode::ObjectModel: if (*filter == '.') { ++filter; @@ -390,7 +412,7 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& val.omVal->ReportAsJson(buf, context, val.param, filter); break; - case TYPE_OF(float): + case TypeCode::Float: if (val.fVal == 0.0) { buf->cat('0'); // replace 0.000... in JSON by 0. This is mostly to save space when writing workplace coordinates. @@ -401,26 +423,26 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } break; - case TYPE_OF(uint32_t): + case TypeCode::Uint32: buf->catf("%" PRIu32, val.uVal); break; - case TYPE_OF(int32_t): + case TypeCode::Int32: buf->catf("%" PRIi32, val.iVal); break; - case TYPE_OF(const char*): + case TypeCode::CString: buf->EncodeString(val.sVal, true); break; #ifdef DUET3 - case TYPE_OF(CanExpansionBoardDetails): + case TypeCode::CanExpansionBoardDetails: ReportExpansionBoardDetail(buf, val); break; #endif - case TYPE_OF(Bitmap<uint16_t>): - case TYPE_OF(Bitmap<uint32_t>): + case TypeCode::Bitmap16: + case TypeCode::Bitmap32: if (*filter == '[') { ++filter; @@ -466,7 +488,7 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } break; - case TYPE_OF(Bitmap<uint64_t>): + case TypeCode::Bitmap64: if (*filter == '[') { ++filter; @@ -512,7 +534,7 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } break; - case TYPE_OF(Enum32): + case TypeCode::Enum32: if (context.ShortFormReport()) { buf->catf("%" PRIu32, val.uVal); @@ -524,17 +546,17 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } break; - case TYPE_OF(bool): + case TypeCode::Bool: buf->cat((val.bVal) ? "true" : "false"); break; - case TYPE_OF(char): + case TypeCode::Char: buf->cat('"'); buf->EncodeChar(val.cVal); buf->cat('"'); break; - case TYPE_OF(IPAddress): + case TypeCode::IPAddress: { const IPAddress ipVal(val.uVal); char sep = '"'; @@ -547,11 +569,11 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& } break; - case TYPE_OF(DateTime): + case TypeCode::DateTime: ReportDateTime(buf, val); break; - case TYPE_OF(DriverId): + case TypeCode::DriverId: #if SUPPORT_CAN_EXPANSION buf->catf("\"%u.%u\"", (unsigned int)(val.uVal >> 8), (unsigned int)(val.uVal & 0xFF)); #else @@ -559,13 +581,22 @@ void ObjectModel::ReportItemAsJson(OutputBuffer *buf, ObjectExplorationContext& #endif break; - case TYPE_OF(MacAddress): + case TypeCode::MacAddress: buf->catf("\"%02x:%02x:%02x:%02x:%02x:%02x\"", (unsigned int)(val.uVal & 0xFF), (unsigned int)((val.uVal >> 8) & 0xFF), (unsigned int)((val.uVal >> 16) & 0xFF), (unsigned int)((val.uVal >> 24) & 0xFF), (unsigned int)(val.param & 0xFF), (unsigned int)((val.param >> 8) & 0xFF)); break; - case NoType: + case TypeCode::Special: + switch ((ExpressionValue::SpecialType)val.param) + { + case ExpressionValue::SpecialType::sysDir: + reprap.GetPlatform().EncodeSysDir(buf); + break; + } + break; + + case TypeCode::None: buf->cat("null"); break; } @@ -649,7 +680,7 @@ bool ObjectModelTableEntry::ReportAsJson(OutputBuffer* buf, ObjectExplorationCon { const char * nextElement = ObjectModel::GetNextElement(filter); const ExpressionValue val = func(self, context); - if (val.type != NoType || context.ShouldIncludeNulls()) + if (val.GetType() != TypeCode::None || context.ShouldIncludeNulls()) { if (*filter == 0) { @@ -698,9 +729,9 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, c ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, ExpressionValue val, const char *idString) const { - switch (val.type) + switch (val.GetType()) { - case TYPE_OF(const ObjectModelArrayDescriptor*): + case TypeCode::Array: { if (*idString == 0 && context.WantArrayLength()) { @@ -724,7 +755,7 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, E return GetObjectValue(context, arrayElement, idString + 1); } - case TYPE_OF(const ObjectModel*): + case TypeCode::ObjectModel: switch (*idString) { case 0: @@ -738,15 +769,15 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, E } break; - case NoType: + case TypeCode::None: if (*idString == 0) { return val; // a null value can be compared to null } throw context.ConstructParseException("reached null object before end of selector string"); - case TYPE_OF(Bitmap<uint16_t>): - case TYPE_OF(Bitmap<uint32_t>): + case TypeCode::Bitmap16: + case TypeCode::Bitmap32: if (context.WantArrayLength()) { if (*idString != 0) @@ -776,7 +807,7 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, E } return ExpressionValue((int32_t)val.uVal); - case TYPE_OF(Bitmap<uint64_t>): + case TypeCode::Bitmap64: if (context.WantArrayLength()) { if (*idString != 0) @@ -806,7 +837,7 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, E } return ExpressionValue((int32_t)val.uVal); - case TYPE_OF(MacAddress): + case TypeCode::MacAddress: if (*idString == 0) { return (context.WantArrayLength()) ? ExpressionValue((int32_t)17) : val; @@ -814,7 +845,7 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, E break; #ifdef DUET3 - case TYPE_OF(CanExpansionBoardDetails): + case TypeCode::CanExpansionBoardDetails: if (*idString == 0) { if (context.WantArrayLength()) @@ -826,7 +857,7 @@ ExpressionValue ObjectModel::GetObjectValue(ObjectExplorationContext& context, E break; #endif - case TYPE_OF(const char*): + case TypeCode::CString: if (*idString == 0 && context.WantArrayLength()) { return ExpressionValue((int32_t)strlen(val.sVal)); diff --git a/src/ObjectModel/ObjectModel.h b/src/ObjectModel/ObjectModel.h index 46ee6b8d..db34689d 100644 --- a/src/ObjectModel/ObjectModel.h +++ b/src/ObjectModel/ObjectModel.h @@ -18,13 +18,38 @@ #include <RTOSIface/RTOSIface.h> #include <Networking/NetworkDefs.h> -typedef uint8_t TypeCode; -constexpr TypeCode NoType = 0; // code for an invalid or unknown type +// Type codes to indicate what type of expression we have and how it is represented. +// The "Special" type is for items that we have to evaluate when we are ready to write them out, in particular strings whose storage might disappear. +enum class TypeCode : uint8_t +{ + None = 0, + Bool, + Char, + Uint32, + Int32, + Float, + Bitmap16, + Bitmap32, + Bitmap64, // only 56 bits actually available + Enum32, + ObjectModel, + CString, + IPAddress, + Array, + DateTime, + DriverId, + MacAddress, + Special, +#if SUPPORT_CAN_EXPANSION + CanExpansionBoardDetails +#endif +}; // Dummy types, used to define type codes class Bitmap32; class Bitmap64; class Enum32; +class SpecialString; #if SUPPORT_CAN_EXPANSION @@ -48,33 +73,6 @@ struct DateTime time_t tim; }; -// Function template used to get constexpr type codes -// Each type must return a unique type code in the range 1 to 127 (0 is NoType) -template<class T> constexpr TypeCode TypeOf() noexcept; - -template<> constexpr TypeCode TypeOf<bool> () noexcept { return 1; } -template<> constexpr TypeCode TypeOf<char> () noexcept { return 2; } -template<> constexpr TypeCode TypeOf<uint32_t> () noexcept { return 3; } -template<> constexpr TypeCode TypeOf<int32_t> () noexcept { return 4; } -template<> constexpr TypeCode TypeOf<float> () noexcept { return 5; } -template<> constexpr TypeCode TypeOf<Bitmap<uint16_t>> () noexcept { return 6; } -template<> constexpr TypeCode TypeOf<Bitmap<uint32_t>> () noexcept { return 7; } -template<> constexpr TypeCode TypeOf<Bitmap<uint64_t>> () noexcept { return 8; } -template<> constexpr TypeCode TypeOf<Enum32> () noexcept { return 9; } -template<> constexpr TypeCode TypeOf<const ObjectModel*> () noexcept { return 10; } -template<> constexpr TypeCode TypeOf<const char*> () noexcept { return 11; } -template<> constexpr TypeCode TypeOf<IPAddress> () noexcept { return 12; } -template<> constexpr TypeCode TypeOf<const ObjectModelArrayDescriptor*> () noexcept { return 13; } -template<> constexpr TypeCode TypeOf<DateTime> () noexcept { return 14; } -template<> constexpr TypeCode TypeOf<DriverId> () noexcept { return 15; } -template<> constexpr TypeCode TypeOf<MacAddress> () noexcept { return 16; } - -#if SUPPORT_CAN_EXPANSION -template<> constexpr TypeCode TypeOf<CanExpansionBoardDetails> () noexcept { return 17; } -#endif - -#define TYPE_OF(_t) (TypeOf<_t>()) - // Forward declarations class ObjectModelTableEntry; class ObjectModel; @@ -97,33 +95,42 @@ struct ExpressionValue const ObjectModelArrayDescriptor *omadVal; }; - ExpressionValue() noexcept : type(NoType) { } - explicit constexpr ExpressionValue(bool b) noexcept : type(TYPE_OF(bool)), param(0), bVal(b) { } - explicit constexpr ExpressionValue(char c) noexcept : type(TYPE_OF(char)), param(0), cVal(c) { } - explicit constexpr ExpressionValue(float f) noexcept : type(TYPE_OF(float)), param(MaxFloatDigitsDisplayedAfterPoint), fVal(f) { } - constexpr ExpressionValue(float f, uint8_t numDecimalPlaces) noexcept : type(TYPE_OF(float)), param(numDecimalPlaces), fVal(f) { } - explicit constexpr ExpressionValue(int32_t i) noexcept : type(TYPE_OF(int32_t)), param(0), iVal(i) { } - explicit constexpr ExpressionValue(const ObjectModel *om) noexcept : type((om == nullptr) ? NoType : TYPE_OF(const ObjectModel*)), param(0), omVal(om) { } - constexpr ExpressionValue(const ObjectModel *om, uint8_t tableNumber) noexcept : type((om == nullptr) ? NoType : TYPE_OF(const ObjectModel*)), param(tableNumber), omVal(om) { } - explicit constexpr ExpressionValue(const char *s) noexcept : type(TYPE_OF(const char*)), param(0), sVal(s) { } - explicit constexpr ExpressionValue(const ObjectModelArrayDescriptor *omad) noexcept : type(TYPE_OF(const ObjectModelArrayDescriptor*)), param(0), omadVal(omad) { } - explicit constexpr ExpressionValue(IPAddress ip) noexcept : type(TYPE_OF(IPAddress)), param(0), uVal(ip.GetV4LittleEndian()) { } - explicit constexpr ExpressionValue(nullptr_t dummy) noexcept : type(NoType), param(0), uVal(0) { } - explicit ExpressionValue(DateTime t) noexcept : type((t.tim == 0) ? NoType : TYPE_OF(DateTime)), param(t.tim >> 32), uVal((uint32_t)t.tim) { } - explicit ExpressionValue(DriverId id) noexcept : type(TYPE_OF(DriverId)), param(0), uVal(id.AsU32()) { } - explicit ExpressionValue(Bitmap<uint16_t> bm) noexcept : type(TYPE_OF(Bitmap<uint16_t>)), param(0), uVal(bm.GetRaw()) { } - explicit ExpressionValue(Bitmap<uint32_t> bm) noexcept : type(TYPE_OF(Bitmap<uint32_t>)), param(0), uVal(bm.GetRaw()) { } - explicit ExpressionValue(Bitmap<uint64_t> bm) noexcept : type(TYPE_OF(Bitmap<uint64_t>)), param(bm.GetRaw() >> 32), uVal((uint32_t)bm.GetRaw()) { } + enum class SpecialType : uint32_t + { + sysDir = 0 + }; + + ExpressionValue() noexcept : type((uint32_t)TypeCode::None) { } + explicit constexpr ExpressionValue(bool b) noexcept : type((uint32_t)TypeCode::Bool), param(0), bVal(b) { } + explicit constexpr ExpressionValue(char c) noexcept : type((uint32_t)TypeCode::Char), param(0), cVal(c) { } + explicit constexpr ExpressionValue(float f) noexcept : type((uint32_t)TypeCode::Float), param(MaxFloatDigitsDisplayedAfterPoint), fVal(f) { } + constexpr ExpressionValue(float f, uint8_t numDecimalPlaces) noexcept : type((uint32_t)TypeCode::Float), param(numDecimalPlaces), fVal(f) { } + explicit constexpr ExpressionValue(int32_t i) noexcept : type((uint32_t)TypeCode::Int32), param(0), iVal(i) { } + explicit constexpr ExpressionValue(const ObjectModel *om) noexcept : type((om == nullptr) ? (uint32_t)TypeCode::None : (uint32_t)TypeCode::ObjectModel), param(0), omVal(om) { } + constexpr ExpressionValue(const ObjectModel *om, uint8_t tableNumber) noexcept : type((om == nullptr) ? (uint32_t)TypeCode::None : (uint32_t)TypeCode::ObjectModel), param(tableNumber), omVal(om) { } + explicit constexpr ExpressionValue(const char *s) noexcept : type((uint32_t)TypeCode::CString), param(0), sVal(s) { } + explicit constexpr ExpressionValue(const ObjectModelArrayDescriptor *omad) noexcept : type((uint32_t)TypeCode::Array), param(0), omadVal(omad) { } + explicit constexpr ExpressionValue(IPAddress ip) noexcept : type((uint32_t)TypeCode::IPAddress), param(0), uVal(ip.GetV4LittleEndian()) { } + explicit constexpr ExpressionValue(nullptr_t dummy) noexcept : type((uint32_t)TypeCode::None), param(0), uVal(0) { } + explicit ExpressionValue(DateTime t) noexcept : type((t.tim == 0) ? (uint32_t)TypeCode::None : (uint32_t)TypeCode::DateTime), param(t.tim >> 32), uVal((uint32_t)t.tim) { } + explicit ExpressionValue(DriverId id) noexcept : type((uint32_t)TypeCode::DriverId), param(0), uVal(id.AsU32()) { } + explicit ExpressionValue(Bitmap<uint16_t> bm) noexcept : type((uint32_t)TypeCode::Bitmap16), param(0), uVal(bm.GetRaw()) { } + explicit ExpressionValue(Bitmap<uint32_t> bm) noexcept : type((uint32_t)TypeCode::Bitmap32), param(0), uVal(bm.GetRaw()) { } + explicit ExpressionValue(Bitmap<uint64_t> bm) noexcept : type((uint32_t)TypeCode::Bitmap64), param(bm.GetRaw() >> 32), uVal((uint32_t)bm.GetRaw()) { } explicit ExpressionValue(const MacAddress& mac) noexcept; + explicit ExpressionValue(SpecialType s) noexcept : type((uint32_t)TypeCode::Special), param((uint32_t)s), uVal(0) { } #if SUPPORT_CAN_EXPANSION - ExpressionValue(const char*s, ExpansionDetail p) noexcept : type(TYPE_OF(CanExpansionBoardDetails)), param((uint32_t)p), sVal(s) { } + ExpressionValue(const char*s, ExpansionDetail p) noexcept : type((uint32_t)TypeCode::CanExpansionBoardDetails), param((uint32_t)p), sVal(s) { } #endif - void Set(bool b) noexcept { type = TYPE_OF(bool); bVal = b; } - void Set(char c) noexcept { type = TYPE_OF(char); cVal = c; } - void Set(int32_t i) noexcept { type = TYPE_OF(int32_t); iVal = i; } - void Set(float f) noexcept { type = TYPE_OF(float); fVal = f; param = 1; } - void Set(const char *s) noexcept { type = TYPE_OF(const char*); sVal = s; } + TypeCode GetType() const noexcept { return (TypeCode)type; } + void SetType(TypeCode t) noexcept { type = (uint32_t)t; } + + void Set(bool b) noexcept { type = (uint32_t)TypeCode::Bool; bVal = b; } + void Set(char c) noexcept { type = (uint32_t)TypeCode::Char; cVal = c; } + void Set(int32_t i) noexcept { type = (uint32_t)TypeCode::Int32; iVal = i; } + void Set(float f) noexcept { type = (uint32_t)TypeCode::Float; fVal = f; param = 1; } + void Set(const char *s) noexcept { type = (uint32_t)TypeCode::CString; sVal = s; } // Extract a 56-bit value that we have stored. Used to retrieve date/times and large bitmaps. uint64_t Get56BitValue() const noexcept { return ((uint64_t)param << 32) | uVal; } |