$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_05_04
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef artdaq_core_Data_ContainerFragmentLoader_hh 00002 #define artdaq_core_Data_ContainerFragmentLoader_hh 00003 00005 // ContainerFragmentLoader 00006 // 00007 // This class gives write access to a ContainerFragment. It should be 00008 // used when multiple fragments are generated by one BoardReader for a 00009 // single event. 00010 // 00012 00013 #include "artdaq-core/Data/ContainerFragment.hh" 00014 #include "artdaq-core/Data/Fragment.hh" 00015 00016 #include "tracemf.h" 00017 00018 #include <iostream> 00019 00020 namespace artdaq { 00021 class ContainerFragmentLoader; 00022 } 00023 00027 class artdaq::ContainerFragmentLoader : public artdaq::ContainerFragment 00028 { 00029 public: 00036 explicit ContainerFragmentLoader(Fragment& f, Fragment::type_t expectedFragmentType); 00037 00038 // ReSharper disable once CppMemberFunctionMayBeConst 00043 Metadata* metadata() 00044 { 00045 assert(artdaq_Fragment_.hasMetadata()); 00046 return reinterpret_cast<Metadata*>(&*artdaq_Fragment_.metadataAddress()); 00047 } 00048 00053 void set_fragment_type(Fragment::type_t type) 00054 { 00055 metadata()->fragment_type = type; 00056 } 00057 00066 void set_missing_data(bool isDataMissing) 00067 { 00068 metadata()->missing_data = isDataMissing; 00069 } 00070 00076 void addFragment(artdaq::Fragment& frag); 00077 00082 void addFragment(artdaq::FragmentPtr& frag); 00083 00088 void addFragments(artdaq::FragmentPtrs& frags); 00089 00090 private: 00091 // Note that this non-const reference hides the const reference in the base class 00092 artdaq::Fragment& artdaq_Fragment_; 00093 00094 static size_t words_to_frag_words_(size_t nWords); 00095 00096 void addSpace_(size_t bytes); 00097 00098 uint8_t* dataBegin_() { return reinterpret_cast<uint8_t*>(&*artdaq_Fragment_.dataBegin()); } 00099 void* dataEnd_() { return reinterpret_cast<void*>(dataBegin_() + lastFragmentIndex()); } 00100 }; 00101 00102 inline artdaq::ContainerFragmentLoader::ContainerFragmentLoader(artdaq::Fragment& f, artdaq::Fragment::type_t expectedFragmentType = Fragment::EmptyFragmentType) 00103 : ContainerFragment(f) 00104 , artdaq_Fragment_(f) 00105 { 00106 artdaq_Fragment_.setSystemType(Fragment::ContainerFragmentType); 00107 Metadata m; 00108 m.block_count = 0; 00109 m.fragment_type = expectedFragmentType; 00110 m.missing_data = false; 00111 m.has_index = true; 00112 m.version = ContainerFragment::CURRENT_VERSION; 00113 m.index_offset = 0; 00114 artdaq_Fragment_.setMetadata<Metadata>(m); 00115 00116 if (artdaq_Fragment_.size() != 00117 artdaq::detail::RawFragmentHeader::num_words() + 00118 words_to_frag_words_(Metadata::size_words)) 00119 { 00120 TLOG(TLVL_ERROR, "ContainerFragmentLoader") << "ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object"; 00121 TLOG(TLVL_ERROR, "ContainerFragmentLoader") << "artdaq_Fragment size: " << artdaq_Fragment_.size() << ", Expected size: " << artdaq::detail::RawFragmentHeader::num_words() + words_to_frag_words_(Metadata::size_words); 00122 00123 throw cet::exception("InvalidFragment") << "ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object"; 00124 } 00125 00126 artdaq_Fragment_.resize(1); 00127 *artdaq_Fragment_.dataBegin() = CONTAINER_MAGIC; 00128 } 00129 00130 inline size_t artdaq::ContainerFragmentLoader::words_to_frag_words_(size_t nWords) 00131 { 00132 size_t mod = nWords % words_per_frag_word_(); 00133 return mod ? nWords / words_per_frag_word_() + 1 : nWords / words_per_frag_word_(); 00134 } 00135 00136 inline void artdaq::ContainerFragmentLoader::addSpace_(size_t bytes) 00137 { 00138 auto currSize = sizeof(artdaq::Fragment::value_type) * artdaq_Fragment_.dataSize(); // Resize takes into account header and metadata size 00139 artdaq_Fragment_.resizeBytesWithCushion(bytes + currSize, 1.3); 00140 reset_index_ptr_(); // Must reset index_ptr after resize operation! 00141 TLOG(TLVL_TRACE, "ContainerFragmentLoader") << "addSpace_: dataEnd_ is now at " << (void*)dataEnd_() << " (oldSizeBytes/deltaBytes: " << currSize << "/" << bytes << ")"; 00142 } 00143 00144 inline void artdaq::ContainerFragmentLoader::addFragment(artdaq::Fragment& frag) 00145 { 00146 TLOG(TLVL_TRACE, "ContainerFragmentLoader") << "addFragment: Adding Fragment with payload size " << frag.dataSizeBytes() << " to Container"; 00147 if (metadata()->fragment_type == Fragment::EmptyFragmentType) 00148 metadata()->fragment_type = frag.type(); 00149 else if (frag.type() != metadata()->fragment_type) 00150 { 00151 TLOG(TLVL_ERROR, "ContainerFragmentLoader") << "addFragment: Trying to add a fragment of different type than what's already been added!"; 00152 throw cet::exception("WrongFragmentType") << "ContainerFragmentLoader::addFragment: Trying to add a fragment of different type than what's already been added!"; 00153 } 00154 00155 TLOG(TLVL_TRACE, "ContainerFragmentLoader") << "addFragment: Payload Size is " << artdaq_Fragment_.dataSizeBytes() << ", lastFragmentIndex is " << lastFragmentIndex() << ", and frag.size is " << frag.sizeBytes(); 00156 if (artdaq_Fragment_.dataSizeBytes() < (lastFragmentIndex() + frag.sizeBytes() + sizeof(size_t) * (metadata()->block_count + 2))) 00157 { 00158 addSpace_((lastFragmentIndex() + frag.sizeBytes() + sizeof(size_t) * (metadata()->block_count + 2)) - artdaq_Fragment_.dataSizeBytes()); 00159 } 00160 frag.setSequenceID(artdaq_Fragment_.sequenceID()); 00161 TLOG(TLVL_TRACE, "ContainerFragmentLoader") << "addFragment, copying " << frag.sizeBytes() << " bytes from " << (void*)frag.headerAddress() << " to " << (void*)dataEnd_(); 00162 memcpy(dataEnd_(), frag.headerAddress(), frag.sizeBytes()); 00163 metadata()->has_index = 0; 00164 00165 metadata()->block_count++; 00166 00167 auto index = create_index_(); 00168 metadata()->index_offset = index[metadata()->block_count - 1]; 00169 memcpy(dataBegin_() + metadata()->index_offset, index, sizeof(size_t) * (metadata()->block_count + 1)); 00170 delete[] index; 00171 metadata()->has_index = 1; 00172 reset_index_ptr_(); 00173 } 00174 00175 inline void artdaq::ContainerFragmentLoader::addFragment(artdaq::FragmentPtr& frag) 00176 { 00177 addFragment(*frag); 00178 } 00179 00180 inline void artdaq::ContainerFragmentLoader::addFragments(artdaq::FragmentPtrs& frags) 00181 { 00182 for (auto& frag : frags) 00183 { 00184 addFragment((*frag)); 00185 } 00186 } 00187 00188 #endif /* artdaq_core_Data_ContainerFragmentLoader_hh */