16 #include "../third-party/rapidxml/rapidxml.hpp" 21 typedef std::function<void(const uint8_t*, const section&, std::stringstream&)>
xml_parser_function;
124 bool in_is_decimal,
bool in_is_reverse_bytes,
125 int in_format_length)
127 format_length(in_format_length),
128 is_decimal(in_is_decimal),
129 is_reverse_bytes(in_is_reverse_bytes),
136 is_reverse_bytes(false),
168 bool is_write_only =
false;
169 bool is_read_command =
false;
171 int time_out = 20000;
172 int num_of_parameters = 0;
173 bool is_cmd_write_data =
false;
203 res +=
"0123456789ABCDEF"[n % 16];
207 std::reverse(res.begin(), res.end());
219 transform(x.begin(), x.end(), x.begin(), tolower);
232 auto pos = str.find(delimiter);
233 str.erase(0,
pos + delimiter.length());
235 std::stringstream ss;
238 ss >> std::hex >>
value;
245 auto doc = std::make_shared<rapidxml::xml_document<>>();
246 doc->parse<0>(doc->allocate_string(content));
248 auto node = doc->first_node(
"Commands");
250 throw std::logic_error(
"Invalid XML file - expecting Commands node to be present");
252 for (
auto NodeI = node->first_node(); NodeI; NodeI = NodeI->next_sibling())
254 if (!strcmp(NodeI->name(),
"Command"))
257 for (
auto AttI = NodeI->first_attribute(); AttI; AttI = AttI->next_attribute())
261 if (att_name ==
"Name") { cmd.
name =
value; }
267 else if (att_name ==
"TimeOut") { cmd.
time_out =
stoi(value); }
275 for (
auto SubNodeI = NodeI->first_node(); SubNodeI; SubNodeI = SubNodeI->next_sibling())
278 if (str_name.find(
"Parameter") != std::string::npos)
282 for (
auto paramAtt = SubNodeI->first_attribute(); paramAtt; paramAtt = paramAtt->next_attribute())
286 if (att_name ==
"Name") { param.
name =
value; }
291 else if (str_name ==
"Data")
296 for (
auto dataAtt = SubNodeI->first_attribute(); dataAtt; dataAtt = dataAtt->next_attribute())
301 if (data_att_name ==
"Name") { param.
name =
value; }
307 else if (str_name ==
"ReadData")
309 for (
auto sectionNode = SubNodeI->first_node(); sectionNode; sectionNode = sectionNode->next_sibling())
312 for (
auto sectionAtt = sectionNode->first_attribute(); sectionAtt; sectionAtt = sectionAtt->next_attribute())
316 if (section_att_name ==
"Name") { sec.
name =
value; }
317 else if (section_att_name ==
"Title") { sec.
title =
value; }
318 else if (section_att_name ==
"Offset") { sec.
offset =
stoi(value); }
319 else if (section_att_name ==
"Size") { sec.
size =
stoi(value); }
328 else if (!strcmp(NodeI->name(),
"CustomFormatter"))
331 for (
auto AttI = NodeI->first_attribute(); AttI; AttI = AttI->next_attribute())
335 if (atti_name ==
"KeySize") { customFormatter.
key_size =
value; }
336 else if (atti_name ==
"Name") { customFormatter.
name =
value; }
339 for (
auto SubNodeI = NodeI->first_node(); SubNodeI; SubNodeI = SubNodeI->next_sibling())
342 if (sub_nodei_name.find(
"KVP") != std::string::npos)
345 for (
auto paramAtt = SubNodeI->first_attribute(); paramAtt; paramAtt = paramAtt->next_attribute())
349 if (param_att_name ==
"Key") { kvp.
key =
value; }
350 else if (param_att_name ==
"Value") { kvp.
value =
value; }
352 customFormatter.
kv.push_back(kvp);
363 std::ifstream fin(xml_full_file_path);
368 std::stringstream ss;
379 std::string exception_str(
"Size of section %s is bigger than %s struct.");
380 if (section_size > struct_size)
382 auto msg =
"Size of section " + section_name +
" is bigger than " + struct_name +
" struct!";
383 throw std::runtime_error(msg);
389 format_type_to_lambda.insert(std::make_pair(
"ChangeSetVersion", [](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
392 tempStr << static_cast<int>(changeSetVersion->Version_Major) <<
393 ((sec.
size >= 2) ? (
"." +
std::to_string(static_cast<int>(changeSetVersion->Version_Minor))) :
"") <<
394 ((sec.
size >= 3) ? (
"." +
std::to_string(static_cast<int>(changeSetVersion->Version_Number))) :
"") <<
395 ((sec.
size >= 4) ? (
"." +
std::to_string(static_cast<int>(changeSetVersion->Version_Revision))) :
"") <<
396 ((sec.
size >= 5) ? (
" (" +
std::to_string(changeSetVersion->Version_spare)) +
")" :
"");
399 format_type_to_lambda.insert(std::make_pair(
"MajorMinorVersion", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
402 tempStr << static_cast<int>(majorMinorVersion->Version_Major) <<
403 ((sec.
size >= 2) ? (
"." +
std::to_string(static_cast<int>(majorMinorVersion->Version_Minor))) :
"");
406 format_type_to_lambda.insert(std::make_pair(
"HexByte", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
408 auto hexByte =
reinterpret_cast<const HexByte*
>(data_offset + sec.
offset);
409 tempStr <<
hexify(hexByte->Version4);
412 format_type_to_lambda.insert(std::make_pair(
"LiguriaVersion", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
415 tempStr << static_cast<int>(liguriaVersion->Version1) <<
416 ((sec.
size >= 2) ? (
"." +
std::to_string(static_cast<int>(liguriaVersion->Version2))) :
"");
419 format_type_to_lambda.insert(std::make_pair(
"Bool", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
421 auto BooL =
reinterpret_cast<const Bool*
>(data_offset + sec.
offset);
422 tempStr << ((static_cast<int>(BooL->sts)) ?
"TRUE" :
"FALSE");
425 format_type_to_lambda.insert(std::make_pair(
"HwTypeNumber", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
428 tempStr << static_cast<int>(hwTypeNumber->num);
431 format_type_to_lambda.insert(std::make_pair(
"Ascii", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
433 auto ascii =
reinterpret_cast<const Ascii*
>(data_offset + sec.
offset);
434 auto temp =
new char[sec.
size + 1];
435 memcpy(temp, ascii->value, sec.
size);
436 temp[sec.
size] =
'\0';
441 format_type_to_lambda.insert(std::make_pair(
"DecByte", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
443 auto decByte =
reinterpret_cast<const DecByte*
>(data_offset + sec.
offset);
444 tempStr << static_cast<int>(decByte->version);
447 format_type_to_lambda.insert(std::make_pair(
"HexNumber", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
449 auto hexNumber =
reinterpret_cast<const HexNumber*
>(data_offset + sec.
offset);
450 tempStr <<
hexify(hexNumber->number1) <<
451 ((sec.
size >= 2) ?
hexify(hexNumber->number2) :
"") <<
452 ((sec.
size >= 3) ?
hexify(hexNumber->number3) :
"") <<
453 ((sec.
size >= 4) ?
hexify(hexNumber->number4) :
"");
456 format_type_to_lambda.insert(std::make_pair(
"HexNumberTwoBytes", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
458 auto hexNumber =
reinterpret_cast<const HexNumber*
>(data_offset + sec.
offset);
459 tempStr <<
hexify(hexNumber->number2) <<
460 ((sec.
size >= 2) ?
hexify(hexNumber->number1) :
"");
463 format_type_to_lambda.insert(std::make_pair(
"HexNumberReversed", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
466 tempStr <<
hexify(hexNumberReversed->number4) <<
467 ((sec.
size >= 2) ?
hexify(hexNumberReversed->number3) :
"") <<
468 ((sec.
size >= 3) ?
hexify(hexNumberReversed->number2) :
"") <<
469 ((sec.
size >= 4) ?
hexify(hexNumberReversed->number1) :
"");
472 format_type_to_lambda.insert(std::make_pair(
"BarCodeSerial12Char", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
475 tempStr <<
hexify(barCodeSerial12Char->number1) <<
476 ((sec.
size >= 2) ?
hexify(barCodeSerial12Char->number2) :
"") <<
477 ((sec.
size >= 3) ?
hexify(barCodeSerial12Char->number3) :
"") <<
478 ((sec.
size >= 4) ?
hexify(barCodeSerial12Char->number4) :
"") <<
479 ((sec.
size >= 5) ?
hexify(barCodeSerial12Char->number5) :
"") <<
480 ((sec.
size >= 6) ?
hexify(barCodeSerial12Char->number6) :
"") <<
481 ((sec.
size >= 7) ?
hexify(barCodeSerial12Char->number7) :
"") <<
482 ((sec.
size >= 8) ?
hexify(barCodeSerial12Char->number8) :
"");
485 format_type_to_lambda.insert(std::make_pair(
"WideMajorMinorVersion", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
488 tempStr << static_cast<int>(wideMajorMinorVersion->Version_Minor) <<
489 ((sec.
size >= 2) ? (
"." +
std::to_string(static_cast<int>(wideMajorMinorVersion->Version_Major))) :
"");
492 format_type_to_lambda.insert(std::make_pair(
"Double", [&](
const uint8_t* data_offset,
const section& sec, std::stringstream& tempStr) {
495 tempStr << std::setprecision(10) << number->
number;
499 inline void update_sections_data(
const uint8_t* data_offset, std::vector<section>& sections,
const std::map<std::string, custom_formatter>& custom_formatters,
const std::map<std::string, xml_parser_function>& format_type_to_lambda)
501 for (
auto& sec : sections)
503 std::stringstream tempStr;
504 auto pair = format_type_to_lambda.find(sec.format_type);
505 if (pair != format_type_to_lambda.end())
507 pair->second(data_offset, sec, tempStr);
512 auto it = custom_formatters.find(
to_lower(sec.format_type));
513 if (
it != custom_formatters.end())
515 if (
it->second.key_size ==
"Byte")
517 auto key =
uint8_t(*(data_offset + sec.offset));
518 for (
auto& elem :
it->second.kv)
521 if (elem.key == keyStr)
523 tempStr << elem.value;
531 std::vector<uint8_t> raw_data;
533 throw std::runtime_error(
std::string(
"Size of section " + sec.name +
" is 0!").c_str());
535 raw_data.resize(sec.size);
536 memcpy(raw_data.data(), data_offset + sec.offset, sec.size);
537 sec.data = tempStr.str();
543 auto data_offset = raw_data_offset + 4;
546 throw std::runtime_error(
"Raw data is empty!");
548 std::stringstream ss_output;
550 auto num_of_bytes_for_space = 1;
551 auto num_of_bytes_for_new_line = 16;
553 if (read_format ==
"Bytes")
554 num_of_bytes_for_space = 1;
555 else if (read_format ==
"Words")
556 num_of_bytes_for_space = 2;
557 else if (read_format ==
"Doubles")
558 num_of_bytes_for_space = 4;
563 std::vector<std::string>
buffer;
565 auto bytes_per_line = 0;
566 auto start_address =
"0";
568 std::stringstream dec_to_hex;
569 auto end_address =
std::stoi(start_address) + data_size;
570 auto num_of_zeros = 1;
572 if (curr_address.size() == 1)
574 auto temp_curr_address = curr_address;
575 auto temp_end_address = end_address;
576 auto temp_bytes_per_line = bytes_per_line;
580 ++temp_bytes_per_line;
581 if (temp_bytes_per_line == num_of_bytes_for_new_line)
584 unsigned int next_add =
stoi(temp_curr_address) + num_of_bytes_for_new_line;
586 if (next_add >= temp_end_address)
590 dec_to_hex << std::hex << next_add;
591 temp_curr_address = dec_to_hex.str();
593 if (temp_curr_address.size() == 1)
594 temp_curr_address.insert(0,
"0");
597 temp_bytes_per_line = 0;
601 num_of_zeros = int(dec_to_hex.str().length());
602 ss_output <<
"Offset: 0x";
605 for (
auto i = 1;
i < num_of_zeros; ++
i)
611 ss_output <<
"Offset: 0x";
613 ss_output << std::hex <<
stoi(curr_address) <<
" => ";
619 buffer.push_back(
hexify(static_cast<unsigned char>(*(data_offset +
offset))));
621 if (bytes == num_of_bytes_for_space)
624 reverse(buffer.begin(), buffer.end());
626 for (
auto str : buffer)
631 if (bytes_per_line == num_of_bytes_for_new_line)
633 unsigned int next_add =
stoi(curr_address) + num_of_bytes_for_new_line;
635 if (next_add >= end_address)
639 dec_to_hex << std::hex << next_add;
640 curr_address = dec_to_hex.str();
642 auto putZeros = num_of_zeros - int(curr_address.size());
643 ss_output <<
"\nOffset: 0x";
645 for (
auto i = 0;
i < putZeros; ++
i)
650 ss_output << curr_address <<
" => ";
656 if ((
offset + 1) < data_size)
666 unsigned max_line_len = 0;
667 for (
auto& elem : sections)
668 max_line_len = ((elem.name.size() > max_line_len) ?
unsigned(elem.name.size()) : max_line_len);
670 const int spaces = 3;
671 for (
auto& elem : sections)
672 ss_output << elem.name <<
":" << std::setw((max_line_len + spaces) - elem.name.size() + elem.data.length()) <<
std::right << elem.data << std::endl;
675 output = ss_output.str();
680 auto cmd_op_code = xml_cmd_info.
op_code;
685 if (
int(params.size()) < num_of_required_parameters)
686 throw std::runtime_error(
"Number of given parameters is less than required!");
689 if (is_cmd_writes_data)
692 const uint16_t pre_header_data = 0xcdab;
694 auto write_ptr = raw_data.data();
695 auto header_size = 4;
699 *
reinterpret_cast<uint16_t *
>(write_ptr + cur_index) = pre_header_data;
701 *
reinterpret_cast<unsigned int *
>(write_ptr + cur_index) = cmd_op_code;
702 cur_index +=
sizeof(
unsigned int);
705 for (
auto param_index = 0; param_index <
MAX_PARAMS; ++param_index)
710 std::stringstream ss;
711 ss << params[param_index].data;
712 ss >> std::hex >> decimal;
713 *
reinterpret_cast<unsigned*
>(write_ptr + cur_index) = decimal;
714 cur_index +=
sizeof(unsigned);
718 *
reinterpret_cast<unsigned *
>(write_ptr + cur_index) = 0;
719 cur_index +=
sizeof(unsigned);
724 if (is_cmd_writes_data)
729 std::stringstream ss;
730 ss << params[
j].data;
731 ss >> std::hex >> decimal;
735 *
reinterpret_cast<uint8_t*
>(write_ptr + cur_index) = static_cast<uint8_t>(decimal);
740 *
reinterpret_cast<short *
>(write_ptr + cur_index) = static_cast<short>(decimal);
741 cur_index +=
sizeof(short);
745 *
reinterpret_cast<unsigned *
>(write_ptr + cur_index) = static_cast<unsigned>(decimal);
746 cur_index +=
sizeof(unsigned);
750 *
reinterpret_cast<uint8_t*
>(write_ptr + cur_index) = static_cast<uint8_t>(decimal);
757 *
reinterpret_cast<uint16_t*
>(raw_data.data()) = static_cast<uint16_t>(cur_index - header_size);
758 raw_data.resize(cur_index);
std::string to_lower(std::string x)
GLuint const GLchar * name
bool parse_xml_from_file(const std::string &xml_full_file_path, commands_xml &cmd_xml)
const uint16_t HW_MONITOR_BUFFER_SIZE
unsigned int string_to_hex(std::string str)
std::string cmd_interface
std::string hexify(unsigned char n)
parameter(std::string in_name, std::string in_data, bool in_is_decimal, bool in_is_reverse_bytes, int in_format_length)
struct command command_from_xml
void update_sections_data(const uint8_t *data_offset, std::vector< section > §ions, const std::map< std::string, custom_formatter > &custom_formatters, const std::map< std::string, xml_parser_function > &format_type_to_lambda)
void decode_string_from_raw_data(const command_from_xml &command, const std::map< std::string, custom_formatter > &custom_formatters, const uint8_t *raw_data_offset, size_t data_size, std::string &output, const std::map< std::string, xml_parser_function > &format_type_to_lambda)
std::string cmd_permission
GLsizei const GLchar *const * string
std::vector< section > sections
std::pair< int, std::string > kvp
void parse_xml_from_memory(const char *content, commands_xml &cmd_xml)
std::vector< parameter > parameters
void check_section_size(unsigned section_size, unsigned struct_size, const std::string §ion_name, const std::string &struct_name)
void update_format_type_to_lambda(std::map< std::string, xml_parser_function > &format_type_to_lambda)
GLenum const GLfloat * params
std::map< std::string, command_from_xml > commands
std::function< void(const uint8_t *, const section &, std::stringstream &)> xml_parser_function
int stoi(const std::string &value)
GLuint GLenum GLenum transform
bool string_to_bool(const std::string &x)
std::map< std::string, custom_formatter > custom_formatters
std::string i2c_reg_offset
void encode_raw_data_command(const command_from_xml &xml_cmd_info, const std::vector< parameter > ¶ms, std::vector< uint8_t > &raw_data)
std::string to_string(T value)