]>
Commit | Line | Data |
---|---|---|
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 | ||
18 | /* $Id$ */ | |
19 | ||
20 | /** | |
21 | * @file AliHLTMUONDataBlockWriter.h | |
22 | * @author Artur Szostak <artursz@iafrica.com> | |
23 | * @date | |
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 "AliHLTMUONTriggerChannelsBlockStruct.h" | |
33 | #include "AliHLTMUONRecHitsBlockStruct.h" | |
34 | #include "AliHLTMUONClustersBlockStruct.h" | |
35 | #include "AliHLTMUONChannelsBlockStruct.h" | |
90a74d7a | 36 | #include "AliHLTMUONMansoTracksBlockStruct.h" |
37 | #include "AliHLTMUONMansoCandidatesBlockStruct.h" | |
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: | |
48 | * | |
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 | * } | |
75 | * | |
76 | * The slightly slower but safer method is to do the following: | |
77 | * | |
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 | * } | |
96 | */ | |
97 | template < | |
98 | class DataBlockType, | |
99 | class DataElementType, | |
100 | AliHLTMUONDataBlockType blockTypeCode | |
101 | > | |
102 | class AliHLTMUONDataBlockWriter | |
103 | { | |
104 | public: | |
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 | ||
90a74d7a | 177 | /** |
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 | ||
b3eef24e | 190 | /** |
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 | 287 | private: |
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 | ||
299 | typedef AliHLTMUONDataBlockWriter< | |
300 | AliHLTMUONTriggerRecordsBlockStruct, | |
301 | AliHLTMUONTriggerRecordStruct, | |
302 | kTriggerRecordsDataBlock | |
303 | > AliHLTMUONTriggerRecordsBlockWriter; | |
304 | ||
305 | typedef AliHLTMUONDataBlockWriter< | |
306 | AliHLTMUONTrigRecsDebugBlockStruct, | |
307 | AliHLTMUONTrigRecInfoStruct, | |
308 | kTrigRecsDebugDataBlock | |
309 | > AliHLTMUONTrigRecsDebugBlockWriter; | |
310 | ||
311 | typedef AliHLTMUONDataBlockWriter< | |
312 | AliHLTMUONTriggerChannelsBlockStruct, | |
313 | AliHLTMUONTriggerChannelStruct, | |
314 | kTriggerChannelsDataBlock | |
315 | > AliHLTMUONTriggerChannelsBlockWriter; | |
316 | ||
317 | typedef AliHLTMUONDataBlockWriter< | |
318 | AliHLTMUONRecHitsBlockStruct, | |
319 | AliHLTMUONRecHitStruct, | |
320 | kRecHitsDataBlock | |
321 | > AliHLTMUONRecHitsBlockWriter; | |
322 | ||
323 | typedef AliHLTMUONDataBlockWriter< | |
324 | AliHLTMUONClustersBlockStruct, | |
325 | AliHLTMUONClusterStruct, | |
326 | kClustersDataBlock | |
327 | > AliHLTMUONClustersBlockWriter; | |
328 | ||
329 | typedef AliHLTMUONDataBlockWriter< | |
330 | AliHLTMUONChannelsBlockStruct, | |
331 | AliHLTMUONChannelStruct, | |
332 | kChannelsDataBlock | |
333 | > AliHLTMUONChannelsBlockWriter; | |
334 | ||
90a74d7a | 335 | typedef AliHLTMUONDataBlockWriter< |
336 | AliHLTMUONMansoTracksBlockStruct, | |
337 | AliHLTMUONMansoTrackStruct, | |
338 | kMansoTracksDataBlock | |
339 | > AliHLTMUONMansoTracksBlockWriter; | |
340 | ||
341 | typedef AliHLTMUONDataBlockWriter< | |
342 | AliHLTMUONMansoCandidatesBlockStruct, | |
343 | AliHLTMUONMansoCandidateStruct, | |
344 | kMansoCandidatesDataBlock | |
345 | > AliHLTMUONMansoCandidatesBlockWriter; | |
346 | ||
347 | typedef AliHLTMUONDataBlockWriter< | |
348 | AliHLTMUONSinglesDecisionBlockStruct, | |
349 | AliHLTMUONTrackDecisionStruct, | |
350 | kSinglesDecisionDataBlock | |
351 | > AliHLTMUONSinglesDecisionBlockWriter; | |
352 | ||
353 | typedef AliHLTMUONDataBlockWriter< | |
354 | AliHLTMUONPairsDecisionBlockStruct, | |
b12fe461 | 355 | AliHLTMUONPairDecisionStruct, |
90a74d7a | 356 | kPairsDecisionDataBlock |
357 | > AliHLTMUONPairsDecisionBlockWriter; | |
358 | ||
b3eef24e | 359 | #endif // ALIHLTMUONDATABLOCKWRITER_H |