PennMilliSlice.cc
Go to the documentation of this file.
3 #include <iostream>
4 #include <bitset>
5 
6 // #define __DEBUG_payload__
7 
8 dune::PennMilliSlice::PennMilliSlice(uint8_t* address) : buffer_(address), current_payload_(address), current_word_id_(0)
9 {
10 }
11 
13 {
14  return header_()->millislice_size;
15 }
16 
17 #ifdef PENN_DONT_REBLOCK_USLICES
18 dune::PennMilliSlice::Header::microslice_count_t dune::PennMilliSlice::microSliceCount() const
19 {
20  return header_()->microslice_count;
21 }
22 #endif
23 
25 {
26  return header_()->sequence_id;
27 }
28 
30 {
31  return header_()->version;
32 }
33 
35 {
36  return header_()->end_timestamp;
37 }
38 
40 {
41  return header_()->width_in_ticks;
42 }
43 
45 {
46  return header_()->overlap_in_ticks;
47 }
48 
50 {
51  return header_()->payload_count;
52 }
53 
58 {
59  counter = header_()->payload_count_counter;
60  trigger = header_()->payload_count_trigger;
61  timestamp = header_()->payload_count_timestamp;
62  return payloadCount();
63 }
64 
65 #ifdef PENN_DONT_REBLOCK_USLICES
66 // Returns the requested MicroSlice if the requested slice was found,
67 // otherwise returns an empty pointer
68 std::unique_ptr<dune::PennMicroSlice> dune::PennMilliSlice::microSlice(uint32_t index) const
69 {
70  std::unique_ptr<PennMicroSlice> mslice_ptr;
71  if (index < microSliceCount()) {
72  uint8_t* ms_ptr = data_(index);
73  mslice_ptr.reset(new PennMicroSlice(ms_ptr));
74  }
75  return mslice_ptr;
76 }
77 #endif
78 
79 //Returns the requested payload
83  size_t& payload_size)
84 {
85 
86  if(current_word_id_ == 0){
87  current_payload_ = buffer_ + sizeof(Header);
88  }
89  else{
90  //current_payload_ points to the last payload served up
91  //We need to skip over this one
92  dune::PennMicroSlice::Payload_Header* payload_header = reinterpret_cast_checked<dune::PennMicroSlice::Payload_Header*>(current_payload_);
94  switch(type)
95  {
98  break;
101  break;
104  break;
107  break;
110  break;
111  default:
112 // std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
113  return nullptr;
114  break;
115  }//switch(type)
116  }//(current_word_id_ != 0)
117 
118  //Now current_payload_ will point to the next payload. Process the information that we want
119 
120  //Need to make sure we have not gone off the end of the buffer
121  if(current_payload_ >= (buffer_ + size()))
122  return nullptr;
123 
124 
125  dune::PennMicroSlice::Payload_Header* payload_header = reinterpret_cast_checked<dune::PennMicroSlice::Payload_Header*>(current_payload_);
127 
128  //Set the variables passed as references
129  index = current_word_id_;
130  type = payload_header->data_packet_type;
131  data_packet_type = type;
132  short_nova_timestamp = payload_header->short_nova_timestamp;
133 
134  switch(type)
135  {
138  break;
141  break;
144  break;
147  break;
150  break;
151  default:
152  //std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
153  payload_size = 0;
154  break;
155  }//switch(type)
156 
158  //current_payload_ points at the Payload_Header of the next payload
159  //this function assumes that state is true the next time it is called (so it knows how to shift to the next payload)
160  //but the user is expecting just the payload data. Therefore return the buffer offset by the payload_header
161 
163 
164 }
165 
166 
168 
169  // If we are still at the beginning, shift to the beginning of the Millislice and
170  // jump over its header
171  if(current_word_id_ == 0) {
172  current_payload_ = buffer_ + sizeof(Header);
173  }
174  else{
175  //current_payload_ points to the last payload served
176  //We need to skip over this one
177  dune::PennMicroSlice::Payload_Header* payload_header = reinterpret_cast_checked<dune::PennMicroSlice::Payload_Header*>(current_payload_);
179  switch(type)
180  {
183  break;
186  break;
189  break;
192  break;
195  break;
196  default:
197  //std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
198  return nullptr;
199  break;
200  }//switch(type)
201  }//(current_word_id_ != 0)
202 
203  //Now current_payload_ will point to the next payload. Process the information that we want
204 
205  //Need to make sure we have not gone off the end of the buffer
206  if(current_payload_ >= (buffer_ + size()))
207  return nullptr;
208 
209 
210  dune::PennMicroSlice::Payload_Header* payload_header = reinterpret_cast_checked<dune::PennMicroSlice::Payload_Header*>(current_payload_);
211  //dune::PennMicroSlice::Payload_Header::data_packet_type_t type = payload_header->data_packet_type;
212 
213  //Set the variables passed as references
214  index = current_word_id_;
215  //type = payload_header->data_packet_type;
216  data_header = payload_header;
217 
219  //current_payload_ points at the Payload_Header of the next payload
220  //this function assumes that state is true the next time it is called (so it knows how to shift to the next payload)
221  //but the user is expecting just the payload data. Therefore return the buffer offset by the payload_header
222 
224 
225 }
226 
227 // Returns the nearest timestamp word in the future
228 // does not change internal pointers
230  uint8_t* pl_ptr = current_payload_;
231  bool found = false;
232  if(current_word_id_ == 0) {
233  pl_ptr = buffer_ + sizeof(Header);
234  }
235  dune::PennMicroSlice::Payload_Header* payload_header = nullptr;
236  while (!found && (pl_ptr < (buffer_ + size()))) {
237  //current_payload_ points to the last payload served
238  //We need to skip over this one
239  payload_header = reinterpret_cast_checked<dune::PennMicroSlice::Payload_Header*>(pl_ptr);
240  dune::PennMicroSlice::Payload_Header::data_packet_type_t type = payload_header->data_packet_type;
241  switch(type)
242  {
245  break;
248  break;
250  found = true;
251  break;
254  break;
257  break;
258  default:
259  //std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
260  data_header = nullptr;
261  return nullptr;
262  break;
263  }//switch(type)
264  }
265 
266  if (found) {
267  data_header = reinterpret_cast_checked<dune::PennMicroSlice::Payload_Header*>(pl_ptr);
269  }
270  else return nullptr;
271 }
272 
273 //Returns the requested payload
275  dune::PennMicroSlice::Payload_Header*& data_header) const
276 {
277  uint32_t i = 0;
278  uint8_t* pl_ptr = buffer_ + sizeof(Header);
279  while(pl_ptr < (buffer_ + size())) {
280  dune::PennMicroSlice::Payload_Header* payload_header = reinterpret_cast<dune::PennMicroSlice::Payload_Header*>(pl_ptr);
282  if(i == index) {
283  data_header = payload_header;
285  return pl_ptr;
286  }
287  switch(type) {
290  break;
293  break;
296  break;
299  break;
302  break;
303  default:
304  //std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
305  return nullptr;
306  break;
307  }//switch(type)
308  ++i;
309  }
310  std::cerr << "Could not find payload with index " << index << " (the data buffer has overrun)" << std::endl;
311  return nullptr;
312 }
313 
314 //Returns the requested payload
318  size_t& payload_size) const
319 {
320  uint32_t i = 0;
321  uint8_t* pl_ptr = buffer_ + sizeof(Header);
322  while(pl_ptr < (buffer_ + size())) {
323  dune::PennMicroSlice::Payload_Header* payload_header = reinterpret_cast<dune::PennMicroSlice::Payload_Header*>(pl_ptr);
325  if(i == index) {
326  data_packet_type = type;
327  short_nova_timestamp = payload_header->short_nova_timestamp;
328 #ifdef __DEBUG_payload__
329  std::cout << "PennMilliSlice::payload() payload " << i << " has type 0x"
330  << std::hex << (unsigned int)data_packet_type << std::dec
331  << " " << std::bitset<3>(data_packet_type)
332  << " and timestamp " << short_nova_timestamp
333  << " " << std::bitset<28>(short_nova_timestamp)
334  << " payload header bits " << std::bitset<32>(*((uint32_t*)pl_ptr))
335  << std::endl;
336 #endif
338  switch(type)
339  {
342  break;
345  break;
348  break;
351  break;
354  break;
355  default:
356  //std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
357  payload_size = 0;
358  break;
359  }//switch(type)
360  return pl_ptr;
361  }
362  switch(type)
363  {
366  break;
369  break;
372  break;
375  break;
378  break;
379  default:
380  //std::cerr << "Unknown data packet type found 0x" << std::hex << (unsigned int)type << std::endl;
381  return nullptr;
382  break;
383  }//switch(type)
384  i++;
385  }
386  std::cerr << "Could not find payload with ID " << index << " (the data buffer has overrun)" << std::endl;
387  payload_size = 0;
388  return nullptr;
389 }
390 
391 #ifdef ENABLE_PENNMILLISLICE_CHECKSUM
392 
393 dune::PennMilliSlice::checksum_t dune::PennMilliSlice::calculateChecksum() const
394 {
395  try {
396  //NFB: Is the checksum actually used anywhere? It certainly complicates the calculations.
397  boost::crc_32_type checksum;
398  checksum.process_bytes(buffer_, this->size());
399  return checksum.checksum();
400  }
401  catch ( ... ) {
402  std::cout << "Error caught in PennMilliSlice::calculateChecksum()" << std::endl;
403  //TODO handle error cleanly here
404  return 0;
405  }
406 }
407 
408 dune::PennMilliSlice::checksum_t dune::PennMilliSlice::checksum() const
409 {
410  return *(reinterpret_cast<dune::PennMilliSlice::checksum_t*>(buffer_ + this->size() - sizeof(dune::PennMilliSlice::checksum_t)));
411 }
412 #endif
413 
415 {
416  return reinterpret_cast<Header const*>(buffer_);
417 }
418 
419 // returns a pointer to the requested MicroSlice
421 {
422  uint8_t* ms_ptr = buffer_ + sizeof(Header);
423  for (int idx = 0; idx < index; ++idx) {
424  PennMicroSlice tmp_ms(ms_ptr);
425  ms_ptr += tmp_ms.size();
426  }
427  return ms_ptr;
428 }
static microslice_size_t const payload_size_trigger
static microslice_size_t const payload_size_timestamp
Header const * header_() const
uint8_t * payload(uint32_t index, dune::PennMicroSlice::Payload_Header::data_packet_type_t &data_packet_type, dune::PennMicroSlice::Payload_Header::short_nova_timestamp_t &short_nova_timestamp, size_t &payload_size) const
uint8_t * get_next_payload(uint32_t &index, dune::PennMicroSlice::Payload_Header::data_packet_type_t &data_packet_type, dune::PennMicroSlice::Payload_Header::short_nova_timestamp_t &short_nova_timestamp, size_t &payload_size)
static const Payload_Header::data_packet_type_t DataTypeWarning
static microslice_size_t const payload_size_checksum
Header::millislice_size_t size() const
QTextStream & hex(QTextStream &s)
static const Payload_Header::data_packet_type_t DataTypeTimestamp
uint8_t * data_(int index) const
Header::timestamp_t endTimestamp() const
static microslice_size_t const payload_size_counter
short_nova_timestamp_t short_nova_timestamp
Header::ticks_t overlapTicks() const
Header::version_t version() const
uint8_t * get_next_timestamp(dune::PennMicroSlice::Payload_Header *&data_header)
dune::PennMicroSlice::microslice_size_t size() const
static const Payload_Header::data_packet_type_t DataTypeChecksum
PennMilliSlice(uint8_t *address)
Header::ticks_t widthTicks() const
QTextStream & dec(QTextStream &s)
Header::sequence_id_t sequenceID() const
static const Payload_Header::data_packet_type_t DataTypeTrigger
Header::payload_count_t payloadCount() const
static QCString type
Definition: declinfo.cpp:672
Frame header : Common header to everything except warning words.
static microslice_size_t const payload_size_warning
static const Payload_Header::data_packet_type_t DataTypeCounter
QTextStream & endl(QTextStream &s)