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 #if HIDE_FROM_ROOT
00023 #include "trace.h"
00024 #endif
00025
00029 namespace artdaq {
00030 # define DATAVEC_T QuickVec<RawDataType>
00031
00032
00039 typedef detail::RawFragmentHeader::RawDataType RawDataType;
00040
00041 class Fragment;
00045 typedef std::vector<Fragment> Fragments;
00046
00053 typedef std::unique_ptr<Fragment> FragmentPtr;
00054
00058 typedef std::list<FragmentPtr> FragmentPtrs;
00059
00066 bool fragmentSequenceIDCompare(Fragment i, Fragment j);
00067
00074 std::ostream& operator<<(std::ostream& os, Fragment const& f);
00075 }
00076
00084 class artdaq::Fragment
00085 {
00086 public:
00090 Fragment();
00091
00099 typedef uint8_t byte_t;
00100
00101
00102 #if HIDE_FROM_ROOT
00103
00104
00105
00110 Fragment(const Fragment&) = default;
00118 Fragment(Fragment&&) noexcept;
00124 Fragment& operator=(const Fragment&) = default;
00133 Fragment& operator=(Fragment&&) noexcept;
00134
00135 typedef detail::RawFragmentHeader::version_t version_t;
00136 typedef detail::RawFragmentHeader::type_t type_t;
00137 typedef detail::RawFragmentHeader::sequence_id_t sequence_id_t;
00138 typedef detail::RawFragmentHeader::fragment_id_t fragment_id_t;
00139 typedef detail::RawFragmentHeader::timestamp_t timestamp_t;
00140
00141 static constexpr version_t InvalidVersion = detail::RawFragmentHeader::InvalidVersion;
00142 static constexpr sequence_id_t InvalidSequenceID = detail::RawFragmentHeader::InvalidSequenceID;
00143 static constexpr fragment_id_t InvalidFragmentID = detail::RawFragmentHeader::InvalidFragmentID;
00144 static constexpr timestamp_t InvalidTimestamp = detail::RawFragmentHeader::InvalidTimestamp;
00145
00146 static constexpr type_t InvalidFragmentType = detail::RawFragmentHeader::InvalidFragmentType;
00147 static constexpr type_t EndOfDataFragmentType = detail::RawFragmentHeader::EndOfDataFragmentType;
00148 static constexpr type_t DataFragmentType = detail::RawFragmentHeader::DataFragmentType;
00149 static constexpr type_t InitFragmentType = detail::RawFragmentHeader::InitFragmentType;
00150 static constexpr type_t EndOfRunFragmentType = detail::RawFragmentHeader::EndOfRunFragmentType;
00151 static constexpr type_t EndOfSubrunFragmentType = detail::RawFragmentHeader::EndOfSubrunFragmentType;
00152 static constexpr type_t ShutdownFragmentType = detail::RawFragmentHeader::ShutdownFragmentType;
00153 static constexpr type_t FirstUserFragmentType = detail::RawFragmentHeader::FIRST_USER_TYPE;
00154 static constexpr type_t EmptyFragmentType = detail::RawFragmentHeader::EmptyFragmentType;
00155 static constexpr type_t ContainerFragmentType = detail::RawFragmentHeader::ContainerFragmentType;
00156 static constexpr type_t ErrorFragmentType = detail::RawFragmentHeader::ErrorFragmentType;
00157
00163 static constexpr bool isUserFragmentType(type_t fragmentType);
00164
00170 static constexpr bool isSystemFragmentType(type_t fragmentType);
00171
00176 static std::map<type_t, std::string> MakeSystemTypeMap()
00177 {
00178 return detail::RawFragmentHeader::MakeSystemTypeMap();
00179 }
00180
00181 typedef DATAVEC_T::reference reference;
00182 typedef DATAVEC_T::iterator iterator;
00183 typedef DATAVEC_T::const_iterator const_iterator;
00184 typedef DATAVEC_T::value_type value_type;
00185 typedef DATAVEC_T::difference_type difference_type;
00186 typedef DATAVEC_T::size_type size_type;
00187
00193 explicit Fragment(std::size_t n);
00194
00201 static FragmentPtr FragmentBytes(std::size_t nbytes)
00202 {
00203 RawDataType nwords = ceil(nbytes / static_cast<double>(sizeof(RawDataType)));
00204 return FragmentPtr(new Fragment(nwords));
00205 }
00206
00217 template <class T>
00218 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00219 fragment_id_t fragment_id, type_t type, const T& metadata,
00220 timestamp_t timestamp = Fragment::InvalidTimestamp);
00221
00235 template <class T>
00236 static FragmentPtr FragmentBytes(std::size_t payload_size_in_bytes,
00237 sequence_id_t sequence_id,
00238 fragment_id_t fragment_id,
00239 type_t type, const T& metadata,
00240 timestamp_t timestamp = Fragment::InvalidTimestamp)
00241 {
00242 RawDataType nwords = ceil(payload_size_in_bytes /
00243 static_cast<double>(sizeof(RawDataType)));
00244 return FragmentPtr(new Fragment(nwords, sequence_id, fragment_id, type, metadata, timestamp));
00245 }
00246
00254 Fragment(sequence_id_t sequenceID,
00255 fragment_id_t fragID,
00256 type_t type = Fragment::DataFragmentType,
00257 timestamp_t timestamp = Fragment::InvalidTimestamp);
00258
00263 void print(std::ostream& os) const;
00264
00269 std::size_t size() const;
00270
00275 version_t version() const;
00276
00281 type_t type() const;
00282
00287 std::string typeString() const;
00288
00293 sequence_id_t sequenceID() const;
00294
00299 fragment_id_t fragmentID() const;
00300
00305 timestamp_t timestamp() const;
00306
00311 void setUserType(type_t utype);
00312
00317 void setSystemType(type_t stype);
00318
00323 void setSequenceID(sequence_id_t sequence_id);
00324
00329 void setFragmentID(fragment_id_t fragment_id);
00330
00335 void setTimestamp(timestamp_t timestamp);
00336
00341 std::size_t sizeBytes() const { return sizeof(RawDataType) * size(); }
00342
00348 std::size_t dataSize() const;
00349
00350
00356 std::size_t dataSizeBytes() const
00357 {
00358 return sizeof(RawDataType) * dataSize();
00359 }
00360
00365 bool hasMetadata() const;
00366
00374 template <class T>
00375 T* metadata();
00376
00384 template <class T>
00385 T const* metadata() const;
00386
00395 template <class T>
00396 void setMetadata(const T& md);
00397
00405 template <class T>
00406 void updateMetadata(const T& md);
00407
00412 void resize(std::size_t sz);
00413
00419 void resize(std::size_t sz, RawDataType val);
00420
00427 void resizeBytes(std::size_t szbytes);
00428
00437 void resizeBytesWithCushion(std::size_t szbytes, double growthFactor=1.3);
00438
00446 void resizeBytes(std::size_t szbytes, byte_t val);
00447
00451 void autoResize();
00452
00457 iterator dataBegin();
00458
00463 iterator dataEnd();
00464
00484 template <typename T>
00485 T reinterpret_cast_checked(const RawDataType* in) const
00486 {
00487 T newpointer = reinterpret_cast<T>(in);
00488
00489 if (static_cast<const void*>(newpointer) != static_cast<const void*>(in))
00490 {
00491 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00492 }
00493
00494 return newpointer;
00495 }
00496
00512 template <typename T>
00513 T reinterpret_cast_checked(RawDataType* in)
00514 {
00515 T newpointer = reinterpret_cast<T>(in);
00516
00517 if (static_cast<void*>(newpointer) != static_cast<void*>(in))
00518 {
00519 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00520 }
00521
00522 return newpointer;
00523 }
00524
00533 byte_t* dataBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* dataBegin()); }
00534
00543 byte_t* dataEndBytes() { return reinterpret_cast_checked<byte_t*>(&* dataEnd()); }
00544
00550 iterator headerBegin();
00551
00556 byte_t* headerBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* headerBegin()); }
00557
00562 const_iterator dataBegin() const;
00563
00568 const_iterator dataEnd() const;
00569
00578 const byte_t* dataBeginBytes() const
00579 {
00580 return reinterpret_cast_checked<const byte_t*>(&* dataBegin());
00581 }
00582
00591 const byte_t* dataEndBytes() const
00592 {
00593 return reinterpret_cast_checked<const byte_t*>(&* dataEnd());
00594 }
00595
00601 const_iterator headerBegin() const;
00602
00607 const byte_t* headerBeginBytes() const
00608 {
00609 return reinterpret_cast_checked<const byte_t*>(&* headerBegin());
00610 }
00611
00615 void clear();
00616
00621 bool empty();
00622
00627 void reserve(std::size_t cap);
00628
00633 void swap(Fragment& other) noexcept;
00634
00641 void swap(DATAVEC_T& other) noexcept { vals_.swap(other); };
00642
00647 RawDataType* dataAddress();
00648
00655 RawDataType* metadataAddress();
00660 RawDataType* headerAddress();
00661
00667 static FragmentPtr eodFrag(size_t nFragsToExpect);
00668
00680 template<class InputIterator> static FragmentPtr dataFrag(sequence_id_t sequenceID,
00681 fragment_id_t fragID,
00682 InputIterator i,
00683 InputIterator e)
00684 {
00685 FragmentPtr result(new Fragment(sequenceID, fragID));
00686 result->vals_.reserve(std::distance(i, e) + detail::RawFragmentHeader::num_words());
00687 std::copy(i, e, std::back_inserter(result->vals_));
00688 result->updateFragmentHeaderWC_();
00689 return result;
00690 }
00691
00701 static FragmentPtr dataFrag(sequence_id_t sequenceID,
00702 fragment_id_t fragID,
00703 RawDataType const* dataPtr,
00704 size_t dataSize,
00705 timestamp_t timestamp = Fragment::InvalidTimestamp);
00706 #endif
00707
00708 private:
00709 template <typename T>
00710 static std::size_t validatedMetadataSize_();
00711
00712 void updateFragmentHeaderWC_();
00713
00714 DATAVEC_T vals_;
00715
00716 #if HIDE_FROM_ROOT
00717 detail::RawFragmentHeader* fragmentHeader();
00718
00719 detail::RawFragmentHeader const* fragmentHeader() const;
00720 #endif
00721 };
00722
00723 #if HIDE_FROM_ROOT
00724
00725
00726
00727
00728 inline artdaq::Fragment::Fragment(artdaq::Fragment&&) noexcept = default;
00729 inline artdaq::Fragment& artdaq::Fragment::operator=(artdaq::Fragment&&) noexcept = default;
00730
00731 inline
00732 bool
00733 constexpr
00734 artdaq::Fragment::
00735 isUserFragmentType(type_t fragmentType)
00736 {
00737 return fragmentType >= detail::RawFragmentHeader::FIRST_USER_TYPE &&
00738 fragmentType <= detail::RawFragmentHeader::LAST_USER_TYPE;
00739 }
00740
00741 inline
00742 bool
00743 constexpr
00744 artdaq::Fragment::
00745 isSystemFragmentType(type_t fragmentType)
00746 {
00747 return fragmentType >= detail::RawFragmentHeader::FIRST_SYSTEM_TYPE;
00748 }
00749
00750 template <typename T>
00751 std::size_t
00752 artdaq::Fragment::
00753 validatedMetadataSize_()
00754 {
00755
00756
00757
00758 static_assert(sizeof(size_t) >=
00759 sizeof(decltype(std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max())),
00760 "metadata_word_count_t is too big!");
00761
00762 static size_t constexpr max_md_wc =
00763 std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max();
00764 size_t requested_md_wc =
00765 std::ceil(sizeof(T) / static_cast<double>(sizeof(artdaq::RawDataType)));
00766 if (requested_md_wc > max_md_wc)
00767 {
00768 throw cet::exception("InvalidRequest")
00769 << "The requested metadata structure is too large: "
00770 << "requested word count = " << requested_md_wc
00771 << ", maximum word count = " << max_md_wc;
00772 }
00773 return requested_md_wc;
00774 }
00775
00776 template <class T>
00777 artdaq::Fragment::
00778 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00779 fragment_id_t fragment_id,
00780 type_t type, const T& metadata, timestamp_t timestamp) :
00781 vals_((artdaq::detail::RawFragmentHeader::num_words() +
00782 validatedMetadataSize_<T>() +
00783 payload_size)
00784 )
00785 {
00786 TRACEN( "Fragment", 50, "Fragment ctor num_word()=%zu MetadataSize_=%zu payload_size=%zu"
00787 ,artdaq::detail::RawFragmentHeader::num_words(), validatedMetadataSize_<T>(), payload_size );
00788
00789 for (iterator ii = vals_.begin();
00790 ii != (vals_.begin() + detail::RawFragmentHeader::num_words()); ++ii) {
00791 *ii = -1;
00792 }
00793 fragmentHeader()->version = detail::RawFragmentHeader::CurrentVersion;
00794 updateFragmentHeaderWC_();
00795 fragmentHeader()->sequence_id = sequence_id;
00796 fragmentHeader()->fragment_id = fragment_id;
00797 fragmentHeader()->timestamp = timestamp;
00798 fragmentHeader()->type = type;
00799
00800 fragmentHeader()->metadata_word_count =
00801 vals_.size() -
00802 (fragmentHeader()->num_words() + payload_size);
00803
00804 memcpy(metadataAddress(), &metadata, sizeof(T));
00805 }
00806
00807 inline
00808 std::size_t
00809 artdaq::Fragment::size() const
00810 {
00811 return fragmentHeader()->word_count;
00812 }
00813
00814 inline
00815 artdaq::Fragment::version_t
00816 artdaq::Fragment::version() const
00817 {
00818 return fragmentHeader()->version;
00819 }
00820
00821 inline
00822 artdaq::Fragment::type_t
00823 artdaq::Fragment::type() const
00824 {
00825 return static_cast<type_t>(fragmentHeader()->type);
00826 }
00827
00828 inline
00829 std::string
00830 artdaq::Fragment::typeString() const
00831 {
00832 return std::to_string(type()) + (isSystemFragmentType(type()) ? " (" + detail::RawFragmentHeader::SystemTypeToString(type()) + ")" : "");
00833 }
00834
00835 inline
00836 artdaq::Fragment::sequence_id_t
00837 artdaq::Fragment::sequenceID() const
00838 {
00839 return fragmentHeader()->sequence_id;
00840 }
00841
00842 inline
00843 artdaq::Fragment::fragment_id_t
00844 artdaq::Fragment::fragmentID() const
00845 {
00846 return fragmentHeader()->fragment_id;
00847 }
00848
00849 inline
00850 artdaq::Fragment::timestamp_t
00851 artdaq::Fragment::timestamp() const
00852 {
00853 return fragmentHeader()->timestamp;
00854 }
00855
00856 inline
00857 void
00858 artdaq::Fragment::setUserType(type_t type)
00859 {
00860 fragmentHeader()->setUserType(static_cast<uint8_t>(type));
00861 }
00862
00863 inline
00864 void
00865 artdaq::Fragment::setSystemType(type_t type)
00866 {
00867 fragmentHeader()->setSystemType(static_cast<uint8_t>(type));
00868 }
00869
00870 inline
00871 void
00872 artdaq::Fragment::setSequenceID(sequence_id_t sequence_id)
00873 {
00874 assert(sequence_id <= detail::RawFragmentHeader::InvalidSequenceID);
00875 fragmentHeader()->sequence_id = sequence_id;
00876 }
00877
00878 inline
00879 void
00880 artdaq::Fragment::setFragmentID(fragment_id_t fragment_id)
00881 {
00882 fragmentHeader()->fragment_id = fragment_id;
00883 }
00884
00885 inline
00886 void
00887 artdaq::Fragment::setTimestamp(timestamp_t timestamp)
00888 {
00889 fragmentHeader()->timestamp = timestamp;
00890 }
00891
00892 inline
00893 void
00894 artdaq::Fragment::updateFragmentHeaderWC_()
00895 {
00896
00897
00898 assert(vals_.size() < (1ULL << 32));
00899 TRACEN( "Fragment", 50, "Fragment::updateFragmentHeaderWC_ adjusting fragmentHeader()->word_count from %u to %zu", (unsigned)(fragmentHeader()->word_count), vals_.size() );
00900 fragmentHeader()->word_count = vals_.size();
00901 }
00902
00903 inline
00904 std::size_t
00905 artdaq::Fragment::dataSize() const
00906 {
00907 return vals_.size() - fragmentHeader()->num_words() -
00908 fragmentHeader()->metadata_word_count;
00909 }
00910
00911 inline
00912 bool
00913 artdaq::Fragment::hasMetadata() const
00914 {
00915 return fragmentHeader()->metadata_word_count != 0;
00916 }
00917
00918 template <class T>
00919 T*
00920 artdaq::Fragment::metadata()
00921 {
00922 if (fragmentHeader()->metadata_word_count == 0)
00923 {
00924 throw cet::exception("InvalidRequest")
00925 << "No metadata has been stored in this Fragment.";
00926 }
00927
00928 return reinterpret_cast_checked<T *>
00929 (&vals_[fragmentHeader()->num_words()]);
00930 }
00931
00932 template <class T>
00933 T const*
00934 artdaq::Fragment::metadata() const
00935 {
00936 if (fragmentHeader()->metadata_word_count == 0)
00937 {
00938 throw cet::exception("InvalidRequest")
00939 << "No metadata has been stored in this Fragment.";
00940 }
00941 return reinterpret_cast_checked<T const *>
00942 (&vals_[fragmentHeader()->num_words()]);
00943 }
00944
00945 template <class T>
00946 void
00947 artdaq::Fragment::setMetadata(const T& metadata)
00948 {
00949 if (fragmentHeader()->metadata_word_count != 0)
00950 {
00951 throw cet::exception("InvalidRequest")
00952 << "Metadata has already been stored in this Fragment.";
00953 }
00954 auto const mdSize = validatedMetadataSize_<T>();
00955 vals_.insert(dataBegin(), mdSize, 0);
00956 updateFragmentHeaderWC_();
00957 fragmentHeader()->metadata_word_count = mdSize;
00958
00959 memcpy(metadataAddress(), &metadata, sizeof(T));
00960 }
00961
00962 template <class T>
00963 void
00964 artdaq::Fragment::updateMetadata(const T& metadata)
00965 {
00966 if (fragmentHeader()->metadata_word_count == 0)
00967 {
00968 throw cet::exception("InvalidRequest")
00969 << "No metadata in fragment; please use Fragment::setMetadata instead of Fragment::updateMetadata";
00970 }
00971
00972 auto const mdSize = validatedMetadataSize_<T>();
00973
00974 if (fragmentHeader()->metadata_word_count != mdSize)
00975 {
00976 throw cet::exception("InvalidRequest")
00977 << "Mismatch between type of metadata struct passed to updateMetadata and existing metadata struct";
00978 }
00979
00980 memcpy(metadataAddress(), &metadata, sizeof(T));
00981 }
00982
00983 inline void
00984 artdaq::Fragment::resize(std::size_t sz)
00985 {
00986 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00987 fragmentHeader()->num_words());
00988 updateFragmentHeaderWC_();
00989 }
00990
00991 inline
00992 void
00993 artdaq::Fragment::resize(std::size_t sz, RawDataType v)
00994 {
00995 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00996 fragmentHeader()->num_words(), v);
00997 updateFragmentHeaderWC_();
00998 }
00999
01000 inline void
01001 artdaq::Fragment::resizeBytes(std::size_t szbytes)
01002 {
01003 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
01004 resize(nwords);
01005 }
01006
01007 inline void
01008 artdaq::Fragment::resizeBytesWithCushion(std::size_t szbytes, double growthFactor)
01009 {
01010 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
01011 vals_.resizeWithCushion(nwords + fragmentHeader()->metadata_word_count +
01012 fragmentHeader()->num_words(), growthFactor);
01013 updateFragmentHeaderWC_();
01014 }
01015
01016 inline
01017 void
01018 artdaq::Fragment::resizeBytes(std::size_t szbytes, byte_t v)
01019 {
01020 RawDataType defaultval;
01021 byte_t* ptr = reinterpret_cast_checked<byte_t*>(&defaultval);
01022
01023 for (uint8_t i = 0; i < sizeof(RawDataType); ++i)
01024 {
01025 *ptr = v;
01026 ptr++;
01027 }
01028
01029 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
01030
01031 resize(nwords, defaultval);
01032 }
01033
01034
01035 inline
01036 void
01037 artdaq::Fragment::autoResize()
01038 {
01039 vals_.resize(fragmentHeader()->word_count);
01040 updateFragmentHeaderWC_();
01041 }
01042
01043 inline
01044 artdaq::Fragment::iterator
01045 artdaq::Fragment::dataBegin()
01046 {
01047 return vals_.begin() + fragmentHeader()->num_words() +
01048 fragmentHeader()->metadata_word_count;
01049 }
01050
01051 inline
01052 artdaq::Fragment::iterator
01053 artdaq::Fragment::dataEnd()
01054 {
01055 return vals_.end();
01056 }
01057
01058 inline
01059 artdaq::Fragment::iterator
01060 artdaq::Fragment::headerBegin()
01061 {
01062 return vals_.begin();
01063 }
01064
01065 inline
01066 artdaq::Fragment::const_iterator
01067 artdaq::Fragment::dataBegin() const
01068 {
01069 return vals_.begin() + fragmentHeader()->num_words() +
01070 fragmentHeader()->metadata_word_count;
01071 }
01072
01073 inline
01074 artdaq::Fragment::const_iterator
01075 artdaq::Fragment::dataEnd() const
01076 {
01077 return vals_.end();
01078 }
01079
01080 inline
01081 artdaq::Fragment::const_iterator
01082 artdaq::Fragment::headerBegin() const
01083 {
01084 return vals_.begin();
01085 }
01086
01087
01088 inline
01089 void
01090 artdaq::Fragment::clear()
01091 {
01092 vals_.erase(dataBegin(), dataEnd());
01093 updateFragmentHeaderWC_();
01094 }
01095
01096 inline
01097 bool
01098 artdaq::Fragment::empty()
01099 {
01100 return (vals_.size() - fragmentHeader()->num_words() -
01101 fragmentHeader()->metadata_word_count) == 0;
01102 }
01103
01104 inline
01105 void
01106 artdaq::Fragment::reserve(std::size_t cap)
01107 {
01108 vals_.reserve(cap + fragmentHeader()->num_words() +
01109 fragmentHeader()->metadata_word_count);
01110 }
01111
01112 inline
01113 void
01114 artdaq::Fragment::swap(Fragment& other) noexcept
01115 {
01116 vals_.swap(other.vals_);
01117 }
01118
01119 inline
01120 artdaq::RawDataType*
01121 artdaq::Fragment::dataAddress()
01122 {
01123 return &vals_[0] + fragmentHeader()->num_words() +
01124 fragmentHeader()->metadata_word_count;
01125 }
01126
01127 inline
01128 artdaq::RawDataType*
01129 artdaq::Fragment::metadataAddress()
01130 {
01131 if (fragmentHeader()->metadata_word_count == 0)
01132 {
01133 throw cet::exception("InvalidRequest")
01134 << "No metadata has been stored in this Fragment.";
01135 }
01136 return &vals_[0] + fragmentHeader()->num_words();
01137 }
01138
01139 inline
01140 artdaq::RawDataType*
01141 artdaq::Fragment::headerAddress()
01142 {
01143 return &vals_[0];
01144 }
01145
01146 inline
01147 artdaq::detail::RawFragmentHeader*
01148 artdaq::Fragment::fragmentHeader()
01149 {
01150 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader *>(&vals_[0]);
01151 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01152 {
01153 switch (hdr->version)
01154 {
01155 case 0xFFFF:
01156
01157 break;
01158 case 0:
01159 {
01160 std::cout << "Upgrading RawFragmentHeaderV0 (non const)" << std::endl;
01161 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 *>(&vals_[0]);
01162 auto new_hdr = old_hdr->upgrade();
01163
01164 auto szDiff = hdr->num_words() - old_hdr->num_words();
01165 if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
01166 memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01167 }
01168 break;
01169 default:
01170 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01171 break;
01172 }
01173 }
01174 return hdr;
01175 }
01176
01177 inline
01178 artdaq::detail::RawFragmentHeader const*
01179 artdaq::Fragment::fragmentHeader() const
01180 {
01181 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
01182 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01183 {
01184 switch (hdr->version)
01185 {
01186 case 0xFFFF:
01187
01188 break;
01189 case 0:
01190 {
01191 std::cout << "Upgrading RawFragmentHeaderV0 (const)" << std::endl;
01192 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
01193 auto new_hdr = old_hdr->upgrade();
01194
01195 auto szDiff = hdr->num_words() - old_hdr->num_words();
01196 auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
01197 if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
01198 memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01199 }
01200 break;
01201 default:
01202 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01203 break;
01204 }
01205 }
01206 return hdr;
01207 }
01208
01209 inline
01210 void
01211 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
01212 {
01213 x.swap(y);
01214 }
01215
01216 inline
01217 std::ostream&
01218 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
01219 {
01220 f.print(os);
01221 return os;
01222 }
01223 #endif
01224
01225 #endif