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