#include "tdm_ripper.hpp" tdm_ripper::tdm_ripper(std::string tdmfile, std::string tdxfile): tdmfile_(tdmfile), tdxfile_(tdxfile), num_channels_(0), num_groups_(0), channel_id_(0), inc_id_(0), units_(0), channel_name_(0), group_id_(0), group_name_(0), num_channels_group_(0), channels_group_(0), channel_ext_(0), minmax_(0), byteoffset_(0), length_(0), type_(0), external_id_(0) { datatypes_ = { {"eInt8Usi",8}, {"eInt16Usi",16}, {"eInt32Usi",32}, {"eInt64Usi",64}, {"eUInt8Usi",8}, {"eUInt16Usi",16}, {"eUInt32Usi",32}, {"eUInt64Usi",64}, {"eFloat32Usi",32}, {"eFloat64Usi",64} }; // make sure the provided file is a .tdm file assert( tdmfile_.compare("") != 0 && "please provide a valid .tdm file" ); std::string::size_type idx; idx = tdmfile_.find_last_of("."); assert( idx != std::string::npos && "there's no file extension at all - .tdm is required" ); assert( tdmfile_.substr(tdmfile_.find_last_of(".")+1).compare("tdm") == 0 && "it's not a .tdm file" ); // setup of xml-parser xml_result_ = xml_doc_.load_file(tdmfile_.c_str()); std::cout<<"\nloading and parsing file: "< tdxbuf((std::istreambuf_iterator(fin)), (std::istreambuf_iterator())); tdxbuf_ = tdxbuf; std::cout<<"number of bytes in binary file: "<(id,val)); } if ( std::string(anode.name()).compare("localcolumn") == 0 ) { std::string id(anode.attribute("id").value()); std::string val = get_str_between(anode.child_value("values"),"\"","\""); xml_values_.insert(std::pair(id,val)); } if ( std::string(anode.name()).compare("double_sequence") == 0 ) { std::string id(anode.attribute("id").value()); std::string val = anode.child("values").attribute("external").value(); xml_double_sequence_.insert(std::pair(id,val)); } } std::cout<<"number of pairs in\n"; std::cout< minmaxchan(atof(anode.child_value("minimum")), atof(anode.child_value("maximum"))); minmax_.push_back(minmaxchan); // get correct assignment of channels to byteoffset, length and datatype // std::string locol = get_str_between(anode.child_value("local_columns"),"\"","\""); // std::string locolval; // locolval = local_columns_val_[locol]; // for (pugi::xml_node anode: subtreedata.children()) // { // if ( std::string(anode.name()).compare("localcolumn") == 0 // && std::string(anode.attribute("id").value()).compare(locol) == 0 ) // { // locolval = get_str_between(anode.child_value("values"),"\"","\""); // } // } std::string locolvalext; // locolvalext = double_sequence_id_[locolval]; // for (pugi::xml_node anode: subtreedata.children()) // { // if ( std::string(anode.name()).compare("double_sequence") == 0 // && std::string(anode.attribute("id").value()).compare(locolval) == 0 ) // { // locolvalext = anode.child("values").attribute("external").value(); // } // } locolvalext = xml_double_sequence_[xml_values_[xml_local_columns_[anode.attribute("id").value()]]]; // save external id of channel and get corresponding channel index inc_id_.push_back(locolvalext); int extid = 1; for ( int i = 0; i < (int)external_id_.size(); i++ ) { if ( external_id_[i].compare(locolvalext) == 0 ) extid = i+1; } channel_ext_.push_back(extid); } } // std::string keyinit("usi23258"); // std::cout<<"xml test "< maxshow ) { for ( int i = num_channels_-maxshow; i < num_channels_; i++ ) { gout< maxshow ) { for ( int i = num_groups_-maxshow; i < num_channels_; i++ ) { gout< bych) { assert( bych.size() == sizeof(int) ); assert( endianness_ ); int df = 0.0; uint8_t *dfcast = reinterpret_cast(&df); for ( int i = 0; i < (int)sizeof(int); i++ ) { dfcast[i] = (int)bych[i]; } return df; } // disassemble single integer into array of chars std::vector tdm_ripper::convert_int(int df) { assert( endianness_ ); std::vector bych((int)sizeof(int)); uint8_t *dfcast = reinterpret_cast(&df); for ( int i = 0; i < (int)sizeof(int); i++ ) { bych[i] = (int)dfcast[i]; } return bych; } // convert array of chars to floating point double double tdm_ripper::convert_double(std::vector bych) { assert( bych.size() == sizeof(double) ); assert( endianness_ ); // check for IEEE754 floating point standard assert( std::numeric_limits::is_iec559 ); double df = 0.0; uint8_t *dfcast = reinterpret_cast(&df); for ( int i = 0; i < (int)sizeof(double); i++ ) { dfcast[i] = (int)bych[i]; } return df; } std::vector tdm_ripper::convert_channel(int channelid) { // obtain offset, length of channel and size of datatype int byteoffset = byteoffset_[channelid-1]; int length = length_[channelid-1]; int typesize = datatypes_[type_[channelid-1]]/CHAR_BIT; // declare resulting array std::vector chann(length); for ( int i = 0; i < length; i++ ) { std::vector cseg(tdxbuf_.begin()+byteoffset+i*typesize, tdxbuf_.begin()+byteoffset+(i+1)*typesize); if ( type_[channelid-1].compare("eInt32Usi") == 0 ) { chann[i] = convert_int(cseg); } else if ( type_[channelid-1].compare("eFloat64Usi") == 0 ) { chann[i] = convert_double(cseg); } else { assert( false && "datatype not supported!" ); } } return chann; } std::vector tdm_ripper::get_channel(int channelid) { assert( channelid > 0 && channelid <= num_channels_ && "please provide valid channel id" ); std::vector chann = convert_channel(channel_ext_[channelid-1]); // check if converted value is within expected range // for ( int i = 0; i < (int)chann.size(); i++ ) // { // if ( chann[i] < minmax_[channelid-1].first // || chann[i] > minmax_[channelid-1].second ) std::cout<= minmax_[channelid-1].first - 1.0e-6 // && chann[i] <= minmax_[channelid-1].second + 1.0e-6 ); // } return chann; } void tdm_ripper::print_channel(int channelid, const char* filename, int width) { assert( channelid > 0 && channelid <= num_channels_ && "please provide valid channel id" ); std::ofstream fout(filename); std::vector channdat = get_channel(channelid); for ( auto el: channdat ) fout<