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