Fix for 64-bit platforms
[u/mrichter/AliRoot.git] / RAW / AliRawEventHeaderBase.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 // Author: Cvetan Cheshkov  10/10/2005
19
20 //////////////////////////////////////////////////////////////////////////
21 //                                                                      //
22 // AliRawEventHeaderBase                                                //
23 // This a new versioning scheme for raw data root-ification and reading //
24 // For details look at offline weekly meeting 20/10/2005                //
25 //                                                                      //
26 //////////////////////////////////////////////////////////////////////////
27
28 #include <unistd.h>
29
30 #include <Bytes.h>
31 #include <TClass.h>
32 #include <TDataMember.h>
33 #include <TList.h>
34 #include <TMethodCall.h>
35
36 #include "AliLog.h"
37 #include "AliRawEventHeaderBase.h"
38
39
40 ClassImp(AliRawEventHeaderBase)
41
42 //______________________________________________________________________________
43 AliRawEventHeaderBase::AliRawEventHeaderBase():
44 fSize(0),
45 fMagic(0),
46 fHeadSize(0),
47 fVersion(0),
48 fExtendedDataSize(0),
49 fExtendedData(NULL),
50 fIsSwapped(kFALSE)
51 {
52   // Default constructor
53 }
54
55 //______________________________________________________________________________
56 void *AliRawEventHeaderBase::HeaderBegin()
57 {
58   // Returns the pointer to the first data member
59   // beyond the base class data members
60
61   TList *datalist = IsA()->GetListOfDataMembers();
62   TIter next(datalist);                           
63   TDataMember *member = (TDataMember *)next();
64
65   if(!strcmp(member->GetTypeName(),"TClass"))
66     member = (TDataMember *)next();
67
68   return (void *)((char *)this+member->GetOffset());
69 }
70
71 //______________________________________________________________________________
72 Int_t AliRawEventHeaderBase::HeaderSize() const
73 {
74   // Returns the size of the data members list
75   // beyond the base class data members
76
77   Int_t size = 0;
78
79   TList *datalist = IsA()->GetListOfDataMembers();
80   TIter next(datalist);                           
81   TDataMember *member;
82   while ((member=(TDataMember *)next()) != 0x0) {
83     if (!strcmp(member->GetTypeName(),"TClass")) continue;
84     UInt_t unitsize = member->GetUnitSize();
85     UInt_t ndim = member->GetArrayDim();
86     if (ndim == 0)
87       size += unitsize;
88     else
89       for(UInt_t i=0;i<ndim;i++) size += member->GetMaxIndex(i)*unitsize;
90   }
91
92   return size;
93 }
94
95 //______________________________________________________________________________
96 void AliRawEventHeaderBase::Swap()
97 {
98    // Swap base header data.
99    // Update the fIsSwapped flag which
100    // is then use to copy in an appropriate way
101    // the rest of the header data from the raw data stream
102
103    if (IsSwapped()) {
104       fIsSwapped    = kTRUE;
105       fSize         = net2host(fSize);
106       fMagic        = net2host(fMagic);
107       fHeadSize     = net2host(fHeadSize);
108       fVersion      = net2host(fVersion);
109    }
110 }
111
112 //______________________________________________________________________________
113 const char *AliRawEventHeaderBase::GetTypeName()
114 {
115    // Get event type as a string.
116    // Will fail in case data header
117    // does not contain eventType field
118    Int_t eventType = Get("Type");
119
120    switch (eventType) {
121       case kStartOfRun:
122          return "START_OF_RUN";
123          break;
124       case kEndOfRun:
125          return "END_OF_RUN";
126          break;
127       case kStartOfRunFiles:
128          return "START_OF_RUN_FILES";
129          break;
130       case kEndOfRunFiles:
131          return "END_OF_RUN_FILES";
132          break;
133       case kStartOfBurst:
134          return "START_OF_BURST";
135          break;
136       case kEndOfBurst:
137          return "END_OF_BURST";
138          break;
139       case kPhysicsEvent:
140          return "PHYSICS_EVENT";
141          break;
142       case kCalibrationEvent:
143          return "CALIBRATION_EVENT";
144          break;
145       case kFormatError:
146          return "EVENT_FORMAT_ERROR";
147          break;
148       case kStartOfData:
149          return "START_OF_DATA";
150          break;
151       case kEndOfData:
152          return "END_OF_DATA";
153          break;
154       case kSystemSoftwareTriggerEvent:
155          return "SYSTEM_SOFTWARE_TRIGGER_EVENT";
156          break;
157       case kDetectorSoftwareTriggerEvent:
158          return "DETECTOR_SOFTWARE_TRIGGER_EVENT";
159          break;
160       default:
161          return "UNKNOWN EVENT TYPE NUMBER";
162          break;
163    }
164 }
165
166 //______________________________________________________________________________
167 AliRawEventHeaderBase* AliRawEventHeaderBase::Create(char*& data)
168 {
169   // Static method to create AliRawEventHeaderVX object
170   // The actual header class version is taken from the
171   // raw data
172
173   // First create AlirawEVentHeaderBase class object
174   AliRawEventHeaderBase header;
175
176   // Copy the first common part of the raw data header
177   memcpy(header.HeaderBaseBegin(), data, header.HeaderBaseSize());
178  
179     // Swap header data if needed
180   if (header.IsSwapped())
181     header.Swap();
182
183   // Is header valid...
184   if (!header.IsValid()) {
185     AliFatalClass("Invalid header format!");
186     // try recovery... how?
187     return 0x0;
188   }
189
190   if (header.GetEventSize() < (UInt_t)header.HeaderBaseSize()) {
191     AliFatalClass("Invalid header base size!");
192     // try recovery... how?
193     return 0x0;
194   }
195
196   // Now check the DATE version and create the corresponding header
197   // class object
198   UInt_t version = header.GetVersion();
199   UInt_t majorversion = (version>>16)&0x0000ffff;
200   UInt_t minorversion = version&0x0000ffff;
201   TString classname;
202   classname.Form("AliRawEventHeaderV%d_%d",majorversion,minorversion);
203     
204   TClass *tcl = TClass::GetClass(classname.Data());
205   if (!tcl) {
206     AliFatalClass(Form("Unknown header version (%s)!",classname.Data()));
207     return 0x0;
208   }
209
210   //  header.Dump(); tcl->Dump();
211
212   AliRawEventHeaderBase *hdr = (AliRawEventHeaderBase *)tcl->New();
213   if (!hdr) {
214     AliFatalClass(Form("Can not create object of class %s",classname.Data()));
215     return 0x0;
216   }
217
218   // Copy the base header data members and initialize other data members
219   memcpy(hdr->HeaderBaseBegin(),header.HeaderBaseBegin(), header.HeaderBaseSize());
220   memset(hdr->HeaderBegin(),0, hdr->HeaderSize());
221   hdr->fIsSwapped = header.fIsSwapped;
222
223   // Consistency check
224   if (hdr->GetEventSize() < ((UInt_t)hdr->HeaderBaseSize() + (UInt_t)hdr->HeaderSize())) {
225     AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
226                        hdr->GetEventSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
227     // try recovery... how?
228     return 0x0;
229   }
230
231   // Check for the presence of header extension and its size
232   Int_t extsize = (Int_t)hdr->GetHeadSize() - (hdr->HeaderBaseSize() + hdr->HeaderSize());
233   if (extsize < 0) {
234     AliFatalClass(Form("Invalid header size (%d < %d +%d)!",
235                        hdr->GetHeadSize(),hdr->HeaderBaseSize(),hdr->HeaderSize()));
236     // try recovery... how?
237     return 0x0;
238   }
239   else {
240     if (extsize > 0) {
241       hdr->SetExtendedDataSize(extsize);
242       char *extdata = new char[extsize];
243       memset(extdata,0,extsize);
244       hdr->SetExtendedData(extdata);
245     }
246   }
247
248   return hdr;
249 }
250
251 //______________________________________________________________________________
252 Int_t AliRawEventHeaderBase::ReadHeader(char*& data)
253 {
254   // Read header info from DATE data stream.
255   // Returns bytes read
256
257   Long_t start = (Long_t)data;
258   // Swap header data if needed
259   if (DataIsSwapped()) {
260     swab(data,HeaderBaseBegin(), HeaderBaseSize());
261     data += HeaderBaseSize();
262     swab(data, HeaderBegin(), HeaderSize());
263     data += HeaderSize();
264     if(GetExtendedDataSize()>0) {
265       swab(data, GetExtendedData(), GetExtendedDataSize());
266       data += GetExtendedDataSize();
267     }
268   }
269   else {
270     memcpy(HeaderBaseBegin(), data, HeaderBaseSize());
271     data += HeaderBaseSize();
272     memcpy(HeaderBegin(), data, HeaderSize());
273     data += HeaderSize();
274     if(GetExtendedDataSize()>0) {
275       memcpy(GetExtendedData(), data, GetExtendedDataSize());
276       data += GetExtendedDataSize();
277     }
278   }
279
280   return (Int_t)((Long_t)data - start);
281 }
282
283 //______________________________________________________________________________
284 UInt_t AliRawEventHeaderBase::Get(const char *datamember) const
285 {
286   // The method to get a data member from the header object
287   // Except for the data members of the base class, all the
288   // other header data should be retrieved ONLY by this method
289   // The name of the data member should be supplied without "f"
290   // in front
291
292   char buf[256] = "f";
293   strcat(buf,datamember);
294
295   TDataMember *member = IsA()->GetDataMember(buf);
296   if (!member) {
297     AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
298     return 0;
299   }
300
301   if (member->GetArrayDim() != 0) {
302     AliFatal(Form("Member %s is an array! Use the GetP() method!",buf));
303     return 0;
304   }
305
306   if (strcmp(member->GetTypeName(),"UInt_t") != 0) {
307     AliFatal(Form("Member %s is not of type UInt_t!",buf));
308     return 0;
309   }
310
311   const void *pointer = (char *)this+member->GetOffset();
312
313   return *((UInt_t *)pointer);
314 }
315
316 //______________________________________________________________________________
317 const UInt_t* AliRawEventHeaderBase::GetP(const char *datamember) const
318 {
319   // The method to get a data member from the header object
320   // Except for the data members of the base class, all the
321   // other header data should be retrieved ONLY by this method
322   // The name of the data member should be supplied without "f"
323   // in front
324
325   char buf[256] = "f";
326   strcat(buf,datamember);
327
328   TDataMember *member = IsA()->GetDataMember(buf);
329   if (!member) {
330     AliFatal(Form("No data member %s is found! Check the raw data version!",buf));
331     return 0;
332   }
333
334   //  if (member->GetArrayDim() == 0) {
335   //    AliFatal(Form("Member %s is not an array! Use the Get() method!",buf));
336   //    return 0;
337   //  }
338
339   if (strcmp(member->GetTypeName(),"UInt_t") != 0) {
340     AliFatal(Form("Member %s is not of type UInt_t*!",buf));
341     return 0;
342   }
343
344   const void *pointer = (char *)this+member->GetOffset();
345
346   return (const UInt_t*)pointer;
347 }