00001 #ifndef artdaq_core_Data_ContainerFragmentLoader_hh
00002 #define artdaq_core_Data_ContainerFragmentLoader_hh
00003
00005
00006
00007
00008
00009
00010
00012
00013 #include "artdaq-core/Data/Fragment.hh"
00014 #include "artdaq-core/Data/ContainerFragment.hh"
00015 #include "tracemf.h"
00016
00017 #include <iostream>
00018
00019 namespace artdaq
00020 {
00021 class ContainerFragmentLoader;
00022 }
00023
00024
00028 class artdaq::ContainerFragmentLoader : public artdaq::ContainerFragment
00029 {
00030 public:
00031
00032
00038 explicit ContainerFragmentLoader(Fragment& f);
00039
00040
00045 Metadata* metadata()
00046 {
00047 assert(artdaq_Fragment_.hasMetadata());
00048 return reinterpret_cast<Metadata *>(&*artdaq_Fragment_.metadataAddress());
00049 }
00050
00055 void set_fragment_type(Fragment::type_t type)
00056 {
00057 metadata()->fragment_type = type;
00058 }
00059
00068 void set_missing_data(bool isDataMissing)
00069 {
00070 metadata()->missing_data = isDataMissing;
00071 }
00072
00078 void addFragment(artdaq::Fragment& frag);
00079
00084 void addFragment(artdaq::FragmentPtr& frag);
00085
00090 void addFragments(artdaq::FragmentPtrs& frags);
00091
00092 private:
00093
00094 artdaq::Fragment& artdaq_Fragment_;
00095
00096 static size_t words_to_frag_words_(size_t nWords);
00097
00098 void addSpace_(size_t bytes);
00099
00100 uint8_t* dataBegin_() { return reinterpret_cast<uint8_t*>(&*artdaq_Fragment_.dataBegin()); }
00101 void* dataEnd_() { return reinterpret_cast<void*>(dataBegin_() + lastFragmentIndex()); }
00102 };
00103
00104 inline artdaq::ContainerFragmentLoader::ContainerFragmentLoader(artdaq::Fragment& f) :
00105 ContainerFragment(f)
00106 , artdaq_Fragment_(f)
00107 {
00108 artdaq_Fragment_.setSystemType(Fragment::ContainerFragmentType);
00109 Metadata m;
00110 m.block_count = 0;
00111 m.fragment_type = Fragment::EmptyFragmentType;
00112 m.missing_data = false;
00113 for (int ii = 0; ii < CONTAINER_FRAGMENT_COUNT_MAX; ++ii)
00114 {
00115 m.index[ii] = 0;
00116 }
00117 artdaq_Fragment_.setMetadata<Metadata>(m);
00118
00119 if (artdaq_Fragment_.size() !=
00120 artdaq::detail::RawFragmentHeader::num_words() +
00121 words_to_frag_words_(Metadata::size_words))
00122 {
00123 std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
00124 std::cerr << "Expected size: " << artdaq::detail::RawFragmentHeader::num_words() +
00125 words_to_frag_words_(Metadata::size_words) << std::endl;
00126
00127 throw cet::exception("ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object");
00128 }
00129 }
00130
00131 inline size_t artdaq::ContainerFragmentLoader::words_to_frag_words_(size_t nWords)
00132 {
00133 size_t mod = nWords % words_per_frag_word_();
00134 return mod ?
00135 nWords / words_per_frag_word_() + 1 :
00136 nWords / words_per_frag_word_();
00137 }
00138
00139 inline void artdaq::ContainerFragmentLoader::addSpace_(size_t bytes)
00140 {
00141 auto currSize = sizeof(artdaq::Fragment::value_type) * artdaq_Fragment_.dataSize();
00142 artdaq_Fragment_.resizeBytes(bytes + currSize);
00143 TRACE(4, "ContainerFragmentLoader::addSpace_: dataEnd_ is now at %p", dataEnd_());
00144 }
00145
00146 inline void artdaq::ContainerFragmentLoader::addFragment(artdaq::Fragment& frag)
00147 {
00148 TRACE(4, "ContainerFragmentLoader::addFragment: Adding Fragment with payload size %llu to Container", (unsigned long long)frag.dataSizeBytes());
00149 if (metadata()->fragment_type == Fragment::EmptyFragmentType) metadata()->fragment_type = frag.type();
00150 else if (frag.type() != metadata()->fragment_type)
00151 {
00152 throw cet::exception("ContainerFragmentLoader::addFragment: Trying to add a fragment of different type than what's already been added!");
00153 }
00154 TRACE(4, "ContainerFragmentLoader::addFragment: Payload Size is %llu, lastFragmentIndex is %llu, and frag.size is %llu", (unsigned long long)artdaq_Fragment_.dataSizeBytes(), (unsigned long long)lastFragmentIndex(), (unsigned long long)frag.sizeBytes());
00155 if (artdaq_Fragment_.dataSizeBytes() < lastFragmentIndex() + frag.sizeBytes())
00156 {
00157 addSpace_(frag.sizeBytes());
00158 }
00159 frag.setSequenceID(artdaq_Fragment_.sequenceID());
00160 TRACE(4, "ContainerFragmentLoader::addFragment, copying %llu bytes from %p to %p", (long long unsigned int)frag.sizeBytes(), (void*)frag.headerAddress(), dataEnd_());
00161 memcpy(dataEnd_(), frag.headerAddress(), frag.sizeBytes());
00162 metadata()->index[block_count()] = lastFragmentIndex() + frag.sizeBytes();
00163 metadata()->block_count++;
00164 }
00165
00166 inline void artdaq::ContainerFragmentLoader::addFragment(artdaq::FragmentPtr& frag)
00167 {
00168 addFragment(*frag);
00169 }
00170
00171 inline void artdaq::ContainerFragmentLoader::addFragments(artdaq::FragmentPtrs& frags)
00172 {
00173 for (auto& frag : frags)
00174 {
00175 addFragment((*frag));
00176 }
00177 }
00178
00179 #endif