* 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:
@@ -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
|
||||
|
@@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user