RawDataBlockV0.cpp
Go to the documentation of this file.
1 #include "DAQDataFormats/RawDataBlockV0.h"
2 #include "DAQDataFormats/RawDataBlock.h"
3 #include "DAQDataFormats/RawMilliSliceHeader.h"
4 #include "DAQDataFormats/DataFormatException.h"
5 
6 #include <sys/time.h> // gettimeofday
7 #include <stdarg.h> // va_start
8 #include <stdio.h> // printf
9 
10 #include <boost/lexical_cast.hpp>
11 #include <boost/format.hpp>
12 
13 /// It is requred to
14 /// 1. include DAQDataFormats/DataFormatFirst.inc
15 /// 2. define CURRENT_CLASS
16 /// 3. define CURRENT_CLASS_VERSION for version of the class
17 /// OR define LAST_CLASS_VERSION for the main structure of the class
18 /// 4. (optional) define CURRENT_FIELDS_SUB_NAMESPACE
19 /// 5. include DAQDataFormats/DataFormatLast.inc
20 /// before the declaration of the DataFormat version class in the header.
21 #include "DAQDataFormats/DataFormatFirst.inc"
22 #define CURRENT_CLASS RawDataBlock
23 #define CURRENT_CLASS_VERSION 0
24 #define CURRENT_FIELDS_SUB_NAMESPACE rawnano
25 #include "DAQDataFormats/DataFormatLast.inc"
26 
27 namespace daqdataformats{
28 namespace VERSION_NAMESPACE{
29 //------------------------------------------------------------------------------
30 // Default constructor
31 RawDataBlock::RawDataBlock(const version_t version, const uint32_t tlvl):
32  RawDAQData(version, true, (sizeofdata_t) &RawDataBlock::getPredeterminedSize)
33  ,_function_readDataFromFileDescriptor(&RawDataBlock::readDataUnknownVersion)
35  ,ZEROOUT_FUNCTION(setFloatingMicroBlockToBufferSource)
37  ,ZEROOUT_FUNCTION(softclear)
38  ,ZEROOUT_FUNCTION(getVersion)
39  ,ZEROOUT_FUNCTION(getMarker)
40  ,ZEROOUT_FUNCTION(getTrigNumLo)
41  ,ZEROOUT_FUNCTION(getTrigNumHi)
42  ,ZEROOUT_FUNCTION(getTrigNum)
43  ,ZEROOUT_FUNCTION(getNumMicroBlocks)
44  ,ZEROOUT_FUNCTION(getBuffId)
45  ,ZEROOUT_FUNCTION(getDataSize)
46  ,ZEROOUT_FUNCTION(getMonteCarloFlag)
47  ,ZEROOUT_FUNCTION(isCRCCalculationUsed)
48  ,ZEROOUT_FUNCTION(isConnectionInitialization)
49  ,ZEROOUT_FUNCTION(isCloseConnection)
50  ,ZEROOUT_FUNCTION(isMissingData)
51  ,ZEROOUT_FUNCTION(setFloatingMicroBlock)
52  ,ZEROOUT_FUNCTION(getCRC)
53  ,ZEROOUT_FUNCTION(setTrigNumLo)
54  ,ZEROOUT_FUNCTION(setTrigNumHi)
55  ,ZEROOUT_FUNCTION(setTrigNum)
56  ,ZEROOUT_FUNCTION(setBuffId)
57  ,ZEROOUT_FUNCTION(setConnectionInitialization)
58  ,ZEROOUT_FUNCTION(setMonteCarloFlag)
59  ,ZEROOUT_FUNCTION(setCloseConnection)
60  ,ZEROOUT_FUNCTION(setMissingData)
61  ,ZEROOUT_FUNCTION(addMicroBlock1)
62  ,ZEROOUT_FUNCTION(addMicroBlock2)
63  ,ZEROOUT_FUNCTION(addMicroBlock3)
64  ,ZEROOUT_FUNCTION(addMicroBlock4)
65  ,_Header (NULL)
66  ,_FloatingMicroBlock (NULL)
67  ,_FloatingMicroBlockNumber (-1)
68  ,_microBlockVersion (rawdaqdataformat::DAQDATAFORMAT_UNKNOWN_VERSION)
69  ,_tlvl (tlvl)
70  ,_fd_read_bytes (0)
71 {}
72 //------------------------------------------------------------------------------
74  RawDAQData(copyin)
75  ,DEEPCOPY_FUNCTION(readDataFromFileDescriptor)
77  ,DEEPCOPY_FUNCTION(setFloatingMicroBlockToBufferSource)
79  ,DEEPCOPY_FUNCTION(softclear)
80  ,DEEPCOPY_FUNCTION(getVersion)
81  ,DEEPCOPY_FUNCTION(getMarker)
82  ,DEEPCOPY_FUNCTION(getTrigNumLo)
83  ,DEEPCOPY_FUNCTION(getTrigNumHi)
84  ,DEEPCOPY_FUNCTION(getTrigNum)
85  ,DEEPCOPY_FUNCTION(getNumMicroBlocks)
86  ,DEEPCOPY_FUNCTION(getBuffId)
87  ,DEEPCOPY_FUNCTION(getDataSize)
88  ,DEEPCOPY_FUNCTION(getMonteCarloFlag)
89  ,DEEPCOPY_FUNCTION(isCRCCalculationUsed)
90  ,DEEPCOPY_FUNCTION(isConnectionInitialization)
91  ,DEEPCOPY_FUNCTION(isCloseConnection)
92  ,DEEPCOPY_FUNCTION(isMissingData)
93  ,DEEPCOPY_FUNCTION(setFloatingMicroBlock)
94  ,DEEPCOPY_FUNCTION(getCRC)
95  ,DEEPCOPY_FUNCTION(setTrigNumLo)
96  ,DEEPCOPY_FUNCTION(setTrigNumHi)
97  ,DEEPCOPY_FUNCTION(setTrigNum)
98  ,DEEPCOPY_FUNCTION(setBuffId)
99  ,DEEPCOPY_FUNCTION(setConnectionInitialization)
100  ,DEEPCOPY_FUNCTION(setMonteCarloFlag)
101  ,DEEPCOPY_FUNCTION(setCloseConnection)
102  ,DEEPCOPY_FUNCTION(setMissingData)
107  ,_Header (NULL)
108  ,_FloatingMicroBlock (NULL)
111  ,_tlvl (copyin._tlvl)
113 { }
114 
115 //------------------------------------------------------------------------------
116 // Destructor
118  if(_Header) delete _Header;
120 }
121 
122 //------------------------------------------------------------------------------
123 bool RawDataBlock::clear(){
124  _fd_read_bytes = 0;
125  return RawDAQData::clear();
126 }
127 
128 //------------------------------------------------------------------------------
129 bool RawDataBlock::softclear(){
130  _fd_read_bytes = 0;
131  return true;
132 }
133 
134 //------------------------------------------------------------------------------
135 // General initialization
137 
138  /// This is needed for the formats with variable size
139  /// If buffer is internal, need to resize it
140  if(_shouldBufferBeInternal){
141  resizeInternalBuffer(_Header->sizeofdata() + 1);
142  /// Check pointers after each read or resize buffer
143  checkBufferInternalness();
144  }
145 
146  _Header->init();
147 
148  /// Initialize _FloatingMicroBlockNumber
150 }
151 
152 //------------------------------------------------------------------------------
153 // Add a MicroBlock into the DataBlock
154 bool RawDataBlock::addMicroBlock1(const void* microblock_buffer, const bool check_mc_flag){
155 
156  PRINT_ON_DEBUG("In "<<__PRETTY_FUNCTION__<<" 0. Version "<<_microBlockVersion);
157 
158  /// Construct a temporary nanoslice with external buffer
159  const daqdataformats::RawMicroBlock tmp_microblock(microblock_buffer, _microBlockVersion);
160 
161  PRINT_ON_DEBUG("In "<<__PRETTY_FUNCTION__<<" 1");
162 
163  /// Check the MicroBlock version
165  _microBlockVersion = tmp_microblock.getHeader()->getVersion();
166  }// end of checking the MicroBlock version
167 
168  PRINT_ON_DEBUG("In "<<__PRETTY_FUNCTION__<<" 2");
169  PRINT_ON_DEBUG("About to add "<<tmp_microblock.sizeofdata()<<" words");
170 
171  RETURN_FUNCTION(addMicroBlock2)(microblock_buffer, tmp_microblock.sizeofdata(), check_mc_flag);
172 }
173 
174 //------------------------------------------------------------------------------
175 // Add a MicroBlock of a given size into the DataBlock
176 bool RawDataBlock::addMicroBlock2(const void* microblock_buffer, const uint32_t microblock_size, const bool check_mc_flag){
177 
178  PRINT_ON_DEBUG("In "<<__PRETTY_FUNCTION__<<" 0");
179 
180  PRINT_ON_DEBUG("Size of internal buffer before reading "<<_InternalBuffer.size());
181 
182 
183  /// Before reading, we need to adjust the size of the DataBlock
184  /// Cannot rely on the size adjustment from readDataGeneral, because we don't read CRC from microblock
185  const uint32_t new_sizeofdata = EXECUTE_FUNCTION(sizeofdata)() + microblock_size;
186 
187  /// If buffer is internal, we need to adjust its size
188  if(_shouldBufferBeInternal) {
189  /// Microblock size is the size of the header and the microslice
190 
191  /// Add the microblock size
192  resizeInternalBuffer(new_sizeofdata);
193 
194  /// Check pointers after each read or resize buffer
195  checkBufferInternalness();
196  }// end of adjusting the internal buffer size
197 
198  /// Read the MicroBlock to the _Buffer starting from the previous position
199  /// -1 because of CRC
200  readDataGeneral(microblock_buffer, microblock_size, EXECUTE_FUNCTION(sizeofdata)() - 1);
201  /// Check pointers after each read or resize buffer
202  checkBufferInternalness();
203 
204  PRINT_ON_DEBUG("Size of internal buffer after reading "<<_InternalBuffer.size());
205 
206  /// Change the DataBlock header appropriately
207  _Header->setDataSize(new_sizeofdata);
208  _Header->advanceNumMicroBlocks();
209 
210  /// Check if the MicroSlice in the MicroBlock is MC generated
211  /// If it is, set the appropriate DataBlock MC flag
212  if(check_mc_flag){
213  daqdataformats::RawMicroBlock tmp_microblock(microblock_buffer, _microBlockVersion);
214  setMonteCarloFlag(tmp_microblock.getMicroSlice()->getMonteCarloFlag());
215  }
216 
217  return true;
218 }
219 //------------------------------------------------------------------------------
220 /// Add the MicroBlock to _Buffer by passing the references of
221 /// the MilliSlice and the MicroSlice. MilliSlice is the one that contains the MicroSlice.
222 bool RawDataBlock::addMicroBlock3(const void* millislice_buffer
223  ,const void* microslice_buffer
224  ,const version_t microblock_version
225  ,const bool check_mc_flag
226  )
227 {
228  const daqdataformats::RawMicroSliceHeader tmp_microslice_header(microslice_buffer, rawdaqdataformat::DAQDATAFORMAT_UNKNOWN_VERSION);
229 
230  EXECUTE_FUNCTION(addMicroBlock4)(millislice_buffer, microslice_buffer, tmp_microslice_header.getMicroSliceSize(), microblock_version, check_mc_flag);
231  return true;
232 }
233 
234 //------------------------------------------------------------------------------
235 /// Add the MicroBlock to _Buffer by passing the references of
236 /// the MilliSlice and the MicroSlice of a known size.
237 /// MilliSlice is the one that contains the MicroSlice.
238 bool RawDataBlock::addMicroBlock4(const void* millislice_buffer, const void* microslice_buffer, const uint32_t microslice_size, const version_t microblock_version, const bool check_mc_flag){
239 
240  _microBlockVersion = microblock_version;
241 
242  /// Size of the MicroBlock that we are adding
243  /// Start with the microslice size
244  uint32_t microblock_size = microslice_size;
245 
246  /// Now, add microBlock Header size to it.
247  /// If floating Microblock already exists, get its header size.
249  microblock_size += _FloatingMicroBlock->getHeader()->sizeofdata();
250  }
251  else{
252  /// Need to figure out the header size for a given version
254  microblock_size += tmp_header.sizeofdata();
255  }
256 
257  const uint32_t new_sizeofdata = EXECUTE_FUNCTION(sizeofdata)() + microblock_size;
258 
259  /// If buffer is internal, we need to adjust its size
260  if(_shouldBufferBeInternal) {
261  /// Microblock size is the size of the header and the microslice
262 
263  /// Add the microblock size
264  resizeInternalBuffer(new_sizeofdata);
265 
266  /// Check pointers after each read or resize buffer
267  checkBufferInternalness();
268  }// end of adjusting the internal buffer size
269 
270  const uint32_t current_number_of_microblocks = EXECUTE_FUNCTION(getNumMicroBlocks)();
271 
272  /// Setup the DataBlock header by adding the size and the number of MicroBlocks in the DataBlock
273  /// Need to have DataSize setup before setting FloatingMicroBlock
274  /// This is because there is a check for going outside sizeofdata, so it's going to fail otherwise.
275  _Header->setDataSize(new_sizeofdata);
276  _Header->setNumMicroBlocks(current_number_of_microblocks + 1);
277 
278  /// Set the floating microblock
279  EXECUTE_FUNCTION(setFloatingMicroBlock)(current_number_of_microblocks);
280 
281  /// Need to initialize the header version and such
282  _FloatingMicroBlock->getHeader()->init();
283 
284  /// Read the MicroBlockHeader and the MicroSlice
285  _FloatingMicroBlock->setMicroBlockHeader(millislice_buffer);
286  _FloatingMicroBlock->setMicroSlice(microslice_buffer);
287  /// Check if the MicroSlice in the MicroBlock is MC generated
288  /// If it is, set the appropriate DataBlock MC flag
289  if(check_mc_flag){
290  setMonteCarloFlag(_FloatingMicroBlock->getMicroSlice()->getMonteCarloFlag());
291  }// end of checking MC flag
292 
293  return true;
294 
295 }
296 
297 //------------------------------------------------------------------------------
298 // Closing the DataBlock by adding the CRC and increasing the DataBlock size by one (CRC).
299 bool RawDataBlock::close(const bool produce_crc){
300 
301  /// Add CRC at the very end of _Buffer
302  if(produce_crc){
303  _Header->setCRCCalculationUsed(true);
304  /// Must be the last operation
305  addCheckSum();
306  }
307 
308  return true;
309 }
310 
311 
312 //------------------------------------------------------------------------------
313 //Getters
314 
315  uint32_t RawDataBlock::getVersion() const { return _Header->getVersion();}
316  uint32_t RawDataBlock::getMarker() const { return _Header->getMarker();}
317  uint32_t RawDataBlock::getTrigNumLo() const { return _Header->getTrigNumLo();}
318  uint32_t RawDataBlock::getTrigNumHi() const { return _Header->getTrigNumHi();}
319  uint64_t RawDataBlock::getTrigNum() const { return _Header->getTrigNum();}
320  uint16_t RawDataBlock::getNumMicroBlocks() const { return _Header->getNumMicroBlocks();}
321  uint16_t RawDataBlock::getBuffId() const { return _Header->getBuffId(); }
322  uint32_t RawDataBlock::getDataSize() const { return _Header->getDataSize();}
323  bool RawDataBlock::getMonteCarloFlag() const { return _Header->getMonteCarloFlag();}
324  bool RawDataBlock::isCRCCalculationUsed() const { return _Header->isCRCCalculationUsed();}
325  bool RawDataBlock::isConnectionInitialization() const { return _Header->isConnectionInitialization();}
326  bool RawDataBlock::isCloseConnection() const { return _Header->isCloseConnection();}
327  bool RawDataBlock::isMissingData() const { return _Header->isMissingData();}
328 
329 //------------------------------------------------------------------------------
330 //Setters
331  bool RawDataBlock::setTrigNumLo (const uint32_t tr) { return _Header->setTrigNumLo(tr);}
332  bool RawDataBlock::setTrigNumHi (const uint32_t tr) { return _Header->setTrigNumHi(tr);}
333  bool RawDataBlock::setTrigNum (const uint64_t tr) { return _Header->setTrigNum(tr);}
334  bool RawDataBlock::setBuffId (const uint16_t b) { return _Header->setBuffId(b);}
335  bool RawDataBlock::setMonteCarloFlag (const bool ft) { return _Header->setMonteCarloFlag(ft);}
336  bool RawDataBlock::setConnectionInitialization (const bool ft) { return _Header->setConnectionInitialization(ft);}
337  bool RawDataBlock::setCloseConnection (const bool ft) { return _Header->setCloseConnection(ft);}
338  bool RawDataBlock::setMissingData (const bool ft) { return _Header->setMissingData(ft);}
339 
340 //------------------------------------------------------------------------------
341 bool RawDataBlock::setBufferSource(const void* pointer){
342 
343  PRINT_ON_DEBUG(__PRETTY_FUNCTION__<<"version = "<<_version);
344 
345  /// Set the Buffer and its header pointers
346  const uint32_t* old_buffer = (uint32_t*)_Buffer;
347  _Buffer = (void*)pointer;
348  _shouldBufferBeInternal = isInternalBuffer();
349 
350  /// If Header is already defined, then set its buffer source
351  /// Otherwise, need to construct it
352  if(_Header){
353  _Header->setBufferSource(pointer);
354 
355  /// It's possible that Floating Microblock was already constructed.
356  /// If so, need to reassign its pointer
357  if(_FloatingMicroBlockNumber > -1){
358 
359  /// See how many Microblocks in the new buffer.
360  /// If it's greater, then make the floating MicroBlock non-valid.
361  if(_FloatingMicroBlockNumber > _Header->getNumMicroBlocks()){
363  return true;
364  }// end of checking number of microblocks
365 
366  /// New Floating MicroBlock pointer
367  const uint32_t* floating_microblock_pointer =((uint32_t*)_Buffer) + ((uint32_t*)_FloatingMicroBlock->getBuffer() - old_buffer);
368  RETURN_FUNCTION(setFloatingMicroBlockToBufferSource)(floating_microblock_pointer);
369  }// end of setting new floating MicroBlock pointer
370 
371  return true;
372  }
373 
374  PRINT_ON_DEBUG("Setting Header "<<"version = "<<_version);
375  _Header = new daqdataformats::RawDataBlockHeader(_Buffer, _version); ///< version of the DataBlockSliceHeader equals the version of the DataBlockSlice
376 
377  _function_sizeofdata = (sizeofdata_t) &version0::RawDataBlock::sizeofdata;
378 
379  return true;
380 }
381 
382 //------------------------------------------------------------------------------
383 bool RawDataBlock::setFloatingMicroBlockToBufferSource(const void* internal_buffer_pointer) const {
384 
385  /// If it exists, just set its buffer
387  return _FloatingMicroBlock->setBufferSource(internal_buffer_pointer);
388 
389  /// Otherwise, create new Floating MicroSlice pointing to the buffer
391 
392  return true;
393 }
394 
395 //------------------------------------------------------------------------------
396 bool RawDataBlock::setFloatingMicroBlock (const uint32_t imicro) const {
397 
398  /// If it's already the same, nothing needs to be done
399  if((int)imicro == _FloatingMicroBlockNumber)
400  return true;
401 
402  /// Pointer that we are going to use
403  uint32_t* pointer = NULL;
404 
405  /// If microslice number is greater than current floating Microslice number, then no need
406  /// to loop over all MicroSlices, just start from the current floating MicroSlice
407  if((int)imicro > _FloatingMicroBlockNumber && _FloatingMicroBlockNumber > -1){
408  pointer = (uint32_t*)_FloatingMicroBlock->getBuffer();
409  }
410  else{
411  /// Otherwise, start from scratch
412  /// First point to the first MicroSlice
413  pointer = (uint32_t*)&RAWBUFF32[datablockheader::DATABLOCKHEADER_SIZE];
414 
415  /// Set floating MicroSlice to pointer
416  /// If it doesn't exist, create it
417  EXECUTE_FUNCTION(setFloatingMicroBlockToBufferSource)(pointer);
419  }// end of setting the first floating MicroSlice
420 
421 
422  /// Pointer to the end of the buffer for checks
423  const uint32_t* end_of_buffer_pointer = &RAWBUFF32[EXECUTE_FUNCTION(sizeofdata)()];
424 
425  /// Start loop over microslices
427  pointer += _FloatingMicroBlock->sizeofdata();
428 
429  /// Check if the pointer is not valid
430  if (pointer >= end_of_buffer_pointer) return false;
431 
432  _FloatingMicroBlock->setBufferSource(pointer);
433  }// end of loop over microslices
434 
435  return true;
436 }
437 
438 
439 //------------------------------------------------------------------------------
440 // Read an entire DataBlock from datablock_buffer into _Buffer
441 void* RawDataBlock::readData(const void* datablock_buffer){
442 
443  //Read the header and unpack it
444  void* datablock_buffer_new = readDataGeneral(datablock_buffer, datablockheader::DATABLOCKHEADER_SIZE, 0);
445 
446  /// Check pointers after each read or resize buffer
447  checkBufferInternalness();
448 
449  // read the rest of
450  datablock_buffer_new = readDataGeneral(datablock_buffer_new, EXECUTE_FUNCTION(sizeofdata)() - datablockheader::DATABLOCKHEADER_SIZE, datablockheader::DATABLOCKHEADER_SIZE);
451 
452  /// Check pointers after each read or resize buffer
453  checkBufferInternalness();
454 
455  return datablock_buffer_new;
456 }
457 
458 // Method to read data in to a file descriptor
459 // The assumption is that the read will not block because a poll or select
460 // (in the case that the fd is a socket) has determined that data is ready.
461 // (Of course, the fd is always "ready" if the fd is associate with a file
462 // on disk). But no assumption is made that a 2nd rseead will not block, so
463 // only one read (within this readData routine) is every done. The caller
464 // is responsible for doing the necessary number of readData calls to get a
465 // "complete" object.
466 readDataStatus RawDataBlock::readDataFromFileDescriptor(const int fd)
467 {
468 
469  if (fd >= 0)
470  {
471  if (isInternalBuffer())
472  {
473  size_t bytes_to_read = 0;
474 
475 
477  { const size_t min_words = datablockheader::DATABLOCKHEADER_SIZE;
478  const size_t min_bytes = min_words*sizeof (uint32_t);
479 
480  if (_InternalBuffer.size() < min_words)
481  {
482  _InternalBuffer.resize(min_words);
483  resetBufferSource();
484  }
485 
486  bytes_to_read = min_bytes - _fd_read_bytes;
487  }
488  else
489  { uint32_t ss=EXECUTE_FUNCTION(sizeofdata)();
490  // check before using size
491  if ( (!_Header->checkMarker())
492  || (ss > 0x400000/*arbitrary val*/) )
493  { return rds_error;
494  }
495  if (_InternalBuffer.size() < (size_t)ss)
496  { _InternalBuffer.resize( ss );
497  resetBufferSource();
498  }
499  bytes_to_read = (size_t)ss*sizeof(uint32_t) - _fd_read_bytes;
500  }
501 
502  const ssize_t ss = read(fd, (char*)_Buffer+_fd_read_bytes, bytes_to_read );
503  if (ss==-1)
504  { perror("read");
505  return rds_error;
506  }
507  else if (ss==0)
508  { tprintf( 5, "connection closed\n" );
509  return rds_error;
510  }
511 
512  _fd_read_bytes += ss;
513  if (ss != (int)bytes_to_read)
514  { return rds_incomplete;
515  }
516 
517  const uint32_t size_of_data = EXECUTE_FUNCTION(sizeofdata)();
518 
519  // at this point, the header should have been read in and the
520  // size from within can be examined.
521  // check for reasonableness
522  if ( (!_Header->checkMarker())
523  || (size_of_data > 0x400000/*arbitrary val*/) )
524  { return rds_error;
525  }
526 
527  if (((size_t)size_of_data*sizeof (uint32_t)) == _fd_read_bytes)
528  return rds_complete;
529  return rds_incomplete;
530  }
531  else
532  {
533  // assume there is enough space???
534  return RawDAQData::readData(fd);
535  }
536  }
537  return rds_error;
538 }
539 
540 //------------------------------------------------------------------------------
542 {
543  if (fd >= 0)
544  {
545  if (isInternalBuffer())
546  {
547  size_t bytes_to_read;
548 
549  /// See if we already read the header
550  /// Identifying the size of the bytes to read
552  { const size_t min_words = datablockheader::DATABLOCKHEADER_SIZE;
553  const size_t min_bytes = min_words*sizeof (uint32_t);
554 
555  if (_InternalBuffer.size() < min_words)
556  {
557  _InternalBuffer.resize(min_words);
558  _Buffer = (void*)(&_InternalBuffer[0]);
559  }
560 
561  bytes_to_read = min_bytes - _fd_read_bytes;
562  }
563  else
564  { const uint32_t size_of_data = EXECUTE_FUNCTION(sizeofdata)();
565  // check before using size
566  if ( (!_Header->checkMarker())
567  || (size_of_data > 0x400000/*arbitrary val*/) )
568  { return rds_error;
569  }
570  if (_InternalBuffer.size() < (size_t)size_of_data)
571  { _InternalBuffer.resize(size_of_data);
572  _Buffer = (void*)(&_InternalBuffer[0]);
573  }
574  bytes_to_read = (size_t)size_of_data*sizeof(uint32_t) - _fd_read_bytes;
575  }
576 
577  const ssize_t ss = read(fd, (char*)_Buffer+_fd_read_bytes, bytes_to_read );
578  if (ss==-1)
579  { perror("read");
580  return rds_error;
581  }
582  else if (ss==0)
583  { tprintf( 5, "connection closed\n" );
584  return rds_error;
585  }
586 
587  _fd_read_bytes += ss;
588  if (ss != (int)bytes_to_read)
589  { return rds_incomplete;
590  }
591 
592  // at this point, the header should have been read in and the
593  // size from within can be examined.
594  // check for reasonableness
595 
596  _version = figureOutTheVersion(_Buffer);
597 
598  /// Now that we know the version, initialize function pointers
599  setFunctionPointers();
600 
601  /// Need to construct all Headers and stuff
602  resetBufferSource();
603 
604  /// Now need to adjust the internal buffer size
605  const uint32_t size_of_data = EXECUTE_FUNCTION(sizeofdata)();
606  resizeInternalBuffer(size_of_data);
607 
608  /// Reset buffer source, so that we can construct other things (like headers and such)
609  resetBufferSource();
610 
611  if ( (!_Header->checkMarker())
612  || (size_of_data > 0x400000/*arbitrary val*/) )
613  { return rds_error;
614  }
615 
616  if (((size_t)size_of_data*sizeof (uint32_t)) == _fd_read_bytes)
617  return rds_complete;
618  return rds_incomplete;
619  }
620  else
621  {
622  // assume there is enough space???
623  return RawDAQData::readData(fd);
624  }
625  }
626  return rds_error;
627 }
628 
629 //------------------------------------------------------------------------------
630 uint32_t RawDataBlock::getCRC() const{
631 
632  if(!isCRCCalculationUsed()) return 0;
633 
634  return RAWBUFF32[EXECUTE_FUNCTION(sizeofdata)() - 1];
635 }
636 
637 //------------------------------------------------------------------------------
638 // Print the DataBlock structure
639 void RawDataBlock::print(std::ostream& os) const {
640 
641  const uint32_t size_of_data = EXECUTE_FUNCTION(sizeofdata)();
642 
643  os<<boost::format("\n---RawDataBlock----------------------------------------------------(size=%u, version=%u)\n")
644  % size_of_data % _version;
645 
646  printBuffer(os);
647 
648  _Header->print(os);
649 
650  for(uint32_t i = 0; i < size_of_data; ++i){
651  os<<" ";
652  printWord(i, false, os);
653  os<<"\n";
654  }
655 
656 
657  const uint32_t num_microblocks = _Header->getNumMicroBlocks();
658  os<<"Number of MicroBlocks = "<<num_microblocks<<std::endl;
659  if(num_microblocks){
660  daqdataformats::RawDataBlock datablock_copy(_Buffer, _version, 0);
661 
662  /// Print all MicroBlocks
663  for(uint32_t imicroblock = 0; imicroblock <num_microblocks ; ++imicroblock){
664  if(!datablock_copy.setFloatingMicroBlock(imicroblock)){
665  const std::string error_message = "Some failure during setFloatingMicroBlock number "
666  + boost::lexical_cast<std::string>(imicroblock)
667  + ". Total number of microblocks = "
668  + boost::lexical_cast<std::string>(num_microblocks)
669  + "\n";
670  os<<error_message;
671  GENERATE_DATAFORMAT_EXCEPTION(error_message);
672  return;
673  }
674 
675  //os<<"Micro "<<imicroblock<<" MicroBuff="<<datablock_copy.getBuffer()<<"\n";
676  datablock_copy.getFloatingMicroBlock()->print(os);
677  }// end of looping over microblocks
678  }
679 
680  if(isCRCCalculationUsed())os<<"--- CRC = "<<getCRC()<<"\n";
681 
682 }
683 
684 //------------------------------------------------------------------------------
685 void RawDataBlock::tprintf( unsigned lvl, const char *fmt, ... )
686 { if (lvl > 31) lvl=31;
687  if (_tlvl & (1<<lvl))
688  { timeval tv;
689  char str[80];
690  time_t local;
691  const char* indent=" ";//32 spaces
692  va_list ap;
693  va_start( ap, fmt);
694  gettimeofday( &tv, NULL );
695  local = tv.tv_sec;
696  strftime( str, sizeof(str), "%T", localtime(&local) );
697  printf( "%s.%06ld%s", str, (long)tv.tv_usec, &indent[31-lvl] );
698  vprintf( fmt, ap );
699  }
700 } // tprintf
701 
702 
703 }} // end of namespaces
#define ZEROOUT_FUNCTION(FUNC)
Definition: FunctionBind.h:52
#define DEEPCOPY_FUNCTION(FUNC)
Definition: FunctionBind.h:40
#define EXECUTE_FUNCTION(FULLFUNCTIONNAME)
Execute and return the delegate.
Definition: Macros.h:54
void print(std::ostream &os=std::cout) const
#define GENERATE_DATAFORMAT_EXCEPTION(msg)
#define sizeofdata_t
Definition: FunctionBind.h:30
daqdataformats::RawMicroBlock * _FloatingMicroBlock
DataBlock header.
bool addMicroBlock4(const void *millislice_buffer, const void *microslice_buffer, const uint32_t microslice_size, const version_t microblock_version, const bool check_mc_flag)
#define VERSION_NAMESPACE
RawDataBlock(const version_t, const uint32_t tlvl)
Constructors.
vector< vector< double > > clear
Float_t ss
Definition: plot.C:24
bool addMicroBlock1(const void *microblock_buffer, const bool check_mc_flag)
void tprintf(unsigned lvl, const char *fmt,...) __attribute__((format(printf
#define RETURN_FUNCTION(FULLFUNCTIONNAME)
Definition: Macros.h:57
version_t _microBlockVersion
Floating MicroBlock Number.
bool close(bool produce_crc=false)
Definition: RawDataBlock.h:80
#define local
Definition: gzguts.h:107
std::string indent(std::size_t const i)
printf("%d Experimental points found\n", nlines)
daqdataformats::RawDataBlockHeader * _Header
std::string format(const int32_t &value, const int &ndigits=8)
Definition: HexUtils.cpp:14
virtual bool clear()
reset _Buffer to point to InternalBuffer
Definition: RawDAQData.cpp:573
const XML_Char * version
Definition: expat.h:187
bool addMicroBlock2(const void *microblock_buffer, const uint32_t microblock_size, const bool check_mc_flag)
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
#define RAWBUFF32
Definition: RawDAQData.h:16
void * readData(const void *buffer)
Shallow copy constructor.
Definition: RawDAQData.cpp:181
int32_t version_t
Definition: RawDAQData.h:72
const hit & b
Definition: hits.cxx:21
#define PRINT_ON_DEBUG(x)
Definition: RawDAQData.h:35
static const version_t DAQDATAFORMAT_UNKNOWN_VERSION
Definition: RawDAQData.h:81
Class to hold the data from the FEBs in correct formats.
bool addMicroBlock3(const void *millislice_buffer, const void *microslice_buffer, const version_t microblock_version, const bool check_mc_flag)
procfile close()