]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/AliHLTMUONDataBlockWriter.h
Adding light weight helper classes for reading and writing the internal dHLT data...
[u/mrichter/AliRoot.git] / HLT / MUON / AliHLTMUONDataBlockWriter.h
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"
36
37 /**
38  * A light weight class for writing an internal dimuon HLT data block.
39  * Suppose we are given a pointer 'buffer' to some empty memory buffer where we
40  * can store our new data block and the size of the data block is given by the
41  * variable 'size'. The data block is of type 'block_type', the data block entries
42  * are of type 'entries_type' and the data block type code is 'type_code'.
43  * The data block can be written in the following way:
44  *
45  *   void* buffer = somebuffer;
46  *   AliHLTUInt32_t size = somebuffer_size;
47  *   
48  *   // Initialise the data block writer.
49  *   AliHLTMUONDataBlockWriter<block_type, entries_type, type_code>
50  *   block(buffer, size);
51  *   
52  *   // Initialise the block header
53  *   if (not block.InitHeader())
54  *   {
55  *      // handle error and exit...
56  *   }
57  *   
58  *   // Tell the writer how many entries we are going to use.
59  *   if (not block.SetNumberOfEntries(somevalue))
60  *   {
61  *      // handle error and exit...
62  *   }
63  *
64  *   // Add all the entries to the data block.
65  *   for (AliHLTUInt32_t i = 0; i < block.Nentries(); i++)
66  *   {
67  *      entries_type& entry = block[i];
68  *      // fill the new entry...
69  *      entry.somefield = somevalue;
70  *   }
71  *
72  * The slightly slower but safer method is to do the following:
73  *
74  *   AliHLTMUONDataBlockWriter<block_type, entries_type, type_code>
75  *   block(buffer, size);
76  *   if (not block.InitHeader())
77  *   {
78  *      // handle error and exit...
79  *   }
80  *   
81  *   // For each new entry add it to the data block.
82  *   while (HaveMoreEntries())
83  *   {
84  *      entries_type* entry = block.AddEntry();
85  *      // fill the new entry...
86  *      entry->somefield = somevalue;
87  *   }
88  */
89 template <
90         class DataBlockType,
91         class DataElementType,
92         AliHLTMUONDataBlockType blockTypeCode
93 >
94 class AliHLTMUONDataBlockWriter
95 {
96 public:
97
98         /**
99          * Constructor that sets the internal pointer to the start of the buffer
100          * space to write to and the total size of the buffer in bytes.
101          * @param buffer  The pointer to the first byte of the memory buffer.
102          * @param size    The total size of the buffer in bytes.
103          */
104         AliHLTMUONDataBlockWriter(void* buffer, AliHLTUInt32_t size) :
105                 fSize(size),
106                 fMaxArraySize(size - sizeof(DataBlockType)),
107                 fBlock(reinterpret_cast<DataBlockType*>(buffer)),
108                 fData(reinterpret_cast<DataElementType*>(
109                        reinterpret_cast<DataBlockType*>(buffer) + 1
110                       ))
111         {
112                 assert( buffer != NULL );
113         }
114
115         /**
116          * Initialises the data block header by setting the type and record width
117          * fields. If the buffer size was to small to create the header then this
118          * method returns false, otherwise true on success.
119          */
120         bool InitHeader() const
121         {
122                 // The block size must be at least sizeof(DataBlockType) bytes.
123                 if (fSize < sizeof(DataBlockType)) return false;
124
125                 // Now fill the fields in the header.
126                 fBlock->fHeader.fType = blockTypeCode;
127                 fBlock->fHeader.fRecordWidth = sizeof(DataElementType);
128                 fBlock->fHeader.fNrecords = 0;
129                 return true;
130         }
131         
132         /**
133          * Returns the data block header.
134          */
135         const AliHLTMUONDataBlockHeader& BlockHeader() const
136         {
137                 return fBlock->fHeader;
138         }
139         
140         /**
141          * Returns a pointer to the next location where a data entry can be
142          * written and increments the number of entries.
143          * If the buffer is already full then NULL is returned and the number of
144          * entries is not changed.
145          */
146         DataElementType* AddEntry() const
147         {
148                 if ( (Nentries() + 1) * sizeof(DataElementType) > fMaxArraySize )
149                         return NULL;
150                 DataElementType* newentry = &fData[fBlock->fHeader.fNrecords];
151                 fBlock->fHeader.fNrecords++;
152                 return newentry;
153         }
154         
155         /**
156          * Sets the number of entries that will be filled into the buffer.
157          * If the number of entries is to many to fit into the buffer then this
158          * method returns false, otherwise true.
159          */
160         bool SetNumberOfEntries(AliHLTUInt32_t n) const
161         {
162                 if (n * sizeof(DataElementType) > fMaxArraySize) return false;
163                 fBlock->fHeader.fNrecords = n;
164         }
165
166         /**
167          * Returns the total number of entries already added to the data block.
168          */
169         AliHLTUInt32_t Nentries() const { return fBlock->fHeader.fNrecords; }
170
171         /**
172          * Returns a pointer to the i'th entry.
173          * If the index 'i' is out of bounds then NULL is returned.
174          * This is a safe access method because it does bounds checking but is
175          * a little slower than the array operators.
176          * @param i  The index number of the entry to be returned.
177          * @return  A pointer to the entry or NULL.
178          */
179         DataElementType* Entry(AliHLTUInt32_t i)
180         {
181                 return (i < Nentries()) ? &fData[i] : NULL;
182         }
183         
184         const DataElementType* Entry(AliHLTUInt32_t i) const
185         {
186                 return (i < Nentries()) ? &fData[i] : NULL;
187         }
188
189         /**
190          * Array operator for accessing the data entries directly.
191          * The index variable 'i' is not checked (except in debug compilations)
192          * so one should make sure they are within the valid range.
193          */
194         DataElementType& operator [] (AliHLTUInt32_t i)
195         {
196                 assert( i < Nentries() );
197                 return fData[i];
198         }
199         
200         const DataElementType& operator [] (AliHLTUInt32_t i) const
201         {
202                 assert( i < Nentries() );
203                 return fData[i];
204         }
205
206         /**
207          * Returns a pointer to the array of elements in the data block.
208          * Care must be taken not to read beyond the array limits given by
209          * Nentries().
210          */
211         DataElementType* GetArray() { return fData; }
212         const DataElementType* GetArray() const { return fData; }
213         
214         /**
215          * Calculates the number of bytes used for the data block in the buffer.
216          * This value will only make sense if a call to InitHeader() was made
217          * and it returned true.
218          */
219         AliHLTUInt32_t BytesUsed() const
220         {
221                 assert( Nentries() * sizeof(DataElementType)
222                         == Nentries() * fBlock->fHeader.fRecordWidth
223                 );
224                 
225                 return sizeof(DataBlockType) + Nentries() * sizeof(DataElementType);
226         }
227         
228         /**
229          * Calculates the maximum number of entries that will fit into the
230          * memory buffer.
231          */
232         AliHLTUInt32_t MaxNumberOfEntries() const
233         {
234                 return fMaxArraySize / sizeof(DataElementType);
235         }
236         
237 private:
238
239         AliHLTUInt32_t fSize;   // Size of the buffer in bytes.
240         AliHLTUInt32_t fMaxArraySize; // Maximum size of the fData array in bytes.
241         DataBlockType* fBlock; // Pointer to the start of the data block.
242         DataElementType* fData; // Pointer to the start of the data array.
243 };
244
245
246 // We now define the writer classes for the various data block types from the
247 // template class AliHLTMUONDataBlockWriter.
248
249 typedef AliHLTMUONDataBlockWriter<
250                 AliHLTMUONTriggerRecordsBlockStruct,
251                 AliHLTMUONTriggerRecordStruct,
252                 kTriggerRecordsDataBlock
253         > AliHLTMUONTriggerRecordsBlockWriter;
254
255 typedef AliHLTMUONDataBlockWriter<
256                 AliHLTMUONTrigRecsDebugBlockStruct,
257                 AliHLTMUONTrigRecInfoStruct,
258                 kTrigRecsDebugDataBlock
259         > AliHLTMUONTrigRecsDebugBlockWriter;
260
261 typedef AliHLTMUONDataBlockWriter<
262                 AliHLTMUONTriggerChannelsBlockStruct,
263                 AliHLTMUONTriggerChannelStruct,
264                 kTriggerChannelsDataBlock
265         > AliHLTMUONTriggerChannelsBlockWriter;
266
267 typedef AliHLTMUONDataBlockWriter<
268                 AliHLTMUONRecHitsBlockStruct,
269                 AliHLTMUONRecHitStruct,
270                 kRecHitsDataBlock
271         > AliHLTMUONRecHitsBlockWriter;
272
273 typedef AliHLTMUONDataBlockWriter<
274                 AliHLTMUONClustersBlockStruct,
275                 AliHLTMUONClusterStruct,
276                 kClustersDataBlock
277         > AliHLTMUONClustersBlockWriter;
278
279 typedef AliHLTMUONDataBlockWriter<
280                 AliHLTMUONChannelsBlockStruct,
281                 AliHLTMUONChannelStruct,
282                 kChannelsDataBlock
283         > AliHLTMUONChannelsBlockWriter;
284
285 #endif // ALIHLTMUONDATABLOCKWRITER_H