TOBI Interface A  0.1
/home/breidi/Dropbox/libtia/src/tia/datapacket/data_packet_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 #include "tia-private/datapacket/data_packet_impl.h"
00043 #include "tia-private/datapacket/raw_mem.h"
00044 
00045 namespace tia
00046 {
00047 
00048 using boost::uint16_t;
00049 using boost::uint32_t;
00050 using boost::uint64_t;
00051 using boost::int32_t;
00052 
00053 using std::vector;
00054 using std::map;
00055 using std::string;
00056 using std::stringstream;
00057 using std::make_pair;
00058 
00059 uint64_t  DataPacketImpl::sample_nr_ = 0;
00060 
00061 //-----------------------------------------------------------------------------
00062 void DataPacketImpl::reset(void* mem)
00063 {
00064   #ifdef DEBUG
00065       cout << "DataPacket: RAW Constructor" << endl;
00066   #endif
00067 
00068   flags_ = 0;
00069   packet_nr_ = 0;
00070   nr_of_signal_types_ = 0;
00071 
00072   uint32_t* f = reinterpret_cast<uint32_t*>(mem);
00073 
00074   if(PACKETCODE != ( *f & PACKETCODE ))
00075   {
00076     string ex_str("DataPacket(void* mem): ERROR -- PacketCode doesn't match!");
00077     throw(std::runtime_error(ex_str));
00078   }
00079 
00080   if(PACKETVERSION != ( *f & PACKETVERSION ))
00081   {
00082     stringstream ss (stringstream::in | stringstream::out);
00083     string ex_str("DataPacket(void* mem): ERROR -- Packet versions don't match!");
00084     ex_str = ex_str + " -Raw packet version: ";
00085     ss << ( (*f >> (8*sizeof(flags_)-BYTES4SIGNALFLAGS)) );
00086     ss >> ex_str;
00087 
00088     ss << ( (PACKETVERSION >> (8*sizeof(flags_)-BYTES4SIGNALFLAGS)) );
00089     ex_str = ex_str + " -Needed packet version: ";
00090     ss >> ex_str;
00091     throw(std::invalid_argument(ex_str));
00092   }
00093 
00094   flags_ = (*f & (~PACKETVERSION) & (~PACKETCODE) );
00095 
00096   nr_of_signal_types_ = calcNrOfSignalTypes(flags_);
00097 
00098   uint64_t* ui64_ptr = reinterpret_cast<uint64_t*>(++f);
00099   sample_nr_ = *ui64_ptr;
00100   ui64_ptr++;
00101   packet_nr_ = *ui64_ptr;
00102 
00103   boost::posix_time::ptime* ptime_ptr
00104     = reinterpret_cast<boost::posix_time::ptime*>(++ui64_ptr);
00105   timestamp_ = *ptime_ptr;
00106 
00107   uint16_t* ui16_ptr = reinterpret_cast<uint16_t*>(++ptime_ptr);
00108   for(unsigned int n = 0; n < nr_of_signal_types_; n++)
00109   {
00110     nr_values_.push_back(*ui16_ptr);
00111     ui16_ptr++;
00112   }
00113 
00114   for(unsigned int n = 0; n < nr_of_signal_types_; n++)
00115   {
00116     nr_blocks_.push_back(*ui16_ptr);
00117     ui16_ptr++;
00118   }
00119 
00120   float* data_ptr = reinterpret_cast<float*>(ui16_ptr);
00121   for(unsigned int j = 0; j < nr_values_.size(); j++)
00122     for(unsigned int k = 0; k < nr_values_[j]; k++)
00123     {
00124       data_.push_back(*data_ptr);
00125       data_ptr++;
00126     }
00127 }
00128 
00129 //-----------------------------------------------------------------------------
00130 DataPacketImpl::~DataPacketImpl()
00131 {
00132   for(std::map<boost::uint32_t, RawMem*>::iterator it(raw_map_.begin());
00133     it != raw_map_.end(); it++)
00134   {
00135     delete(it->second);
00136     it->second = 0;
00137   }
00138 }
00139 
00140 
00141 //-----------------------------------------------------------------------------
00142 
00143 void DataPacketImpl::reset()
00144 {
00145   #ifdef DEBUG
00146     cout << "DataPacket: reset" << endl;
00147   #endif
00148 
00149   flags_ = 0;
00150   packet_nr_ = 0;
00151   nr_of_signal_types_ = 0;
00152   nr_blocks_.clear();
00153   nr_values_.clear();
00154   setTimestamp();
00155   data_.clear();
00156   for(map<uint32_t, RawMem*>::iterator it(raw_map_.begin()); it != raw_map_.end(); it++)
00157     if(it->second)
00158     {
00159       delete(it->second);
00160       it->second = 0;
00161     }
00162   raw_map_.clear();
00163 }
00164 
00165 //-----------------------------------------------------------------------------
00166 
00167 void DataPacketImpl::incSampleNr()
00168 {
00169   sample_nr_++;
00170 }
00171 
00172 //-----------------------------------------------------------------------------
00173 
00174 void DataPacketImpl::insertDataBlock(vector<double> v, uint32_t signal_flag, uint16_t blocks, bool prepend)
00175 {
00176 
00177   if(!flagsOK())
00178     throw(std::logic_error("DataPacket::insertDataBlock() -- Flags differ from Amount of Signals in DataPacket!"));
00179 
00180   if(calcNrOfSignalTypes(signal_flag) >1)
00181     throw(std::logic_error("DataPacket::insertDataBlock() -- Trying to insert more than 1 signal type at the same time!"));
00182 
00183   if(hasFlag(signal_flag))
00184   {
00185     if(prepend)
00186       prependDataBlock(v, signal_flag, blocks);
00187     else
00188       appendDataBlock(v, signal_flag, blocks);
00189 
00190     return;
00191     /*     throw(std::logic_error("DataPacket::insertDataBlock() -- Error ... Flag already defined, \
00192         equal signal types simultaneously from different sources not supported at the moment!")); */
00193   }
00194 
00195   uint32_t pos = getDataPos(signal_flag);
00196 
00197   setFlag(signal_flag);
00198 
00199   vector<double>::iterator it_data(data_.begin() + getOffset(pos));
00200   data_.insert(it_data,v.begin(),v.end());
00201 
00202   vector<uint16_t>::iterator it_nr(nr_blocks_.begin() + pos );
00203   nr_blocks_.insert(it_nr, blocks);
00204 
00205   it_nr = nr_values_.begin() + pos;
00206   nr_values_.insert(it_nr, v.size());
00207 
00208   nr_of_signal_types_++;
00209 }
00210 
00211 //-----------------------------------------------------------------------------
00212 
00213 void DataPacketImpl::appendDataBlock(vector<double> &v, uint32_t signal_flag, uint16_t blocks)
00214 {
00215   if(getNrOfBlocks(signal_flag) != blocks)
00216     throw(std::logic_error("DataPacket::appendDataBlock() -- Blocksize of appended signal does not \
00217           match the stored one -- check your settings!"));
00218 
00219   uint32_t pos = getDataPos(signal_flag);
00220 
00221   vector<double>::iterator it_data(data_.begin() + getOffset(pos) + nr_values_[pos]);
00222   data_.insert(it_data,v.begin(),v.end());
00223 
00224   nr_values_[pos] += v.size();
00225 }
00226 
00227 //-----------------------------------------------------------------------------
00228 
00229 void DataPacketImpl::prependDataBlock(vector<double> &v, uint32_t signal_flag, uint16_t blocks)
00230 {
00231   if(getNrOfBlocks(signal_flag) != blocks)
00232     throw(std::logic_error("DataPacket::appendDataBlock() -- Blocksize of appended signal does not \
00233           match the stored one -- check your settings!"));
00234 
00235   uint32_t pos = getDataPos(signal_flag);
00236 
00237   vector<double>::iterator it_data(data_.begin() + getOffset(pos));
00238   data_.insert(it_data,v.begin(),v.end());
00239 
00240   nr_values_[pos] += v.size();
00241 }
00242 
00243 //-----------------------------------------------------------------------------
00244 
00245 void DataPacketImpl::setPacketNr(uint64_t nr)
00246 {
00247   packet_nr_ = nr;
00248 }
00249 
00250 //-----------------------------------------------------------------------------
00251 
00252 uint64_t DataPacketImpl::getPacketNr()
00253 {
00254   return(packet_nr_);
00255 }
00256 
00257 //-----------------------------------------------------------------------------
00258 
00259 void DataPacketImpl::setBoostPosixTimestamp()
00260 {
00261   timestamp_ =  boost::posix_time::microsec_clock::local_time();
00262 }
00263 
00264 //-----------------------------------------------------------------------------
00265 
00266 bool DataPacketImpl::hasFlag(boost::uint32_t f)
00267 {
00268   return( (f & flags_) == f);
00269 }
00270 
00271 //-----------------------------------------------------------------------------
00272 
00273 boost::uint32_t DataPacketImpl::getFlags()
00274 {
00275   if(!flagsOK())
00276     throw(std::logic_error("DataPacket::getFlags() -- Flags differ from Amount of Signals in DataPacket!"));
00277   return(flags_ | PACKETVERSION);
00278 }
00279 
00280 //-----------------------------------------------------------------------------
00281 
00282 boost::uint64_t DataPacketImpl::getSampleNr()
00283 {
00284   return(sample_nr_);
00285 }
00286 
00287 //-----------------------------------------------------------------------------
00288 
00289 boost::uint16_t DataPacketImpl::getNrOfSignalTypes()
00290 {
00291   if(!flagsOK())
00292     throw(std::logic_error("DataPacket::getNrOfSignalTypes() -- Flags differ from Amount of Signals in DataPacket!"));
00293 
00294   return(nr_of_signal_types_);
00295 }
00296 
00297 //-----------------------------------------------------------------------------
00298 
00299 vector<boost::uint16_t> DataPacketImpl::getNrOfBlocks()
00300 {
00301   return(nr_blocks_);
00302 }
00303 
00304 //-----------------------------------------------------------------------------
00305 
00306 vector<uint16_t> DataPacketImpl::getNrOfSamples()
00307 {
00308   return(nr_values_);
00309 }
00310 
00311 //-----------------------------------------------------------------------------
00312 
00313 const vector<double>& DataPacketImpl::getData()
00314 {
00315   if(!flagsOK())
00316     throw(std::logic_error("DataPacket::getData() -- Flags differ from Amount of Signals in DataPacket!"));
00317   return(data_);
00318 }
00319 
00320 //-----------------------------------------------------------------------------
00321 
00322 vector<double> DataPacketImpl::getSingleDataBlock(boost::uint32_t flag)
00323 {
00324   if(!flagsOK())
00325     throw(std::logic_error("DataPacket::getSingleDataBlock() -- Flags differ from Amount of Signals in DataPacket!"));
00326 
00327   if(!hasFlag(flag))
00328     throw(std::invalid_argument("DataPacket::getSingleDataBlock() -- Error ... Flag not set, unable to get Data!"));
00329 
00330   uint32_t position = getDataPos(flag);
00331 
00332   vector<double> v(data_.begin()    + getOffset(position),  \
00333               data_.begin() + getOffset(position) + nr_values_.at(position));
00334   return(v);
00335 }
00336 
00337 //-----------------------------------------------------------------------------
00338 
00339 boost::uint16_t DataPacketImpl::getNrOfSamples(boost::uint32_t flag)
00340 {
00341   if(!flagsOK())
00342     throw(std::logic_error("DataPacket::getNrOfValues() -- Flags differ from Amount of Signals in DataPacket!"));
00343 
00344   if(!hasFlag(flag))
00345     throw(std::invalid_argument("DataPacket::getNrOfValues() -- Error ... Flag not set, unable to get Data!"));
00346 
00347   return(nr_values_[getDataPos(flag)]);
00348 }
00349 
00350 //-----------------------------------------------------------------------------
00351 
00352 boost::uint16_t DataPacketImpl::getNrOfBlocks(boost::uint32_t flag)
00353 {
00354   if(!flagsOK())
00355     throw(std::logic_error("DataPacket::getNrOfBlocks() -- Flags differ from Amount of Signals in DataPacket!"));
00356 
00357   if(!hasFlag(flag))
00358     throw(std::invalid_argument("DataPacket::getNrOfBlocks() -- Error ... Flag not set, unable to get Data!"));
00359 
00360   return(nr_blocks_[getDataPos(flag)]);
00361 }
00362 
00363 //-----------------------------------------------------------------------------
00364 
00365 boost::uint16_t DataPacketImpl::calcNrOfSignalTypes(boost::uint32_t f)
00366 {
00367   uint16_t count = 0;
00368   uint32_t shift = 1;
00369   for(unsigned int n = 0; n < (sizeof(f)*(BYTES4SIGNALFLAGS*2)); n++)
00370     count += (((shift << n) & f) >= 1) ;
00371 
00372   return(count);
00373 }
00374 
00375 //-----------------------------------------------------------------------------
00376 
00377 bool DataPacketImpl::flagsOK()
00378 {
00379   if(calcNrOfSignalTypes(flags_) != nr_of_signal_types_)
00380     return(false);
00381 
00382   return(true);
00383 }
00384 
00385 //-----------------------------------------------------------------------------
00386 
00387 void DataPacketImpl::setFlag(boost::uint32_t f)
00388 {
00389   flags_ |= f;
00390 }
00391 
00392 //-----------------------------------------------------------------------------
00393 
00394 boost::uint32_t DataPacketImpl::getDataPos(boost::uint32_t flag)
00395 {
00396   if(flag > flags_)
00397     return(nr_of_signal_types_);
00398 
00399   uint32_t pos = 0;
00400   uint32_t shift = 1;
00401 
00402   while(shift < flag)
00403   {
00404     if(flags_ & shift)
00405       pos++;
00406     shift <<= 1;
00407   }
00408 
00409   return(pos);
00410 }
00411 
00412 //-----------------------------------------------------------------------------
00413 
00414 boost::uint32_t DataPacketImpl::getOffset(boost::uint32_t pos)
00415 {
00416   uint32_t offset = 0;
00417 
00418   for(uint32_t n = 0; n<pos; n++)
00419     offset += nr_values_[n];
00420   return(offset);
00421 }
00422 
00423 //-----------------------------------------------------------------------------
00424 
00425 boost::uint32_t DataPacketImpl::getRawMemorySize()
00426 {
00427   map<uint32_t, RawMem*>::iterator it(raw_map_.find(flags_));
00428 
00429   if(it == raw_map_.end()) return 0;
00430 
00431   return it->second->size();
00432 }
00433 
00434 //-----------------------------------------------------------------------------
00435 
00436 void* DataPacketImpl::getRaw()
00437 {
00438   map<uint32_t, RawMem*>::iterator it(raw_map_.find(flags_));
00439   RawMem* r;
00440 
00441   if(it == raw_map_.end())
00442   {
00443     if(packet_nr_ == 0)
00444       packet_nr_ = sample_nr_;
00445 
00446     r = new RawMem((flags_ | PACKETVERSION | PACKETCODE) , sample_nr_, packet_nr_, \
00447                     timestamp_, nr_values_, nr_blocks_, data_);
00448 
00449     raw_map_.insert(make_pair(flags_,r));
00450   }
00451   else
00452     r = it->second;
00453 
00454   return(r->getMemPtr());
00455 }
00456 
00457 //-----------------------------------------------------------------------------
00458 
00459 boost::uint32_t DataPacketImpl::getRequiredRawMemorySize()
00460 {
00461   uint32_t size = sizeof(flags_) + sizeof(sample_nr_) + sizeof(packet_nr_) \
00462     + sizeof(timestamp_) \
00463     + nr_blocks_.size() * sizeof(nr_blocks_[0]) \
00464     + nr_values_.size() * sizeof(nr_values_[0]) \
00465     + data_.size() * sizeof(float);  // FIXME  ...  hardcoded sizeof() !!!!
00466   return(size);
00467 }
00468 
00469 //-----------------------------------------------------------------------------
00470 
00471 boost::uint32_t DataPacketImpl::getRequiredRawMemorySize(void* mem, boost::uint32_t ba)
00472 {
00473   uint32_t bytes_available = 0;
00474 
00475   if(ba <= 0)
00476     return(0);
00477   else
00478     bytes_available = ba;
00479 
00480   uint32_t* f = reinterpret_cast<uint32_t*>(mem);
00481 
00482   if(PACKETCODE != ( *f & PACKETCODE ))
00483   {
00484     string ex_str("DataPacket(void* mem, int32_t ba): ERROR -- PacketCode doesn't match!");
00485     throw(std::runtime_error(ex_str));
00486   }
00487 
00488   if(PACKETVERSION != ( *f & PACKETVERSION ))
00489   {
00490     stringstream ss (stringstream::in | stringstream::out);
00491     string ex_str("DataPacket(void* mem, int32_t ba): ERROR -- Packet versions don't match!");
00492     ex_str = ex_str + " -Raw packet version: ";
00493     ss << ( (*f >> (8*sizeof(flags_)-BYTES4SIGNALFLAGS)) );
00494     ss >> ex_str;
00495 
00496     ss << ( (PACKETVERSION >> (8*sizeof(flags_)-BYTES4SIGNALFLAGS)) );
00497     ex_str = ex_str + " -Needed packet version: ";
00498     ss >> ex_str;
00499     throw(std::invalid_argument(ex_str));
00500   }
00501 
00502   vector<uint16_t>  nr_blocks;
00503   vector<uint16_t>  nr_values;
00504 
00505   uint32_t flags  = (*f & (~PACKETVERSION) & (~PACKETCODE) );
00506 
00507   uint32_t nr_of_signal_types = calcNrOfSignalTypes(flags);
00508 
00509   uint32_t size = sizeof(flags) + sizeof(sample_nr_) \
00510                   + sizeof(packet_nr_) + sizeof(timestamp_);
00511 
00512   if(size > bytes_available)
00513     return(0);
00514 
00515   uint64_t* ui64_ptr = reinterpret_cast<uint64_t*>(++f);
00516   ui64_ptr++;
00517   boost::posix_time::ptime* ptime_ptr
00518     = reinterpret_cast<boost::posix_time::ptime*>(++ui64_ptr);
00519 
00520   uint16_t* ui16_ptr = reinterpret_cast<uint16_t*>(++ptime_ptr);
00521   for(unsigned int n = 0; n < nr_of_signal_types; n++)
00522   {
00523     size += sizeof(uint16_t);
00524     if(size > bytes_available)
00525       return(0);
00526 
00527     nr_values.push_back(*ui16_ptr);
00528     ui16_ptr++;
00529   }
00530 
00531   for(unsigned int n = 0; n < nr_of_signal_types; n++)
00532   {
00533     size += sizeof(uint16_t);
00534     if(size > bytes_available)
00535       return(0);
00536 
00537     nr_blocks.push_back(*ui16_ptr);
00538     ui16_ptr++;
00539   }
00540 
00541   for(unsigned int j = 0; j < nr_values.size(); j++)
00542     for(unsigned int k = 0; k < nr_values[j]; k++)
00543       size +=  sizeof(float);
00544 
00545     return(size);
00546 }
00547 
00548 } // Namespace tobiss
00549 
00550 //-----------------------------------------------------------------------------
 All Data Structures Files Functions Variables Typedefs Enumerations