00001 #ifndef artdaq_core_Data_Fragment_hh
00002 #define artdaq_core_Data_Fragment_hh
00003
00004 #include <algorithm>
00005
00006 #include <cstddef>
00007 #include <iosfwd>
00008 #include <iterator>
00009 #include <vector>
00010 #include <list>
00011 #include <memory>
00012 #include <map>
00013 #include <cmath>
00014 #include <stdint.h>
00015 #include <string.h>
00016
00017 #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
00018 #include "artdaq-core/Data/detail/RawFragmentHeaderV0.hh"
00019 #include "artdaq-core/Data/dictionarycontrol.hh"
00020 #include "artdaq-core/Core/QuickVec.hh"
00021 #include <iostream>
00022 #include "trace.h"
00023
00027 namespace artdaq {
00028 # define DATAVEC_T QuickVec<RawDataType>
00029
00030
00037 typedef detail::RawFragmentHeader::RawDataType RawDataType;
00038
00039 class Fragment;
00043 typedef std::vector<Fragment> Fragments;
00044
00051 typedef std::unique_ptr<Fragment> FragmentPtr;
00052
00056 typedef std::list<FragmentPtr> FragmentPtrs;
00057
00064 bool fragmentSequenceIDCompare(Fragment i, Fragment j);
00065
00072 std::ostream& operator<<(std::ostream& os, Fragment const& f);
00073 }
00074
00082 class artdaq::Fragment
00083 {
00084 public:
00088 Fragment();
00089
00097 typedef uint8_t byte_t;
00098
00099
00100 #if HIDE_FROM_ROOT
00101
00102
00103
00108 Fragment(const Fragment&) = default;
00116 Fragment(Fragment&&) noexcept;
00122 Fragment& operator=(const Fragment&) = default;
00131 Fragment& operator=(Fragment&&) noexcept;
00132
00133 typedef detail::RawFragmentHeader::version_t version_t;
00134 typedef detail::RawFragmentHeader::type_t type_t;
00135 typedef detail::RawFragmentHeader::sequence_id_t sequence_id_t;
00136 typedef detail::RawFragmentHeader::fragment_id_t fragment_id_t;
00137 typedef detail::RawFragmentHeader::timestamp_t timestamp_t;
00138
00139 static constexpr version_t InvalidVersion = detail::RawFragmentHeader::InvalidVersion;
00140 static constexpr sequence_id_t InvalidSequenceID = detail::RawFragmentHeader::InvalidSequenceID;
00141 static constexpr fragment_id_t InvalidFragmentID = detail::RawFragmentHeader::InvalidFragmentID;
00142 static constexpr timestamp_t InvalidTimestamp = detail::RawFragmentHeader::InvalidTimestamp;
00143
00144 static constexpr type_t InvalidFragmentType = detail::RawFragmentHeader::InvalidFragmentType;
00145 static constexpr type_t EndOfDataFragmentType = detail::RawFragmentHeader::EndOfDataFragmentType;
00146 static constexpr type_t DataFragmentType = detail::RawFragmentHeader::DataFragmentType;
00147 static constexpr type_t InitFragmentType = detail::RawFragmentHeader::InitFragmentType;
00148 static constexpr type_t EndOfRunFragmentType = detail::RawFragmentHeader::EndOfRunFragmentType;
00149 static constexpr type_t EndOfSubrunFragmentType = detail::RawFragmentHeader::EndOfSubrunFragmentType;
00150 static constexpr type_t ShutdownFragmentType = detail::RawFragmentHeader::ShutdownFragmentType;
00151 static constexpr type_t FirstUserFragmentType = detail::RawFragmentHeader::FIRST_USER_TYPE;
00152 static constexpr type_t EmptyFragmentType = detail::RawFragmentHeader::EmptyFragmentType;
00153 static constexpr type_t ContainerFragmentType = detail::RawFragmentHeader::ContainerFragmentType;
00154
00160 static constexpr bool isUserFragmentType(type_t fragmentType);
00161
00167 static constexpr bool isSystemFragmentType(type_t fragmentType);
00168
00173 static std::map<type_t, std::string> MakeSystemTypeMap()
00174 {
00175 return detail::RawFragmentHeader::MakeSystemTypeMap();
00176 }
00177
00178 typedef DATAVEC_T::reference reference;
00179 typedef DATAVEC_T::iterator iterator;
00180 typedef DATAVEC_T::const_iterator const_iterator;
00181 typedef DATAVEC_T::value_type value_type;
00182 typedef DATAVEC_T::difference_type difference_type;
00183 typedef DATAVEC_T::size_type size_type;
00184
00190 explicit Fragment(std::size_t n);
00191
00198 static FragmentPtr FragmentBytes(std::size_t nbytes)
00199 {
00200 RawDataType nwords = ceil(nbytes / static_cast<double>(sizeof(RawDataType)));
00201 return FragmentPtr(new Fragment(nwords));
00202 }
00203
00214 template <class T>
00215 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00216 fragment_id_t fragment_id, type_t type, const T& metadata,
00217 timestamp_t timestamp = Fragment::InvalidTimestamp);
00218
00232 template <class T>
00233 static FragmentPtr FragmentBytes(std::size_t payload_size_in_bytes,
00234 sequence_id_t sequence_id,
00235 fragment_id_t fragment_id,
00236 type_t type, const T& metadata,
00237 timestamp_t timestamp = Fragment::InvalidTimestamp)
00238 {
00239 RawDataType nwords = ceil(payload_size_in_bytes /
00240 static_cast<double>(sizeof(RawDataType)));
00241 return FragmentPtr(new Fragment(nwords, sequence_id, fragment_id, type, metadata, timestamp));
00242 }
00243
00251 Fragment(sequence_id_t sequenceID,
00252 fragment_id_t fragID,
00253 type_t type = Fragment::DataFragmentType,
00254 timestamp_t timestamp = Fragment::InvalidTimestamp);
00255
00260 void print(std::ostream& os) const;
00261
00266 std::size_t size() const;
00267
00272 version_t version() const;
00273
00278 type_t type() const;
00279
00284 std::string typeString() const;
00285
00290 sequence_id_t sequenceID() const;
00291
00296 fragment_id_t fragmentID() const;
00297
00302 timestamp_t timestamp() const;
00303
00308 void setUserType(type_t utype);
00309
00314 void setSystemType(type_t stype);
00315
00320 void setSequenceID(sequence_id_t sequence_id);
00321
00326 void setFragmentID(fragment_id_t fragment_id);
00327
00332 void setTimestamp(timestamp_t timestamp);
00333
00338 std::size_t sizeBytes() const { return sizeof(RawDataType) * size(); }
00339
00345 std::size_t dataSize() const;
00346
00347
00353 std::size_t dataSizeBytes() const
00354 {
00355 return sizeof(RawDataType) * dataSize();
00356 }
00357
00362 bool hasMetadata() const;
00363
00371 template <class T>
00372 T* metadata();
00373
00381 template <class T>
00382 T const* metadata() const;
00383
00392 template <class T>
00393 void setMetadata(const T& md);
00394
00402 template <class T>
00403 void updateMetadata(const T& md);
00404
00409 void resize(std::size_t sz);
00410
00416 void resize(std::size_t sz, RawDataType val);
00417
00424 void resizeBytes(std::size_t szbytes);
00425
00433 void resizeBytes(std::size_t szbytes, byte_t val);
00434
00438 void autoResize();
00439
00444 iterator dataBegin();
00445
00450 iterator dataEnd();
00451
00471 template <typename T>
00472 T reinterpret_cast_checked(const RawDataType* in) const
00473 {
00474 T newpointer = reinterpret_cast<T>(in);
00475
00476 if (static_cast<const void*>(newpointer) != static_cast<const void*>(in))
00477 {
00478 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00479 }
00480
00481 return newpointer;
00482 }
00483
00499 template <typename T>
00500 T reinterpret_cast_checked(RawDataType* in)
00501 {
00502 T newpointer = reinterpret_cast<T>(in);
00503
00504 if (static_cast<void*>(newpointer) != static_cast<void*>(in))
00505 {
00506 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00507 }
00508
00509 return newpointer;
00510 }
00511
00520 byte_t* dataBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* dataBegin()); }
00521
00530 byte_t* dataEndBytes() { return reinterpret_cast_checked<byte_t*>(&* dataEnd()); }
00531
00537 iterator headerBegin();
00538
00543 byte_t* headerBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* headerBegin()); }
00544
00549 const_iterator dataBegin() const;
00550
00555 const_iterator dataEnd() const;
00556
00565 const byte_t* dataBeginBytes() const
00566 {
00567 return reinterpret_cast_checked<const byte_t*>(&* dataBegin());
00568 }
00569
00578 const byte_t* dataEndBytes() const
00579 {
00580 return reinterpret_cast_checked<const byte_t*>(&* dataEnd());
00581 }
00582
00588 const_iterator headerBegin() const;
00589
00594 const byte_t* headerBeginBytes() const
00595 {
00596 return reinterpret_cast_checked<const byte_t*>(&* headerBegin());
00597 }
00598
00602 void clear();
00603
00608 bool empty();
00609
00614 void reserve(std::size_t cap);
00615
00620 void swap(Fragment& other) noexcept;
00621
00628 void swap(DATAVEC_T& other) noexcept { vals_.swap(other); };
00629
00634 RawDataType* dataAddress();
00635
00642 RawDataType* metadataAddress();
00647 RawDataType* headerAddress();
00648
00654 static FragmentPtr eodFrag(size_t nFragsToExpect);
00655
00667 template<class InputIterator> static FragmentPtr dataFrag(sequence_id_t sequenceID,
00668 fragment_id_t fragID,
00669 InputIterator i,
00670 InputIterator e)
00671 {
00672 FragmentPtr result(new Fragment(sequenceID, fragID));
00673 result->vals_.reserve(std::distance(i, e) + detail::RawFragmentHeader::num_words());
00674 std::copy(i, e, std::back_inserter(result->vals_));
00675 result->updateFragmentHeaderWC_();
00676 return result;
00677 }
00678
00688 static FragmentPtr dataFrag(sequence_id_t sequenceID,
00689 fragment_id_t fragID,
00690 RawDataType const* dataPtr,
00691 size_t dataSize,
00692 timestamp_t timestamp = Fragment::InvalidTimestamp);
00693 #endif
00694
00695 private:
00696 template <typename T>
00697 static std::size_t validatedMetadataSize_();
00698
00699 void updateFragmentHeaderWC_();
00700
00701 DATAVEC_T vals_;
00702
00703 #if HIDE_FROM_ROOT
00704 detail::RawFragmentHeader* fragmentHeader();
00705
00706 detail::RawFragmentHeader const* fragmentHeader() const;
00707 #endif
00708 };
00709
00710 #if HIDE_FROM_ROOT
00711
00712
00713
00714
00715 inline artdaq::Fragment::Fragment(artdaq::Fragment&&) noexcept = default;
00716 inline artdaq::Fragment& artdaq::Fragment::operator=(artdaq::Fragment&&) noexcept = default;
00717
00718 inline
00719 bool
00720 constexpr
00721 artdaq::Fragment::
00722 isUserFragmentType(type_t fragmentType)
00723 {
00724 return fragmentType >= detail::RawFragmentHeader::FIRST_USER_TYPE &&
00725 fragmentType <= detail::RawFragmentHeader::LAST_USER_TYPE;
00726 }
00727
00728 inline
00729 bool
00730 constexpr
00731 artdaq::Fragment::
00732 isSystemFragmentType(type_t fragmentType)
00733 {
00734 return fragmentType >= detail::RawFragmentHeader::FIRST_SYSTEM_TYPE;
00735 }
00736
00737 template <typename T>
00738 std::size_t
00739 artdaq::Fragment::
00740 validatedMetadataSize_()
00741 {
00742
00743
00744
00745 static_assert(sizeof(size_t) >=
00746 sizeof(decltype(std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max())),
00747 "metadata_word_count_t is too big!");
00748
00749 static size_t constexpr max_md_wc =
00750 std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max();
00751 size_t requested_md_wc =
00752 std::ceil(sizeof(T) / static_cast<double>(sizeof(artdaq::RawDataType)));
00753 if (requested_md_wc > max_md_wc)
00754 {
00755 throw cet::exception("InvalidRequest")
00756 << "The requested metadata structure is too large: "
00757 << "requested word count = " << requested_md_wc
00758 << ", maximum word count = " << max_md_wc;
00759 }
00760 return requested_md_wc;
00761 }
00762
00763 template <class T>
00764 artdaq::Fragment::
00765 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00766 fragment_id_t fragment_id,
00767 type_t type, const T& metadata, timestamp_t timestamp) :
00768 vals_((artdaq::detail::RawFragmentHeader::num_words() +
00769 validatedMetadataSize_<T>() +
00770 payload_size)
00771 )
00772 {
00773 TRACE( 50, "Fragment ctor num_word()=%zu MetadataSize_=%zu payload_size=%zu"
00774 ,artdaq::detail::RawFragmentHeader::num_words(), validatedMetadataSize_<T>(), payload_size );
00775
00776 for (iterator ii = vals_.begin();
00777 ii != (vals_.begin() + detail::RawFragmentHeader::num_words()); ++ii) {
00778 *ii = -1;
00779 }
00780 fragmentHeader()->version = detail::RawFragmentHeader::CurrentVersion;
00781 updateFragmentHeaderWC_();
00782 fragmentHeader()->sequence_id = sequence_id;
00783 fragmentHeader()->fragment_id = fragment_id;
00784 fragmentHeader()->timestamp = timestamp;
00785 fragmentHeader()->type = type;
00786
00787 fragmentHeader()->metadata_word_count =
00788 vals_.size() -
00789 (fragmentHeader()->num_words() + payload_size);
00790
00791 memcpy(metadataAddress(), &metadata, sizeof(T));
00792 }
00793
00794 inline
00795 std::size_t
00796 artdaq::Fragment::size() const
00797 {
00798 return fragmentHeader()->word_count;
00799 }
00800
00801 inline
00802 artdaq::Fragment::version_t
00803 artdaq::Fragment::version() const
00804 {
00805 return fragmentHeader()->version;
00806 }
00807
00808 inline
00809 artdaq::Fragment::type_t
00810 artdaq::Fragment::type() const
00811 {
00812 return static_cast<type_t>(fragmentHeader()->type);
00813 }
00814
00815 inline
00816 std::string
00817 artdaq::Fragment::typeString() const
00818 {
00819 return std::to_string(type()) + (isSystemFragmentType(type()) ? " (" + detail::RawFragmentHeader::SystemTypeToString(type()) + ")" : "");
00820 }
00821
00822 inline
00823 artdaq::Fragment::sequence_id_t
00824 artdaq::Fragment::sequenceID() const
00825 {
00826 return fragmentHeader()->sequence_id;
00827 }
00828
00829 inline
00830 artdaq::Fragment::fragment_id_t
00831 artdaq::Fragment::fragmentID() const
00832 {
00833 return fragmentHeader()->fragment_id;
00834 }
00835
00836 inline
00837 artdaq::Fragment::timestamp_t
00838 artdaq::Fragment::timestamp() const
00839 {
00840 return fragmentHeader()->timestamp;
00841 }
00842
00843 inline
00844 void
00845 artdaq::Fragment::setUserType(type_t type)
00846 {
00847 fragmentHeader()->setUserType(static_cast<uint8_t>(type));
00848 }
00849
00850 inline
00851 void
00852 artdaq::Fragment::setSystemType(type_t type)
00853 {
00854 fragmentHeader()->setSystemType(static_cast<uint8_t>(type));
00855 }
00856
00857 inline
00858 void
00859 artdaq::Fragment::setSequenceID(sequence_id_t sequence_id)
00860 {
00861 assert(sequence_id <= detail::RawFragmentHeader::InvalidSequenceID);
00862 fragmentHeader()->sequence_id = sequence_id;
00863 }
00864
00865 inline
00866 void
00867 artdaq::Fragment::setFragmentID(fragment_id_t fragment_id)
00868 {
00869 fragmentHeader()->fragment_id = fragment_id;
00870 }
00871
00872 inline
00873 void
00874 artdaq::Fragment::setTimestamp(timestamp_t timestamp)
00875 {
00876 fragmentHeader()->timestamp = timestamp;
00877 }
00878
00879 inline
00880 void
00881 artdaq::Fragment::updateFragmentHeaderWC_()
00882 {
00883
00884
00885 assert(vals_.size() < (1ULL << 32));
00886 TRACE( 50, "Fragment::updateFragmentHeaderWC_ adjusting fragmentHeader()->word_count from %u to %zu", (unsigned)(fragmentHeader()->word_count), vals_.size() );
00887 fragmentHeader()->word_count = vals_.size();
00888 }
00889
00890 inline
00891 std::size_t
00892 artdaq::Fragment::dataSize() const
00893 {
00894 return vals_.size() - fragmentHeader()->num_words() -
00895 fragmentHeader()->metadata_word_count;
00896 }
00897
00898 inline
00899 bool
00900 artdaq::Fragment::hasMetadata() const
00901 {
00902 return fragmentHeader()->metadata_word_count != 0;
00903 }
00904
00905 template <class T>
00906 T*
00907 artdaq::Fragment::metadata()
00908 {
00909 if (fragmentHeader()->metadata_word_count == 0)
00910 {
00911 throw cet::exception("InvalidRequest")
00912 << "No metadata has been stored in this Fragment.";
00913 }
00914
00915 return reinterpret_cast_checked<T *>
00916 (&vals_[fragmentHeader()->num_words()]);
00917 }
00918
00919 template <class T>
00920 T const*
00921 artdaq::Fragment::metadata() const
00922 {
00923 if (fragmentHeader()->metadata_word_count == 0)
00924 {
00925 throw cet::exception("InvalidRequest")
00926 << "No metadata has been stored in this Fragment.";
00927 }
00928 return reinterpret_cast_checked<T const *>
00929 (&vals_[fragmentHeader()->num_words()]);
00930 }
00931
00932 template <class T>
00933 void
00934 artdaq::Fragment::setMetadata(const T& metadata)
00935 {
00936 if (fragmentHeader()->metadata_word_count != 0)
00937 {
00938 throw cet::exception("InvalidRequest")
00939 << "Metadata has already been stored in this Fragment.";
00940 }
00941 auto const mdSize = validatedMetadataSize_<T>();
00942 vals_.insert(dataBegin(), mdSize, 0);
00943 updateFragmentHeaderWC_();
00944 fragmentHeader()->metadata_word_count = mdSize;
00945
00946 memcpy(metadataAddress(), &metadata, sizeof(T));
00947 }
00948
00949 template <class T>
00950 void
00951 artdaq::Fragment::updateMetadata(const T& metadata)
00952 {
00953 if (fragmentHeader()->metadata_word_count == 0)
00954 {
00955 throw cet::exception("InvalidRequest")
00956 << "No metadata in fragment; please use Fragment::setMetadata instead of Fragment::updateMetadata";
00957 }
00958
00959 auto const mdSize = validatedMetadataSize_<T>();
00960
00961 if (fragmentHeader()->metadata_word_count != mdSize)
00962 {
00963 throw cet::exception("InvalidRequest")
00964 << "Mismatch between type of metadata struct passed to updateMetadata and existing metadata struct";
00965 }
00966
00967 memcpy(metadataAddress(), &metadata, sizeof(T));
00968 }
00969
00970 inline void
00971 artdaq::Fragment::resize(std::size_t sz)
00972 {
00973 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00974 fragmentHeader()->num_words());
00975 updateFragmentHeaderWC_();
00976 }
00977
00978 inline
00979 void
00980 artdaq::Fragment::resize(std::size_t sz, RawDataType v)
00981 {
00982 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00983 fragmentHeader()->num_words(), v);
00984 updateFragmentHeaderWC_();
00985 }
00986
00987 inline void
00988 artdaq::Fragment::resizeBytes(std::size_t szbytes)
00989 {
00990 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
00991 resize(nwords);
00992 }
00993
00994 inline
00995 void
00996 artdaq::Fragment::resizeBytes(std::size_t szbytes, byte_t v)
00997 {
00998 RawDataType defaultval;
00999 byte_t* ptr = reinterpret_cast_checked<byte_t*>(&defaultval);
01000
01001 for (uint8_t i = 0; i < sizeof(RawDataType); ++i)
01002 {
01003 *ptr = v;
01004 ptr++;
01005 }
01006
01007 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
01008
01009 resize(nwords, defaultval);
01010 }
01011
01012
01013 inline
01014 void
01015 artdaq::Fragment::autoResize()
01016 {
01017 vals_.resize(fragmentHeader()->word_count);
01018 updateFragmentHeaderWC_();
01019 }
01020
01021 inline
01022 artdaq::Fragment::iterator
01023 artdaq::Fragment::dataBegin()
01024 {
01025 return vals_.begin() + fragmentHeader()->num_words() +
01026 fragmentHeader()->metadata_word_count;
01027 }
01028
01029 inline
01030 artdaq::Fragment::iterator
01031 artdaq::Fragment::dataEnd()
01032 {
01033 return vals_.end();
01034 }
01035
01036 inline
01037 artdaq::Fragment::iterator
01038 artdaq::Fragment::headerBegin()
01039 {
01040 return vals_.begin();
01041 }
01042
01043 inline
01044 artdaq::Fragment::const_iterator
01045 artdaq::Fragment::dataBegin() const
01046 {
01047 return vals_.begin() + fragmentHeader()->num_words() +
01048 fragmentHeader()->metadata_word_count;
01049 }
01050
01051 inline
01052 artdaq::Fragment::const_iterator
01053 artdaq::Fragment::dataEnd() const
01054 {
01055 return vals_.end();
01056 }
01057
01058 inline
01059 artdaq::Fragment::const_iterator
01060 artdaq::Fragment::headerBegin() const
01061 {
01062 return vals_.begin();
01063 }
01064
01065
01066 inline
01067 void
01068 artdaq::Fragment::clear()
01069 {
01070 vals_.erase(dataBegin(), dataEnd());
01071 updateFragmentHeaderWC_();
01072 }
01073
01074 inline
01075 bool
01076 artdaq::Fragment::empty()
01077 {
01078 return (vals_.size() - fragmentHeader()->num_words() -
01079 fragmentHeader()->metadata_word_count) == 0;
01080 }
01081
01082 inline
01083 void
01084 artdaq::Fragment::reserve(std::size_t cap)
01085 {
01086 vals_.reserve(cap + fragmentHeader()->num_words() +
01087 fragmentHeader()->metadata_word_count);
01088 }
01089
01090 inline
01091 void
01092 artdaq::Fragment::swap(Fragment& other) noexcept
01093 {
01094 vals_.swap(other.vals_);
01095 }
01096
01097 inline
01098 artdaq::RawDataType*
01099 artdaq::Fragment::dataAddress()
01100 {
01101 return &vals_[0] + fragmentHeader()->num_words() +
01102 fragmentHeader()->metadata_word_count;
01103 }
01104
01105 inline
01106 artdaq::RawDataType*
01107 artdaq::Fragment::metadataAddress()
01108 {
01109 if (fragmentHeader()->metadata_word_count == 0)
01110 {
01111 throw cet::exception("InvalidRequest")
01112 << "No metadata has been stored in this Fragment.";
01113 }
01114 return &vals_[0] + fragmentHeader()->num_words();
01115 }
01116
01117 inline
01118 artdaq::RawDataType*
01119 artdaq::Fragment::headerAddress()
01120 {
01121 return &vals_[0];
01122 }
01123
01124 inline
01125 artdaq::detail::RawFragmentHeader*
01126 artdaq::Fragment::fragmentHeader()
01127 {
01128 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader *>(&vals_[0]);
01129 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01130 {
01131 switch (hdr->version)
01132 {
01133 case 0xFFFF:
01134
01135 break;
01136 case 0:
01137 {
01138 std::cout << "Upgrading RawFragmentHeaderV0 (non const)" << std::endl;
01139 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 *>(&vals_[0]);
01140 auto new_hdr = old_hdr->upgrade();
01141
01142 auto szDiff = hdr->num_words() - old_hdr->num_words();
01143 if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
01144 memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01145 }
01146 break;
01147 default:
01148 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01149 break;
01150 }
01151 }
01152 return hdr;
01153 }
01154
01155 inline
01156 artdaq::detail::RawFragmentHeader const*
01157 artdaq::Fragment::fragmentHeader() const
01158 {
01159 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
01160 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01161 {
01162 switch (hdr->version)
01163 {
01164 case 0xFFFF:
01165
01166 break;
01167 case 0:
01168 {
01169 std::cout << "Upgrading RawFragmentHeaderV0 (const)" << std::endl;
01170 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
01171 auto new_hdr = old_hdr->upgrade();
01172
01173 auto szDiff = hdr->num_words() - old_hdr->num_words();
01174 auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
01175 if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
01176 memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01177 }
01178 break;
01179 default:
01180 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01181 break;
01182 }
01183 }
01184 return hdr;
01185 }
01186
01187 inline
01188 void
01189 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
01190 {
01191 x.swap(y);
01192 }
01193
01194 inline
01195 std::ostream&
01196 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
01197 {
01198 f.print(os);
01199 return os;
01200 }
01201 #endif
01202
01203 #endif