Line data Source code
1 : #ifndef artdaq_ots_Overlays_UDPFragment_hh
2 : #define artdaq_ots_Overlays_UDPFragment_hh
3 :
4 : #include "artdaq-core/Data/Fragment.hh"
5 : #include "cetlib_except/exception.h"
6 :
7 : #include <ostream>
8 : #include <vector>
9 :
10 : /// Implementation of "UDPFragment", an artdaq::Fragment overlay class
11 : ///
12 : namespace ots
13 : {
14 : class UDPFragment;
15 :
16 : /// Let the "<<" operator dump the UDPFragment's data to stdout
17 : std::ostream& operator<<(std::ostream&, UDPFragment const&);
18 : } // namespace ots
19 :
20 : class ots::UDPFragment
21 : {
22 : public:
23 : /// The "Metadata" struct is used to store info primarily related to
24 : /// the upstream hardware environment from where the fragment came
25 : ///
26 : /// "data_t" is a typedef of the fundamental unit of data the
27 : /// metadata structure thinks of itself as consisting of; it can give
28 : /// its size via the static "size_words" variable (
29 : /// UDPFragment::Metadata::size_words )
30 : ///
31 : struct Metadata
32 : {
33 : typedef uint64_t data_t;
34 :
35 : data_t port : 16;
36 : data_t address : 32;
37 : data_t unused : 16;
38 :
39 : static size_t const size_words = 1ull; ///< Units of Metadata::data_t
40 : };
41 :
42 : static_assert(sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t),
43 : "UDPFragment::Metadata size changed");
44 :
45 : /// The "Header" struct contains "metadata" specific to the fragment
46 : /// which is not hardware-related
47 : ///
48 : /// Header::data_t -- not to be confused with Metadata::data_t ! --
49 : /// describes the standard size of a data type not just for the
50 : /// header data, but ALSO the physics data beyond it; the size of the
51 : /// header in units of Header::data_t is given by "size_words", and
52 : /// the size of the fragment beyond the header in units of
53 : /// Header::data_t is given by "event_size"
54 : ///
55 : /// Notice only the first 28 bits of the first 32-bit unsigned
56 : /// integer in the Header is used to hold the event_size ; this means
57 : /// that you can't represent a fragment larger than 2**28 units of
58 : /// data_t, or 1,073,741,824 bytes
59 : ///
60 : struct Header
61 : {
62 : typedef uint32_t data_t;
63 :
64 : typedef uint32_t event_size_t;
65 : typedef uint32_t data_type_t;
66 :
67 : event_size_t event_size : 28;
68 : event_size_t type : 4;
69 :
70 : static size_t const size_words = 1ul; ///< Units of Header::data_t
71 : };
72 :
73 : static_assert(sizeof(Header) == Header::size_words * sizeof(Header::data_t),
74 : "UDPFragment::Header size changed");
75 :
76 : /// The constructor simply sets its const private member "artdaq_Fragment_"
77 : /// to refer to the artdaq::Fragment object
78 : ///
79 0 : UDPFragment(artdaq::Fragment const& f)
80 0 : : artdaq_Fragment_(f) {}
81 :
82 : /// const getter functions for the data in the header
83 : ///
84 0 : Header::event_size_t hdr_event_size() const { return header_()->event_size; }
85 0 : Header::data_type_t hdr_data_type() const { return header_()->type; }
86 0 : static constexpr size_t hdr_size_words() { return Header::size_words; }
87 :
88 : /// UDP Data Word Count
89 0 : size_t udp_data_words() const
90 : {
91 0 : return (hdr_event_size() - hdr_size_words()) * bytes_per_word_();
92 : }
93 :
94 : /// Start of the UDP data, returned as a pointer
95 0 : uint8_t const* dataBegin() const
96 : {
97 0 : return reinterpret_cast<uint8_t const*>(header_() + 1);
98 : }
99 :
100 : /// End of the UDP data, returned as a pointer
101 0 : uint8_t const* dataEnd() const { return dataBegin() + udp_data_words(); }
102 :
103 : protected:
104 : /// Functions to translate between byte size and the size of
105 : /// this fragment overlay's concept of a unit of data (i.e.,
106 : /// Header::data_t).
107 : ///
108 0 : static constexpr size_t bytes_per_word_()
109 : {
110 0 : return sizeof(Header::data_t) / sizeof(uint8_t);
111 : }
112 :
113 : /// header_() simply takes the address of the start of this overlay's
114 : /// data (i.e., where the UDPFragment::Header object begins) and
115 : /// casts it as a pointer to UDPFragment::Header
116 : ///
117 0 : Header const* header_() const
118 : {
119 : return reinterpret_cast<UDPFragment::Header const*>(
120 0 : artdaq_Fragment_.dataBeginBytes());
121 : }
122 :
123 : private:
124 : artdaq::Fragment const& artdaq_Fragment_;
125 : };
126 :
127 : #endif /* artdaq_ots_Overlays_UDPFragment_hh */
|