artdaq_core  v1_06_00
 All Classes Namespaces Functions
ContainerFragment.hh
1 #ifndef artdaq_core_Data_ContainerFragment_hh
2 #define artdaq_core_Data_ContainerFragment_hh
3 
4 #include "artdaq-core/Data/Fragment.hh"
5 #include "cetlib/exception.h"
6 
7 #include <ostream>
8 #include <vector>
9 
10 // Implementation of "ContainerFragment", an artdaq::Fragment overlay class
11 
12 // The maximum capacity of the ContainerFragment (in fragments)
13 #ifndef CONTAINER_FRAGMENT_CAPACITY
14 #define CONTAINER_FRAGMENT_CAPACITY 100
15 #endif
16 
17 namespace artdaq {
18  class ContainerFragment;
19 
20  static const int FRAGMENT_COUNT_MAX = CONTAINER_FRAGMENT_CAPACITY;
21 }
22 
24 public:
25 
26  struct Metadata {
27  typedef uint8_t data_t;
28  typedef uint64_t count_t;
29 
30  count_t block_count : 55;
31  count_t fragment_type : 8;
32  count_t missing_data : 1;
33 
34  size_t index[FRAGMENT_COUNT_MAX];
35 
36  static size_t const size_words = 8ul + FRAGMENT_COUNT_MAX * sizeof(size_t) / sizeof(data_t); // Units of Header::data_t
37  };
38 
39  static_assert (sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t), "ContainerFragment::Metadata size changed");
40 
41  // The constructor simply sets its const private member "artdaq_Fragment_"
42  // to refer to the artdaq::Fragment object
43 
44  ContainerFragment(Fragment const & f) : artdaq_Fragment_(f) { }
45 
46  // const getter functions for the metadata
47  Metadata const * metadata() const { return artdaq_Fragment_.metadata<Metadata>(); }
48  Metadata::count_t block_count() const { return metadata()->block_count; }
49  Fragment::type_t fragment_type() const { return static_cast<Fragment::type_t>(metadata()->fragment_type); }
50  bool missing_data() const { return static_cast<bool>(metadata()->missing_data); }
51 
52  // Start of the Fragments
53  Fragment const * dataBegin() const {
54  return reinterpret_cast<Fragment const *>(&*artdaq_Fragment_.dataBegin());
55  }
56 
57  Fragment const * dataEnd() const {
58  return reinterpret_cast<Fragment const *>(reinterpret_cast<uint8_t const *>(dataBegin()) + lastFragmentIndex());
59  }
60 
61  Fragment const * operator[](size_t index) const {
62  if (index > block_count()) throw cet::exception("Buffer overrun detected! ContainerFragment::operator[] was asked for a non-existant Fragment!");
63  return reinterpret_cast<Fragment const *>(reinterpret_cast<uint8_t const *>(dataBegin()) + fragmentIndex(index));
64  }
65 
66  size_t fragmentIndex(size_t index) const {
67  assert(index <= block_count());
68  if (index == 0) { return 0; }
69  return metadata()->index[index - 1];
70  }
71 
72  size_t lastFragmentIndex() const {
73  return fragmentIndex(block_count());
74  }
75 
76 protected:
77 
78  static constexpr size_t words_per_frag_word_() {
79  return sizeof(Fragment::value_type) / sizeof(Metadata::data_t);
80  }
81 
82 private:
83 
84  Fragment const & artdaq_Fragment_;
85 };
86 
87 #endif /* artdaq_core_Data_ContainerFragment_hh */