p18: fix variable field lengths in get-p-rated

This commit is contained in:
Evgeny Zinoviev 2021-11-29 02:28:21 +03:00
parent 46c308bc14
commit 0d7e12ce55
2 changed files with 42 additions and 5 deletions

View File

@ -8,7 +8,6 @@
#include "response.h" #include "response.h"
#include "exceptions.h" #include "exceptions.h"
#include "../logging.h"
#define RETURN_TABLE(...) \ #define RETURN_TABLE(...) \
return std::shared_ptr<formatter::Table<VariantHolder>>( \ return std::shared_ptr<formatter::Table<VariantHolder>>( \
@ -27,6 +26,19 @@ typedef formatter::TableItem<VariantHolder> LINE;
using formatter::Unit; 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 * Base responses
*/ */
@ -58,7 +70,7 @@ size_t GetResponse::getDataSize() const {
return rawSize_ - 5; return rawSize_ - 5;
} }
std::vector<std::string> GetResponse::getList(std::vector<size_t> itemLengths, int expectAtLeast) const { std::vector<std::string> GetResponse::getList(std::vector<FieldLength> itemLengths, int expectAtLeast) const {
std::string buf(getData(), getDataSize()); std::string buf(getData(), getDataSize());
auto list = ::split(buf, ','); auto list = ::split(buf, ',');
@ -77,7 +89,7 @@ std::vector<std::string> GetResponse::getList(std::vector<size_t> itemLengths, i
// check each item's length // check each item's length
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
if (list[i].size() != itemLengths[i]) { if (!itemLengths[i].validate(list[i].size())) {
std::ostringstream error; std::ostringstream error;
error << "while parsing " << demangle_type_name(typeid(*this).name()); error << "while parsing " << demangle_type_name(typeid(*this).name());
error << ": item " << i << " is expected to be " << itemLengths[i] << " characters long, "; error << ": item " << i << " is expected to be " << itemLengths[i] << " characters long, ";
@ -635,7 +647,12 @@ void ParallelRatedInformation::unpack() {
20, // CCCCCCCCCCCCCCCCCCCC 20, // CCCCCCCCCCCCCCCCCCCC
1, // D 1, // D
3, // EEE 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 1 // G
}); });

View File

@ -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 * Base responses
*/ */
@ -145,7 +165,7 @@ class GetResponse : public BaseResponse {
protected: protected:
const char* getData() const; const char* getData() const;
size_t getDataSize() const; size_t getDataSize() const;
std::vector<std::string> getList(std::vector<size_t> itemLengths, int expectAtLeast = -1) const; std::vector<std::string> getList(std::vector<FieldLength> itemLengths, int expectAtLeast = -1) const;
public: public:
using BaseResponse::BaseResponse; using BaseResponse::BaseResponse;