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/Fragments.hh"
00015 #include "artdaq-core/Data/ContainerFragment.hh"
00016 #include "trace.h"
00017
00018 #include <iostream>
00019
00020 namespace artdaq {
00021 class ContainerFragmentLoader;
00022 }
00023
00024
00025 class artdaq::ContainerFragmentLoader : public artdaq::ContainerFragment {
00026 public:
00027
00028
00029 ContainerFragmentLoader(Fragment & f);
00030
00031 Metadata * metadata() {
00032 assert(artdaq_Fragment_.hasMetadata());
00033 return reinterpret_cast<Metadata *>(&*artdaq_Fragment_.metadataAddress());
00034 }
00035
00036 void set_fragment_type(Fragment::type_t type) {
00037 metadata()->fragment_type = type;
00038 }
00039
00040 void set_missing_data(bool isDataMissing) {
00041 metadata()->missing_data = isDataMissing;
00042 }
00043
00044 void addFragment(artdaq::Fragment & frag);
00045 void addFragment(artdaq::FragmentPtr& frag);
00046 void addFragments(artdaq::FragmentPtrs & frags);
00047
00048 private:
00049
00050 artdaq::Fragment & artdaq_Fragment_;
00051 static size_t words_to_frag_words_(size_t nWords);
00052 void addSpace_(size_t bytes);
00053 uint8_t* dataBegin_() { return reinterpret_cast<uint8_t*>(&*artdaq_Fragment_.dataBegin()); }
00054 void* dataEnd_() { return reinterpret_cast<void*>(dataBegin_() + lastFragmentIndex()); }
00055 };
00056
00057
00058
00059
00060
00061 artdaq::ContainerFragmentLoader::ContainerFragmentLoader(artdaq::Fragment& f) :
00062 ContainerFragment(f), artdaq_Fragment_(f) {
00063 artdaq_Fragment_.setSystemType(Fragment::ContainerFragmentType);
00064 Metadata m;
00065 m.block_count = 0;
00066 m.fragment_type = Fragment::EmptyFragmentType;
00067 m.missing_data = false;
00068 for (int ii = 0; ii < FRAGMENT_COUNT_MAX; ++ii) {
00069 m.index[ii] = 0;
00070 }
00071 artdaq_Fragment_.setMetadata<Metadata>(m);
00072
00073 if (artdaq_Fragment_.size() !=
00074 artdaq::detail::RawFragmentHeader::num_words() +
00075 words_to_frag_words_(Metadata::size_words))
00076 {
00077 std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
00078 std::cerr << "Expected size: " << artdaq::detail::RawFragmentHeader::num_words() +
00079 words_to_frag_words_(Metadata::size_words) << std::endl;
00080
00081 throw cet::exception("ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object");
00082 }
00083 }
00084
00085 inline size_t artdaq::ContainerFragmentLoader::words_to_frag_words_(size_t nWords)
00086 {
00087 size_t mod = nWords % words_per_frag_word_();
00088 return mod ?
00089 nWords / words_per_frag_word_() + 1 :
00090 nWords / words_per_frag_word_();
00091 }
00092
00093 void artdaq::ContainerFragmentLoader::addSpace_(size_t bytes)
00094 {
00095 auto currSize = sizeof(artdaq::Fragment::value_type) * artdaq_Fragment_.dataSize();
00096 artdaq_Fragment_.resizeBytes(bytes + currSize);
00097 TRACE(4, "ContainerFragmentLoader::addSpace_: dataEnd_ is now at %p", dataEnd_());
00098 }
00099
00100 void artdaq::ContainerFragmentLoader::addFragment(artdaq::Fragment & frag)
00101 {
00102 TRACE(4, "ContainerFragmentLoader::addFragment: Adding Fragment with payload size %llu to Container", (unsigned long long)frag.dataSizeBytes());
00103 if (metadata()->fragment_type == Fragment::EmptyFragmentType) metadata()->fragment_type = frag.type();
00104 else if (frag.type() != metadata()->fragment_type) {
00105 throw cet::exception("ContainerFragmentLoader::addFragment: Trying to add a fragment of different type than what's already been added!");
00106 }
00107 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());
00108 if (artdaq_Fragment_.dataSizeBytes() < lastFragmentIndex() + frag.sizeBytes()) {
00109 addSpace_(frag.sizeBytes());
00110 }
00111 frag.setSequenceID(artdaq_Fragment_.sequenceID());
00112 TRACE(4, "ContainerFragmentLoader::addFragment, copying %llu bytes from %p to %p", (long long unsigned int)frag.sizeBytes(), (void*)frag.headerAddress(), dataEnd_());
00113 memcpy(dataEnd_(), frag.headerAddress(), frag.sizeBytes());
00114 metadata()->index[block_count()] = lastFragmentIndex() + frag.sizeBytes();
00115 metadata()->block_count++;
00116 }
00117
00118 void artdaq::ContainerFragmentLoader::addFragment(artdaq::FragmentPtr & frag)
00119 {
00120 addFragment(*frag);
00121 }
00122
00123 void artdaq::ContainerFragmentLoader::addFragments(artdaq::FragmentPtrs & frags)
00124 {
00125 for (auto & frag : frags)
00126 {
00127 addFragment((*frag));
00128 }
00129 }
00130
00131 #endif