implement polymorphic tdmdatatype

This commit is contained in:
Mario Fink 2021-01-22 10:34:46 +01:00
parent 1d70e7b58e
commit ac4417accf
4 changed files with 254 additions and 97 deletions

View File

@ -119,23 +119,172 @@ static std::string join_strings(std::vector<std::string> &thestring, const char*
// https://zone.ni.com/reference/de-XX/help/370858P-0113/tdmdatamodel/tdmdatamodel/tdm_header_tdx_data/
// define mapping of locally supported datatypes to tdm datatypes
typedef short int eInt16Usi;
typedef int eInt32Usi;
typedef unsigned char eUInt8Usi;
typedef unsigned short int eUInt16Usi;
typedef unsigned int eUInt32Usi;
typedef float eFloat32Usi;
typedef double eFloat64Usi;
// define mapping of C++ supported datatypes to tdm datatypes
enum class tdmdatatype {
eInt16Usi,
eInt32Usi,
eUInt8Usi,
eUInt16Usi,
eUInt32Usi,
eFloat32Usi,
eFloat64Usi
// define mapping of locally supported datatypes to tdm datatypes
// typedef short int eInt16Usi;
// typedef int eInt32Usi;
// typedef unsigned char eUInt8Usi;
// typedef unsigned short int eUInt16Usi;
// typedef unsigned int eUInt32Usi;
// typedef float eFloat32Usi;
// typedef double eFloat64Usi;
// enum class tdmdatatype {
// eInt16Usi,
// eInt32Usi,
// eUInt8Usi,
// eUInt16Usi,
// eUInt32Usi,
// eFloat32Usi,
// eFloat64Usi
// };
// base class for all tdm datatypes
class tdmdatatype
{
protected:
short int sint16_;
int sint32_;
unsigned char uint8_;
unsigned short int uint16_;
unsigned int uint32_;
float float32_;
double float64_;
public:
tdmdatatype(): sint16_(0), sint32_(0),
uint8_(0), uint16_(0), uint32_(0),
float32_(0.0), float64_(0.0) {};
friend std::ostream& operator<<(std::ostream& out, const tdmdatatype& num)
{
return num.print(out);
}
virtual std::ostream& print(std::ostream& out) const
{
out<<"tdmdatatype";
return out;
}
};
class eInt16Usi: public tdmdatatype
{
public:
eInt16Usi() { }
eInt16Usi(short int num) { sint16_ = num; }
// eInt16Usi& operator=(const eInt16Usi &num)
// {
// // self-assignment check
// if ( this != &num)
// {
// this->sint16_ = num.sint16_;
// }
// return *this;
// }
friend std::ostream& operator<<(std::ostream& out, const eInt16Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<sint16_;
return out;
}
};
class eInt32Usi: public tdmdatatype
{
public:
eInt32Usi() { }
eInt32Usi(int num) { sint32_ = num; }
friend std::ostream& operator<<(std::ostream& out, const eInt32Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<sint32_;
return out;
}
};
class eUInt8Usi: public tdmdatatype
{
public:
eUInt8Usi() { }
eUInt8Usi(int num) { uint8_ = num; }
friend std::ostream& operator<<(std::ostream& out, const eUInt8Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<uint8_;
return out;
}
};
class eUInt16Usi: public tdmdatatype
{
public:
eUInt16Usi() { }
eUInt16Usi(int num) { uint16_ = num; }
friend std::ostream& operator<<(std::ostream& out, const eUInt16Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<uint16_;
return out;
}
};
class eUInt32Usi: public tdmdatatype
{
public:
eUInt32Usi() { }
eUInt32Usi(int num) { uint32_ = num; }
friend std::ostream& operator<<(std::ostream& out, const eUInt32Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<uint32_;
return out;
}
};
class eFloat32Usi: public tdmdatatype
{
public:
eFloat32Usi() { }
eFloat32Usi(int num) { float32_ = num; }
friend std::ostream& operator<<(std::ostream& out, const eFloat32Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<float32_;
return out;
}
};
class eFloat64Usi: public tdmdatatype
{
public:
eFloat64Usi() { }
eFloat64Usi(int num) { float64_ = num; }
friend std::ostream& operator<<(std::ostream& out, const eFloat64Usi& num)
{
return num.print(out);
}
std::ostream& print(std::ostream& out) const override
{
out<<float64_;
return out;
}
};
struct tdm_datatype {

View File

@ -567,7 +567,9 @@ std::string tdm_reaper::get_block_overview(format formatter)
// -------------------------------------------------------------------------- //
std::vector<double> tdm_reaper::get_channel(std::string &id)
// extract channel by id
template<typename tdmtype>
std::vector<tdmtype> tdm_reaper::get_channel(std::string& id)
{
// check for existence of required channel id (=key)
if ( tdmchannels_.count(id) == 1 )
@ -576,39 +578,108 @@ std::vector<double> tdm_reaper::get_channel(std::string &id)
tdm_channel chn = tdmchannels_.at(id);
// extract (first) "localcolumn" for channel
if ( chn.local_columns_.size() != 1 )
{
throw std::runtime_error(std::string("invalid local_columns_ of channel: ") + id);
}
localcolumn loccol = localcolumns_.at(chn.local_columns_[0]);
if ( loccol.sequence_representation_ != "explicit" )
{
throw std::runtime_error(std::string("unsupported sequence_representation: ")
+ loccol.sequence_representation_);
}
// use "values" id to map to external block
block blk = tdx_blocks_.at(loccol.external_id_);
// declare buffer covering the required range of "tdxbuffer_"
std::vector<unsigned char> blkbuff( tdxbuffer_.begin()+blk.byte_offset_,
tdxbuffer_.begin()+blk.byte_offset_
+ blk.length_*sizeof(double) );
std::vector<double> datvec(blk.length_);
this->convert_data_to_type<double>(blkbuff,datvec);
return datvec;
// // distinguish numeric datatypes
// switch ( blk.value_type_ )
// {
// case "eInt16Usi" :
// break;
// case "eInt32Usi" :
// break;
// case "eUInt8Usi" :
// break;
// case "eUInt16Usi" :
// break;
// case "eUInt32Usi" :
// break;
// case "eFloat32Usi" :
// // declare buffer covering the required range of "tdxbuffer_"
// std::vector<unsigned char> blkF32( tdxbuffer_.begin()+blk.byte_offset_,
// tdxbuffer_.begin()+blk.byte_offset_
// + blk.length_*sizeof(eFloat32Usi) );
// std::vector<eFloat32Usi> datvecF32(blk.length_);
// this->convert_data_to_type<eFloat32Usi>(blkF32,datvecF32);
// return datvecF32;
// break;
// case "eFloat64Usi" :
// // declare buffer covering the required range of "tdxbuffer_"
// std::vector<unsigned char> blkF64( tdxbuffer_.begin()+blk.byte_offset_,
// tdxbuffer_.begin()+blk.byte_offset_
// + blk.length_*sizeof(eFloat64Usi) );
// std::vector<eFloat64Usi> datvecF64(blk.length_);
// this->convert_data_to_type<eFloat64Usi>(blkF64,datvecF64);
// return datvecF64;
// break;
// case "eStringUsi" :
// throw std::runtime_error("datatype 'eStringUsi' is not supported");
// break;
// }
}
else
{
throw std::invalid_argument(std::string("channel id does not exist: ") + id);
}
return std::vector<tdmtype>();
}
template std::vector<tdmdatatype> tdm_reaper::get_channel<tdmdatatype>(std::string& id);
// std::vector<double> tdm_reaper::get_channel(std::string &id)
// {
// // check for existence of required channel id (=key)
// if ( tdmchannels_.count(id) == 1 )
// {
// // retrieve full channel info
// tdm_channel chn = tdmchannels_.at(id);
//
// // extract (first) "localcolumn" for channel
// localcolumn loccol = localcolumns_.at(chn.local_columns_[0]);
//
// // use "values" id to map to external block
// block blk = tdx_blocks_.at(loccol.external_id_);
//
// // declare buffer covering the required range of "tdxbuffer_"
// std::vector<unsigned char> blkbuff( tdxbuffer_.begin()+blk.byte_offset_,
// tdxbuffer_.begin()+blk.byte_offset_
// + blk.length_*sizeof(double) );
//
// std::vector<double> datvec(blk.length_);
// this->convert_data_to_type<double>(blkbuff,datvec);
//
// return datvec;
// }
// else
// {
// throw std::invalid_argument(std::string("channel id does not exist: ") + id);
// }
// }
void tdm_reaper::print_channel(std::string &id, const char* filename)
{
std::ofstream fou(filename);
std::vector<double> chn = this->get_channel(id);
std::vector<double> chn; // = this->get_channel(id);
for ( auto el: chn ) fou<<el<<"\n";
fou.close();
}
// -------------------------------------------------------------------------- //
template<typename datatype>

View File

@ -180,76 +180,10 @@ public:
// extract channel by id
template<typename tdmtype>
std::vector<tdmtype> get_channel(std::string& id)
{
// check for existence of required channel id (=key)
if ( tdmchannels_.count(id) == 1 )
{
// // retrieve full channel info
// tdm_channel chn = tdmchannels_.at(id);
//
// // extract (first) "localcolumn" for channel
// if ( chn.local_columns_.size() != 1 )
// {
// throw std::runtime_error(std::string("invalid local_columns_ of channel: ") + id);
// }
// localcolumn loccol = localcolumns_.at(chn.local_columns_[0]);
//
// if ( loccol.sequence_representation_ != "explicit" )
// {
// throw std::runtime_error(std::string("unsupported sequence_representation: ")
// + loccol.sequence_representation_);
// }
//
// // use "values" id to map to external block
// block blk = tdx_blocks_.at(loccol.external_id_);
//
// // distinguish numeric datatypes
// switch ( blk.value_type_ )
// {
// case "eInt16Usi" :
// break;
// case "eInt32Usi" :
// break;
// case "eUInt8Usi" :
// break;
// case "eUInt16Usi" :
// break;
// case "eUInt32Usi" :
// break;
// case "eFloat32Usi" :
// // declare buffer covering the required range of "tdxbuffer_"
// std::vector<unsigned char> blkF32( tdxbuffer_.begin()+blk.byte_offset_,
// tdxbuffer_.begin()+blk.byte_offset_
// + blk.length_*sizeof(eFloat32Usi) );
// std::vector<eFloat32Usi> datvecF32(blk.length_);
// this->convert_data_to_type<eFloat32Usi>(blkF32,datvecF32);
// return datvecF32;
// break;
// case "eFloat64Usi" :
// // declare buffer covering the required range of "tdxbuffer_"
// std::vector<unsigned char> blkF64( tdxbuffer_.begin()+blk.byte_offset_,
// tdxbuffer_.begin()+blk.byte_offset_
// + blk.length_*sizeof(eFloat64Usi) );
// std::vector<eFloat64Usi> datvecF64(blk.length_);
// this->convert_data_to_type<eFloat64Usi>(blkF64,datvecF64);
// return datvecF64;
// break;
// case "eStringUsi" :
// throw std::runtime_error("datatype 'eStringUsi' is not supported");
// break;
// }
}
else
{
throw std::invalid_argument(std::string("channel id does not exist: ") + id);
}
return std::vector<tdmtype>();
}
std::vector<tdmtype> get_channel(std::string& id);
// (TODO introduce template T to reference specific datatype instead of double in general)
std::vector<double> get_channel(std::string &id);
// std::vector<double> get_channel(std::string &id);
void print_channel(std::string &id, const char* filename);

View File

@ -204,6 +204,9 @@ int main(int argc, char* argv[])
std::string chid("usi14");
std::vector<tdmdatatype> chdata = jack.get_channel<tdmdatatype>(chid);
std::cout<<"channel size: "<<chdata.size()<<"\n";
for ( tdmdatatype el: chdata ) std::cout<<el<<"\n";
// std::vector<std::string> chgrids = jack.get_channelgroup_ids();
// for ( auto el: chgrids ) std::cout<<el<<",";
// std::cout<<"\n";