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