BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
Event/eformat/include/eformat/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:Andre.dos.Anjos@cern.ch>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/BadVersionIssue.h"
19#include "eformat/NoSuchChildIssue.h"
20#include "eformat/SizeCheckIssue.h"
21#include "eformat/SourceIdentifier.h"
22#include "eformat/Version.h"
23#include "eformat/WrongMarkerIssue.h"
24#include "eformat/WrongSizeIssue.h"
25#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 * To build a header given the containing buffer. I need to know
45 * where the header starts in order to do that.
46 *
47 * @param it The exact position where this header should start.
48 * @param match The word that this header should match.
49 */
50 Header( const TPointer& it, uint32_t match );
51
52 /**
53 * Builds an empty, otherwise useless Header
54 */
55 Header() : m_start() {}
56
57 /**
58 * Copy constructor
59 *
60 * @param other The other header to construct from
61 */
62 Header( const Header& other ) : m_start( other.m_start ) {}
63
64 /**
65 * Destructor virtualisation
66 */
67 virtual ~Header() {}
68
69 /**
70 * Assigment operator
71 *
72 * @param other The other header to assign from
73 */
74 Header& operator=( const Header& other ) {
75 m_start = other.m_start;
76 return *this;
77 }
78
79 /**
80 * Reassign this header
81 *
82 * @param it The exact position where this header should start.
83 * @param match The word that this header should match.
84 */
85 Header& assign( const TPointer& it, uint32_t match );
86
87 /**
88 * Says if the generic part of the header is valid. This may throw
89 * exceptions.
90 */
91 virtual bool check() const;
92
93 /**
94 * Returns the fragment type.
95 */
96 inline uint32_t marker() const { return m_start[0]; }
97
98 /**
99 * Returns the size, in words, of the current fragment.
100 */
101 inline uint32_t fragment_size_word() const { return m_start[1]; }
102
103 /**
104 * Returns the size, in words, of the current header. That does include
105 * the specific part of the header.
106 */
107 inline uint32_t header_size_word() const { return m_start[2]; }
108
109 /**
110 * Returns the formatting version.
111 */
112 inline uint32_t version() const { return m_start[3]; }
113
114 /**
115 * Returns the full source identifier.
116 */
117 inline uint32_t source_id() const { return m_start[4]; }
118
119 /**
120 * Returns the number of status words available
121 */
122 inline uint32_t nstatus() const { return m_start[5]; }
123
124 /**
125 * Sets the pointer to my start
126 *
127 * @param it The pointer to set
128 */
129 inline void start( TPointer& it ) const { it = m_start; }
130
131 /**
132 * Sets the pointer to where the payload starts
133 *
134 * @param it The pointer to set
135 */
136 inline void payload( TPointer& it ) const {
137 it = m_start;
138 it += header_size_word();
139 }
140
141 /**
142 * Sets the pointer to one-past my end position
143 *
144 * @param it The pointer to set
145 */
146 inline void end( TPointer& it ) const {
147 it = m_start;
148 it += fragment_size_word();
149 }
150
151 /**
152 * Returns the payload size
153 */
154 inline uint32_t payload_size_word( void ) const {
156 }
157
158 /**
159 * Returns the status words, as an iterator to the status words available.
160 *
161 * @param it An <em>updateable</em> iterator you should provide.
162 */
163 inline void status( TPointer& it ) const {
164 it = m_start;
165 it += 6;
166 }
167
168 /**
169 * Returns the number of specific words available in the specific header
170 * part
171 */
172 inline uint32_t nspecific() const { return m_start[6 + nstatus()]; }
173
174 /**
175 * Returns an iterator to the start of the specific header part (this
176 * does not include the number of specific header fragments)
177 *
178 * @param it An <em>updateable</em> iterator you should provide.
179 */
180 inline void specific_header( TPointer& it ) const {
181 it = m_start;
182 it += 7 + nstatus();
183 }
184
185 /**
186 * Returns the number of children available.
187 */
188 virtual uint32_t nchildren() const;
189
190 /**
191 * Returns the nth child fragment. If the nth fragment doesn't exist, the
192 * behaviour is undefined.
193 *
194 * @param p A preallocated pointer you should provide.
195 * @param n The fragment position, starting at zero, of the child fragment
196 * you would like to get.
197 */
198 virtual void child( TPointer& p, size_t n ) const;
199
200 /**
201 * Returns the nth child fragment. If the nth fragment doesn't exist, an
202 * exception is thrown.
203 *
204 * @warning Use this method with care, it is slower than the equivalent
205 * method that doesn't check.
206 *
207 * @param p A preallocated pointer you should provide.
208 * @param n The fragment position, starting at zero, of the child fragment
209 * you would like to get.
210 */
211 virtual void child_check( TPointer& p, size_t n ) const;
212
213 /**
214 * Returns all the children of this fragment. The input to this method is a
215 * valid set of iterators to existing, pre-allocated pointers
216 *
217 * @param p A pointer to a set of preallocated TPointer's to set to the
218 * position of the children of this fragment.
219 * @param max The maximum number of children, p can point to.
220 *
221 * @return The number of children found on this fragment
222 */
223 virtual uint32_t children( TPointer* p, size_t max ) const;
224
225 private: ///< representation
226 TPointer m_start; ///< my start word
227 };
228
229} // namespace eformat
230
231template <class TPointer>
232eformat::Header<TPointer>::Header( const TPointer& it, uint32_t match ) : m_start( it ) {
233 ERS_DEBUG_3( "Building header 0x%x from iterator", match );
234 if ( marker() != match ) { throw EFORMAT_WRONG_MARKER( marker(), match ); }
235 ERS_DEBUG_1( "Initialized header with source identifier = %s",
236 eformat::helper::SourceIdentifier( match ).human().c_str() );
237}
238
239template <class TPointer>
241 uint32_t match ) {
242 ERS_DEBUG_3( "Rebuilding header 0x%x from iterator", match );
243 m_start = it;
244 if ( marker() != match ) { throw EFORMAT_WRONG_MARKER( marker(), match ); }
245 ERS_DEBUG_1( "Re-initialized header with source identifier = %s",
246 eformat::helper::SourceIdentifier( match ).human().c_str() );
247 return *this;
248}
249
250template <class TPointer> bool eformat::Header<TPointer>::check() const {
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() );
256 if ( header_size_word() != ( 7 + nstatus() + nspecific() ) )
257 throw EFORMAT_SIZE_CHECK( header_size_word(), ( 7 + nstatus() + nspecific() ) );
258 return true;
259}
260
261template <class TPointer> uint32_t eformat::Header<TPointer>::nchildren() const {
262 ERS_DEBUG_2( "User asked for number of children of fragment type %s [%s]",
263 eformat::marker2string( marker() ).c_str(),
264 eformat::helper::SourceIdentifier( source_id() ).human().c_str() );
265 return children( 0, 0 );
266}
267
268template <class TPointer>
269void eformat::Header<TPointer>::child( TPointer& p, size_t n ) const {
270 ERS_DEBUG_2( "User asked for child %ud of fragment type %s [%s]", n,
271 eformat::marker2string( marker() ).c_str(),
272 eformat::helper::SourceIdentifier( source_id() ).human().c_str() );
273 TPointer next;
274 payload( next );
275 for ( size_t i = 0; i < n; ++i ) next += next[1];
276 ERS_DEBUG_3( "Set user object" );
277 p = next;
278}
279
280template <class TPointer>
281void eformat::Header<TPointer>::child_check( TPointer& p, size_t n ) const {
282 uint32_t total = nchildren();
283 if ( n >= total ) throw EFORMAT_NO_SUCH_CHILD( n, total );
284 child( p, n );
285}
286
287template <class TPointer>
288uint32_t eformat::Header<TPointer>::children( TPointer* p, size_t max ) const {
289 ERS_DEBUG_2( "Retrieving all children..." );
290 TPointer payload_start;
291 payload( payload_start );
292 try
293 {
294 return find_fragments( child_marker( static_cast<HeaderMarker>( marker() ) ),
295 payload_start, payload_size_word(), p, max );
296 } catch ( WrongMarkerIssue& ex )
297 {
298 // This normally means the fragment size is wrong...
300 }
301 return 0;
302}
303
304#endif // EFORMAT_HEADER_H
const Int_t n
#define max(a, b)
#define EFORMAT_BAD_VERSION(current, supported)
#define EFORMAT_NO_SUCH_CHILD(req, total)
#define EFORMAT_SIZE_CHECK(actual, informed)
#define EFORMAT_WRONG_MARKER(current, expected)
#define ERS_DEBUG_1(...)
#define ERS_DEBUG_3(...)
#define ERS_DEBUG_2(...)
virtual uint32_t children(TPointer *p, size_t max) const
Header & operator=(const Header &other)
Header(const TPointer &it, uint32_t match)
Header & assign(const TPointer &it, uint32_t match)
void specific_header(TPointer &it) const
virtual void child(TPointer &p, size_t n) const
virtual void child_check(TPointer &p, size_t n) const
size_t find_fragments(eformat::HeaderMarker marker, TPointer block_start, size_t block_size, TPointer *frag=0, size_t max_count=0)
HeaderMarker child_marker(HeaderMarker e)
std::string marker2string(const eformat::HeaderMarker &e)