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