#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), group_id_(0), channel_name_(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: "< minmaxchan(atof(anode.child_value("minimum")), atof(anode.child_value("maximum"))); minmax_.push_back(minmaxchan); // TODO correct order of channels w.r.t. to list of offset, length and type by // considering the xpointer id's !!!! // follow xpointers to get external id std::string locol = get_str_between(anode.child_value("local_columns"),"\"","\""); std::string locolval; 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; 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(); } } // std::cout< maxshow ) { for ( int i = num_channels_-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); if ( type_[channelid-1].compare("eFloat64Usi") == 0 ) chann[i] = convert_double(cseg); // check if converted value is within expected range // if ( chann[i] < minmax_[channelid-1].first || chann[i] > minmax_[channelid-1].second ) std::cout<= minmax_[channelid-1].first && chann[i] <= minmax_[channelid-1].second ); } return chann; } std::vector tdm_ripper::get_channel(int channelid) { assert( channelid > 0 && channelid <= num_channels_ && "please provide valid channel id" ); return convert_channel(channel_ext_[channelid-1]); } 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<