$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_04_20a
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef artdaq_core_Data_Fragment_hh 00002 #define artdaq_core_Data_Fragment_hh 00003 00004 #include <algorithm> 00005 //#include <cassert> 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" // TRACE 00024 #endif 00025 00029 namespace artdaq { 00030 # define DATAVEC_T QuickVec<RawDataType> 00031 //#define DATAVEC_T std::vector<RawDataType> 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 // Hide most things from ROOT. 00102 #if HIDE_FROM_ROOT 00103 00104 // http://stackoverflow.com/questions/33939687 00105 // This should generate an exception if artdaq::Fragment is not move-constructible 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; // See note for non-const, above. 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 // http://stackoverflow.com/questions/33939687 00727 // This should generate an exception if artdaq::Fragment is not move-constructible 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 // Make sure a size_t is big enough to hold the maximum metadata 00756 // size. This *should* always be true, but it is a compile-time check 00757 // and therefore cheap. 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() + // Header 00782 validatedMetadataSize_<T>() + // Metadata 00783 payload_size) // User data 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 // vals ctor w/o init val is used; make sure header is ALL initialized. 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 // Make sure vals_.size() fits inside 32 bits. Left-shift here should 00897 // match bitfield size of word_count in RawFragmentHeader. 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 //std::cout << "Not upgrading InvalidVersion Fragment" << std::endl; 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 //std::cout << "Not upgrading InvalidVersion Fragment" << std::endl; 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/* HIDE_FROM_ROOT */ 01224 01225 #endif /* artdaq_core_Data_Fragment_hh */