ROOTANA
TMidasEvent.cxx
Go to the documentation of this file.
1 //
2 // TMidasEvent.cxx.
3 //
4 // $Id$
5 //
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <time.h>
10 #include <string.h>
11 #include <assert.h>
12 
13 #include "TMidasEvent.h"
14 
16 {
17  fData = NULL;
18  fAllocatedByUs = false;
19 
20  fBanksN = 0;
21  fBankList = NULL;
22 
28 }
29 
31 {
33 
34  fData = (char*)malloc(fEventHeader.fDataSize);
35  assert(fData);
36  memcpy(fData, rhs.fData, fEventHeader.fDataSize);
37  fAllocatedByUs = true;
38 
39  fBanksN = rhs.fBanksN;
40  fBankList = strdup(rhs.fBankList);
41  assert(fBankList);
42 }
43 
45 {
46  Copy(rhs);
47 }
48 
50 {
51  Clear();
52 }
53 
55 {
56  if (&rhs != this)
57  Clear();
58 
59  this->Copy(rhs);
60  return *this;
61 }
62 
64 {
65  if (fBankList)
66  free(fBankList);
67  fBankList = NULL;
68 
69  if (fData && fAllocatedByUs)
70  free(fData);
71  fData = NULL;
72 
73  fAllocatedByUs = false;
74  fBanksN = 0;
75 
81 }
82 
83 void TMidasEvent::SetData(uint32_t size, char* data)
84 {
85  fEventHeader.fDataSize = size;
86  assert(!fAllocatedByUs);
87  assert(IsGoodSize());
88  fData = data;
89  fAllocatedByUs = false;
90  SwapBytes(false);
91 }
92 
93 uint16_t TMidasEvent::GetEventId() const
94 {
95  return fEventHeader.fEventId;
96 }
97 
99 {
100  return fEventHeader.fTriggerMask;
101 }
102 
104 {
106 }
107 
109 {
110  return fEventHeader.fTimeStamp;
111 }
112 
113 uint32_t TMidasEvent::GetDataSize() const
114 {
115  return fEventHeader.fDataSize;
116 }
117 
119 {
120  if (!fData)
121  AllocateData();
122  return fData;
123 }
124 
126 {
127  return &fEventHeader;
128 }
129 
131 {
132  return fEventHeader.fDataSize > 0 && fEventHeader.fDataSize <= 500 * 1024 * 1024;
133 }
134 
136 {
137  return (((TMidas_BANK_HEADER *)fData)->fFlags & (3<<4)) == 0x10;
138 }
139 
141 {
142  return (((TMidas_BANK_HEADER *)fData)->fFlags & (3<<4)) == 0x30;
143 }
144 
145 int TMidasEvent::LocateBank(const void *unused, const char *name, void **pdata) const
146 {
147  /// See FindBank()
148 
149  int bktype, bklen;
150 
151  int status = FindBank(name, &bklen, &bktype, pdata);
152 
153  if (!status)
154  {
155  *pdata = NULL;
156  return 0;
157  }
158 
159  return bklen;
160 }
161 
162 static const unsigned TID_SIZE[] = {0, 1, 1, 1, 2, 2, 4, 4, 4, 4, 8, 1, 0, 0, 0, 0, 0, 8, 8};
163 static const unsigned TID_MAX = (sizeof(TID_SIZE)/sizeof(TID_SIZE[0]));
164 
165 int TMidasEvent::FindBank(const char* name, int *bklen, int *bktype, void **pdata) const
166 {
167  /// Find a data bank.
168  /// \param [in] name Name of the data bank to look for.
169  /// \param [out] bklen Number of array elements in this bank.
170  /// \param [out] bktype Bank data type (MIDAS TID_xxx).
171  /// \param [out] pdata Pointer to bank data, Returns NULL if bank not found.
172  /// \returns 1 if bank found, 0 otherwise.
173  ///
174 
175  const TMidas_BANK_HEADER *pbkh = (const TMidas_BANK_HEADER*)fData;
176  TMidas_BANK *pbk;
177  //uint32_t dname;
178 
179  if (((pbkh->fFlags & (1<<5)) > 0)) {
180 #if 0
181  TMidas_BANK32 *pbk32;
182  pbk32 = (TMidas_BANK32 *) (pbkh + 1);
183  memcpy(&dname, name, 4);
184  do {
185  if (*((uint32_t *) pbk32->fName) == dname) {
186  *pdata = pbk32 + 1;
187  if (TID_SIZE[pbk32->fType & 0xFF] == 0)
188  *bklen = pbk32->fDataSize;
189  else
190  *bklen = pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
191 
192  *bktype = pbk32->fType;
193  return 1;
194  }
195  pbk32 = (TMidas_BANK32 *) ((char*) (pbk32 + 1) +
196  (((pbk32->fDataSize)+7) & ~7));
197  } while ((char*) pbk32 < (char*) pbkh + pbkh->fDataSize + sizeof(TMidas_BANK_HEADER));
198 #endif
199 
200  TMidas_BANK32a *pbk32a = NULL;
201 
202  while (1) {
203  IterateBank32a(&pbk32a, (char**)pdata);
204  //printf("looking for [%s] got [%s]\n", name, pbk32->fName);
205  if (pbk32a == NULL)
206  break;
207 
208  if (name[0]==pbk32a->fName[0] &&
209  name[1]==pbk32a->fName[1] &&
210  name[2]==pbk32a->fName[2] &&
211  name[3]==pbk32a->fName[3]) {
212 
213  if (TID_SIZE[pbk32a->fType & 0xFF] == 0)
214  *bklen = pbk32a->fDataSize;
215  else
216  *bklen = pbk32a->fDataSize / TID_SIZE[pbk32a->fType & 0xFF];
217 
218  *bktype = pbk32a->fType;
219  return 1;
220  }
221  }
222  } else if (((pbkh->fFlags & (1<<4)) > 0)) {
223 #if 0
224  TMidas_BANK32 *pbk32;
225  pbk32 = (TMidas_BANK32 *) (pbkh + 1);
226  memcpy(&dname, name, 4);
227  do {
228  if (*((uint32_t *) pbk32->fName) == dname) {
229  *pdata = pbk32 + 1;
230  if (TID_SIZE[pbk32->fType & 0xFF] == 0)
231  *bklen = pbk32->fDataSize;
232  else
233  *bklen = pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
234 
235  *bktype = pbk32->fType;
236  return 1;
237  }
238  pbk32 = (TMidas_BANK32 *) ((char*) (pbk32 + 1) +
239  (((pbk32->fDataSize)+7) & ~7));
240  } while ((char*) pbk32 < (char*) pbkh + pbkh->fDataSize + sizeof(TMidas_BANK_HEADER));
241 #endif
242 
243  TMidas_BANK32 *pbk32 = NULL;
244 
245  while (1) {
246  IterateBank32(&pbk32, (char**)pdata);
247  //printf("looking for [%s] got [%s]\n", name, pbk32->fName);
248  if (pbk32 == NULL)
249  break;
250 
251  if (name[0]==pbk32->fName[0] &&
252  name[1]==pbk32->fName[1] &&
253  name[2]==pbk32->fName[2] &&
254  name[3]==pbk32->fName[3]) {
255 
256  if (TID_SIZE[pbk32->fType & 0xFF] == 0)
257  *bklen = pbk32->fDataSize;
258  else
259  *bklen = pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
260 
261  *bktype = pbk32->fType;
262  return 1;
263  }
264  }
265  } else {
266  pbk = (TMidas_BANK *) (pbkh + 1);
267  do {
268  if (name[0]==pbk->fName[0] &&
269  name[1]==pbk->fName[1] &&
270  name[2]==pbk->fName[2] &&
271  name[3]==pbk->fName[3]) {
272  *pdata = pbk + 1;
273  if (TID_SIZE[pbk->fType & 0xFF] == 0)
274  *bklen = pbk->fDataSize;
275  else
276  *bklen = pbk->fDataSize / TID_SIZE[pbk->fType & 0xFF];
277 
278  *bktype = pbk->fType;
279  return 1;
280  }
281  pbk = (TMidas_BANK *) ((char*) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
282  } while ((char*) pbk < (char*) pbkh + pbkh->fDataSize + sizeof(TMidas_BANK_HEADER));
283  }
284  //
285  // bank not found
286  //
287  *pdata = NULL;
288  return 0;
289 }
290 
291 void TMidasEvent::Print(const char *option) const
292 {
293  /// Print data held in this class.
294  /// \param [in] option If 'a' (for "all") then the raw data will be
295  /// printed out too.
296  ///
297 
298  time_t t = (time_t)fEventHeader.fTimeStamp;
299 
300  printf("Event start:\n");
301  printf(" event id: 0x%04x\n", fEventHeader.fEventId);
302  printf(" trigger mask: 0x%04x\n", fEventHeader.fTriggerMask);
303  printf(" serial number:%8d\n", fEventHeader.fSerialNumber);
304  printf(" time stamp: %d, %s", fEventHeader.fTimeStamp, ctime(&t));
305  printf(" data size: %8d\n", fEventHeader.fDataSize);
306  if ((fEventHeader.fEventId & 0xffff) == 0x8000)
307  {
308  printf("Begin of run %d\n", fEventHeader.fSerialNumber);
309  }
310  else if ((fEventHeader.fEventId & 0xffff) == 0x8001)
311  {
312  printf("End of run %d\n", fEventHeader.fSerialNumber);
313  }
314  else if (fBanksN <= 0)
315  {
316  printf("TMidasEvent::Print: Use SetBankList() before Print() to print bank data\n");
317  }
318  else
319  {
320  printf("Banks: %s\n", fBankList);
321 
322  for (int i = 0; i < fBanksN * 4; i += 4)
323  {
324  int bankLength = 0;
325  int bankType = 0;
326  void *pdata = 0;
327  int found = FindBank(&fBankList[i], &bankLength, &bankType, &pdata);
328 
329  printf("Bank %c%c%c%c, length %6d, type %2d\n",
330  fBankList[i], fBankList[i+1], fBankList[i+2], fBankList[i+3],
331  bankLength, bankType);
332 
333  if (option[0] == 'a' && found)
334  switch (bankType)
335  {
336  case 4: // TID_WORD
337  for (int j = 0; j < bankLength; j++)
338  printf("0x%04x%c", ((uint16_t*)pdata)[j], (j%10==9)?'\n':' ');
339  printf("\n");
340  break;
341  case 6: // TID_DWORD
342  for (int j = 0; j < bankLength; j++)
343  printf("0x%08x%c", ((uint32_t*)pdata)[j], (j%10==9)?'\n':' ');
344  printf("\n");
345  break;
346  case 7: // TID_nd280 (like a DWORD?)
347  for (int j = 0; j < bankLength; j++)
348  printf("0x%08x%c", ((uint32_t*)pdata)[j], (j%10==9)?'\n':' ');
349  printf("\n");
350  break;
351  case 9: // TID_FLOAT
352  for (int j = 0; j < bankLength; j++)
353  printf("%.8g%c", ((float*)pdata)[j], (j%10==9)?'\n':' ');
354  printf("\n");
355  break;
356  case 10: // TID_DOUBLE
357  for (int j = 0; j < bankLength; j++)
358  printf("%.16g%c", ((double*)pdata)[j], (j%10==9)?'\n':' ');
359  printf("\n");
360  break;
361  default:
362  printf("TMidasEvent::Print: Do not know how to print bank of type %d\n", bankType);
363  break;
364  }
365  }
366  }
367 }
368 
370 {
371  assert(!fAllocatedByUs);
372  assert(IsGoodSize());
373  fData = (char*)malloc(fEventHeader.fDataSize);
374  assert(fData);
375  fAllocatedByUs = true;
376 }
377 
378 const char* TMidasEvent::GetBankList() const
379 {
380  return fBankList;
381 }
382 
384 {
385  if (fEventHeader.fEventId <= 0)
386  return 0;
387 
388  // Check if it is FIXED-style event ; but comment out check for now
389  if(0){
391  if(GetEventHeader()->fDataSize - (pbh->fDataSize + 8) != 0){
392  printf("Found FIXED-style event. Skipping.\n");
393  return 0;
394  }
395  }
396 
397  if (fBankList)
398  return fBanksN;
399 
400  int listSize = 0;
401 
402  fBanksN = 0;
403 
404  TMidas_BANK32a *pmbk32a = NULL;
405  TMidas_BANK32 *pmbk32 = NULL;
406  TMidas_BANK *pmbk = NULL;
407  char *pdata = NULL;
408 
409  while (1)
410  {
411  if (fBanksN*4 >= listSize)
412  {
413  listSize += 400;
414  fBankList = (char*)realloc(fBankList, listSize);
415  }
416 
417  if (IsBank32a())
418  {
419  IterateBank32a(&pmbk32a, &pdata);
420  if (pmbk32a == NULL)
421  break;
422  memcpy(fBankList+fBanksN*4, pmbk32a->fName, 4);
423  fBanksN++;
424  }
425  else if (IsBank32())
426  {
427  IterateBank32(&pmbk32, &pdata);
428  if (pmbk32 == NULL)
429  break;
430  memcpy(fBankList+fBanksN*4, pmbk32->fName, 4);
431  fBanksN++;
432  }
433  else
434  {
435  IterateBank(&pmbk, &pdata);
436  if (pmbk == NULL)
437  break;
438  memcpy(fBankList+fBanksN*4, pmbk->fName, 4);
439  fBanksN++;
440  }
441  }
442 
443  fBankList[fBanksN*4] = 0;
444 
445  return fBanksN;
446 }
447 
448 int TMidasEvent::IterateBank(TMidas_BANK **pbk, char **pdata) const
449 {
450  /// Iterates through banks inside an event. The function can be used
451  /// to enumerate all banks of an event.
452  /// \param [in] pbk Pointer to the bank header, must be NULL for the
453  /// first call to this function. Returns NULL if no more banks
454  /// \param [in] pdata Pointer to data area of bank. Returns NULL if no more banks
455  /// \returns Size of bank in bytes or 0 if no more banks.
456  ///
457  const TMidas_BANK_HEADER* event = (const TMidas_BANK_HEADER*)fData;
458 
459  if (*pbk == NULL)
460  *pbk = (TMidas_BANK *) (event + 1);
461  else
462  *pbk = (TMidas_BANK *) ((char*) (*pbk + 1) + ((((*pbk)->fDataSize)+7) & ~7));
463 
464  *pdata = (char*)((*pbk) + 1);
465 
466  if ((char*) *pbk >= (char*) event + event->fDataSize + sizeof(TMidas_BANK_HEADER))
467  {
468  *pbk = NULL;
469  *pdata = NULL;
470  return 0;
471  }
472 
473  return (*pbk)->fDataSize;
474 }
475 
476 int TMidasEvent::IterateBank32(TMidas_BANK32 **pbk, char **pdata) const
477 {
478  /// See IterateBank()
479 
480  const TMidas_BANK_HEADER* event = (const TMidas_BANK_HEADER*)fData;
481  if (*pbk == NULL)
482  *pbk = (TMidas_BANK32 *) (event + 1);
483  else {
484  uint32_t length = (*pbk)->fDataSize;
485  uint32_t length_adjusted = (length+7) & ~7;
486  //printf("length %6d 0x%08x, 0x%08x\n", length, length, length_adjusted);
487  *pbk = (TMidas_BANK32 *) ((char*) (*pbk + 1) + length_adjusted);
488  }
489 
490  TMidas_BANK32 *bk4 = (TMidas_BANK32*)(((char*) *pbk) + 4);
491 
492  //printf("iterate bank32: pbk 0x%p, align %d, type %d %d, name [%s], next [%s], TID_MAX %d\n", *pbk, (int)( ((uint64_t)(*pbk))&7), (*pbk)->fType, bk4->fType, (*pbk)->fName, bk4->fName, TID_MAX);
493 
494  if ((*pbk)->fType > TID_MAX) // bad - unknown bank type - it's invalid MIDAS file?
495  {
496  if (bk4->fType <= TID_MAX) // okey, this is a malformed T2K/ND280 data file
497  {
498  *pbk = bk4;
499 
500  //printf("iterate bank32: pbk 0x%p, align %d, type %d, name [%s]\n", *pbk, (int)(((uint64_t)(*pbk))&7), (*pbk)->fType, (*pbk)->fName);
501  }
502  else
503  {
504  // truncate invalid data
505  *pbk = NULL;
506  *pdata = NULL;
507  return 0;
508  }
509  }
510 
511  *pdata = (char*)((*pbk) + 1);
512 
513  if ((char*) *pbk >= (char*)event + event->fDataSize + sizeof(TMidas_BANK_HEADER))
514  {
515  *pbk = NULL;
516  *pdata = NULL;
517  return 0;
518  }
519 
520  return (*pbk)->fDataSize;
521 }
522 
523 int TMidasEvent::IterateBank32a(TMidas_BANK32a **pbk, char **pdata) const
524 {
525  /// See IterateBank()
526 
527  const TMidas_BANK_HEADER* event = (const TMidas_BANK_HEADER*)fData;
528  if (*pbk == NULL)
529  *pbk = (TMidas_BANK32a *) (event + 1);
530  else {
531  uint32_t length = (*pbk)->fDataSize;
532  uint32_t length_adjusted = (length+7) & ~7;
533  //printf("length %6d 0x%08x, 0x%08x\n", length, length, length_adjusted);
534  *pbk = (TMidas_BANK32a *) ((char*) (*pbk + 1) + length_adjusted);
535  }
536 
537  TMidas_BANK32a *bk4 = (TMidas_BANK32a*)(((char*) *pbk) + 4);
538 
539  //printf("iterate bank32: pbk 0x%p, align %d, type %d %d, name [%s], next [%s], TID_MAX %d\n", *pbk, (int)( ((uint64_t)(*pbk))&7), (*pbk)->fType, bk4->fType, (*pbk)->fName, bk4->fName, TID_MAX);
540 
541  if ((*pbk)->fType > TID_MAX) // bad - unknown bank type - it's invalid MIDAS file?
542  {
543  if (bk4->fType <= TID_MAX) // okey, this is a malformed T2K/ND280 data file
544  {
545  *pbk = bk4;
546 
547  //printf("iterate bank32: pbk 0x%p, align %d, type %d, name [%s]\n", *pbk, (int)(((uint64_t)(*pbk))&7), (*pbk)->fType, (*pbk)->fName);
548  }
549  else
550  {
551  // truncate invalid data
552  *pbk = NULL;
553  *pdata = NULL;
554  return 0;
555  }
556  }
557 
558  *pdata = (char*)((*pbk) + 1);
559 
560  if ((char*) *pbk >= (char*)event + event->fDataSize + sizeof(TMidas_BANK_HEADER))
561  {
562  *pbk = NULL;
563  *pdata = NULL;
564  return 0;
565  }
566 
567  return (*pbk)->fDataSize;
568 }
569 
570 typedef uint8_t BYTE;
571 
572 /// Byte swapping routine.
573 ///
574 #define QWORD_SWAP(x) { BYTE _tmp; \
575 _tmp= *((BYTE *)(x)); \
576 *((BYTE *)(x)) = *(((BYTE *)(x))+7); \
577 *(((BYTE *)(x))+7) = _tmp; \
578 _tmp= *(((BYTE *)(x))+1); \
579 *(((BYTE *)(x))+1) = *(((BYTE *)(x))+6); \
580 *(((BYTE *)(x))+6) = _tmp; \
581 _tmp= *(((BYTE *)(x))+2); \
582 *(((BYTE *)(x))+2) = *(((BYTE *)(x))+5); \
583 *(((BYTE *)(x))+5) = _tmp; \
584 _tmp= *(((BYTE *)(x))+3); \
585 *(((BYTE *)(x))+3) = *(((BYTE *)(x))+4); \
586 *(((BYTE *)(x))+4) = _tmp; }
587 
588 /// Byte swapping routine.
589 ///
590 #define DWORD_SWAP(x) { BYTE _tmp; \
591 _tmp= *((BYTE *)(x)); \
592 *((BYTE *)(x)) = *(((BYTE *)(x))+3); \
593 *(((BYTE *)(x))+3) = _tmp; \
594 _tmp= *(((BYTE *)(x))+1); \
595 *(((BYTE *)(x))+1) = *(((BYTE *)(x))+2); \
596 *(((BYTE *)(x))+2) = _tmp; }
597 
598 /// Byte swapping routine.
599 ///
600 #define WORD_SWAP(x) { BYTE _tmp; \
601 _tmp= *((BYTE *)(x)); \
602 *((BYTE *)(x)) = *(((BYTE *)(x))+1); \
603 *(((BYTE *)(x))+1) = _tmp; }
604 
606 {
612 }
613 
614 int TMidasEvent::SwapBytes(bool force)
615 {
616  TMidas_BANK_HEADER *pbh;
617  TMidas_BANK *pbk;
618  TMidas_BANK32 *pbk32;
619  void *pdata;
620  uint16_t type;
621 
622  pbh = (TMidas_BANK_HEADER *) fData;
623 
624  uint32_t dssw = pbh->fDataSize;
625 
626  DWORD_SWAP(&dssw);
627 
628  //printf("SwapBytes %d, flags 0x%x 0x%x\n", force, pbh->fFlags, pbh->fDataSize);
629  //printf("evh.datasize: 0x%08x, SwapBytes: %d, pbh.flags: 0x%08x, pbh.datasize: 0x%08x swapped 0x%08x\n", fEventHeader.fDataSize, force, pbh->fFlags, pbh->fDataSize, dssw);
630 
631  //
632  // only swap if flags in high 16-bit
633  //
634  if (pbh->fFlags < 0x10000 && ! force)
635  return 0;
636 
637  if (pbh->fDataSize == 0x6d783f3c) // string "<xml..." in wrong-endian format
638  return 1;
639 
640  if (pbh->fDataSize == 0x3c3f786d) // string "<xml..."
641  return 1;
642 
643  if (dssw > fEventHeader.fDataSize + 100) // swapped data size looks wrong. do not swap.
644  return 1;
645 
646  //
647  // swap bank header
648  //
649  DWORD_SWAP(&pbh->fDataSize);
650  DWORD_SWAP(&pbh->fFlags);
651  //
652  // check for 32-bit banks
653  //
654  bool b32 = IsBank32();
655  bool b32a = IsBank32a();
656 
657  if (b32a) {
658  fprintf(stderr, "TMidasEvent::SwapBytes() cannot swap bk_init32a data, sorry. bye!\n");
659  abort();
660  }
661 
662  pbk = (TMidas_BANK *) (pbh + 1);
663  pbk32 = (TMidas_BANK32 *) pbk;
664  //
665  // scan event
666  //
667  while ((char*) pbk < (char*) pbh + pbh->fDataSize + sizeof(TMidas_BANK_HEADER)) {
668  //
669  // swap bank header
670  //
671  if (b32) {
672  DWORD_SWAP(&pbk32->fType);
673  DWORD_SWAP(&pbk32->fDataSize);
674  pdata = pbk32 + 1;
675  type = (uint16_t) pbk32->fType;
676  } else {
677  WORD_SWAP(&pbk->fType);
678  WORD_SWAP(&pbk->fDataSize);
679  pdata = pbk + 1;
680  type = pbk->fType;
681  }
682  //
683  // pbk points to next bank
684  //
685  if (b32) {
686  assert(pbk32->fDataSize < fEventHeader.fDataSize + 100);
687  pbk32 = (TMidas_BANK32 *) ((char*) (pbk32 + 1) +
688  (((pbk32->fDataSize)+7) & ~7));
689  pbk = (TMidas_BANK *) pbk32;
690  } else {
691  assert(pbk->fDataSize < fEventHeader.fDataSize + 100);
692  pbk = (TMidas_BANK *) ((char*) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
693  pbk32 = (TMidas_BANK32 *) pbk;
694  }
695 
696  switch (type) {
697  case 4:
698  case 5:
699  while (pdata < pbk) {
700  WORD_SWAP(pdata);
701  pdata = ((char*)pdata) + 2;
702  }
703  break;
704  case 6:
705  case 7:
706  case 8:
707  case 9:
708  while (pdata < pbk) {
709  DWORD_SWAP(pdata);
710  pdata = ((char*)pdata) + 4;
711  }
712  break;
713  case 10: // TID_DOUBLE
714  while (pdata < pbk) {
715  QWORD_SWAP(pdata);
716  pdata = ((char*)pdata) + 8;
717  }
718  break;
719  case 17: // TID_INT64
720  case 18: // TID_UINT64
721  while (pdata < pbk) {
722  QWORD_SWAP(pdata);
723  pdata = ((char*)pdata) + 8;
724  }
725  break;
726  }
727  }
728  return 1;
729 }
730 
731 #include "midasio.h"
732 
733 // read and write functions
735 {
736  static uint32_t endian = 0x12345678;
737  static bool once = true;
738  static bool gDoByteSwap = false;
739  if (once) {
740  once = false;
741  gDoByteSwap = *(char*)(&endian) != 0x78;
742  }
743 
744  event->Clear();
745 
746  int rd = reader->Read((char*)event->GetEventHeader(), sizeof(TMidas_EVENT_HEADER));
747 
748  if (rd == 0)
749  {
750  return false;
751  }
752  else if (rd != sizeof(TMidas_EVENT_HEADER))
753  {
754  return false;
755  }
756 
757  if (gDoByteSwap)
758  event->SwapBytesEventHeader();
759 
760  if (!event->IsGoodSize())
761  {
762  return false;
763  }
764 
765  rd = reader->Read((char*)event->GetData(), event->GetDataSize());
766 
767  if (rd != (int)event->GetDataSize())
768  {
769  return false;
770  }
771 
772  event->SwapBytes(false);
773 
774  return true;
775 }
776 
778 {
779  int wr = writer->Write((char*)event->GetEventHeader(), sizeof(TMidas_EVENT_HEADER));
780 
781  if (wr != sizeof(TMidas_EVENT_HEADER)) {
782  printf("TMidasFile: error on write event header, return %d, size requested %d\n", wr, (int)sizeof(TMidas_EVENT_HEADER));
783  return false;
784  }
785 
786  wr = writer->Write((char*)event->GetData(), event->GetDataSize());
787 
788  if (wr != (int)event->GetDataSize()) {
789  printf("TMidasFile: error on write event header, return %d, size requested %d\n", wr, (int)event->GetDataSize());
790  return false;
791  }
792 
793  return true;
794 }
795 
796 // end
bool TMWriteEvent(TMWriterInterface *writer, TMidasEvent *event)
#define WORD_SWAP(x)
static const unsigned TID_MAX
#define QWORD_SWAP(x)
static const unsigned TID_SIZE[]
uint8_t BYTE
bool TMReadEvent(TMReaderInterface *reader, TMidasEvent *event)
#define DWORD_SWAP(x)
virtual int Read(void *buf, int count)=0
virtual int Write(const void *buf, int count)=0
MIDAS event.
Definition: TMidasEvent.h:22
int FindBank(const char *bankName, int *bankLength, int *bankType, void **bankPtr) const
int SwapBytes(bool)
convert event data between little-endian (Linux-x86) and big endian (MacOS-PPC)
bool IsBank32() const
returns "true" if event uses bk_init32() banks
int IterateBank32(TMidas_BANK32 **, char **pdata) const
iterate through 32-bit data banks
TMidas_EVENT_HEADER * GetEventHeader()
return pointer to the event header
void Clear()
clear event for reuse
Definition: TMidasEvent.cxx:63
uint32_t GetDataSize() const
return the event size
int fBanksN
number of banks in this event
Definition: TMidasEvent.h:73
int SetBankList()
create the list of data banks, return number of banks
int IterateBank32a(TMidas_BANK32a **, char **pdata) const
iterate through 32-bit data banks
void AllocateData()
allocate data buffer using the existing event header
const char * GetBankList() const
return a list of data banks
int IterateBank(TMidas_BANK **, char **pdata) const
iterate through 16-bit data banks
uint16_t GetEventId() const
return the event id
Definition: TMidasEvent.cxx:93
int LocateBank(const void *unused, const char *bankName, void **bankPtr) const
bool IsBank32a() const
returns "true" if event uses bk_init32a() banks
uint32_t GetTimeStamp() const
return the time stamp (unix time in seconds)
TMidasEvent()
default constructor
Definition: TMidasEvent.cxx:15
TMidasEvent & operator=(const TMidasEvent &)
assignement operator
Definition: TMidasEvent.cxx:54
void SetData(uint32_t dataSize, char *dataBuffer)
set an externally allocated data buffer
Definition: TMidasEvent.cxx:83
bool fAllocatedByUs
"true" if we own the data buffer
Definition: TMidasEvent.h:75
char * fData
event data buffer
Definition: TMidasEvent.h:72
void Print(const char *option="") const
show all event information
~TMidasEvent()
destructor
Definition: TMidasEvent.cxx:49
uint32_t GetSerialNumber() const
return the serial number
uint16_t GetTriggerMask() const
return the triger mask
Definition: TMidasEvent.cxx:98
TMidas_EVENT_HEADER fEventHeader
event header
Definition: TMidasEvent.h:71
bool IsGoodSize() const
validate the event length
void Copy(const TMidasEvent &)
copy helper
Definition: TMidasEvent.cxx:30
char * GetData()
return pointer to the data buffer
char * fBankList
list of bank names in this event
Definition: TMidasEvent.h:74
void SwapBytesEventHeader()
convert event header between little-endian (Linux-x86) and big endian (MacOS-PPC)
32-bit data bank
Definition: TMidasStructs.h:41
char fName[4]
bank name
Definition: TMidasStructs.h:42
uint32_t fType
type of data (see midas.h TID_xxx)
Definition: TMidasStructs.h:43
uint32_t fDataSize
Definition: TMidasStructs.h:44
uint32_t fDataSize
Definition: TMidasStructs.h:50
uint32_t fType
type of data (see midas.h TID_xxx)
Definition: TMidasStructs.h:49
char fName[4]
bank name
Definition: TMidasStructs.h:48
Bank header.
Definition: TMidasStructs.h:26
16-bit data bank
Definition: TMidasStructs.h:33
char fName[4]
bank name
Definition: TMidasStructs.h:34
uint16_t fType
type of data (see midas.h TID_xxx)
Definition: TMidasStructs.h:35
uint16_t fDataSize
Definition: TMidasStructs.h:36
Event header.
Definition: TMidasStructs.h:16
uint32_t fDataSize
event size in bytes
Definition: TMidasStructs.h:21
uint16_t fTriggerMask
event trigger mask
Definition: TMidasStructs.h:18
uint16_t fEventId
event id
Definition: TMidasStructs.h:17
uint32_t fSerialNumber
event serial number
Definition: TMidasStructs.h:19
uint32_t fTimeStamp
event timestamp in seconds
Definition: TMidasStructs.h:20