otsdaq  v1_01_04
 All Classes Namespaces Functions
UDPFragmentWriter.hh
1 #ifndef artdaq_ots_Overlays_UDPFragmentWriter_hh
2 #define artdaq_ots_Overlays_UDPFragmentWriter_hh
3 
5 // UDPFragmentWriter
6 //
7 // Class derived from UDPFragment which allows writes to the data (for
8 // simulation purposes). Note that for this reason it contains
9 // non-const members which hide the const members in its parent class,
10 // UDPFragment, including its reference to the artdaq::Fragment
11 // object, artdaq_Fragment_, as well as its functions pointing to the
12 // beginning and end of ADC values in the fragment, dataBegin() and
13 // dataEnd()
14 //
16 
17 #include "artdaq-core/Data/Fragment.hh"
18 #include "artdaq-ots/Overlays/UDPFragment.hh"
19 
20 #include <iostream>
21 
22 namespace ots {
23  class UDPFragmentWriter;
24 }
25 
26 
28 public:
29 
30 
31  UDPFragmentWriter(artdaq::Fragment & f);
32 
33  // These functions form overload sets with const functions from
34  // ots::UDPFragment
35 
36  uint8_t * dataBegin();
37  uint8_t * dataEnd();
38 
39  // We'll need to hide the const version of header in UDPFragment in
40  // order to be able to perform writes
41 
42  Header * header_() {
43  assert(artdaq_Fragment_.dataSizeBytes() >= sizeof(Header) );
44  return reinterpret_cast<Header *>( artdaq_Fragment_.dataBeginBytes());
45  }
46 
47  void set_hdr_type(Header::data_type_t dataType) {
48  header_()->type = dataType & 0xF;
49  }
50 
51  void resize(size_t nBytes);
52 
53 private:
54  size_t calc_event_size_words_(size_t nBytes);
55 
56  static size_t bytes_to_words_(size_t nBytes);
57 
58  // Note that this non-const reference hides the const reference in the base class
59  artdaq::Fragment & artdaq_Fragment_;
60 };
61 
62 // The constructor will expect the artdaq::Fragment object it's been
63 // passed to contain the artdaq::Fragment header + the
64 // UDPFragment::Metadata object, otherwise it throws
65 
66 ots::UDPFragmentWriter::UDPFragmentWriter(artdaq::Fragment& f ) :
67  UDPFragment(f), artdaq_Fragment_(f) {
68 
69  if ( ! f.hasMetadata() || f.dataSizeBytes() > 0 ) {
70  throw cet::exception("Error in UDPFragmentWriter: Raw artdaq::Fragment object does not appear to consist of (and only of) its own header + the UDPFragment::Metadata object");
71  }
72 
73  // Allocate space for the header
74  artdaq_Fragment_.resizeBytes( sizeof(Header) );
75 }
76 
77 
78 inline uint8_t * ots::UDPFragmentWriter::dataBegin() {
79  // Make sure there's data past the UDPFragment header
80  assert(artdaq_Fragment_.dataSizeBytes() >= sizeof(Header) + sizeof(artdaq::Fragment::value_type) );
81  return reinterpret_cast<uint8_t *>(header_() + 1);
82 }
83 
84 inline uint8_t * ots::UDPFragmentWriter::dataEnd() {
85  return dataBegin() + udp_data_words();
86 }
87 
88 
89 inline void ots::UDPFragmentWriter::resize(size_t nBytes) {
90 
91  artdaq_Fragment_.resizeBytes(sizeof(Header::data_t) * calc_event_size_words_(nBytes) );
92  header_()->event_size = calc_event_size_words_(nBytes);
93 }
94 
95 inline size_t ots::UDPFragmentWriter::calc_event_size_words_(size_t nBytes) {
96  return bytes_to_words_(nBytes) + hdr_size_words();
97 }
98 
99 inline size_t ots::UDPFragmentWriter::bytes_to_words_(size_t nBytes) {
100  auto mod(nBytes % bytes_per_word_());
101  return (mod == 0) ?
102  nBytes / bytes_per_word_() :
103  nBytes / bytes_per_word_() + 1;
104 }
105 
106 #endif /* artdaq_demo_Overlays_UDPFragmentWriter_hh */