|
TOBI Interface A
0.1
|
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 //-----------------------------------------------------------------------------