Line data Source code
1 : #ifndef ALIHLTMUONDATABLOCKWRITER_H
2 : #define ALIHLTMUONDATABLOCKWRITER_H
3 : /**************************************************************************
4 : * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
5 : * *
6 : * Author: The ALICE Off-line Project. *
7 : * Contributors are mentioned in the code where appropriate. *
8 : * *
9 : * Permission to use, copy, modify and distribute this software and its *
10 : * documentation strictly for non-commercial purposes is hereby granted *
11 : * without fee, provided that the above copyright notice appears in all *
12 : * copies and that both the copyright notice and this permission notice *
13 : * appear in the supporting documentation. The authors make no claims *
14 : * about the suitability of this software for any purpose. It is *
15 : * provided "as is" without express or implied warranty. *
16 : **************************************************************************/
17 :
18 : // $Id$
19 :
20 : /**
21 : * @file AliHLTMUONDataBlockWriter.h
22 : * @author Artur Szostak <artursz@iafrica.com>
23 : * @date 19 May 2007
24 : * @brief Definition of a writer class for internal dimuon HLT raw data blocks.
25 : */
26 :
27 : #include "AliHLTMUONDataTypes.h"
28 : #include <cassert>
29 :
30 : #include "AliHLTMUONTriggerRecordsBlockStruct.h"
31 : #include "AliHLTMUONTrigRecsDebugBlockStruct.h"
32 : #include "AliHLTMUONRecHitsBlockStruct.h"
33 : #include "AliHLTMUONClustersBlockStruct.h"
34 : #include "AliHLTMUONChannelsBlockStruct.h"
35 : #include "AliHLTMUONMansoTracksBlockStruct.h"
36 : #include "AliHLTMUONMansoCandidatesBlockStruct.h"
37 : #include "AliHLTMUONTracksBlockStruct.h"
38 : #include "AliHLTMUONSinglesDecisionBlockStruct.h"
39 : #include "AliHLTMUONPairsDecisionBlockStruct.h"
40 :
41 : /**
42 : * A light weight class for writing an internal dimuon HLT data block.
43 : * Suppose we are given a pointer 'buffer' to some empty memory buffer where we
44 : * can store our new data block and the size of the data block is given by the
45 : * variable 'size'. The data block is of type 'block_type', the data block entries
46 : * are of type 'entries_type' and the data block type code is 'type_code'.
47 : * The data block can be written in the following way:
48 : * \code
49 : * void* buffer = somebuffer;
50 : * AliHLTUInt32_t size = somebuffer_size;
51 : *
52 : * // Initialise the data block writer.
53 : * AliHLTMUONDataBlockWriter<block_type, entries_type, type_code>
54 : * block(buffer, size);
55 : *
56 : * // Initialise the block header
57 : * if (not block.InitCommonHeader())
58 : * {
59 : * // handle error and exit...
60 : * }
61 : *
62 : * // Tell the writer how many entries we are going to use.
63 : * if (not block.SetNumberOfEntries(somevalue))
64 : * {
65 : * // handle error and exit...
66 : * }
67 : *
68 : * // Add all the entries to the data block.
69 : * for (AliHLTUInt32_t i = 0; i < block.Nentries(); i++)
70 : * {
71 : * entries_type& entry = block[i];
72 : * // fill the new entry...
73 : * entry.somefield = somevalue;
74 : * }
75 : * \endcode
76 : * The slightly slower but safer method is to do the following:
77 : * \code
78 : * AliHLTMUONDataBlockWriter<block_type, entries_type, type_code>
79 : * block(buffer, size);
80 : * if (not block.InitCommonHeader())
81 : * {
82 : * // handle error and exit...
83 : * }
84 : *
85 : * // For each new entry add it to the data block.
86 : * while (HaveMoreEntries())
87 : * {
88 : * entries_type* entry = block.AddEntry();
89 : * if (entry == NULL)
90 : * {
91 : * // handle buffer overflow and exit...
92 : * }
93 : * // fill the new entry...
94 : * entry->somefield = somevalue;
95 : * }
96 : * \endcode
97 : */
98 : template <
99 : class DataBlockType,
100 : class DataElementType,
101 : AliHLTMUONDataBlockType blockTypeCode
102 : >
103 : class AliHLTMUONDataBlockWriter
104 : {
105 : public:
106 : typedef DataBlockType HeaderType;
107 : typedef DataElementType ElementType;
108 :
109 : /**
110 : * Constructor that sets the internal pointer to the start of the buffer
111 : * space to write to and the total size of the buffer in bytes.
112 : * @param buffer The pointer to the first byte of the memory buffer.
113 : * @param size The total size of the buffer in bytes.
114 : */
115 : AliHLTMUONDataBlockWriter(void* buffer, AliHLTUInt32_t size) :
116 0 : fSize(size),
117 0 : fMaxArraySize(size > sizeof(DataBlockType) ? size - sizeof(DataBlockType) : 0),
118 0 : fBlock(reinterpret_cast<DataBlockType*>(buffer)),
119 0 : fData(reinterpret_cast<DataElementType*>(
120 0 : reinterpret_cast<DataBlockType*>(buffer) + 1
121 : ))
122 0 : {
123 0 : assert( buffer != NULL );
124 0 : }
125 :
126 : /**
127 : * Copy constructor that performs a shallow copy.
128 : * Since this class does not take direct ownership of the buffer, never
129 : * allocates or deallocates memory, this can be allowed.
130 : */
131 : AliHLTMUONDataBlockWriter(const AliHLTMUONDataBlockWriter& writer)
132 : {
133 : fSize = writer.fSize;
134 : fMaxArraySize = writer.fMaxArraySize;
135 : fBlock = writer.fBlock;
136 : fData = writer.fData;
137 : }
138 :
139 : /**
140 : * Assignment operator performs a shallow copy.
141 : * This is OK because this class does not take direct ownership of the
142 : * output memory buffer.
143 : */
144 : AliHLTMUONDataBlockWriter& operator = (const AliHLTMUONDataBlockWriter& writer)
145 : {
146 : fSize = writer.fSize;
147 : fMaxArraySize = writer.fMaxArraySize;
148 : fBlock = writer.fBlock;
149 : fData = writer.fData;
150 : return *this;
151 : }
152 :
153 : /**
154 : * Initialises the common data block header by setting the type and record
155 : * width fields. If the buffer size was to small to create the header then
156 : * this method returns false, otherwise true on success.
157 : */
158 : bool InitCommonHeader() const
159 : {
160 : // The block size must be at least sizeof(DataBlockType) bytes.
161 0 : if (fSize < sizeof(DataBlockType)) return false;
162 :
163 : // Now fill the fields in the header.
164 0 : fBlock->fHeader.fType = blockTypeCode;
165 0 : fBlock->fHeader.fRecordWidth = sizeof(DataElementType);
166 0 : fBlock->fHeader.fNrecords = 0;
167 0 : return true;
168 0 : }
169 :
170 : /**
171 : * Returns the common data block header.
172 : */
173 : const AliHLTMUONDataBlockHeader& CommonBlockHeader() const
174 : {
175 : return fBlock->fHeader;
176 : }
177 :
178 : /**
179 : * Returns the whole data block header.
180 : */
181 : DataBlockType& BlockHeader()
182 : {
183 0 : return *fBlock;
184 : }
185 :
186 : const DataBlockType& BlockHeader() const
187 : {
188 : return *fBlock;
189 : }
190 :
191 : /**
192 : * Returns a pointer to the next location where a data entry can be
193 : * written and increments the number of entries.
194 : * If the buffer is already full then NULL is returned and the number of
195 : * entries is not changed.
196 : */
197 : DataElementType* AddEntry() const
198 : {
199 0 : if ( (Nentries() + 1) * sizeof(DataElementType) > fMaxArraySize )
200 0 : return NULL;
201 0 : DataElementType* newentry = &fData[fBlock->fHeader.fNrecords];
202 0 : fBlock->fHeader.fNrecords++;
203 : return newentry;
204 0 : }
205 :
206 : /**
207 : * Sets the number of entries that will be filled into the buffer.
208 : * If the number of entries is to many to fit into the buffer then this
209 : * method returns false, otherwise true.
210 : */
211 : bool SetNumberOfEntries(AliHLTUInt32_t n) const
212 : {
213 0 : if (n * sizeof(DataElementType) > fMaxArraySize) return false;
214 0 : fBlock->fHeader.fNrecords = n;
215 0 : return true;
216 0 : }
217 :
218 : /**
219 : * Returns the total number of entries already added to the data block.
220 : */
221 0 : AliHLTUInt32_t Nentries() const { return fBlock->fHeader.fNrecords; }
222 :
223 : /**
224 : * Returns a pointer to the i'th entry.
225 : * If the index 'i' is out of bounds then NULL is returned.
226 : * This is a safe access method because it does bounds checking but is
227 : * a little slower than the array operators.
228 : * @param i The index number of the entry to be returned.
229 : * @return A pointer to the entry or NULL.
230 : */
231 : DataElementType* Entry(AliHLTUInt32_t i)
232 : {
233 : return (i < Nentries()) ? &fData[i] : NULL;
234 : }
235 :
236 : const DataElementType* Entry(AliHLTUInt32_t i) const
237 : {
238 : return (i < Nentries()) ? &fData[i] : NULL;
239 : }
240 :
241 : /**
242 : * Array operator for accessing the data entries directly.
243 : * The index variable 'i' is not checked (except in debug compilations)
244 : * so one should make sure they are within the valid range.
245 : */
246 : DataElementType& operator [] (AliHLTUInt32_t i)
247 : {
248 0 : assert( i < Nentries() );
249 0 : return fData[i];
250 : }
251 :
252 : const DataElementType& operator [] (AliHLTUInt32_t i) const
253 : {
254 : assert( i < Nentries() );
255 : return fData[i];
256 : }
257 :
258 : /**
259 : * Returns a pointer to the array of elements in the data block.
260 : * Care must be taken not to read beyond the array limits given by
261 : * Nentries().
262 : */
263 0 : DataElementType* GetArray() { return fData; }
264 : const DataElementType* GetArray() const { return fData; }
265 :
266 : /**
267 : * Calculates the number of bytes used for the data block in the buffer.
268 : * This value will only make sense if a call to InitCommonHeader() was
269 : * made and it returned true.
270 : */
271 : AliHLTUInt32_t BytesUsed() const
272 : {
273 0 : assert( sizeof(DataElementType) == fBlock->fHeader.fRecordWidth);
274 0 : return sizeof(DataBlockType) + Nentries() * sizeof(DataElementType);
275 : }
276 :
277 : /**
278 : * Calculates the maximum number of entries that will fit into the
279 : * memory buffer.
280 : */
281 : AliHLTUInt32_t MaxNumberOfEntries() const
282 : {
283 0 : return fMaxArraySize / sizeof(DataElementType);
284 : }
285 :
286 0 : AliHLTUInt32_t BufferSize() { return fSize; }
287 :
288 : private:
289 :
290 : AliHLTUInt32_t fSize; // Size of the buffer in bytes.
291 : AliHLTUInt32_t fMaxArraySize; // Maximum size of the fData array in bytes.
292 : DataBlockType* fBlock; // Pointer to the start of the data block.
293 : DataElementType* fData; // Pointer to the start of the data array.
294 : };
295 :
296 :
297 : // We now define the writer classes for the various data block types from the
298 : // template class AliHLTMUONDataBlockWriter.
299 :
300 : typedef AliHLTMUONDataBlockWriter<
301 : AliHLTMUONTriggerRecordsBlockStruct,
302 : AliHLTMUONTriggerRecordStruct,
303 : kTriggerRecordsDataBlock
304 : > AliHLTMUONTriggerRecordsBlockWriter;
305 :
306 : typedef AliHLTMUONDataBlockWriter<
307 : AliHLTMUONTrigRecsDebugBlockStruct,
308 : AliHLTMUONTrigRecInfoStruct,
309 : kTrigRecsDebugDataBlock
310 : > AliHLTMUONTrigRecsDebugBlockWriter;
311 :
312 : typedef AliHLTMUONDataBlockWriter<
313 : AliHLTMUONRecHitsBlockStruct,
314 : AliHLTMUONRecHitStruct,
315 : kRecHitsDataBlock
316 : > AliHLTMUONRecHitsBlockWriter;
317 :
318 : typedef AliHLTMUONDataBlockWriter<
319 : AliHLTMUONClustersBlockStruct,
320 : AliHLTMUONClusterStruct,
321 : kClustersDataBlock
322 : > AliHLTMUONClustersBlockWriter;
323 :
324 : typedef AliHLTMUONDataBlockWriter<
325 : AliHLTMUONChannelsBlockStruct,
326 : AliHLTMUONChannelStruct,
327 : kChannelsDataBlock
328 : > AliHLTMUONChannelsBlockWriter;
329 :
330 : typedef AliHLTMUONDataBlockWriter<
331 : AliHLTMUONMansoTracksBlockStruct,
332 : AliHLTMUONMansoTrackStruct,
333 : kMansoTracksDataBlock
334 : > AliHLTMUONMansoTracksBlockWriter;
335 :
336 : typedef AliHLTMUONDataBlockWriter<
337 : AliHLTMUONMansoCandidatesBlockStruct,
338 : AliHLTMUONMansoCandidateStruct,
339 : kMansoCandidatesDataBlock
340 : > AliHLTMUONMansoCandidatesBlockWriter;
341 :
342 : typedef AliHLTMUONDataBlockWriter<
343 : AliHLTMUONTracksBlockStruct,
344 : AliHLTMUONTrackStruct,
345 : kTracksDataBlock
346 : > AliHLTMUONTracksBlockWriter;
347 :
348 : typedef AliHLTMUONDataBlockWriter<
349 : AliHLTMUONSinglesDecisionBlockStruct,
350 : AliHLTMUONTrackDecisionStruct,
351 : kSinglesDecisionDataBlock
352 : > AliHLTMUONSinglesDecisionBlockWriter;
353 :
354 : typedef AliHLTMUONDataBlockWriter<
355 : AliHLTMUONPairsDecisionBlockStruct,
356 : AliHLTMUONPairDecisionStruct,
357 : kPairsDecisionDataBlock
358 : > AliHLTMUONPairsDecisionBlockWriter;
359 :
360 : #endif // ALIHLTMUONDATABLOCKWRITER_H
|