BOSS 7.1.2
BESIII Offline Software System
Loading...
Searching...
No Matches
Header.h
Go to the documentation of this file.
1//Dear emacs, this is -*- c++ -*-
2
3/**
4 * @file eformat/Header.h
5 * @author <a href="mailto:[email protected]>Andr� Rabello dos
6 * ANJOS</a>
7 * $Author: zhangy $
8 * $Revision: 1.1.1.1 $
9 * $Date: 2009/06/19 07:35:41 $
10 *
11 * @brief Defines the Header entity. The definition is based on the
12 * update of ATL-DAQ-98-129, by D.Francis et al.
13 */
14
15#ifndef EFORMAT_HEADER_H
16#define EFORMAT_HEADER_H
17
18#include "eformat/Version.h"
20#include "eformat/util.h"
26#include "ers/ers.h"
27
28namespace eformat {
29
30 /**
31 * Contains the information on the Header of a fragment as described
32 * by the original note. The header is a composite entity, build from
33 * two parts:
34 *
35 * -# The generic part, containing the header type, size and version
36 * information;
37 * -# The specific part, containing data that is specific for a
38 * particular fragment.
39 */
40 template <class TPointer> class Header {
41
42 public:
43
44 /**
45 * To build a header given the containing buffer. I need to know
46 * where the header starts in order to do that.
47 *
48 * @param it The exact position where this header should start.
49 * @param match The word that this header should match.
50 */
51 Header (const TPointer& it, uint32_t match);
52
53 /**
54 * Builds an empty, otherwise useless Header
55 */
56 Header () : m_start() {}
57
58 /**
59 * Copy constructor
60 *
61 * @param other The other header to construct from
62 */
63 Header (const Header& other) : m_start(other.m_start) {}
64
65 /**
66 * Destructor virtualisation
67 */
68 virtual ~Header() {}
69
70 /**
71 * Assigment operator
72 *
73 * @param other The other header to assign from
74 */
75 Header& operator= (const Header& other)
76 { m_start = other.m_start; return *this; }
77
78 /**
79 * Reassign this header
80 *
81 * @param it The exact position where this header should start.
82 * @param match The word that this header should match.
83 */
84 Header& assign (const TPointer& it, uint32_t match);
85
86 /**
87 * Says if the generic part of the header is valid. This may throw
88 * exceptions.
89 */
90 virtual bool check () const;
91
92 /**
93 * Returns the fragment type.
94 */
95 inline uint32_t marker() const { return m_start[0]; }
96
97 /**
98 * Returns the size, in words, of the current fragment.
99 */
100 inline uint32_t fragment_size_word() const { return m_start[1]; }
101
102 /**
103 * Returns the size, in words, of the current header. That does include
104 * the specific part of the header.
105 */
106 inline uint32_t header_size_word() const { return m_start[2]; }
107
108 /**
109 * Returns the formatting version.
110 */
111 inline uint32_t version() const { return m_start[3]; }
112
113 /**
114 * Returns the full source identifier.
115 */
116 inline uint32_t source_id() const { return m_start[4]; }
117
118 /**
119 * Returns the number of status words available
120 */
121 inline uint32_t nstatus () const { return m_start[5]; }
122
123 /**
124 * Sets the pointer to my start
125 *
126 * @param it The pointer to set
127 */
128 inline void start (TPointer& it) const { it = m_start; }
129
130 /**
131 * Sets the pointer to where the payload starts
132 *
133 * @param it The pointer to set
134 */
135 inline void payload (TPointer& it) const
136 { it = m_start; it+= header_size_word(); }
137
138 /**
139 * Sets the pointer to one-past my end position
140 *
141 * @param it The pointer to set
142 */
143 inline void end (TPointer& it) const
144 { it = m_start; it += fragment_size_word(); }
145
146 /**
147 * Returns the payload size
148 */
149 inline uint32_t payload_size_word (void) const
150 { return fragment_size_word() - header_size_word(); }
151
152 /**
153 * Returns the status words, as an iterator to the status words available.
154 *
155 * @param it An <em>updateable</em> iterator you should provide.
156 */
157 inline void status (TPointer& it) const { it = m_start; it += 6; }
158
159
160 /**
161 * Returns the number of specific words available in the specific header
162 * part
163 */
164 inline uint32_t nspecific () const { return m_start[6 + nstatus()]; }
165
166 /**
167 * Returns an iterator to the start of the specific header part (this
168 * does not include the number of specific header fragments)
169 *
170 * @param it An <em>updateable</em> iterator you should provide.
171 */
172 inline void specific_header (TPointer& it) const
173 { it = m_start; it += 7 + nstatus(); }
174
175 /**
176 * Returns the number of children available.
177 */
178 virtual uint32_t nchildren () const;
179
180 /**
181 * Returns the nth child fragment. If the nth fragment doesn't exist, the
182 * behaviour is undefined.
183 *
184 * @param p A preallocated pointer you should provide.
185 * @param n The fragment position, starting at zero, of the child fragment
186 * you would like to get.
187 */
188 virtual void child (TPointer& p, size_t n) const;
189
190 /**
191 * Returns the nth child fragment. If the nth fragment doesn't exist, an
192 * exception is thrown.
193 *
194 * @warning Use this method with care, it is slower than the equivalent
195 * method that doesn't check.
196 *
197 * @param p A preallocated pointer you should provide.
198 * @param n The fragment position, starting at zero, of the child fragment
199 * you would like to get.
200 */
201 virtual void child_check (TPointer& p, size_t n) const;
202
203 /**
204 * Returns all the children of this fragment. The input to this method is a
205 * valid set of iterators to existing, pre-allocated pointers
206 *
207 * @param p A pointer to a set of preallocated TPointer's to set to the
208 * position of the children of this fragment.
209 * @param max The maximum number of children, p can point to.
210 *
211 * @return The number of children found on this fragment
212 */
213 virtual uint32_t children (TPointer* p, size_t max) const;
214
215 private: ///< representation
216
217 TPointer m_start; ///< my start word
218
219 };
220
221}
222
223template <class TPointer>
224eformat::Header<TPointer>::Header (const TPointer& it, uint32_t match)
225 : m_start(it)
226{
227 ERS_DEBUG_3("Building header 0x%x from iterator", match);
228 if (marker() != match) {
229 throw EFORMAT_WRONG_MARKER(marker(), match);
230 }
231 ERS_DEBUG_1("Initialized header with source identifier = %s",
232 eformat::helper::SourceIdentifier(match).human().c_str());
233}
234
235template <class TPointer> eformat::Header<TPointer>&
236eformat::Header<TPointer>::assign (const TPointer& it, uint32_t match)
237{
238 ERS_DEBUG_3("Rebuilding header 0x%x from iterator", match);
239 m_start = it;
240 if (marker() != match) {
241 throw EFORMAT_WRONG_MARKER(marker(), match);
242 }
243 ERS_DEBUG_1("Re-initialized header with source identifier = %s",
244 eformat::helper::SourceIdentifier(match).human().c_str());
245 return *this;
246}
247
248template <class TPointer>
250{
251 ERS_DEBUG_2("Checking for consistency of fragment of type %s [%s]",
252 eformat::marker2string(marker()).c_str(),
253 eformat::helper::SourceIdentifier(source_id()).human().c_str());
254 if ( version() >> 16 != eformat::MAJOR_DEFAULT_VERSION )
256 if ( header_size_word() != (7 + nstatus() + nspecific()) )
257 throw EFORMAT_SIZE_CHECK(header_size_word(),
258 (7 + nstatus() + nspecific()));
259 return true;
260}
261
262template <class TPointer>
264{
265 ERS_DEBUG_2("User asked for number of children of fragment type %s [%s]",
266 eformat::marker2string(marker()).c_str(),
267 eformat::helper::SourceIdentifier(source_id()).human().c_str());
268 return children(0,0);
269}
270
271template <class TPointer>
272void eformat::Header<TPointer>::child (TPointer& p, size_t n) const
273{
274 ERS_DEBUG_2("User asked for child %ud of fragment type %s [%s]", n,
275 eformat::marker2string(marker()).c_str(),
276 eformat::helper::SourceIdentifier(source_id()).human().c_str());
277 TPointer next;
278 payload(next);
279 for (size_t i=0; i<n; ++i) next += next[1];
280 ERS_DEBUG_3("Set user object");
281 p = next;
282}
283
284template <class TPointer>
285void eformat::Header<TPointer>::child_check (TPointer& p, size_t n) const
286{
287 uint32_t total = nchildren();
288 if (n >= total) throw EFORMAT_NO_SUCH_CHILD(n, total);
289 child(p, n);
290}
291
292template <class TPointer>
293uint32_t eformat::Header<TPointer>::children (TPointer* p, size_t max) const
294{
295 ERS_DEBUG_2("Retrieving all children...");
296 TPointer payload_start;
297 payload(payload_start);
298 try {
299 return find_fragments(child_marker(static_cast<HeaderMarker>(marker())),
300 payload_start, payload_size_word(), p, max);
301 }
302 catch (WrongMarkerIssue& ex) {
303 //This normally means the fragment size is wrong...
304 throw EFORMAT_WRONG_SIZE(fragment_size_word());
305 }
306 return 0;
307}
308
309#endif //EFORMAT_HEADER_H
Exception thrown when versions do not match.
#define EFORMAT_BAD_VERSION(current, supported)
const Int_t n
Exception thrown when the position of a child doesn't exist in the current fragment.
#define EFORMAT_NO_SUCH_CHILD(req, total)
When size checks do not match, this exception must be thrown.
#define EFORMAT_SIZE_CHECK(actual, informed)
Declares a type that can perform the conversion between source identifier components and the its 32-b...
#define ERS_DEBUG_1(...)
#define ERS_DEBUG_3(...)
#define ERS_DEBUG_2(...)
Defines a helper class to encode and decode version numbers.
Defines the wrong-marker exception, to be used when the wrong marker is found on the event stream.
#define EFORMAT_WRONG_MARKER(current, expected)
When size checks do not match, this exception must be thrown.
#define EFORMAT_WRONG_SIZE(size)
virtual uint32_t children(TPointer *p, size_t max) const
Definition Header.h:293
void end(TPointer &it) const
Definition Header.h:143
uint32_t marker() const
Definition Header.h:95
uint32_t source_id() const
Definition Header.h:116
uint32_t nspecific() const
Definition Header.h:164
virtual uint32_t nchildren() const
Definition Header.h:263
uint32_t nstatus() const
Definition Header.h:121
uint32_t version() const
Definition Header.h:111
Header(const Header &other)
Definition Header.h:63
uint32_t header_size_word() const
Definition Header.h:106
uint32_t payload_size_word(void) const
Definition Header.h:149
Header & operator=(const Header &other)
Definition Header.h:75
Header & assign(const TPointer &it, uint32_t match)
Definition Header.h:236
uint32_t fragment_size_word() const
Definition Header.h:100
void specific_header(TPointer &it) const
Definition Header.h:172
virtual void child(TPointer &p, size_t n) const
Definition Header.h:272
void status(TPointer &it) const
Definition Header.h:157
void start(TPointer &it) const
Definition Header.h:128
void payload(TPointer &it) const
Definition Header.h:135
virtual void child_check(TPointer &p, size_t n) const
Definition Header.h:285
virtual ~Header()
Definition Header.h:68
virtual bool check() const
Definition Header.h:249
ers header and documentation file
size_t find_fragments(eformat::HeaderMarker marker, TPointer block_start, size_t block_size, TPointer *frag=0, size_t max_count=0)
Definition util.h:111
HeaderMarker child_marker(HeaderMarker e)
std::string marker2string(const eformat::HeaderMarker &e)
const uint16_t MAJOR_DEFAULT_VERSION
Definition Version.h:29
Defines a set of utilities common to many event operations.