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 <memory>
00011 #include <map>
00012 #include <cmath>
00013 #include <stdint.h>
00014 #include <string.h>
00015
00016 #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
00017 #include "artdaq-core/Data/detail/RawFragmentHeaderV0.hh"
00018 #include "artdaq-core/Data/dictionarycontrol.hh"
00019 #include "artdaq-core/Core/QuickVec.hh"
00020 #include <iostream>
00021
00025 namespace artdaq {
00026 # define DATAVEC_T QuickVec<RawDataType>
00027
00028
00035 typedef detail::RawFragmentHeader::RawDataType RawDataType;
00036
00037 class Fragment;
00041 typedef std::vector<Fragment> Fragments;
00042
00049 typedef std::unique_ptr<Fragment> FragmentPtr;
00050
00054 typedef std::list<FragmentPtr> FragmentPtrs;
00055
00062 bool fragmentSequenceIDCompare(Fragment i, Fragment j);
00063
00070 std::ostream& operator<<(std::ostream& os, Fragment const& f);
00071 }
00072
00080 class artdaq::Fragment
00081 {
00082 public:
00086 Fragment();
00087
00095 typedef uint8_t byte_t;
00096
00097
00098 #if HIDE_FROM_ROOT
00099
00100
00101
00106 Fragment(const Fragment&) = default;
00114 Fragment(Fragment&&) noexcept;
00120 Fragment& operator=(const Fragment&) = default;
00129 Fragment& operator=(Fragment&&) noexcept;
00130
00131 typedef detail::RawFragmentHeader::version_t version_t;
00132 typedef detail::RawFragmentHeader::type_t type_t;
00133 typedef detail::RawFragmentHeader::sequence_id_t sequence_id_t;
00134 typedef detail::RawFragmentHeader::fragment_id_t fragment_id_t;
00135 typedef detail::RawFragmentHeader::timestamp_t timestamp_t;
00136
00137 static constexpr version_t InvalidVersion = detail::RawFragmentHeader::InvalidVersion;
00138 static constexpr sequence_id_t InvalidSequenceID = detail::RawFragmentHeader::InvalidSequenceID;
00139 static constexpr fragment_id_t InvalidFragmentID = detail::RawFragmentHeader::InvalidFragmentID;
00140 static constexpr timestamp_t InvalidTimestamp = detail::RawFragmentHeader::InvalidTimestamp;
00141
00142 static constexpr type_t InvalidFragmentType = detail::RawFragmentHeader::InvalidFragmentType;
00143 static constexpr type_t EndOfDataFragmentType = detail::RawFragmentHeader::EndOfDataFragmentType;
00144 static constexpr type_t DataFragmentType = detail::RawFragmentHeader::DataFragmentType;
00145 static constexpr type_t InitFragmentType = detail::RawFragmentHeader::InitFragmentType;
00146 static constexpr type_t EndOfRunFragmentType = detail::RawFragmentHeader::EndOfRunFragmentType;
00147 static constexpr type_t EndOfSubrunFragmentType = detail::RawFragmentHeader::EndOfSubrunFragmentType;
00148 static constexpr type_t ShutdownFragmentType = detail::RawFragmentHeader::ShutdownFragmentType;
00149 static constexpr type_t FirstUserFragmentType = detail::RawFragmentHeader::FIRST_USER_TYPE;
00150 static constexpr type_t EmptyFragmentType = detail::RawFragmentHeader::EmptyFragmentType;
00151 static constexpr type_t ContainerFragmentType = detail::RawFragmentHeader::ContainerFragmentType;
00152
00158 static constexpr bool isUserFragmentType(type_t fragmentType);
00159
00165 static constexpr bool isSystemFragmentType(type_t fragmentType);
00166
00171 static std::map<type_t, std::string> MakeSystemTypeMap()
00172 {
00173 return detail::RawFragmentHeader::MakeSystemTypeMap();
00174 }
00175
00176 typedef DATAVEC_T::reference reference;
00177 typedef DATAVEC_T::iterator iterator;
00178 typedef DATAVEC_T::const_iterator const_iterator;
00179 typedef DATAVEC_T::value_type value_type;
00180 typedef DATAVEC_T::difference_type difference_type;
00181 typedef DATAVEC_T::size_type size_type;
00182
00188 explicit Fragment(std::size_t n);
00189
00196 static FragmentPtr FragmentBytes(std::size_t nbytes)
00197 {
00198 RawDataType nwords = ceil(nbytes / static_cast<double>(sizeof(RawDataType)));
00199 return FragmentPtr(new Fragment(nwords));
00200 }
00201
00212 template <class T>
00213 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00214 fragment_id_t fragment_id, type_t type, const T& metadata,
00215 timestamp_t timestamp = Fragment::InvalidTimestamp);
00216
00230 template <class T>
00231 static FragmentPtr FragmentBytes(std::size_t payload_size_in_bytes,
00232 sequence_id_t sequence_id,
00233 fragment_id_t fragment_id,
00234 type_t type, const T& metadata,
00235 timestamp_t timestamp = Fragment::InvalidTimestamp)
00236 {
00237 RawDataType nwords = ceil(payload_size_in_bytes /
00238 static_cast<double>(sizeof(RawDataType)));
00239 return FragmentPtr(new Fragment(nwords, sequence_id, fragment_id, type, metadata, timestamp));
00240 }
00241
00249 Fragment(sequence_id_t sequenceID,
00250 fragment_id_t fragID,
00251 type_t type = Fragment::DataFragmentType,
00252 timestamp_t timestamp = Fragment::InvalidTimestamp);
00253
00258 void print(std::ostream& os) const;
00259
00264 std::size_t size() const;
00265
00270 version_t version() const;
00271
00276 type_t type() const;
00277
00282 sequence_id_t sequenceID() const;
00283
00288 fragment_id_t fragmentID() const;
00289
00294 timestamp_t timestamp() const;
00295
00300 void setUserType(type_t utype);
00301
00306 void setSystemType(type_t stype);
00307
00312 void setSequenceID(sequence_id_t sequence_id);
00313
00318 void setFragmentID(fragment_id_t fragment_id);
00319
00324 void setTimestamp(timestamp_t timestamp);
00325
00330 std::size_t sizeBytes() const { return sizeof(RawDataType) * size(); }
00331
00337 std::size_t dataSize() const;
00338
00339
00345 std::size_t dataSizeBytes() const
00346 {
00347 return sizeof(RawDataType) * dataSize();
00348 }
00349
00354 bool hasMetadata() const;
00355
00363 template <class T>
00364 T* metadata();
00365
00373 template <class T>
00374 T const* metadata() const;
00375
00384 template <class T>
00385 void setMetadata(const T& md);
00386
00394 template <class T>
00395 void updateMetadata(const T& md);
00396
00401 void resize(std::size_t sz);
00402
00408 void resize(std::size_t sz, RawDataType val);
00409
00416 void resizeBytes(std::size_t szbytes);
00417
00425 void resizeBytes(std::size_t szbytes, byte_t val);
00426
00430 void autoResize();
00431
00436 iterator dataBegin();
00437
00442 iterator dataEnd();
00443
00463 template <typename T>
00464 T reinterpret_cast_checked(const RawDataType* in) const
00465 {
00466 T newpointer = reinterpret_cast<T>(in);
00467
00468 if (static_cast<const void*>(newpointer) != static_cast<const void*>(in))
00469 {
00470 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00471 }
00472
00473 return newpointer;
00474 }
00475
00491 template <typename T>
00492 T reinterpret_cast_checked(RawDataType* in)
00493 {
00494 T newpointer = reinterpret_cast<T>(in);
00495
00496 if (static_cast<void*>(newpointer) != static_cast<void*>(in))
00497 {
00498 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00499 }
00500
00501 return newpointer;
00502 }
00503
00512 byte_t* dataBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* dataBegin()); }
00513
00522 byte_t* dataEndBytes() { return reinterpret_cast_checked<byte_t*>(&* dataEnd()); }
00523
00529 iterator headerBegin();
00530
00535 byte_t* headerBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* headerBegin()); }
00536
00541 const_iterator dataBegin() const;
00542
00547 const_iterator dataEnd() const;
00548
00557 const byte_t* dataBeginBytes() const
00558 {
00559 return reinterpret_cast_checked<const byte_t*>(&* dataBegin());
00560 }
00561
00570 const byte_t* dataEndBytes() const
00571 {
00572 return reinterpret_cast_checked<const byte_t*>(&* dataEnd());
00573 }
00574
00580 const_iterator headerBegin() const;
00581
00586 const byte_t* headerBeginBytes() const
00587 {
00588 return reinterpret_cast_checked<const byte_t*>(&* headerBegin());
00589 }
00590
00594 void clear();
00595
00600 bool empty();
00601
00606 void reserve(std::size_t cap);
00607
00612 void swap(Fragment& other) noexcept;
00613
00620 void swap(DATAVEC_T& other) noexcept { vals_.swap(other); };
00621
00626 RawDataType* dataAddress();
00627
00634 RawDataType* metadataAddress();
00639 RawDataType* headerAddress();
00640
00646 static FragmentPtr eodFrag(size_t nFragsToExpect);
00647
00659 template<class InputIterator> static FragmentPtr dataFrag(sequence_id_t sequenceID,
00660 fragment_id_t fragID,
00661 InputIterator i,
00662 InputIterator e)
00663 {
00664 FragmentPtr result(new Fragment(sequenceID, fragID));
00665 result->vals_.reserve(std::distance(i, e) + detail::RawFragmentHeader::num_words());
00666 std::copy(i, e, std::back_inserter(result->vals_));
00667 return result;
00668 }
00669
00679 static FragmentPtr dataFrag(sequence_id_t sequenceID,
00680 fragment_id_t fragID,
00681 RawDataType const* dataPtr,
00682 size_t dataSize,
00683 timestamp_t timestamp = Fragment::InvalidTimestamp);
00684 #endif
00685
00686 private:
00687 template <typename T>
00688 static std::size_t validatedMetadataSize_();
00689
00690 void updateFragmentHeaderWC_();
00691
00692 DATAVEC_T vals_;
00693
00694 #if HIDE_FROM_ROOT
00695 detail::RawFragmentHeader* fragmentHeader();
00696
00697 detail::RawFragmentHeader const* fragmentHeader() const;
00698 #endif
00699 };
00700
00701 #if HIDE_FROM_ROOT
00702
00703
00704
00705
00706 inline artdaq::Fragment::Fragment(artdaq::Fragment&&) noexcept = default;
00707 inline artdaq::Fragment& artdaq::Fragment::operator=(artdaq::Fragment&&) noexcept = default;
00708
00709 inline
00710 bool
00711 constexpr
00712 artdaq::Fragment::
00713 isUserFragmentType(type_t fragmentType)
00714 {
00715 return fragmentType >= detail::RawFragmentHeader::FIRST_USER_TYPE &&
00716 fragmentType <= detail::RawFragmentHeader::LAST_USER_TYPE;
00717 }
00718
00719 inline
00720 bool
00721 constexpr
00722 artdaq::Fragment::
00723 isSystemFragmentType(type_t fragmentType)
00724 {
00725 return fragmentType >= detail::RawFragmentHeader::FIRST_SYSTEM_TYPE;
00726 }
00727
00728 template <typename T>
00729 std::size_t
00730 artdaq::Fragment::
00731 validatedMetadataSize_()
00732 {
00733
00734
00735
00736 static_assert(sizeof(size_t) >=
00737 sizeof(decltype(std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max())),
00738 "metadata_word_count_t is too big!");
00739
00740 static size_t constexpr max_md_wc =
00741 std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max();
00742 size_t requested_md_wc =
00743 std::ceil(sizeof(T) / static_cast<double>(sizeof(artdaq::RawDataType)));
00744 if (requested_md_wc > max_md_wc)
00745 {
00746 throw cet::exception("InvalidRequest")
00747 << "The requested metadata structure is too large: "
00748 << "requested word count = " << requested_md_wc
00749 << ", maximum word count = " << max_md_wc;
00750 }
00751 return requested_md_wc;
00752 }
00753
00754 template <class T>
00755 artdaq::Fragment::
00756 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00757 fragment_id_t fragment_id,
00758 type_t type, const T& metadata, timestamp_t timestamp) :
00759 vals_((artdaq::detail::RawFragmentHeader::num_words() +
00760 validatedMetadataSize_<T>() +
00761 payload_size),
00762 0)
00763 {
00764 updateFragmentHeaderWC_();
00765 fragmentHeader()->version = detail::RawFragmentHeader::CurrentVersion;
00766 fragmentHeader()->sequence_id = sequence_id;
00767 fragmentHeader()->fragment_id = fragment_id;
00768 fragmentHeader()->timestamp = timestamp;
00769 fragmentHeader()->type = type;
00770
00771 fragmentHeader()->metadata_word_count =
00772 vals_.size() -
00773 (fragmentHeader()->num_words() + payload_size);
00774
00775 memcpy(metadataAddress(), &metadata, sizeof(T));
00776 }
00777
00778 inline
00779 std::size_t
00780 artdaq::Fragment::size() const
00781 {
00782 return fragmentHeader()->word_count;
00783 }
00784
00785 inline
00786 artdaq::Fragment::version_t
00787 artdaq::Fragment::version() const
00788 {
00789 return fragmentHeader()->version;
00790 }
00791
00792 inline
00793 artdaq::Fragment::type_t
00794 artdaq::Fragment::type() const
00795 {
00796 return static_cast<type_t>(fragmentHeader()->type);
00797 }
00798
00799 inline
00800 artdaq::Fragment::sequence_id_t
00801 artdaq::Fragment::sequenceID() const
00802 {
00803 return fragmentHeader()->sequence_id;
00804 }
00805
00806 inline
00807 artdaq::Fragment::fragment_id_t
00808 artdaq::Fragment::fragmentID() const
00809 {
00810 return fragmentHeader()->fragment_id;
00811 }
00812
00813 inline
00814 artdaq::Fragment::timestamp_t
00815 artdaq::Fragment::timestamp() const
00816 {
00817 return fragmentHeader()->timestamp;
00818 }
00819
00820 inline
00821 void
00822 artdaq::Fragment::setUserType(type_t type)
00823 {
00824 fragmentHeader()->setUserType(static_cast<uint8_t>(type));
00825 }
00826
00827 inline
00828 void
00829 artdaq::Fragment::setSystemType(type_t type)
00830 {
00831 fragmentHeader()->setSystemType(static_cast<uint8_t>(type));
00832 }
00833
00834 inline
00835 void
00836 artdaq::Fragment::setSequenceID(sequence_id_t sequence_id)
00837 {
00838 assert(sequence_id <= detail::RawFragmentHeader::InvalidSequenceID);
00839 fragmentHeader()->sequence_id = sequence_id;
00840 }
00841
00842 inline
00843 void
00844 artdaq::Fragment::setFragmentID(fragment_id_t fragment_id)
00845 {
00846 fragmentHeader()->fragment_id = fragment_id;
00847 }
00848
00849 inline
00850 void
00851 artdaq::Fragment::setTimestamp(timestamp_t timestamp)
00852 {
00853 fragmentHeader()->timestamp = timestamp;
00854 }
00855
00856 inline
00857 void
00858 artdaq::Fragment::updateFragmentHeaderWC_()
00859 {
00860
00861
00862 assert(vals_.size() < (1ULL << 32));
00863 fragmentHeader()->word_count = vals_.size();
00864 }
00865
00866 inline
00867 std::size_t
00868 artdaq::Fragment::dataSize() const
00869 {
00870 return vals_.size() - fragmentHeader()->num_words() -
00871 fragmentHeader()->metadata_word_count;
00872 }
00873
00874 inline
00875 bool
00876 artdaq::Fragment::hasMetadata() const
00877 {
00878 return fragmentHeader()->metadata_word_count != 0;
00879 }
00880
00881 template <class T>
00882 T*
00883 artdaq::Fragment::metadata()
00884 {
00885 if (fragmentHeader()->metadata_word_count == 0)
00886 {
00887 throw cet::exception("InvalidRequest")
00888 << "No metadata has been stored in this Fragment.";
00889 }
00890
00891 return reinterpret_cast_checked<T *>
00892 (&vals_[fragmentHeader()->num_words()]);
00893 }
00894
00895 template <class T>
00896 T const*
00897 artdaq::Fragment::metadata() const
00898 {
00899 if (fragmentHeader()->metadata_word_count == 0)
00900 {
00901 throw cet::exception("InvalidRequest")
00902 << "No metadata has been stored in this Fragment.";
00903 }
00904 return reinterpret_cast_checked<T const *>
00905 (&vals_[fragmentHeader()->num_words()]);
00906 }
00907
00908 template <class T>
00909 void
00910 artdaq::Fragment::setMetadata(const T& metadata)
00911 {
00912 if (fragmentHeader()->metadata_word_count != 0)
00913 {
00914 throw cet::exception("InvalidRequest")
00915 << "Metadata has already been stored in this Fragment.";
00916 }
00917 auto const mdSize = validatedMetadataSize_<T>();
00918 vals_.insert(dataBegin(), mdSize, 0);
00919 updateFragmentHeaderWC_();
00920 fragmentHeader()->metadata_word_count = mdSize;
00921
00922 memcpy(metadataAddress(), &metadata, sizeof(T));
00923 }
00924
00925 template <class T>
00926 void
00927 artdaq::Fragment::updateMetadata(const T& metadata)
00928 {
00929 if (fragmentHeader()->metadata_word_count == 0)
00930 {
00931 throw cet::exception("InvalidRequest")
00932 << "No metadata in fragment; please use Fragment::setMetadata instead of Fragment::updateMetadata";
00933 }
00934
00935 auto const mdSize = validatedMetadataSize_<T>();
00936
00937 if (fragmentHeader()->metadata_word_count != mdSize)
00938 {
00939 throw cet::exception("InvalidRequest")
00940 << "Mismatch between type of metadata struct passed to updateMetadata and existing metadata struct";
00941 }
00942
00943 memcpy(metadataAddress(), &metadata, sizeof(T));
00944 }
00945
00946 inline void
00947 artdaq::Fragment::resize(std::size_t sz)
00948 {
00949 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00950 fragmentHeader()->num_words());
00951 updateFragmentHeaderWC_();
00952 }
00953
00954 inline
00955 void
00956 artdaq::Fragment::resize(std::size_t sz, RawDataType v)
00957 {
00958 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00959 fragmentHeader()->num_words(), v);
00960 updateFragmentHeaderWC_();
00961 }
00962
00963 inline void
00964 artdaq::Fragment::resizeBytes(std::size_t szbytes)
00965 {
00966 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
00967 resize(nwords);
00968 }
00969
00970 inline
00971 void
00972 artdaq::Fragment::resizeBytes(std::size_t szbytes, byte_t v)
00973 {
00974 RawDataType defaultval;
00975 byte_t* ptr = reinterpret_cast_checked<byte_t*>(&defaultval);
00976
00977 for (uint8_t i = 0; i < sizeof(RawDataType); ++i)
00978 {
00979 *ptr = v;
00980 ptr++;
00981 }
00982
00983 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
00984
00985 resize(nwords, defaultval);
00986 }
00987
00988
00989 inline
00990 void
00991 artdaq::Fragment::autoResize()
00992 {
00993 vals_.resize(fragmentHeader()->word_count);
00994 updateFragmentHeaderWC_();
00995 }
00996
00997 inline
00998 artdaq::Fragment::iterator
00999 artdaq::Fragment::dataBegin()
01000 {
01001 return vals_.begin() + fragmentHeader()->num_words() +
01002 fragmentHeader()->metadata_word_count;
01003 }
01004
01005 inline
01006 artdaq::Fragment::iterator
01007 artdaq::Fragment::dataEnd()
01008 {
01009 return vals_.end();
01010 }
01011
01012 inline
01013 artdaq::Fragment::iterator
01014 artdaq::Fragment::headerBegin()
01015 {
01016 return vals_.begin();
01017 }
01018
01019 inline
01020 artdaq::Fragment::const_iterator
01021 artdaq::Fragment::dataBegin() const
01022 {
01023 return vals_.begin() + fragmentHeader()->num_words() +
01024 fragmentHeader()->metadata_word_count;
01025 }
01026
01027 inline
01028 artdaq::Fragment::const_iterator
01029 artdaq::Fragment::dataEnd() const
01030 {
01031 return vals_.end();
01032 }
01033
01034 inline
01035 artdaq::Fragment::const_iterator
01036 artdaq::Fragment::headerBegin() const
01037 {
01038 return vals_.begin();
01039 }
01040
01041
01042 inline
01043 void
01044 artdaq::Fragment::clear()
01045 {
01046 vals_.erase(dataBegin(), dataEnd());
01047 updateFragmentHeaderWC_();
01048 }
01049
01050 inline
01051 bool
01052 artdaq::Fragment::empty()
01053 {
01054 return (vals_.size() - fragmentHeader()->num_words() -
01055 fragmentHeader()->metadata_word_count) == 0;
01056 }
01057
01058 inline
01059 void
01060 artdaq::Fragment::reserve(std::size_t cap)
01061 {
01062 vals_.reserve(cap + fragmentHeader()->num_words() +
01063 fragmentHeader()->metadata_word_count);
01064 }
01065
01066 inline
01067 void
01068 artdaq::Fragment::swap(Fragment& other) noexcept
01069 {
01070 vals_.swap(other.vals_);
01071 }
01072
01073 inline
01074 artdaq::RawDataType*
01075 artdaq::Fragment::dataAddress()
01076 {
01077 return &vals_[0] + fragmentHeader()->num_words() +
01078 fragmentHeader()->metadata_word_count;
01079 }
01080
01081 inline
01082 artdaq::RawDataType*
01083 artdaq::Fragment::metadataAddress()
01084 {
01085 if (fragmentHeader()->metadata_word_count == 0)
01086 {
01087 throw cet::exception("InvalidRequest")
01088 << "No metadata has been stored in this Fragment.";
01089 }
01090 return &vals_[0] + fragmentHeader()->num_words();
01091 }
01092
01093 inline
01094 artdaq::RawDataType*
01095 artdaq::Fragment::headerAddress()
01096 {
01097 return &vals_[0];
01098 }
01099
01100 inline
01101 artdaq::detail::RawFragmentHeader*
01102 artdaq::Fragment::fragmentHeader()
01103 {
01104 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader *>(&vals_[0]);
01105 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01106 {
01107 switch (hdr->version)
01108 {
01109 case 0xFFFF:
01110 std::cout << "Not upgrading InvalidVersion Fragment" << std::endl;
01111 break;
01112 case 0:
01113 {
01114 std::cout << "Upgrading RawFragmentHeaderV0 (non const)" << std::endl;
01115 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 *>(&vals_[0]);
01116 auto new_hdr = old_hdr->upgrade();
01117
01118 auto szDiff = hdr->num_words() - old_hdr->num_words();
01119 if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
01120 memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01121 }
01122 break;
01123 default:
01124 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01125 break;
01126 }
01127 }
01128 return hdr;
01129 }
01130
01131 inline
01132 artdaq::detail::RawFragmentHeader const*
01133 artdaq::Fragment::fragmentHeader() const
01134 {
01135 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
01136 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01137 {
01138 switch (hdr->version)
01139 {
01140 case 0xFFFF:
01141 std::cout << "Not upgrading InvalidVersion Fragment" << std::endl;
01142 break;
01143 case 0:
01144 {
01145 std::cout << "Upgrading RawFragmentHeaderV0 (const)" << std::endl;
01146 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
01147 auto new_hdr = old_hdr->upgrade();
01148
01149 auto szDiff = hdr->num_words() - old_hdr->num_words();
01150 auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
01151 if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
01152 memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01153 }
01154 break;
01155 default:
01156 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01157 break;
01158 }
01159 }
01160 return hdr;
01161 }
01162
01163 inline
01164 void
01165 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
01166 {
01167 x.swap(y);
01168 }
01169
01170 inline
01171 std::ostream&
01172 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
01173 {
01174 f.print(os);
01175 return os;
01176 }
01177 #endif
01178
01179 #endif