00001 #ifndef artdaq_core_Data_ContainerFragment_hh 00002 #define artdaq_core_Data_ContainerFragment_hh 00003 00004 #include "artdaq-core/Data/Fragment.hh" 00005 #include "cetlib/exception.h" 00006 00007 //#include <ostream> 00008 //#include <vector> 00009 00010 // Implementation of "ContainerFragment", an artdaq::Fragment overlay class 00011 00012 #ifndef CONTAINER_FRAGMENT_CAPACITY 00014 #define CONTAINER_FRAGMENT_CAPACITY 100 00015 #endif 00016 00017 namespace artdaq 00018 { 00019 class ContainerFragment; 00020 00024 static const int CONTAINER_FRAGMENT_COUNT_MAX = CONTAINER_FRAGMENT_CAPACITY; 00025 } 00026 00030 class artdaq::ContainerFragment 00031 { 00032 public: 00033 00037 struct Metadata 00038 { 00039 typedef uint8_t data_t; 00040 typedef uint64_t count_t; 00041 00042 count_t block_count : 55; 00043 count_t fragment_type : 8; 00044 count_t missing_data : 1; 00045 00047 size_t index[CONTAINER_FRAGMENT_COUNT_MAX]; 00048 00050 static size_t const size_words = 8ul + CONTAINER_FRAGMENT_COUNT_MAX * sizeof(size_t) / sizeof(data_t); // Units of Header::data_t 00051 }; 00052 00053 static_assert (sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t), "ContainerFragment::Metadata size changed"); 00054 00061 explicit ContainerFragment(Fragment const& f) : artdaq_Fragment_(f) { } 00062 00067 Metadata const* metadata() const { return artdaq_Fragment_.metadata<Metadata>(); } 00068 00073 Metadata::count_t block_count() const { return metadata()->block_count; } 00078 Fragment::type_t fragment_type() const { return static_cast<Fragment::type_t>(metadata()->fragment_type); } 00083 bool missing_data() const { return static_cast<bool>(metadata()->missing_data); } 00084 00089 Fragment const* dataBegin() const 00090 { 00091 return reinterpret_cast<Fragment const *>(&*artdaq_Fragment_.dataBegin()); 00092 } 00093 00098 Fragment const* dataEnd() const 00099 { 00100 return reinterpret_cast<Fragment const *>(reinterpret_cast<uint8_t const *>(dataBegin()) + lastFragmentIndex()); 00101 } 00102 00109 Fragment const* at(size_t index) const 00110 { 00111 if (index > block_count()) throw cet::exception("Buffer overrun detected! ContainerFragment::at was asked for a non-existant Fragment!"); 00112 return reinterpret_cast<Fragment const *>(reinterpret_cast<uint8_t const *>(dataBegin()) + fragmentIndex(index)); 00113 } 00114 00121 size_t fragSize(size_t index) const 00122 { 00123 if (index >= block_count()) throw cet::exception("Buffer overrun detected! ContainerFragment::at was asked for a non-existant Fragment!"); 00124 auto end = metadata()->index[index]; 00125 if (index == 0) return end; 00126 return end - metadata()->index[index - 1]; 00127 } 00128 00135 Fragment const* operator[](size_t index) const 00136 { 00137 return this->at(index); 00138 } 00139 00146 size_t fragmentIndex(size_t index) const 00147 { 00148 if (index > block_count()) throw cet::exception("Buffer overrun detected! ContainerFragment::at was asked for a non-existant Fragment!"); 00149 if (index == 0) { return 0; } 00150 return metadata()->index[index - 1]; 00151 } 00152 00157 size_t lastFragmentIndex() const 00158 { 00159 return fragmentIndex(block_count()); 00160 } 00161 00162 protected: 00163 00168 static constexpr size_t words_per_frag_word_() 00169 { 00170 return sizeof(Fragment::value_type) / sizeof(Metadata::data_t); 00171 } 00172 00173 private: 00174 00175 Fragment const& artdaq_Fragment_; 00176 }; 00177 00178 #endif /* artdaq_core_Data_ContainerFragment_hh */