Update master to aliroot
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONDataBlockWriter.h
CommitLineData
b3eef24e 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
1d8ae082 18// $Id$
b3eef24e 19
20/**
21 * @file AliHLTMUONDataBlockWriter.h
22 * @author Artur Szostak <artursz@iafrica.com>
1d8ae082 23 * @date 19 May 2007
b3eef24e 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"
b3eef24e 32#include "AliHLTMUONRecHitsBlockStruct.h"
33#include "AliHLTMUONClustersBlockStruct.h"
34#include "AliHLTMUONChannelsBlockStruct.h"
90a74d7a 35#include "AliHLTMUONMansoTracksBlockStruct.h"
36#include "AliHLTMUONMansoCandidatesBlockStruct.h"
a8982f78 37#include "AliHLTMUONTracksBlockStruct.h"
90a74d7a 38#include "AliHLTMUONSinglesDecisionBlockStruct.h"
39#include "AliHLTMUONPairsDecisionBlockStruct.h"
b3eef24e 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:
1d970015 48 * \code
b3eef24e 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
b12fe461 57 * if (not block.InitCommonHeader())
b3eef24e 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 * }
1d970015 75 * \endcode
b3eef24e 76 * The slightly slower but safer method is to do the following:
1d970015 77 * \code
b3eef24e 78 * AliHLTMUONDataBlockWriter<block_type, entries_type, type_code>
79 * block(buffer, size);
b12fe461 80 * if (not block.InitCommonHeader())
b3eef24e 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();
b12fe461 89 * if (entry == NULL)
90 * {
91 * // handle buffer overflow and exit...
92 * }
b3eef24e 93 * // fill the new entry...
94 * entry->somefield = somevalue;
95 * }
1d970015 96 * \endcode
b3eef24e 97 */
98template <
99 class DataBlockType,
100 class DataElementType,
101 AliHLTMUONDataBlockType blockTypeCode
102>
103class AliHLTMUONDataBlockWriter
104{
105public:
b12fe461 106 typedef DataBlockType HeaderType;
107 typedef DataElementType ElementType;
b3eef24e 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 fSize(size),
d0665ed6 117 fMaxArraySize(size > sizeof(DataBlockType) ? size - sizeof(DataBlockType) : 0),
b3eef24e 118 fBlock(reinterpret_cast<DataBlockType*>(buffer)),
119 fData(reinterpret_cast<DataElementType*>(
120 reinterpret_cast<DataBlockType*>(buffer) + 1
121 ))
122 {
123 assert( buffer != NULL );
124 }
d0665ed6 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 }
b3eef24e 152
153 /**
90a74d7a 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.
b3eef24e 157 */
90a74d7a 158 bool InitCommonHeader() const
b3eef24e 159 {
160 // The block size must be at least sizeof(DataBlockType) bytes.
161 if (fSize < sizeof(DataBlockType)) return false;
162
163 // Now fill the fields in the header.
164 fBlock->fHeader.fType = blockTypeCode;
165 fBlock->fHeader.fRecordWidth = sizeof(DataElementType);
166 fBlock->fHeader.fNrecords = 0;
167 return true;
168 }
169
170 /**
90a74d7a 171 * Returns the common data block header.
b3eef24e 172 */
90a74d7a 173 const AliHLTMUONDataBlockHeader& CommonBlockHeader() const
b3eef24e 174 {
175 return fBlock->fHeader;
176 }
177
178 /**
90a74d7a 179 * Returns the whole data block header.
180 */
181 DataBlockType& BlockHeader()
182 {
72836b63 183 return *fBlock;
90a74d7a 184 }
185
186 const DataBlockType& BlockHeader() const
187 {
72836b63 188 return *fBlock;
90a74d7a 189 }
190
191 /**
b3eef24e 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 if ( (Nentries() + 1) * sizeof(DataElementType) > fMaxArraySize )
200 return NULL;
201 DataElementType* newentry = &fData[fBlock->fHeader.fNrecords];
202 fBlock->fHeader.fNrecords++;
203 return newentry;
204 }
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 if (n * sizeof(DataElementType) > fMaxArraySize) return false;
214 fBlock->fHeader.fNrecords = n;
72836b63 215 return true;
b3eef24e 216 }
217
218 /**
219 * Returns the total number of entries already added to the data block.
220 */
221 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 assert( i < Nentries() );
249 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 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.
b12fe461 268 * This value will only make sense if a call to InitCommonHeader() was
269 * made and it returned true.
b3eef24e 270 */
271 AliHLTUInt32_t BytesUsed() const
272 {
72836b63 273 assert( sizeof(DataElementType) == fBlock->fHeader.fRecordWidth);
b3eef24e 274 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 return fMaxArraySize / sizeof(DataElementType);
284 }
285
b12fe461 286 AliHLTUInt32_t BufferSize() { return fSize; }
287
b3eef24e 288private:
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
300typedef AliHLTMUONDataBlockWriter<
301 AliHLTMUONTriggerRecordsBlockStruct,
302 AliHLTMUONTriggerRecordStruct,
303 kTriggerRecordsDataBlock
304 > AliHLTMUONTriggerRecordsBlockWriter;
305
306typedef AliHLTMUONDataBlockWriter<
307 AliHLTMUONTrigRecsDebugBlockStruct,
308 AliHLTMUONTrigRecInfoStruct,
309 kTrigRecsDebugDataBlock
310 > AliHLTMUONTrigRecsDebugBlockWriter;
311
312typedef AliHLTMUONDataBlockWriter<
b3eef24e 313 AliHLTMUONRecHitsBlockStruct,
314 AliHLTMUONRecHitStruct,
315 kRecHitsDataBlock
316 > AliHLTMUONRecHitsBlockWriter;
317
318typedef AliHLTMUONDataBlockWriter<
319 AliHLTMUONClustersBlockStruct,
320 AliHLTMUONClusterStruct,
321 kClustersDataBlock
322 > AliHLTMUONClustersBlockWriter;
323
324typedef AliHLTMUONDataBlockWriter<
325 AliHLTMUONChannelsBlockStruct,
326 AliHLTMUONChannelStruct,
327 kChannelsDataBlock
328 > AliHLTMUONChannelsBlockWriter;
329
90a74d7a 330typedef AliHLTMUONDataBlockWriter<
331 AliHLTMUONMansoTracksBlockStruct,
332 AliHLTMUONMansoTrackStruct,
333 kMansoTracksDataBlock
334 > AliHLTMUONMansoTracksBlockWriter;
335
336typedef AliHLTMUONDataBlockWriter<
337 AliHLTMUONMansoCandidatesBlockStruct,
338 AliHLTMUONMansoCandidateStruct,
339 kMansoCandidatesDataBlock
340 > AliHLTMUONMansoCandidatesBlockWriter;
a8982f78 341
342typedef AliHLTMUONDataBlockWriter<
343 AliHLTMUONTracksBlockStruct,
344 AliHLTMUONTrackStruct,
345 kTracksDataBlock
346 > AliHLTMUONTracksBlockWriter;
90a74d7a 347
348typedef AliHLTMUONDataBlockWriter<
349 AliHLTMUONSinglesDecisionBlockStruct,
350 AliHLTMUONTrackDecisionStruct,
351 kSinglesDecisionDataBlock
352 > AliHLTMUONSinglesDecisionBlockWriter;
353
354typedef AliHLTMUONDataBlockWriter<
355 AliHLTMUONPairsDecisionBlockStruct,
b12fe461 356 AliHLTMUONPairDecisionStruct,
90a74d7a 357 kPairsDecisionDataBlock
358 > AliHLTMUONPairsDecisionBlockWriter;
359
b3eef24e 360#endif // ALIHLTMUONDATABLOCKWRITER_H