TOBI Interface A  0.1
/home/breidi/Dropbox/libtia/src/tia/datapacket/data_packet_3_impl.cpp
00001 /*
00002     This file is part of the TOBI Interface A (TiA) library.
00003 
00004     Commercial Usage
00005     Licensees holding valid Graz University of Technology Commercial
00006     licenses may use this file in accordance with the Graz University
00007     of Technology Commercial License Agreement provided with the
00008     Software or, alternatively, in accordance with the terms contained in
00009     a written agreement between you and Graz University of Technology.
00010 
00011     --------------------------------------------------
00012 
00013     GNU Lesser General Public License Usage
00014     Alternatively, this file may be used under the terms of the GNU Lesser
00015     General Public License version 3.0 as published by the Free Software
00016     Foundation and appearing in the file lgpl.txt included in the
00017     packaging of this file.  Please review the following information to
00018     ensure the GNU General Public License version 3.0 requirements will be
00019     met: http://www.gnu.org/copyleft/lgpl.html.
00020 
00021     In case of GNU Lesser General Public License Usage ,the TiA library
00022     is distributed in the hope that it will be useful,
00023     but WITHOUT ANY WARRANTY; without even the implied warranty of
00024     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025     GNU General Public License for more details.
00026 
00027     You should have received a copy of the GNU Lesser General Public License
00028     along with the TiA library. If not, see <http://www.gnu.org/licenses/>.
00029 
00030     Copyright 2010 Graz University of Technology
00031     Contact: TiA@tobi-project.org
00032 */
00033 
00038 #include <sstream>
00039 #include <stdexcept>
00040 
00041 #include "tia/defines.h"
00042 
00043 #include "tia-private/datapacket/data_packet_3_impl.h"
00044 #include "tia-private/clock.h"
00045 #include "tia-private/datapacket/raw_mem3.h"
00046 
00047 namespace tia
00048 {
00049 
00050 using boost::uint16_t;
00051 using boost::uint32_t;
00052 using boost::uint64_t;
00053 using boost::int32_t;
00054 
00055 using std::vector;
00056 using std::map;
00057 using std::string;
00058 using std::stringstream;
00059 using std::make_pair;
00060 
00061 static const unsigned int CURRENT_DATA_PACKET_VERSION = 3;
00062 
00063 //-----------------------------------------------------------------------------
00064 
00065 DataPacket3Impl::DataPacket3Impl()
00066 : version_(CURRENT_DATA_PACKET_VERSION), packet_id_(0),
00067   flags_(0), connection_packet_nr_(0),
00068   timestamp_(0), nr_of_signal_types_(0)
00069 {
00070 
00071 }
00072 
00073 //-----------------------------------------------------------------------------
00074 
00075 DataPacket3Impl::DataPacket3Impl(const DataPacket3Impl &src)
00076 {
00077   version_ = src.version_;
00078   packet_id_ = src.packet_id_;
00079   flags_ = src.flags_;
00080   connection_packet_nr_ = src.connection_packet_nr_;
00081   timestamp_ = src.timestamp_;
00082   nr_of_signal_types_ = src.nr_of_signal_types_;
00083 
00084   nr_channels_ = src.nr_channels_;
00085   samples_per_channel_ = src.samples_per_channel_;
00086   data_ = src.data_;
00087 
00088   std::map<boost::uint32_t, RawMem3*> raw_map_;
00089 }
00090 
00091 //-----------------------------------------------------------------------------
00092 
00093 DataPacket3Impl& DataPacket3Impl::operator=(const DataPacket3Impl &src)
00094 {
00095   version_ = src.version_;
00096   packet_id_ = src.packet_id_;
00097   flags_ = src.flags_;
00098   connection_packet_nr_ = src.connection_packet_nr_;
00099   timestamp_ = src.timestamp_;
00100   nr_of_signal_types_ = src.nr_of_signal_types_;
00101 
00102   nr_channels_ = src.nr_channels_;
00103   samples_per_channel_ = src.samples_per_channel_;
00104   data_ = src.data_;
00105 
00106   std::map<boost::uint32_t, RawMem3*> raw_map_;
00107 
00108   return *this;
00109 }
00110 
00111 //-----------------------------------------------------------------------------
00112 
00113 void DataPacket3Impl::reset(void* mem)
00114 {
00115   #ifdef DEBUG
00116       cout << "DataPacket: RAW Constructor" << endl;
00117   #endif
00118 
00119   flags_ = 0;
00120   connection_packet_nr_ = 0;
00121   nr_of_signal_types_ = 0;
00122 
00123   uint8_t* version_ptr = reinterpret_cast<uint8_t*>(mem);
00124   version_ = *version_ptr;
00125 
00126   if(CURRENT_DATA_PACKET_VERSION != version_)
00127   {
00128     string ex_str("DataPacket(void* mem): ERROR -- DataPacket versions don't match!");
00129     ex_str = ex_str + " - Received packet version: ";
00130     ex_str += version_;
00131     ex_str = ex_str + " - Needed packet version: ";
00132     ex_str += CURRENT_DATA_PACKET_VERSION;
00133     throw(std::runtime_error(ex_str));
00134   }
00135 
00136   uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(++version_ptr);
00137   ++ui32_ptr;         // FIXME ... skip size field
00138   flags_ = *ui32_ptr;
00139 
00140   nr_of_signal_types_ = calcNrOfSignalTypes(flags_);
00141 
00142   uint64_t* ui64_ptr = reinterpret_cast<uint64_t*>(++ui32_ptr);
00143   packet_id_ = *ui64_ptr;
00144   ui64_ptr++;
00145   connection_packet_nr_ = *ui64_ptr;
00146 
00147   uint64_t* time_ptr
00148     = reinterpret_cast<uint64_t*>(++ui64_ptr);
00149   timestamp_ = *time_ptr;
00150 
00151   uint16_t* ui16_ptr = reinterpret_cast<uint16_t*>(++time_ptr);
00152   for(unsigned int n = 0; n < nr_of_signal_types_; n++)
00153   {
00154     nr_channels_.push_back(*ui16_ptr);
00155     ui16_ptr++;
00156   }
00157 
00158   for(unsigned int n = 0; n < nr_of_signal_types_; n++)
00159   {
00160     samples_per_channel_.push_back(*ui16_ptr);
00161     ui16_ptr++;
00162   }
00163 
00164   float* data_ptr = reinterpret_cast<float*>(ui16_ptr);
00165   for(unsigned int j = 0; j < nr_channels_.size(); j++)
00166     for(int32_t k = 0; k < (nr_channels_[j] * samples_per_channel_[j] ) ; k++)
00167     {
00168       data_.push_back(*data_ptr);
00169       data_ptr++;
00170     }
00171 }
00172 
00173 //-----------------------------------------------------------------------------
00174 DataPacket3Impl::~DataPacket3Impl()
00175 {
00176   for(std::map<boost::uint32_t, RawMem3*>::iterator it(raw_map_.begin());
00177       it != raw_map_.end(); it++)
00178   {
00179     delete(it->second);
00180     it->second = 0;
00181   }
00182 }
00183 
00184 
00185 //-----------------------------------------------------------------------------
00186 
00187 void DataPacket3Impl::reset()
00188 {
00189   #ifdef DEBUG
00190     cout << "DataPacket: reset" << endl;
00191   #endif
00192 
00193   flags_ = 0;
00194   connection_packet_nr_ = 0;
00195   nr_of_signal_types_ = 0;
00196   samples_per_channel_.clear();
00197   nr_channels_.clear();
00198   setTimestamp();
00199   data_.clear();
00200   for(map<uint32_t, RawMem3*>::iterator it(raw_map_.begin()); it != raw_map_.end(); it++)
00201     if(it->second)
00202     {
00203       delete(it->second);
00204       it->second = 0;
00205     }
00206   raw_map_.clear();
00207 }
00208 
00209 //-----------------------------------------------------------------------------
00210 
00211 void DataPacket3Impl::incPacketID()
00212 {
00213   packet_id_++;
00214 }
00215 
00216 //-----------------------------------------------------------------------------
00217 
00218 void DataPacket3Impl::setPacketID(boost::uint64_t nr)
00219 {
00220   packet_id_ = nr;
00221 }
00222 
00223 //-----------------------------------------------------------------------------
00224 
00225 void DataPacket3Impl::insertDataBlock(vector<double> v, uint32_t signal_flag, uint16_t blocks, bool prepend)
00226 {
00227 
00228   if(!flagsOK())
00229     throw(std::logic_error("DataPacket3::insertDataBlock() -- Flags differ from Amount of Signals in DataPacket!"));
00230 
00231   if(calcNrOfSignalTypes(signal_flag) != 1)
00232     throw(std::logic_error("DataPacket3::insertDataBlock() -- Trying to insert more or less than 1 signal type at the same time!"));
00233 
00234   if(hasFlag(signal_flag))
00235   {
00236     if(prepend)
00237       prependDataBlock(v, signal_flag, blocks);
00238     else
00239       appendDataBlock(v, signal_flag, blocks);
00240 
00241     return;
00242     /*     throw(std::logic_error("DataPacket3::insertDataBlock() -- Error ... Flag already defined, \
00243         equal signal types simultaneously from different sources not supported at the moment!")); */
00244   }
00245 
00246   uint32_t pos = getDataPos(signal_flag);
00247 
00248   setFlag(signal_flag);
00249 
00250   vector<double>::iterator it_data(data_.begin() + getOffset(pos));
00251   data_.insert(it_data,v.begin(),v.end());
00252 
00253   vector<uint16_t>::iterator it_nr(samples_per_channel_.begin() + pos );
00254   samples_per_channel_.insert(it_nr, blocks);
00255 
00256   it_nr = nr_channels_.begin() + pos;
00257   nr_channels_.insert(it_nr, v.size()/blocks);
00258 
00259   nr_of_signal_types_++;
00260 }
00261 
00262 //-----------------------------------------------------------------------------
00263 
00264 void DataPacket3Impl::appendDataBlock(vector<double> &v, uint32_t signal_flag, uint16_t blocks)
00265 {
00266   if(getNrSamplesPerChannel(signal_flag) != blocks)
00267     throw(std::logic_error("DataPacket3::appendDataBlock() -- Blocksize of appended signal does not \
00268           match the stored one -- check your settings!"));
00269 
00270   uint32_t pos = getDataPos(signal_flag);
00271 
00272   vector<double>::iterator it_data(data_.begin() + getOffset(pos) +
00273                                    (nr_channels_[pos] * samples_per_channel_[pos] ) );
00274   data_.insert(it_data,v.begin(),v.end());
00275 
00276   nr_channels_[pos] += v.size()/blocks;
00277 }
00278 
00279 //-----------------------------------------------------------------------------
00280 
00281 void DataPacket3Impl::prependDataBlock(vector<double> &v, uint32_t signal_flag, uint16_t blocks)
00282 {
00283   if(getNrSamplesPerChannel(signal_flag) != blocks)
00284     throw(std::logic_error("DataPacket3::appendDataBlock() -- Blocksize of appended signal does not \
00285           match the stored one -- check your settings!"));
00286 
00287   uint32_t pos = getDataPos(signal_flag);
00288 
00289   vector<double>::iterator it_data(data_.begin() + getOffset(pos));
00290   data_.insert(it_data,v.begin(),v.end());
00291 
00292   nr_channels_[pos] += v.size()/blocks;
00293 }
00294 
00295 //-----------------------------------------------------------------------------
00296 
00297 void DataPacket3Impl::setConnectionPacketNr(boost::uint64_t nr)
00298 {
00299   connection_packet_nr_ = nr;
00300 }
00301 
00302 //--------------------------------------------------------------------
00303 
00304 uint64_t DataPacket3Impl::getConnectionPacketNr()
00305 {
00306   return(connection_packet_nr_);
00307 }
00308 
00309 //-------------------------------------------------------------------
00310 
00311 void DataPacket3Impl::setTimestamp()
00312 {
00313     timestamp_ =  Clock::instance ().getMicroSeconds ();
00314 }
00315 
00316 //-----------------------------------------------------------------------------
00317 
00318 bool DataPacket3Impl::hasFlag(boost::uint32_t f)
00319 {
00320   return( (f & flags_) == f);
00321 }
00322 
00323 //-----------------------------------------------------------------------------
00324 
00325 boost::uint32_t DataPacket3Impl::getFlags()
00326 {
00327   if(!flagsOK())
00328     throw(std::logic_error("DataPacket3::getFlags() -- Flags differ from Amount of Signals in DataPacket!"));
00329   return(flags_);
00330 }
00331 
00332 //-----------------------------------------------------------------------------
00333 
00334 boost::uint64_t DataPacket3Impl::getPacketID()
00335 {
00336   return(packet_id_);
00337 }
00338 
00339 //-----------------------------------------------------------------------------
00340 
00341 boost::uint16_t DataPacket3Impl::getNrOfSignalTypes()
00342 {
00343   if(!flagsOK())
00344     throw(std::logic_error("DataPacket3::getNrOfSignalTypes() -- Flags differ from Amount of Signals in DataPacket!"));
00345 
00346   return(nr_of_signal_types_);
00347 }
00348 
00349 //-----------------------------------------------------------------------------
00350 
00351 std::vector<boost::uint16_t> DataPacket3Impl::getNrOfSamples()
00352 {
00353   std::vector<boost::uint16_t> vec(samples_per_channel_.size());
00354 
00355   for(unsigned int n = 0; n < samples_per_channel_.size(); n++ )
00356     vec[n] = samples_per_channel_[n] * nr_channels_[n];
00357 
00358   return(vec);
00359 }
00360 
00361 //-----------------------------------------------------------------------------
00362 
00363 vector<boost::uint16_t> DataPacket3Impl::getNrSamplesPerChannel()
00364 {
00365   return(samples_per_channel_);
00366 }
00367 
00368 //-----------------------------------------------------------------------------
00369 
00370 vector<uint16_t> DataPacket3Impl::getNrOfChannels()
00371 {
00372   return(nr_channels_);
00373 }
00374 
00375 //-----------------------------------------------------------------------------
00376 
00377 const vector<double>& DataPacket3Impl::getData()
00378 {
00379   if(!flagsOK())
00380     throw(std::logic_error("DataPacket3::getData() -- Flags differ from Amount of Signals in DataPacket!"));
00381   return(data_);
00382 }
00383 
00384 //-----------------------------------------------------------------------------
00385 
00386 vector<double> DataPacket3Impl::getSingleDataBlock(boost::uint32_t flag)
00387 {
00388   if(!flagsOK())
00389     throw(std::logic_error("DataPacket3::getSingleDataBlock() -- Flags differ from Amount of Signals in DataPacket!"));
00390 
00391   if(!hasFlag(flag))
00392     throw(std::invalid_argument("DataPacket3::getSingleDataBlock() -- Error ... Flag not set, unable to get Data!"));
00393 
00394   uint32_t position = getDataPos(flag);
00395 
00396   vector<double> v(data_.begin() + getOffset(position),  \
00397               data_.begin() + getOffset(position) + \
00398               ( nr_channels_[position] * samples_per_channel_[position] ) );
00399   return(v);
00400 }
00401 
00402 //-----------------------------------------------------------------------------
00403 
00404 boost::uint16_t DataPacket3Impl::getNrOfSamples(boost::uint32_t flag)
00405 {
00406   if(!flagsOK())
00407     throw(std::logic_error("DataPacket3::getNrOfValues() -- Flags differ from Amount of Signals in DataPacket!"));
00408 
00409   if(!hasFlag(flag))
00410     return(0);
00411 
00412   return( getNrOfChannels(flag) * getNrSamplesPerChannel(flag) );
00413 }
00414 
00415 //-----------------------------------------------------------------------------
00416 
00417 boost::uint16_t DataPacket3Impl::getNrOfChannels(boost::uint32_t flag)
00418 {
00419   if(!flagsOK())
00420     throw(std::logic_error("DataPacket3::getNrOfChannels() -- Flags differ from Amount of Signals in DataPacket!"));
00421 
00422   if(!hasFlag(flag))
00423     return(0);
00424 //    throw(std::invalid_argument("DataPacket3::getNrOfChannels() -- Error ... Flag not set, unable to get Data!"));
00425 
00426   return(nr_channels_[getDataPos(flag)]);
00427 }
00428 
00429 //-----------------------------------------------------------------------------
00430 
00431 boost::uint16_t DataPacket3Impl::getNrSamplesPerChannel(boost::uint32_t flag)
00432 {
00433   if(!flagsOK())
00434     throw(std::logic_error("DataPacket3::getSamplesPerChannel() -- Flags differ from Amount of Signals in DataPacket!"));
00435 
00436   if(!hasFlag(flag))
00437     return(0);
00438 //    throw(std::invalid_argument("DataPacket3::getSamplesPerChannel() -- Error ... Flag not set, unable to get Data!"));
00439 
00440   return(samples_per_channel_[getDataPos(flag)]);
00441 }
00442 
00443 //-----------------------------------------------------------------------------
00444 
00445 boost::uint16_t DataPacket3Impl::calcNrOfSignalTypes(boost::uint32_t f)
00446 {
00447   uint16_t count = 0;
00448   uint32_t shift = 1;
00449 
00450   for(unsigned int n = 0; n < sizeof(f) *8; n++)
00451     count += (((shift << n) & f) >= 1) ;
00452 
00453   return(count);
00454 }
00455 
00456 //-----------------------------------------------------------------------------
00457 
00458 bool DataPacket3Impl::flagsOK()
00459 {
00460   if(calcNrOfSignalTypes(flags_) != nr_of_signal_types_)
00461     return(false);
00462 
00463   return(true);
00464 }
00465 
00466 //-----------------------------------------------------------------------------
00467 
00468 void DataPacket3Impl::setFlag(boost::uint32_t f)
00469 {
00470   flags_ |= f;
00471 }
00472 
00473 //-----------------------------------------------------------------------------
00474 
00475 boost::uint32_t DataPacket3Impl::getDataPos(boost::uint32_t flag)
00476 {
00477   if(flag > flags_)
00478     return(nr_of_signal_types_);
00479 
00480   uint32_t pos = 0;
00481   uint32_t shift = 1;
00482 
00483   while(shift < flag)
00484   {
00485     if(flags_ & shift)
00486       pos++;
00487     shift <<= 1;
00488   }
00489 
00490   return(pos);
00491 }
00492 
00493 //-----------------------------------------------------------------------------
00494 
00495 boost::uint32_t DataPacket3Impl::getOffset(boost::uint32_t pos)
00496 {
00497   uint32_t offset = 0;
00498 
00499   for(uint32_t n = 0; n < pos; n++)
00500     offset += (nr_channels_[n] * samples_per_channel_[n]);
00501   return(offset);
00502 }
00503 
00504 //-----------------------------------------------------------------------------
00505 
00506 boost::uint32_t DataPacket3Impl::getRawMemorySize()
00507 {
00508   map<uint32_t, RawMem3*>::iterator it(raw_map_.find(flags_));
00509 
00510   if(it == raw_map_.end()) return 0;
00511 
00512   return it->second->size();
00513 }
00514 
00515 //-----------------------------------------------------------------------------
00516 
00517 void* DataPacket3Impl::getRaw()
00518 {
00519   map<uint32_t, RawMem3*>::iterator it(raw_map_.find(flags_));
00520   RawMem3* r;
00521 
00522   if(it == raw_map_.end())
00523   {
00524     if(connection_packet_nr_ == 0)
00525       connection_packet_nr_ = packet_id_;
00526 
00527     r = new RawMem3(version_, flags_, packet_id_, connection_packet_nr_, \
00528                     timestamp_, nr_channels_, samples_per_channel_, data_);
00529 
00530     raw_map_.insert(make_pair(flags_,r));
00531   }
00532   else
00533     r = it->second;
00534 
00535   return(r->getMemPtr());
00536 }
00537 
00538 //-----------------------------------------------------------------------------
00539 
00540 boost::uint32_t DataPacket3Impl::getRequiredRawMemorySize()
00541 {
00542   uint32_t size_ = sizeof(version_) + sizeof(size_)\
00543                   + sizeof(flags_) + sizeof(packet_id_) + sizeof(connection_packet_nr_) \
00544                   + sizeof(timestamp_) \
00545                   + samples_per_channel_.size() * sizeof(uint16_t) \
00546                   + nr_channels_.size() * sizeof(uint16_t) \
00547                   + data_.size() * sizeof(float);  // FIXME  ...  hardcoded sizeof() !!!!
00548   return(size_);
00549 }
00550 
00551 //-----------------------------------------------------------------------------
00552 
00553 boost::uint32_t DataPacket3Impl::getRequiredRawMemorySize(void* mem, boost::uint32_t ba)
00554 {
00555   if(ba < sizeof(uint8_t) + sizeof(uint32_t) )
00556     return(0);
00557 
00558   uint8_t* version_ptr = reinterpret_cast<uint8_t*>(mem);
00559   uint8_t version = *version_ptr;
00560 
00561   if(version != CURRENT_DATA_PACKET_VERSION)
00562     throw(std::runtime_error("Error -- DataPacket3Impl::getRequiredRawMemorySize: Wrong packet version!"));
00563 
00564   uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(++version_ptr);
00565 
00566   return(*ui32_ptr);
00567 
00568 
00569 }
00570 
00571 } // Namespace tobiss
00572 
00573 //-----------------------------------------------------------------------------
 All Data Structures Files Functions Variables Typedefs Enumerations