From 0d7e12ce55d1ff4f303b37fb89fc01fad5dfb8cf Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Mon, 29 Nov 2021 02:28:21 +0300 Subject: [PATCH] p18: fix variable field lengths in get-p-rated --- src/p18/response.cc | 25 +++++++++++++++++++++---- src/p18/response.h | 22 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/p18/response.cc b/src/p18/response.cc index f361dee..0239b2d 100644 --- a/src/p18/response.cc +++ b/src/p18/response.cc @@ -8,7 +8,6 @@ #include "response.h" #include "exceptions.h" -#include "../logging.h" #define RETURN_TABLE(...) \ return std::shared_ptr>( \ @@ -27,6 +26,19 @@ typedef formatter::TableItem LINE; using formatter::Unit; + +/** + * Helpers + */ +std::ostream& operator<<(std::ostream& os, FieldLength fl) { + if (fl.min_ == fl.max_) + os << fl.min_; + else + os << "[" << fl.min_ << ", " << fl.max_ << "]"; + return os; +} + + /** * Base responses */ @@ -58,7 +70,7 @@ size_t GetResponse::getDataSize() const { return rawSize_ - 5; } -std::vector GetResponse::getList(std::vector itemLengths, int expectAtLeast) const { +std::vector GetResponse::getList(std::vector itemLengths, int expectAtLeast) const { std::string buf(getData(), getDataSize()); auto list = ::split(buf, ','); @@ -77,7 +89,7 @@ std::vector GetResponse::getList(std::vector itemLengths, i // check each item's length for (int i = 0; i < list.size(); i++) { - if (list[i].size() != itemLengths[i]) { + if (!itemLengths[i].validate(list[i].size())) { std::ostringstream error; error << "while parsing " << demangle_type_name(typeid(*this).name()); error << ": item " << i << " is expected to be " << itemLengths[i] << " characters long, "; @@ -635,7 +647,12 @@ void ParallelRatedInformation::unpack() { 20, // CCCCCCCCCCCCCCCCCCCC 1, // D 3, // EEE - 2, // FF + + // FF + // note: protocol documentation says that the following field is 2 bytes long, + // but actual tests of the 6kw unit shows it can be 3 bytes long + FieldLength(2, 3), + 1 // G }); diff --git a/src/p18/response.h b/src/p18/response.h index b14c9b0..42b84b8 100644 --- a/src/p18/response.h +++ b/src/p18/response.h @@ -124,6 +124,26 @@ public: }; +/** + * Some helpers + */ +class FieldLength { +protected: + size_t min_; + size_t max_; + +public: + FieldLength(size_t n) : min_(n), max_(n) {} + FieldLength(size_t min, size_t max) : min_(min), max_(max) {} + + [[nodiscard]] bool validate(size_t len) const { + return len >= min_ && len <= max_; + } + + friend std::ostream& operator<<(std::ostream& os, FieldLength fl); +}; + + /** * Base responses */ @@ -145,7 +165,7 @@ class GetResponse : public BaseResponse { protected: const char* getData() const; size_t getDataSize() const; - std::vector getList(std::vector itemLengths, int expectAtLeast = -1) const; + std::vector getList(std::vector itemLengths, int expectAtLeast = -1) const; public: using BaseResponse::BaseResponse;