00001
00009 #include <iostream>
00010 #include <iomanip>
00011
00012 #include "TMidasEvent.h"
00013
00014 using std::cout;
00015 using std::cerr;
00016 using std::endl;
00017 using std::hex;
00018 using std::dec;
00019 using std::setw;
00020 using std::setfill;
00021 using std::showbase;
00022 using std::bad_alloc;
00023 using std::ios_base;
00024
00025 TMidasEvent::TMidasEvent()
00026 : fBankListMax(64), fStringBankListMax(fBankListMax * 4),
00027 fData(0), fAllocated(false)
00028 {
00031 fEventHeader.fEventId = 0;
00032 fEventHeader.fTriggerMask = 0;
00033 fEventHeader.fSerialNumber = 0;
00034 fEventHeader.fTimeStamp = 0;
00035 fEventHeader.fDataSize = 0;
00036 }
00037
00038 TMidasEvent::TMidasEvent(const TMidasEvent &rhs)
00039 : fBankListMax(64), fStringBankListMax(fBankListMax * 4)
00040 {
00045 fData = rhs.fData;
00046 fEventHeader.fEventId = rhs.fEventHeader.fEventId;
00047 fEventHeader.fTriggerMask = rhs.fEventHeader.fTriggerMask;
00048 fEventHeader.fSerialNumber = rhs.fEventHeader.fSerialNumber;
00049 fEventHeader.fTimeStamp = rhs.fEventHeader.fTimeStamp;
00050 fEventHeader.fDataSize = rhs.fEventHeader.fDataSize;
00051 if (fData)
00052 try {
00053 fData = new Char_t[4096 * (1 + fEventHeader.fDataSize / 4096)];
00054 strcpy(fData, rhs.fData);
00055 fAllocated = true;
00056 } catch(bad_alloc) {
00057 cerr << "operator=: ERROR - unable to copy data" << endl;
00058 fData = 0;
00059 }
00060 }
00061
00062 TMidasEvent::~TMidasEvent()
00063 {
00066 Clear();
00067 }
00068
00069 TMidasEvent & TMidasEvent::operator=(const TMidasEvent &rhs)
00070 {
00075 if (&rhs != this) {
00076 Clear();
00077 fData = rhs.fData;
00078 fEventHeader.fEventId = rhs.fEventHeader.fEventId;
00079 fEventHeader.fTriggerMask = rhs.fEventHeader.fTriggerMask;
00080 fEventHeader.fSerialNumber = rhs.fEventHeader.fSerialNumber;
00081 fEventHeader.fTimeStamp = rhs.fEventHeader.fTimeStamp;
00082 fEventHeader.fDataSize = rhs.fEventHeader.fDataSize;
00083 if (fData)
00084 try {
00085 fData = new Char_t[4096 * (1 + fEventHeader.fDataSize / 4096)];
00086 strcpy(fData, rhs.fData);
00087 fAllocated = true;
00088 } catch(bad_alloc) {
00089 cerr << "operator=: ERROR - unable to copy data" << endl;
00090 fData = 0;
00091 }
00092 }
00093 return *this;
00094 }
00095
00096 void TMidasEvent::Clear(const Char_t *option)
00097 {
00103 if (fData && fAllocated) delete [] fData;
00104 fData = 0;
00105 fEventHeader.fEventId = 0;
00106 fEventHeader.fTriggerMask = 0;
00107 fEventHeader.fSerialNumber = 0;
00108 fEventHeader.fTimeStamp = 0;
00109 fEventHeader.fDataSize = 0;
00110 }
00111
00112 void TMidasEvent::Set(Char_t *eventData)
00113 {
00119 EventHeader_t *h = reinterpret_cast<EventHeader_t *>(eventData);
00120 fEventHeader.fEventId = h->fEventId;
00121 fEventHeader.fTriggerMask = h->fTriggerMask;
00122 fEventHeader.fSerialNumber = h->fSerialNumber;
00123 fEventHeader.fTimeStamp = h->fTimeStamp;
00124 fEventHeader.fDataSize = h->fDataSize;
00125 fData = static_cast<Char_t *>(eventData + sizeof(fEventHeader));
00126 }
00127
00128 Int_t
00129 TMidasEvent::LocateBank(const Char_t *name, void *pdata) const
00130 {
00136 Int_t TID_SIZE[] = {0, 1, 1, 1, 2, 2, 4, 4, 4, 4, 8, 1, 0, 0, 0, 0, 0};
00137 Bank_t *pbk;
00138 Bank32_t *pbk32;
00139 DWORD dname;
00140 void *event = reinterpret_cast<void *>(fData);
00141
00142 if (((((BankHeader_t *) event)->fFlags & (1<<4)) > 0)) {
00143 pbk32 = (Bank32_t *) (((BankHeader_t *) event) + 1);
00144 strncpy((Char_t *) &dname, name, 4);
00145 do {
00146 if (*((DWORD *) pbk32->fName) == dname) {
00147 *((void **) pdata) = pbk32 + 1;
00148 if (TID_SIZE[pbk32->fType & 0xFF] == 0)
00149 return pbk32->fDataSize;
00150 return pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
00151 }
00152 pbk32 = (Bank32_t *) ((Char_t *)(pbk32 + 1)+(((pbk32->fDataSize)+7) & ~7));
00153 } while ((DWORD) pbk32 - (DWORD) event <
00154 ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t));
00155 } else {
00156 pbk = (Bank_t *) (((BankHeader_t *) event) + 1);
00157 strncpy((Char_t *) &dname, name, 4);
00158 do {
00159 if (*((DWORD *) pbk->fName) == dname) {
00160 *((void **) pdata) = pbk + 1;
00161 if (TID_SIZE[pbk->fType & 0xFF] == 0)
00162 return pbk->fDataSize;
00163 return pbk->fDataSize / TID_SIZE[pbk->fType & 0xFF];
00164 }
00165 pbk = (Bank_t *) ((Char_t *) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
00166 } while ((DWORD) pbk - (DWORD) event <
00167 ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t));
00168 }
00169
00170
00171
00172 *((void **) pdata) = NULL;
00173 return 0;
00174 }
00175
00176 Int_t TMidasEvent::FindBank(const Char_t *name, ULong_t *bklen,
00177 ULong_t *bktype, void **pdata) const
00178 {
00186 Int_t TID_SIZE[] = {0, 1, 1, 1, 2, 2, 4, 4, 4, 4, 8, 1, 0, 0, 0, 0, 0};
00187 Bank_t *pbk;
00188 Bank32_t *pbk32;
00189 DWORD dname;
00190 BankHeader_t *pbkh = reinterpret_cast<BankHeader_t *>(fData);
00191
00192 if (((((BankHeader_t *) pbkh)->fFlags & (1<<4)) > 0)) {
00193 pbk32 = (Bank32_t *) (pbkh + 1);
00194 strncpy((Char_t *) &dname, name, 4);
00195 do {
00196 if (*((DWORD *) pbk32->fName) == dname) {
00197 *((void **) pdata) = pbk32 + 1;
00198 if (TID_SIZE[pbk32->fType & 0xFF] == 0)
00199 *bklen = pbk32->fDataSize;
00200 else
00201 *bklen = pbk32->fDataSize / TID_SIZE[pbk32->fType & 0xFF];
00202
00203 *bktype = pbk32->fType;
00204 return 1;
00205 }
00206 pbk32 = (Bank32_t *) ((Char_t *) (pbk32 + 1) +
00207 (((pbk32->fDataSize)+7) & ~7));
00208 } while ((DWORD) pbk32 -
00209 (DWORD) pbkh < pbkh->fDataSize + sizeof(BankHeader_t));
00210 } else {
00211 pbk = (Bank_t *) (pbkh + 1);
00212 strncpy((Char_t *) &dname, name, 4);
00213 do {
00214 if (*((DWORD *) pbk->fName) == dname) {
00215 *((void **) pdata) = pbk + 1;
00216 if (TID_SIZE[pbk->fType & 0xFF] == 0)
00217 *bklen = pbk->fDataSize;
00218 else
00219 *bklen = pbk->fDataSize / TID_SIZE[pbk->fType & 0xFF];
00220
00221 *bktype = pbk->fType;
00222 return 1;
00223 }
00224 pbk = (Bank_t *) ((Char_t *) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
00225 } while ((DWORD) pbk - (DWORD) pbkh < pbkh->fDataSize +
00226 sizeof(BankHeader_t));
00227 }
00228
00229
00230
00231 *((void **) pdata) = NULL;
00232 return 0;
00233 }
00234
00235 Int_t TMidasEvent::SwapBytes(Bool_t force)
00236 {
00249 BankHeader_t *pbh;
00250 Bank_t *pbk;
00251 Bank32_t *pbk32;
00252 void *pdata;
00253 WORD type;
00254 Bool_t b32;
00255
00256 pbh = (BankHeader_t *) fData;
00257
00258
00259
00260 if (pbh->fFlags < 0x10000 && ! force)
00261 return 0;
00262
00263
00264
00265
00266 DWORD_SWAP(&pbh->fDataSize);
00267 DWORD_SWAP(&pbh->fFlags);
00268
00269
00270
00271 b32 = ((pbh->fFlags & (1<<4)) > 0);
00272
00273 pbk = (Bank_t *) (pbh + 1);
00274 pbk32 = (Bank32_t *) pbk;
00275
00276
00277
00278 while ((Int_t) pbk - (Int_t) pbh < (Int_t) pbh->fDataSize +
00279 (Int_t) sizeof(BankHeader_t)) {
00280
00281
00282
00283 if (b32) {
00284 DWORD_SWAP(&pbk32->fType);
00285 DWORD_SWAP(&pbk32->fDataSize);
00286 pdata = pbk32 + 1;
00287 type = (WORD) pbk32->fType;
00288 } else {
00289 WORD_SWAP(&pbk->fType);
00290 WORD_SWAP(&pbk->fDataSize);
00291 pdata = pbk + 1;
00292 type = pbk->fType;
00293 }
00294
00295
00296
00297 if (b32) {
00298 pbk32 = (Bank32_t *) ((Char_t *) (pbk32 + 1) +
00299 (((pbk32->fDataSize)+7) & ~7));
00300 pbk = (Bank_t *) pbk32;
00301 } else {
00302 pbk = (Bank_t *) ((Char_t *) (pbk + 1) + (((pbk->fDataSize)+7) & ~7));
00303 pbk32 = (Bank32_t *) pbk;
00304 }
00305
00306 switch (type) {
00307 case 4:
00308 case 5:
00309 while ((Int_t) pdata < (Int_t) pbk) {
00310 WORD_SWAP(pdata);
00311 pdata = (void *) (((WORD *) pdata) + 1);
00312 }
00313 break;
00314 case 6:
00315 case 7:
00316 case 8:
00317 case 9:
00318 while ((Int_t) pdata < (Int_t) pbk) {
00319 DWORD_SWAP(pdata);
00320 pdata = (void *) (((DWORD *) pdata) + 1);
00321 }
00322 break;
00323 case 10:
00324 while ((Int_t) pdata < (Int_t) pbk) {
00325 QWORD_SWAP(pdata);
00326 pdata = (void *) (((Double_t *) pdata) + 1);
00327 }
00328 break;
00329 }
00330 }
00331 return true;
00332 }
00333
00334 void TMidasEvent::Print(const Char_t *option) const
00335 {
00341 cout.setf(ios_base::showbase | ios_base::internal);
00342 cout.setf(ios_base::hex, ios_base::basefield);
00343 cout.fill('0');
00344 cout << endl << "Event start:" << endl
00345 << " Event ID: " << setw(6) << fEventHeader.fEventId << endl
00346 << " Trigger mask: " << setw(6) << fEventHeader.fTriggerMask << endl
00347 << " Serial number: " << setw(10) << fEventHeader.fSerialNumber << endl
00348 << " Time-stamp: " << setw(10) << fEventHeader.fTimeStamp
00349 << " ==> "
00350 << ctime(reinterpret_cast<time_t const *>(&fEventHeader.fTimeStamp))
00351 << " Data size: " << setw(10) << fEventHeader.fDataSize << endl;
00352 if ((fEventHeader.fEventId & 0xffff) == TMidasEvent::kEV_BOR) {
00353 const Char_t *midasMagic =
00354 reinterpret_cast<const Char_t *>(&fEventHeader.fTriggerMask);
00355 cout << "No banks, start of run:" << endl << " midas magic="
00356 << midasMagic[0] << midasMagic[1] << endl << " run number="
00357 << dec << fEventHeader.fSerialNumber << endl;
00358 } else if ((fEventHeader.fEventId & 0xffff) == TMidasEvent::kEV_EOR) {
00359 cout << "No banks, end of run:" << endl;
00360 } else if (option[0] == 'a' || option[0] == 'b') {
00361 UShort_t banksN;
00362 const Char_t *bankList = GetBankList(banksN);
00363
00364 cout << "Banks: " << bankList << endl;
00365 for (Int_t i = 0; i < banksN * 4; i += 4) {
00366 ULong_t bankLength = 0;
00367 ULong_t bankType = 0;
00368 void *pdata = 0;
00369 Int_t found = FindBank(&bankList[i], &bankLength, &bankType, &pdata);
00370
00371 cout << "Bank=" << bankList[i] << bankList[i + 1]
00372 << bankList[i + 2] << bankList[i + 3] << " length=" << dec
00373 << bankLength << " type=" << bankType << endl;
00374 if (option[0] == 'a' && found) {
00375 cout << "Bank data: " << endl;
00376 switch (bankType) {
00377
00378
00379
00380 case 4:
00381 for (UInt_t j = 0; j < bankLength; j++) {
00382 cout << setw(6) << hex << showbase
00383 << static_cast<Short_t>((static_cast<WORD *>(pdata))[j])
00384 << " ";
00385 if (j % 11 == 10)
00386 cout << endl;
00387 }
00388 cout << endl;
00389 break;
00390
00391
00392
00393 case 6:
00394 for (UInt_t j = 0; j < bankLength; j++) {
00395 cout << setw(10) << hex << showbase
00396 << static_cast<Int_t>((static_cast<DWORD *>(pdata))[j]) << " ";
00397 if (j % 7 == 6)
00398 cout << endl;
00399 }
00400 cout << endl;
00401 break;
00402
00403
00404
00405 case 9:
00406 for (UInt_t j = 0; j < bankLength; j++) {
00407 cout << setw(6) << dec
00408 << static_cast<Float_t>((static_cast<Float_t *>(pdata))[j])
00409 << " ";
00410 if (j % 7 == 6)
00411 cout << endl;
00412 }
00413 cout << endl;
00414 break;
00415 default:
00416 cerr << "Print: ERROR - unknown bank type " << bankType << endl;
00417 }
00418 }
00419 }
00420 delete bankList;
00421 }
00422 }
00423
00424 void TMidasEvent::AllocateData()
00425 {
00428 try {
00429 fData = new Char_t[4096 * (1 + fEventHeader.fDataSize / 4096)];
00430 fAllocated = true;
00431 } catch(bad_alloc) {
00432 cerr << "AllocateData: ERROR - unable to allocate memory for data" << endl;
00433 fData = 0;
00434 fAllocated = false;
00435 }
00436 }
00437
00438 const Char_t * TMidasEvent::GetBankList(UShort_t &banksN) const
00439 {
00445 Char_t bankList[fStringBankListMax];
00446 Char_t *bklist = bankList;
00447 void *event = reinterpret_cast<void *>(fData);
00448 Bank_t *pmbk = NULL;
00449 Bank32_t *pmbk32 = NULL;
00450 Char_t *pdata;
00451 Bool_t moreBanks = 1;
00452
00453
00454
00455
00456 bklist[0] = 0;
00457 banksN = 0;
00458
00459 if (fEventHeader.fEventId > 0) {
00460
00461 do {
00462
00463
00464
00465 if ((((BankHeader_t *) event)->fFlags & (1 << 4)) > 0) {
00466 IterateBank32(event, &pmbk32, &pdata);
00467 if (pmbk32 == NULL)
00468 break;
00469 } else {
00470 IterateBank(event, &pmbk, &pdata);
00471 if (pmbk == NULL)
00472 break;
00473 }
00474 banksN++;
00475
00476 if (banksN > fBankListMax) {
00477 cerr << "GetBankList: Over " << fBankListMax
00478 << " banks -> truncated" << endl;
00479 moreBanks = 0;
00480 } else {
00481 if ((((BankHeader_t *) event)->fFlags & (1 << 4)) > 0)
00482 strncat(bklist, (Char_t *) pmbk32->fName, 4);
00483 else
00484 strncat(bklist, (Char_t *) pmbk->fName, 4);
00485 }
00486 } while (moreBanks);
00487 }
00488 return strdup(bankList);
00489 }
00490
00491 Int_t TMidasEvent::IterateBank(void *event, Bank_t **pbk, void *pdata) const
00492 {
00502 if (*pbk == NULL)
00503 *pbk = (Bank_t *) (((BankHeader_t *) event) + 1);
00504 else
00505 *pbk = (Bank_t *) ((Char_t *) (*pbk + 1) + ((((*pbk)->fDataSize)+7) & ~7));
00506
00507 *((void **) pdata) = (*pbk) + 1;
00508
00509 if ((DWORD) * pbk - (DWORD) event >=
00510 ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t)) {
00511 *pbk = *((Bank_t **) pdata) = NULL;
00512 return 0;
00513 }
00514 return (*pbk)->fDataSize;
00515 }
00516
00517 Int_t TMidasEvent::IterateBank32(void *event, Bank32_t **pbk, void *pdata) const
00518 {
00528 if (*pbk == NULL)
00529 *pbk = (Bank32_t *) (((BankHeader_t *) event) + 1);
00530 else
00531 *pbk = (Bank32_t *) ((Char_t *) (*pbk + 1) +
00532 ((((*pbk)->fDataSize)+7) & ~7));
00533
00534 *((void **) pdata) = (*pbk) + 1;
00535
00536 if ((DWORD) * pbk - (DWORD) event >=
00537 ((BankHeader_t *) event)->fDataSize + sizeof(BankHeader_t)) {
00538 *pbk = *((Bank32_t **) pdata) = NULL;
00539 return 0;
00540 }
00541 return (*pbk)->fDataSize;
00542 }
00543
00544 void TMidasEvent::SwapBytesEventHeader()
00545 {
00548 WORD_SWAP(&fEventHeader.fEventId);
00549 WORD_SWAP(&fEventHeader.fTriggerMask);
00550 DWORD_SWAP(&fEventHeader.fSerialNumber);
00551 DWORD_SWAP(&fEventHeader.fTimeStamp);
00552 DWORD_SWAP(&fEventHeader.fDataSize);
00553 }