132 lines
3.7 KiB
C++
132 lines
3.7 KiB
C++
//---------------------------------------------------------------------------//
|
|
|
|
#ifndef IMCKEY
|
|
#define IMCKEY
|
|
|
|
#include <iomanip>
|
|
#include <map>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
//---------------------------------------------------------------------------//
|
|
|
|
namespace imc
|
|
{
|
|
// define "magic bytes" announcing critical (=C) non-critical keys (=N)
|
|
const unsigned char key_crit_ = 0x43, key_non_crit_ = 0x4e;
|
|
|
|
// define properties of marker/key
|
|
struct key
|
|
{
|
|
// (non)critical key
|
|
bool critical_;
|
|
// name of key (two uppercase letters)
|
|
std::string name_;
|
|
// short description
|
|
std::string description_;
|
|
// version of marker
|
|
int version_;
|
|
|
|
// constructor
|
|
key(bool critical, std::string name,
|
|
std::string description = std::string(""), int version = -1)
|
|
{
|
|
critical_ = critical;
|
|
if ( name.size() != 2 ) throw std::logic_error("invalid key name");
|
|
name_ = name;
|
|
description_ = description;
|
|
version_ = version;
|
|
}
|
|
|
|
// comparison operator
|
|
bool operator==(const key& akey)
|
|
{
|
|
return ( this->critical_ == akey.critical_
|
|
&& this->name_ == akey.name_
|
|
&& this->description_ == akey.description_
|
|
&& this->version_ == akey.version_ );
|
|
}
|
|
|
|
// get info string
|
|
std::string get_info(int width = 20)
|
|
{
|
|
std::stringstream ss;
|
|
ss<<std::setw(width)<<std::left<<"critical:"<<(critical_?"yes":"no")<<"\n"
|
|
<<std::setw(width)<<std::left<<"name:"<<name_<<"\n"
|
|
<<std::setw(width)<<std::left<<"description:"<<description_<<"\n"
|
|
<<std::setw(width)<<std::left<<"version:"<<version_<<"\n";
|
|
return ss.str();
|
|
}
|
|
|
|
};
|
|
|
|
const std::vector<key> keys = {
|
|
|
|
// critical keys
|
|
key(true,"CF","format version and processor",2),
|
|
key(true,"CK","start of group of keys",1),
|
|
key(true,"CB","group of channels",1),
|
|
key(true,"CT","text definition",1),
|
|
key(true,"CG","group of components",1),
|
|
key(true,"CD","abscissa description",1),
|
|
key(true,"CD","abscissa description",2),
|
|
key(true,"CZ","scaling of z-axis",1),
|
|
key(true,"CC","start of component",1),
|
|
key(true,"CP","buffer, datatype and samples of component",1),
|
|
key(true,"Cb","buffer description",1),
|
|
key(true,"CR","permissible range of values in component",1),
|
|
key(true,"CN","name and comment of channel",1),
|
|
key(true,"CS","raw binary data",1),
|
|
key(true,"CI","single numerical value",1),
|
|
key(true,"Ca","add reference key",1),
|
|
|
|
// noncritical keys
|
|
key(false,"NO","origin of data",1),
|
|
key(false,"NT","timestamp of trigger",1),
|
|
key(false,"ND","(color) display properties",1),
|
|
key(false,"NU","user defined key",1),
|
|
key(false,"Np","property of channel",1),
|
|
key(false,"NE","extraction rule for BUS channels",1)
|
|
|
|
};
|
|
|
|
// check for existence of specific key
|
|
bool check_key(key& mykey)
|
|
{
|
|
for ( key ky: keys ) if ( mykey == ky ) return true;
|
|
return false;
|
|
}
|
|
|
|
// get key (with respect to name and evtl. version)
|
|
key get_key(bool critical, std::string name, int version = -1)
|
|
{
|
|
// check validity of required key name
|
|
if ( name.size() > 2 || name.size() < 1 )
|
|
{
|
|
throw std::runtime_error(std::string("invalid key name: ") + name);
|
|
}
|
|
|
|
// declare new key with available data
|
|
key mykey(critical,name,std::string(""),version);
|
|
|
|
// try to find matching key in list of predefined keys
|
|
for ( key ky: keys )
|
|
{
|
|
if ( critical == ky.critical_ && name == ky.name_
|
|
&& ( version == ky.version_ || version == -1 ) )
|
|
{
|
|
mykey = ky;
|
|
}
|
|
}
|
|
|
|
return mykey;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
//---------------------------------------------------------------------------//
|