implement polymorphic tdmdatatype
This commit is contained in:
parent
1d70e7b58e
commit
ac4417accf
@ -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/
|
// 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
|
// define mapping of C++ 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 {
|
// define mapping of locally supported datatypes to tdm datatypes
|
||||||
eInt16Usi,
|
// typedef short int eInt16Usi;
|
||||||
eInt32Usi,
|
// typedef int eInt32Usi;
|
||||||
eUInt8Usi,
|
// typedef unsigned char eUInt8Usi;
|
||||||
eUInt16Usi,
|
// typedef unsigned short int eUInt16Usi;
|
||||||
eUInt32Usi,
|
// typedef unsigned int eUInt32Usi;
|
||||||
eFloat32Usi,
|
// typedef float eFloat32Usi;
|
||||||
eFloat64Usi
|
// 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 {
|
struct tdm_datatype {
|
||||||
|
@ -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)
|
// check for existence of required channel id (=key)
|
||||||
if ( tdmchannels_.count(id) == 1 )
|
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);
|
tdm_channel chn = tdmchannels_.at(id);
|
||||||
|
|
||||||
// extract (first) "localcolumn" for channel
|
// 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]);
|
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
|
// use "values" id to map to external block
|
||||||
block blk = tdx_blocks_.at(loccol.external_id_);
|
block blk = tdx_blocks_.at(loccol.external_id_);
|
||||||
|
|
||||||
// declare buffer covering the required range of "tdxbuffer_"
|
// // distinguish numeric datatypes
|
||||||
std::vector<unsigned char> blkbuff( tdxbuffer_.begin()+blk.byte_offset_,
|
// switch ( blk.value_type_ )
|
||||||
tdxbuffer_.begin()+blk.byte_offset_
|
// {
|
||||||
+ blk.length_*sizeof(double) );
|
// case "eInt16Usi" :
|
||||||
|
// break;
|
||||||
std::vector<double> datvec(blk.length_);
|
// case "eInt32Usi" :
|
||||||
this->convert_data_to_type<double>(blkbuff,datvec);
|
// break;
|
||||||
|
// case "eUInt8Usi" :
|
||||||
return datvec;
|
// 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
|
else
|
||||||
{
|
{
|
||||||
throw std::invalid_argument(std::string("channel id does not exist: ") + id);
|
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)
|
void tdm_reaper::print_channel(std::string &id, const char* filename)
|
||||||
{
|
{
|
||||||
std::ofstream fou(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";
|
for ( auto el: chn ) fou<<el<<"\n";
|
||||||
|
|
||||||
fou.close();
|
fou.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
|
|
||||||
template<typename datatype>
|
template<typename datatype>
|
||||||
|
@ -180,76 +180,10 @@ public:
|
|||||||
|
|
||||||
// extract channel by id
|
// extract channel by id
|
||||||
template<typename tdmtype>
|
template<typename tdmtype>
|
||||||
std::vector<tdmtype> get_channel(std::string& id)
|
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>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// (TODO introduce template T to reference specific datatype instead of double in general)
|
// (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);
|
void print_channel(std::string &id, const char* filename);
|
||||||
|
|
||||||
|
@ -204,6 +204,9 @@ int main(int argc, char* argv[])
|
|||||||
std::string chid("usi14");
|
std::string chid("usi14");
|
||||||
std::vector<tdmdatatype> chdata = jack.get_channel<tdmdatatype>(chid);
|
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();
|
// std::vector<std::string> chgrids = jack.get_channelgroup_ids();
|
||||||
// for ( auto el: chgrids ) std::cout<<el<<",";
|
// for ( auto el: chgrids ) std::cout<<el<<",";
|
||||||
// std::cout<<"\n";
|
// std::cout<<"\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user