* improve runtime detection of endianness

* support decoding of TDM/TDX data with endianness mismatch w.r.t.
  architecture => issue #16
* generate/provide bigEndian TDM/TDX example
This commit is contained in:
Mario Fink
2021-10-19 19:48:44 +02:00
parent b005987531
commit 050256763c
5 changed files with 488 additions and 5 deletions

View File

@@ -194,12 +194,31 @@ void tdm_termite::process_include(bool showlog, pugi::xml_document& xml_doc)
// check endianness
std::string endianness(tdmincl.child("file").attribute("byteOrder").value());
endianness_ = endianness.compare("littleEndian") == 0 ? true : false;
// endianness_ = endianness.compare("littleEndian") == 0 ? true : false;
if ( endianness.compare("littleEndian") == 0 )
{
endianness_ = true;
}
else if ( endianness.compare("bigEndian") == 0 )
{
endianness_ = false;
}
else
{
throw std::runtime_error(std::string("unsupported endianness: ") + endianness);
}
// obtain machine's endianness
int num = 1;
machine_endianness_ = ( *(char*)&num == 1 );
if ( machine_endianness_ != endianness_ ) throw std::runtime_error("endianness mismatch");
machine_endianness_ = this->detect_endianness();
// if ( machine_endianness_ != endianness_ )
// {
// std::stringstream ss;
// ss<<"endianness mismatch: "<<"TDM = "<<(endianness_?"little":"big")
// <<" , "
// <<"Arch = "<<(machine_endianness_?"little":"big");
// // std::cout<<ss.str()<<"\n";
// // throw std::runtime_error(ss.str());
// }
// list block of massdata
for (pugi::xml_node anode: tdmincl.child("file").children())
@@ -1052,7 +1071,15 @@ void tdm_termite::convert_data_to_type(std::vector<unsigned char> &buffer,
for ( unsigned long int j = 0; j < sizeof(datatype); j++ )
{
dfcast[j] = (int)buffer[i*sizeof(datatype)+j];
// matching byte order between TDM/TDX and machine's architecture ?
if ( machine_endianness_ == endianness_ )
{
dfcast[j] = (int)buffer[i*sizeof(datatype)+j];
}
else
{
dfcast[j] = (int)buffer[(i+1)*sizeof(datatype)-(j+1)];
}
}
// save number in channel

View File

@@ -17,6 +17,7 @@
#include <sstream>
#include <filesystem>
#include <regex>
#include <bit>
#include "pugixml.hpp"
#include "tdm_datamodel.hpp"
@@ -64,6 +65,29 @@ class tdm_termite
std::vector<unsigned char> tdxbuffer_;
std::ifstream *tdx_ifstream_;
// find machine's endianness at runtime
// detect machine endianness (C++20 !!)
// if ( std::endian::native == std::endian::little )
// {
// machine_endianness_ = true;
// }
// else if ( std::endian::native == std::endian::big )
// {
// machine_endianness_ = false;
// }
// else
// {
// throw std::runtime_error("mixed endianness architecture is not supported");
// }
bool detect_endianness()
{
// int num = 1;
// machine_endianness_ = ( *(char*)&num == 1 );
std::uint32_t num = 0x11223344;
uint8_t* dfc = reinterpret_cast<uint8_t*>(&num);
return ( dfc[0] == 0x44 );
}
// extract list of identifiers from e.g. "#xpointer(id("usi12") id("usi13"))"
std::vector<std::string> extract_ids(std::string idstring)
{