]>
Commit | Line | Data |
---|---|---|
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 | fSize(size), | |
117 | fMaxArraySize(size > sizeof(DataBlockType) ? size - sizeof(DataBlockType) : 0), | |
118 | fBlock(reinterpret_cast<DataBlockType*>(buffer)), | |
119 | fData(reinterpret_cast<DataElementType*>( | |
120 | reinterpret_cast<DataBlockType*>(buffer) + 1 | |
121 | )) | |
122 | { | |
123 | assert( buffer != NULL ); | |
124 | } | |
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 | 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 | /** | |
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 | 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 | 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; | |
215 | return true; | |
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. | |
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 | assert( sizeof(DataElementType) == fBlock->fHeader.fRecordWidth); | |
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 | ||
286 | 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 |