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
00162 static constexpr bool isUserFragmentType(type_t fragmentType);
00163
00169 static constexpr bool isSystemFragmentType(type_t fragmentType);
00170
00175 static std::map<type_t, std::string> MakeSystemTypeMap()
00176 {
00177 return detail::RawFragmentHeader::MakeSystemTypeMap();
00178 }
00179
00180 typedef DATAVEC_T::reference reference;
00181 typedef DATAVEC_T::iterator iterator;
00182 typedef DATAVEC_T::const_iterator const_iterator;
00183 typedef DATAVEC_T::value_type value_type;
00184 typedef DATAVEC_T::difference_type difference_type;
00185 typedef DATAVEC_T::size_type size_type;
00186
00192 explicit Fragment(std::size_t n);
00193
00200 static FragmentPtr FragmentBytes(std::size_t nbytes)
00201 {
00202 RawDataType nwords = ceil(nbytes / static_cast<double>(sizeof(RawDataType)));
00203 return FragmentPtr(new Fragment(nwords));
00204 }
00205
00216 template <class T>
00217 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00218 fragment_id_t fragment_id, type_t type, const T& metadata,
00219 timestamp_t timestamp = Fragment::InvalidTimestamp);
00220
00234 template <class T>
00235 static FragmentPtr FragmentBytes(std::size_t payload_size_in_bytes,
00236 sequence_id_t sequence_id,
00237 fragment_id_t fragment_id,
00238 type_t type, const T& metadata,
00239 timestamp_t timestamp = Fragment::InvalidTimestamp)
00240 {
00241 RawDataType nwords = ceil(payload_size_in_bytes /
00242 static_cast<double>(sizeof(RawDataType)));
00243 return FragmentPtr(new Fragment(nwords, sequence_id, fragment_id, type, metadata, timestamp));
00244 }
00245
00253 Fragment(sequence_id_t sequenceID,
00254 fragment_id_t fragID,
00255 type_t type = Fragment::DataFragmentType,
00256 timestamp_t timestamp = Fragment::InvalidTimestamp);
00257
00262 void print(std::ostream& os) const;
00263
00268 std::size_t size() const;
00269
00274 version_t version() const;
00275
00280 type_t type() const;
00281
00286 std::string typeString() const;
00287
00292 sequence_id_t sequenceID() const;
00293
00298 fragment_id_t fragmentID() const;
00299
00304 timestamp_t timestamp() const;
00305
00310 void setUserType(type_t utype);
00311
00316 void setSystemType(type_t stype);
00317
00322 void setSequenceID(sequence_id_t sequence_id);
00323
00328 void setFragmentID(fragment_id_t fragment_id);
00329
00334 void setTimestamp(timestamp_t timestamp);
00335
00340 std::size_t sizeBytes() const { return sizeof(RawDataType) * size(); }
00341
00347 std::size_t dataSize() const;
00348
00349
00355 std::size_t dataSizeBytes() const
00356 {
00357 return sizeof(RawDataType) * dataSize();
00358 }
00359
00364 bool hasMetadata() const;
00365
00373 template <class T>
00374 T* metadata();
00375
00383 template <class T>
00384 T const* metadata() const;
00385
00394 template <class T>
00395 void setMetadata(const T& md);
00396
00404 template <class T>
00405 void updateMetadata(const T& md);
00406
00411 void resize(std::size_t sz);
00412
00418 void resize(std::size_t sz, RawDataType val);
00419
00426 void resizeBytes(std::size_t szbytes);
00427
00435 void resizeBytes(std::size_t szbytes, byte_t val);
00436
00440 void autoResize();
00441
00446 iterator dataBegin();
00447
00452 iterator dataEnd();
00453
00473 template <typename T>
00474 T reinterpret_cast_checked(const RawDataType* in) const
00475 {
00476 T newpointer = reinterpret_cast<T>(in);
00477
00478 if (static_cast<const void*>(newpointer) != static_cast<const void*>(in))
00479 {
00480 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00481 }
00482
00483 return newpointer;
00484 }
00485
00501 template <typename T>
00502 T reinterpret_cast_checked(RawDataType* in)
00503 {
00504 T newpointer = reinterpret_cast<T>(in);
00505
00506 if (static_cast<void*>(newpointer) != static_cast<void*>(in))
00507 {
00508 throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
00509 }
00510
00511 return newpointer;
00512 }
00513
00522 byte_t* dataBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* dataBegin()); }
00523
00532 byte_t* dataEndBytes() { return reinterpret_cast_checked<byte_t*>(&* dataEnd()); }
00533
00539 iterator headerBegin();
00540
00545 byte_t* headerBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* headerBegin()); }
00546
00551 const_iterator dataBegin() const;
00552
00557 const_iterator dataEnd() const;
00558
00567 const byte_t* dataBeginBytes() const
00568 {
00569 return reinterpret_cast_checked<const byte_t*>(&* dataBegin());
00570 }
00571
00580 const byte_t* dataEndBytes() const
00581 {
00582 return reinterpret_cast_checked<const byte_t*>(&* dataEnd());
00583 }
00584
00590 const_iterator headerBegin() const;
00591
00596 const byte_t* headerBeginBytes() const
00597 {
00598 return reinterpret_cast_checked<const byte_t*>(&* headerBegin());
00599 }
00600
00604 void clear();
00605
00610 bool empty();
00611
00616 void reserve(std::size_t cap);
00617
00622 void swap(Fragment& other) noexcept;
00623
00630 void swap(DATAVEC_T& other) noexcept { vals_.swap(other); };
00631
00636 RawDataType* dataAddress();
00637
00644 RawDataType* metadataAddress();
00649 RawDataType* headerAddress();
00650
00656 static FragmentPtr eodFrag(size_t nFragsToExpect);
00657
00669 template<class InputIterator> static FragmentPtr dataFrag(sequence_id_t sequenceID,
00670 fragment_id_t fragID,
00671 InputIterator i,
00672 InputIterator e)
00673 {
00674 FragmentPtr result(new Fragment(sequenceID, fragID));
00675 result->vals_.reserve(std::distance(i, e) + detail::RawFragmentHeader::num_words());
00676 std::copy(i, e, std::back_inserter(result->vals_));
00677 result->updateFragmentHeaderWC_();
00678 return result;
00679 }
00680
00690 static FragmentPtr dataFrag(sequence_id_t sequenceID,
00691 fragment_id_t fragID,
00692 RawDataType const* dataPtr,
00693 size_t dataSize,
00694 timestamp_t timestamp = Fragment::InvalidTimestamp);
00695 #endif
00696
00697 private:
00698 template <typename T>
00699 static std::size_t validatedMetadataSize_();
00700
00701 void updateFragmentHeaderWC_();
00702
00703 DATAVEC_T vals_;
00704
00705 #if HIDE_FROM_ROOT
00706 detail::RawFragmentHeader* fragmentHeader();
00707
00708 detail::RawFragmentHeader const* fragmentHeader() const;
00709 #endif
00710 };
00711
00712 #if HIDE_FROM_ROOT
00713
00714
00715
00716
00717 inline artdaq::Fragment::Fragment(artdaq::Fragment&&) noexcept = default;
00718 inline artdaq::Fragment& artdaq::Fragment::operator=(artdaq::Fragment&&) noexcept = default;
00719
00720 inline
00721 bool
00722 constexpr
00723 artdaq::Fragment::
00724 isUserFragmentType(type_t fragmentType)
00725 {
00726 return fragmentType >= detail::RawFragmentHeader::FIRST_USER_TYPE &&
00727 fragmentType <= detail::RawFragmentHeader::LAST_USER_TYPE;
00728 }
00729
00730 inline
00731 bool
00732 constexpr
00733 artdaq::Fragment::
00734 isSystemFragmentType(type_t fragmentType)
00735 {
00736 return fragmentType >= detail::RawFragmentHeader::FIRST_SYSTEM_TYPE;
00737 }
00738
00739 template <typename T>
00740 std::size_t
00741 artdaq::Fragment::
00742 validatedMetadataSize_()
00743 {
00744
00745
00746
00747 static_assert(sizeof(size_t) >=
00748 sizeof(decltype(std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max())),
00749 "metadata_word_count_t is too big!");
00750
00751 static size_t constexpr max_md_wc =
00752 std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max();
00753 size_t requested_md_wc =
00754 std::ceil(sizeof(T) / static_cast<double>(sizeof(artdaq::RawDataType)));
00755 if (requested_md_wc > max_md_wc)
00756 {
00757 throw cet::exception("InvalidRequest")
00758 << "The requested metadata structure is too large: "
00759 << "requested word count = " << requested_md_wc
00760 << ", maximum word count = " << max_md_wc;
00761 }
00762 return requested_md_wc;
00763 }
00764
00765 template <class T>
00766 artdaq::Fragment::
00767 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
00768 fragment_id_t fragment_id,
00769 type_t type, const T& metadata, timestamp_t timestamp) :
00770 vals_((artdaq::detail::RawFragmentHeader::num_words() +
00771 validatedMetadataSize_<T>() +
00772 payload_size)
00773 )
00774 {
00775 TRACE( 50, "Fragment ctor num_word()=%zu MetadataSize_=%zu payload_size=%zu"
00776 ,artdaq::detail::RawFragmentHeader::num_words(), validatedMetadataSize_<T>(), payload_size );
00777
00778 for (iterator ii = vals_.begin();
00779 ii != (vals_.begin() + detail::RawFragmentHeader::num_words()); ++ii) {
00780 *ii = -1;
00781 }
00782 fragmentHeader()->version = detail::RawFragmentHeader::CurrentVersion;
00783 updateFragmentHeaderWC_();
00784 fragmentHeader()->sequence_id = sequence_id;
00785 fragmentHeader()->fragment_id = fragment_id;
00786 fragmentHeader()->timestamp = timestamp;
00787 fragmentHeader()->type = type;
00788
00789 fragmentHeader()->metadata_word_count =
00790 vals_.size() -
00791 (fragmentHeader()->num_words() + payload_size);
00792
00793 memcpy(metadataAddress(), &metadata, sizeof(T));
00794 }
00795
00796 inline
00797 std::size_t
00798 artdaq::Fragment::size() const
00799 {
00800 return fragmentHeader()->word_count;
00801 }
00802
00803 inline
00804 artdaq::Fragment::version_t
00805 artdaq::Fragment::version() const
00806 {
00807 return fragmentHeader()->version;
00808 }
00809
00810 inline
00811 artdaq::Fragment::type_t
00812 artdaq::Fragment::type() const
00813 {
00814 return static_cast<type_t>(fragmentHeader()->type);
00815 }
00816
00817 inline
00818 std::string
00819 artdaq::Fragment::typeString() const
00820 {
00821 return std::to_string(type()) + (isSystemFragmentType(type()) ? " (" + detail::RawFragmentHeader::SystemTypeToString(type()) + ")" : "");
00822 }
00823
00824 inline
00825 artdaq::Fragment::sequence_id_t
00826 artdaq::Fragment::sequenceID() const
00827 {
00828 return fragmentHeader()->sequence_id;
00829 }
00830
00831 inline
00832 artdaq::Fragment::fragment_id_t
00833 artdaq::Fragment::fragmentID() const
00834 {
00835 return fragmentHeader()->fragment_id;
00836 }
00837
00838 inline
00839 artdaq::Fragment::timestamp_t
00840 artdaq::Fragment::timestamp() const
00841 {
00842 return fragmentHeader()->timestamp;
00843 }
00844
00845 inline
00846 void
00847 artdaq::Fragment::setUserType(type_t type)
00848 {
00849 fragmentHeader()->setUserType(static_cast<uint8_t>(type));
00850 }
00851
00852 inline
00853 void
00854 artdaq::Fragment::setSystemType(type_t type)
00855 {
00856 fragmentHeader()->setSystemType(static_cast<uint8_t>(type));
00857 }
00858
00859 inline
00860 void
00861 artdaq::Fragment::setSequenceID(sequence_id_t sequence_id)
00862 {
00863 assert(sequence_id <= detail::RawFragmentHeader::InvalidSequenceID);
00864 fragmentHeader()->sequence_id = sequence_id;
00865 }
00866
00867 inline
00868 void
00869 artdaq::Fragment::setFragmentID(fragment_id_t fragment_id)
00870 {
00871 fragmentHeader()->fragment_id = fragment_id;
00872 }
00873
00874 inline
00875 void
00876 artdaq::Fragment::setTimestamp(timestamp_t timestamp)
00877 {
00878 fragmentHeader()->timestamp = timestamp;
00879 }
00880
00881 inline
00882 void
00883 artdaq::Fragment::updateFragmentHeaderWC_()
00884 {
00885
00886
00887 assert(vals_.size() < (1ULL << 32));
00888 TRACE( 50, "Fragment::updateFragmentHeaderWC_ adjusting fragmentHeader()->word_count from %u to %zu", (unsigned)(fragmentHeader()->word_count), vals_.size() );
00889 fragmentHeader()->word_count = vals_.size();
00890 }
00891
00892 inline
00893 std::size_t
00894 artdaq::Fragment::dataSize() const
00895 {
00896 return vals_.size() - fragmentHeader()->num_words() -
00897 fragmentHeader()->metadata_word_count;
00898 }
00899
00900 inline
00901 bool
00902 artdaq::Fragment::hasMetadata() const
00903 {
00904 return fragmentHeader()->metadata_word_count != 0;
00905 }
00906
00907 template <class T>
00908 T*
00909 artdaq::Fragment::metadata()
00910 {
00911 if (fragmentHeader()->metadata_word_count == 0)
00912 {
00913 throw cet::exception("InvalidRequest")
00914 << "No metadata has been stored in this Fragment.";
00915 }
00916
00917 return reinterpret_cast_checked<T *>
00918 (&vals_[fragmentHeader()->num_words()]);
00919 }
00920
00921 template <class T>
00922 T const*
00923 artdaq::Fragment::metadata() const
00924 {
00925 if (fragmentHeader()->metadata_word_count == 0)
00926 {
00927 throw cet::exception("InvalidRequest")
00928 << "No metadata has been stored in this Fragment.";
00929 }
00930 return reinterpret_cast_checked<T const *>
00931 (&vals_[fragmentHeader()->num_words()]);
00932 }
00933
00934 template <class T>
00935 void
00936 artdaq::Fragment::setMetadata(const T& metadata)
00937 {
00938 if (fragmentHeader()->metadata_word_count != 0)
00939 {
00940 throw cet::exception("InvalidRequest")
00941 << "Metadata has already been stored in this Fragment.";
00942 }
00943 auto const mdSize = validatedMetadataSize_<T>();
00944 vals_.insert(dataBegin(), mdSize, 0);
00945 updateFragmentHeaderWC_();
00946 fragmentHeader()->metadata_word_count = mdSize;
00947
00948 memcpy(metadataAddress(), &metadata, sizeof(T));
00949 }
00950
00951 template <class T>
00952 void
00953 artdaq::Fragment::updateMetadata(const T& metadata)
00954 {
00955 if (fragmentHeader()->metadata_word_count == 0)
00956 {
00957 throw cet::exception("InvalidRequest")
00958 << "No metadata in fragment; please use Fragment::setMetadata instead of Fragment::updateMetadata";
00959 }
00960
00961 auto const mdSize = validatedMetadataSize_<T>();
00962
00963 if (fragmentHeader()->metadata_word_count != mdSize)
00964 {
00965 throw cet::exception("InvalidRequest")
00966 << "Mismatch between type of metadata struct passed to updateMetadata and existing metadata struct";
00967 }
00968
00969 memcpy(metadataAddress(), &metadata, sizeof(T));
00970 }
00971
00972 inline void
00973 artdaq::Fragment::resize(std::size_t sz)
00974 {
00975 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00976 fragmentHeader()->num_words());
00977 updateFragmentHeaderWC_();
00978 }
00979
00980 inline
00981 void
00982 artdaq::Fragment::resize(std::size_t sz, RawDataType v)
00983 {
00984 vals_.resize(sz + fragmentHeader()->metadata_word_count +
00985 fragmentHeader()->num_words(), v);
00986 updateFragmentHeaderWC_();
00987 }
00988
00989 inline void
00990 artdaq::Fragment::resizeBytes(std::size_t szbytes)
00991 {
00992 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
00993 resize(nwords);
00994 }
00995
00996 inline
00997 void
00998 artdaq::Fragment::resizeBytes(std::size_t szbytes, byte_t v)
00999 {
01000 RawDataType defaultval;
01001 byte_t* ptr = reinterpret_cast_checked<byte_t*>(&defaultval);
01002
01003 for (uint8_t i = 0; i < sizeof(RawDataType); ++i)
01004 {
01005 *ptr = v;
01006 ptr++;
01007 }
01008
01009 RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
01010
01011 resize(nwords, defaultval);
01012 }
01013
01014
01015 inline
01016 void
01017 artdaq::Fragment::autoResize()
01018 {
01019 vals_.resize(fragmentHeader()->word_count);
01020 updateFragmentHeaderWC_();
01021 }
01022
01023 inline
01024 artdaq::Fragment::iterator
01025 artdaq::Fragment::dataBegin()
01026 {
01027 return vals_.begin() + fragmentHeader()->num_words() +
01028 fragmentHeader()->metadata_word_count;
01029 }
01030
01031 inline
01032 artdaq::Fragment::iterator
01033 artdaq::Fragment::dataEnd()
01034 {
01035 return vals_.end();
01036 }
01037
01038 inline
01039 artdaq::Fragment::iterator
01040 artdaq::Fragment::headerBegin()
01041 {
01042 return vals_.begin();
01043 }
01044
01045 inline
01046 artdaq::Fragment::const_iterator
01047 artdaq::Fragment::dataBegin() const
01048 {
01049 return vals_.begin() + fragmentHeader()->num_words() +
01050 fragmentHeader()->metadata_word_count;
01051 }
01052
01053 inline
01054 artdaq::Fragment::const_iterator
01055 artdaq::Fragment::dataEnd() const
01056 {
01057 return vals_.end();
01058 }
01059
01060 inline
01061 artdaq::Fragment::const_iterator
01062 artdaq::Fragment::headerBegin() const
01063 {
01064 return vals_.begin();
01065 }
01066
01067
01068 inline
01069 void
01070 artdaq::Fragment::clear()
01071 {
01072 vals_.erase(dataBegin(), dataEnd());
01073 updateFragmentHeaderWC_();
01074 }
01075
01076 inline
01077 bool
01078 artdaq::Fragment::empty()
01079 {
01080 return (vals_.size() - fragmentHeader()->num_words() -
01081 fragmentHeader()->metadata_word_count) == 0;
01082 }
01083
01084 inline
01085 void
01086 artdaq::Fragment::reserve(std::size_t cap)
01087 {
01088 vals_.reserve(cap + fragmentHeader()->num_words() +
01089 fragmentHeader()->metadata_word_count);
01090 }
01091
01092 inline
01093 void
01094 artdaq::Fragment::swap(Fragment& other) noexcept
01095 {
01096 vals_.swap(other.vals_);
01097 }
01098
01099 inline
01100 artdaq::RawDataType*
01101 artdaq::Fragment::dataAddress()
01102 {
01103 return &vals_[0] + fragmentHeader()->num_words() +
01104 fragmentHeader()->metadata_word_count;
01105 }
01106
01107 inline
01108 artdaq::RawDataType*
01109 artdaq::Fragment::metadataAddress()
01110 {
01111 if (fragmentHeader()->metadata_word_count == 0)
01112 {
01113 throw cet::exception("InvalidRequest")
01114 << "No metadata has been stored in this Fragment.";
01115 }
01116 return &vals_[0] + fragmentHeader()->num_words();
01117 }
01118
01119 inline
01120 artdaq::RawDataType*
01121 artdaq::Fragment::headerAddress()
01122 {
01123 return &vals_[0];
01124 }
01125
01126 inline
01127 artdaq::detail::RawFragmentHeader*
01128 artdaq::Fragment::fragmentHeader()
01129 {
01130 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader *>(&vals_[0]);
01131 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01132 {
01133 switch (hdr->version)
01134 {
01135 case 0xFFFF:
01136
01137 break;
01138 case 0:
01139 {
01140 std::cout << "Upgrading RawFragmentHeaderV0 (non const)" << std::endl;
01141 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 *>(&vals_[0]);
01142 auto new_hdr = old_hdr->upgrade();
01143
01144 auto szDiff = hdr->num_words() - old_hdr->num_words();
01145 if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
01146 memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01147 }
01148 break;
01149 default:
01150 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01151 break;
01152 }
01153 }
01154 return hdr;
01155 }
01156
01157 inline
01158 artdaq::detail::RawFragmentHeader const*
01159 artdaq::Fragment::fragmentHeader() const
01160 {
01161 auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
01162 if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
01163 {
01164 switch (hdr->version)
01165 {
01166 case 0xFFFF:
01167
01168 break;
01169 case 0:
01170 {
01171 std::cout << "Upgrading RawFragmentHeaderV0 (const)" << std::endl;
01172 auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
01173 auto new_hdr = old_hdr->upgrade();
01174
01175 auto szDiff = hdr->num_words() - old_hdr->num_words();
01176 auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
01177 if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
01178 memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
01179 }
01180 break;
01181 default:
01182 throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
01183 break;
01184 }
01185 }
01186 return hdr;
01187 }
01188
01189 inline
01190 void
01191 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
01192 {
01193 x.swap(y);
01194 }
01195
01196 inline
01197 std::ostream&
01198 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
01199 {
01200 f.print(os);
01201 return os;
01202 }
01203 #endif
01204
01205 #endif