1 #ifndef artdaq_core_Data_ContainerFragmentLoader_hh
2 #define artdaq_core_Data_ContainerFragmentLoader_hh
13 #include "artdaq-core/Data/ContainerFragment.hh"
14 #include "artdaq-core/Data/Fragment.hh"
21 class ContainerFragmentLoader;
94 static size_t words_to_frag_words_(
size_t nWords);
96 void addSpace_(
size_t bytes);
98 uint8_t* dataBegin_() {
return reinterpret_cast<uint8_t*
>(&*artdaq_Fragment_.
dataBegin()); }
99 void* dataEnd_() {
return reinterpret_cast<void*
>(dataBegin_() +
lastFragmentIndex()); }
104 , artdaq_Fragment_(f)
116 if (artdaq_Fragment_.
size() !=
120 TLOG(TLVL_ERROR,
"ContainerFragmentLoader") <<
"ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object";
123 throw cet::exception(
"InvalidFragment") <<
"ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object";
126 artdaq_Fragment_.
resize(1);
130 inline size_t artdaq::ContainerFragmentLoader::words_to_frag_words_(
size_t nWords)
132 size_t mod = nWords % words_per_frag_word_();
133 return mod ? nWords / words_per_frag_word_() + 1 : nWords / words_per_frag_word_();
136 inline void artdaq::ContainerFragmentLoader::addSpace_(
size_t bytes)
139 artdaq_Fragment_.resizeBytesWithCushion(bytes + currSize, 1.3);
141 TLOG(TLVL_TRACE,
"ContainerFragmentLoader") <<
"addSpace_: dataEnd_ is now at " << (
void*)dataEnd_() <<
" (oldSizeBytes/deltaBytes: " << currSize <<
"/" << bytes <<
")";
146 TLOG(TLVL_TRACE,
"ContainerFragmentLoader") <<
"addFragment: Adding Fragment with payload size " << frag.
dataSizeBytes() <<
" to Container";
148 metadata()->fragment_type = frag.
type();
149 else if (frag.
type() != metadata()->fragment_type)
151 TLOG(TLVL_ERROR,
"ContainerFragmentLoader") <<
"addFragment: Trying to add a fragment of different type than what's already been added!";
152 throw cet::exception(
"WrongFragmentType") <<
"ContainerFragmentLoader::addFragment: Trying to add a fragment of different type than what's already been added!";
155 TLOG(TLVL_TRACE,
"ContainerFragmentLoader") <<
"addFragment: Payload Size is " << artdaq_Fragment_.dataSizeBytes() <<
", lastFragmentIndex is " << lastFragmentIndex() <<
", and frag.size is " << frag.
sizeBytes();
156 if (artdaq_Fragment_.dataSizeBytes() < (lastFragmentIndex() + frag.
sizeBytes() +
sizeof(size_t) * (metadata()->block_count + 2)))
158 addSpace_((lastFragmentIndex() + frag.
sizeBytes() +
sizeof(size_t) * (metadata()->block_count + 2)) - artdaq_Fragment_.dataSizeBytes());
161 TLOG(TLVL_TRACE,
"ContainerFragmentLoader") <<
"addFragment, copying " << frag.
sizeBytes() <<
" bytes from " << (
void*)frag.
headerAddress() <<
" to " << (
void*)dataEnd_();
163 metadata()->has_index = 0;
165 metadata()->block_count++;
167 auto index = create_index_();
168 metadata()->index_offset = index[metadata()->block_count - 1];
169 memcpy(dataBegin_() + metadata()->index_offset, index,
sizeof(
size_t) * (metadata()->block_count + 1));
171 metadata()->has_index = 1;
182 for (
auto& frag : frags)
184 addFragment((*frag));
std::unique_ptr< Fragment > FragmentPtr
A std::unique_ptr to a Fragment object.
The artdaq::ContainerFragment class represents a Fragment which contains other Fragments.
std::size_t dataSizeBytes() const
Return the number of bytes in the data payload. This does not include the number of bytes in the head...
void setSequenceID(sequence_id_t sequence_id)
Sets the Sequence ID of the Fragment.
void setSystemType(type_t stype)
Sets the type of the Fragment, checking that it is a valid system type.
std::size_t size() const
Gets the size of the Fragment, from the Fragment header.
void set_fragment_type(Fragment::type_t type)
Sets the type of Fragment which this ContainerFragment should contain.
A Read-Write version of the ContainerFragment, used for filling ContainerFragment objects with other ...
static constexpr type_t EmptyFragmentType
Copy EmptyFragmentType from RawFragmentHeader.
std::size_t sizeBytes() const
Size of vals_ vector ( header + (optional) metadata + payload) in bytes.
detail::RawFragmentHeader::type_t type_t
typedef for type_t from RawFragmentHeader
void resize(std::size_t sz)
Resize the data payload to hold sz RawDataType words.
static constexpr size_t CONTAINER_MAGIC
Marker word used in index.
size_t lastFragmentIndex() const
Returns the offset of the last Fragment in the ContainerFragment.
Metadata * metadata()
Get the ContainerFragment metadata (includes information about the location of Fragment objects withi...
void addFragment(artdaq::Fragment &frag)
Add a Fragment to the ContainerFragment by reference.
iterator dataBegin()
Return an iterator to the beginning of the data payload (after header and metadata) ...
QuickVec< RawDataType >::value_type value_type
Alias value_type type from QuickVec<RawDataType>
static constexpr type_t ContainerFragmentType
Copy ContainerFragmentType from RawFragmentHeader.
ContainerFragmentLoader(Fragment &f, Fragment::type_t expectedFragmentType)
Constructs the ContainerFragmentLoader.
void setMetadata(const T &md)
Set the metadata in the Fragment to the contents of the specified structure. This throws an exception...
type_t type() const
Type of the Fragment, from the Fragment header.
static constexpr uint8_t CURRENT_VERSION
The current version of the ContainerFragmentHeader.
RawDataType * metadataAddress()
Get the address of the metadata. For internal use only, use metadata() instead.
std::list< FragmentPtr > FragmentPtrs
A std::list of FragmentPtrs.
bool hasMetadata() const
Test whether this Fragment has metadata.
A Fragment contains the data from one piece of the DAQ system for one event The artdaq::Fragment is t...
void set_missing_data(bool isDataMissing)
Sets the missing_data flag.
void addFragments(artdaq::FragmentPtrs &frags)
Add a collection of Fragment objects to the ContainerFragment.
RawDataType * headerAddress()
Gets the address of the header.