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