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
00011
00012
00013 #ifndef CONTAINER_FRAGMENT_CAPACITY
00014 #define CONTAINER_FRAGMENT_CAPACITY 100
00015 #endif
00016
00017 namespace artdaq {
00018 class ContainerFragment;
00019
00020 static const int FRAGMENT_COUNT_MAX = CONTAINER_FRAGMENT_CAPACITY;
00021 }
00022
00023 class artdaq::ContainerFragment {
00024 public:
00025
00026 struct Metadata {
00027 typedef uint8_t data_t;
00028 typedef uint64_t count_t;
00029
00030 count_t block_count : 55;
00031 count_t fragment_type : 8;
00032 count_t missing_data : 1;
00033
00034 size_t index[FRAGMENT_COUNT_MAX];
00035
00036 static size_t const size_words = 8ul + FRAGMENT_COUNT_MAX * sizeof(size_t) / sizeof(data_t);
00037 };
00038
00039 static_assert (sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t), "ContainerFragment::Metadata size changed");
00040
00041
00042
00043
00044 ContainerFragment(Fragment const & f) : artdaq_Fragment_(f) { }
00045
00046
00047 Metadata const * metadata() const { return artdaq_Fragment_.metadata<Metadata>(); }
00048 Metadata::count_t block_count() const { return metadata()->block_count; }
00049 Fragment::type_t fragment_type() const { return static_cast<Fragment::type_t>(metadata()->fragment_type); }
00050 bool missing_data() const { return static_cast<bool>(metadata()->missing_data); }
00051
00052
00053 Fragment const * dataBegin() const {
00054 return reinterpret_cast<Fragment const *>(&*artdaq_Fragment_.dataBegin());
00055 }
00056
00057 Fragment const * dataEnd() const {
00058 return reinterpret_cast<Fragment const *>(reinterpret_cast<uint8_t const *>(dataBegin()) + lastFragmentIndex());
00059 }
00060
00061 Fragment const * at(size_t index) const {
00062 if (index > block_count()) throw cet::exception("Buffer overrun detected! ContainerFragment::at was asked for a non-existant Fragment!");
00063 return reinterpret_cast<Fragment const *>(reinterpret_cast<uint8_t const *>(dataBegin()) + fragmentIndex(index));
00064 }
00065
00066 size_t fragSize(size_t index) const {
00067 if(index >= block_count()) throw cet::exception("Buffer overrun detected! ContainerFragment::at was asked for a non-existant Fragment!");
00068 size_t end = metadata()->index[index];
00069 if (index == 0) return end;
00070 return end - metadata()->index[index - 1];
00071 }
00072
00073 Fragment const * operator[](size_t index) const {
00074 return this->at(index);
00075 }
00076
00077 size_t fragmentIndex(size_t index) const {
00078 assert(index <= block_count());
00079 if (index == 0) { return 0; }
00080 return metadata()->index[index - 1];
00081 }
00082
00083 size_t lastFragmentIndex() const {
00084 return fragmentIndex(block_count());
00085 }
00086
00087 protected:
00088
00089 static constexpr size_t words_per_frag_word_() {
00090 return sizeof(Fragment::value_type) / sizeof(Metadata::data_t);
00091 }
00092
00093 private:
00094
00095 Fragment const & artdaq_Fragment_;
00096 };
00097
00098 #endif