AliRoot Core  3abf5b4 (3abf5b4)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliMUONTriggerDDLDecoder.h
Go to the documentation of this file.
1 #ifndef ALIMUONTRIGGERDDLDECODER_H
2 #define ALIMUONTRIGGERDDLDECODER_H
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project *
5  * All rights reserved. *
6  * *
7  * Primary Authors: *
8  * Artur Szostak <artursz@iafrica.com> *
9  * *
10  * Permission to use, copy, modify and distribute this software and its *
11  * documentation strictly for non-commercial purposes is hereby granted *
12  * without fee, provided that the above copyright notice appears in all *
13  * copies and that both the copyright notice and this permission notice *
14  * appear in the supporting documentation. The authors make no claims *
15  * about the suitability of this software for any purpose. It is *
16  * provided "as is" without express or implied warranty. *
17  **************************************************************************/
18 
19 /* $Id$ */
20 
39 
41 
88 template <class EventHandler>
90 {
91 public:
92 
95  fExitOnError(true), fTryRecover(false),
96  fAutoDetectScalars(false), fHadError(false),
98  fHandler()
99  {}
100 
102  const EventHandler& GetHandler() const { return fHandler; }
103 
105  EventHandler& GetHandler() { return fHandler; }
106 
109  bool ExitOnError() const { return fExitOnError; }
110 
113  void ExitOnError(bool value) { fExitOnError = value; }
114 
118  bool TryRecover() const { return fTryRecover; }
119 
123  void TryRecover(bool value) { fTryRecover = value; }
124 
127  bool AutoDetectScalars() const { return fAutoDetectScalars; }
128 
132  void AutoDetectScalars(bool value) { fAutoDetectScalars = value; }
133 
135  UInt_t MaxRegionals() const { return fMaxRegionals; }
136 
138  void MaxRegionals(UInt_t n) { fMaxRegionals = n; }
139 
141  UInt_t RegionalsDecoded() const { return fNoRegionals; }
142 
145  UInt_t MaxLocals() const { return fMaxLocals; }
146 
149  void MaxLocals(UInt_t n) { fMaxLocals = n; }
150 
152  bool Decode(const void* buffer, UInt_t bufferSize, bool scalarEvent = false);
153 
155  static UInt_t EndOfDarcWord() { return fgkEndOfDarc; }
156 
158  static UInt_t EndOfGlobalWord() { return fgkEndOfGlobal; }
159 
161  static UInt_t EndOfRegionalWord() { return fgkEndOfReg; }
162 
164  static UInt_t RegionalErrorWord() { return fgkErrorWord; }
165 
167  static UInt_t EndOfLocalWord() { return fgkEndOfLocal; }
168 
170  static UInt_t LocalDisableWord() { return fgkDisableWord; }
171 
173  static UInt_t DarcDefaultType() { return fgkDarcDefaultType; }
174 
176  static UInt_t DarcVadorhType() { return fgkDarcVadorhType; }
177 
178 private:
179 
181  bool fTryRecover;
183  bool fHadError;
184  UInt_t fNoRegionals;
185  UInt_t fMaxRegionals;
186  UInt_t fMaxLocals;
187  EventHandler fHandler;
188 
189  void DecodeBuffer(const UChar_t* start, const UChar_t* end, bool scalarEvent);
190  void DecodeRegionalStructs(const UChar_t* start, const UChar_t* end, bool scalarEvent);
191  const UChar_t* DecodeLocalStructs(const UChar_t* start, const UChar_t* end, bool scalarEvent);
192 
193  const UChar_t* FindKey(
194  UInt_t key, const UChar_t* start, const UChar_t* end
195  );
196 
197  static const UInt_t fgkEndOfDarc;
198  static const UInt_t fgkEndOfGlobal;
199  static const UInt_t fgkEndOfReg;
200  static const UInt_t fgkErrorWord;
201  static const UInt_t fgkEndOfLocal;
202  static const UInt_t fgkDisableWord;
203  static const UInt_t fgkDarcDefaultType;
204  static const UInt_t fgkDarcVadorhType;
205 };
206 
207 //_____________________________________________________________________________
208 
209 // The following are the structure key words which are used to demarcate (identify
210 // the end) of the structures within the raw trigger data.
211 template <class EventHandler>
213 template <class EventHandler>
215 template <class EventHandler>
217 template <class EventHandler>
219 template <class EventHandler>
221 template <class EventHandler>
223 template <class EventHandler>
225 template <class EventHandler>
227 
228 
229 template <class EventHandler>
231  const void* buffer, UInt_t bufferSize, bool scalarEvent
232  )
233 {
267 
268  assert( buffer != NULL );
269 
270  fHadError = false;
271 
272  // We are basically implementing something like a recursive decent parser.
273  // So start by marking the start of buffer position and end of buffer.
274  const UChar_t* start = reinterpret_cast<const UChar_t*>(buffer);
275  const UChar_t* end = start + bufferSize;
276 
277  fHandler.OnNewBuffer(buffer, bufferSize);
278  DecodeBuffer(start, end, scalarEvent);
279  fHandler.OnEndOfBuffer(buffer, bufferSize);
280  return not fHadError;
281 }
282 
283 
284 template <class EventHandler>
286  const UChar_t* start, const UChar_t* end, bool scalarEvent
287  )
288 {
303 
304  const UChar_t* current = start;
305 
306  // Mark the DARC header, but check that we do not overrun the buffer.
307  const UInt_t* darcHeader = reinterpret_cast<const UInt_t*>(current);
308  current += sizeof(UInt_t);
309  if (current > end or current < start)
310  {
311  // Indicate we had an error and stop the decoding because we
312  // hit the end of the buffer already.
313  fHandler.OnError(EventHandler::kNoDarcHeader, darcHeader);
314  fHadError = true;
315  return;
316  }
317 
318  // Check if we need to figure out if this is a scalar event.
319  // If we do, then we do this by checking the event type in the DARC header
320  // and double checking this by checking if the fgkEndOfDarc key is in the
321  // expected location for a scalar event DDL payload.
322  if (fAutoDetectScalars)
323  {
324  const UInt_t* expectedEndOfDarc = reinterpret_cast<const UInt_t*>(
325  current + sizeof(AliMUONDarcScalarsStruct)
326  );
327 
328  // First make sure not to read past the end of buffer. Then check
329  // the value of the event type in the DARC header.
330  // Physics events are indicated by the two trigger bits of the
331  // DARC header set to 01b. Everything else is a software trigger
332  // of some sort.
333  if (reinterpret_cast<const UChar_t*>(expectedEndOfDarc+1) <= end and
334  reinterpret_cast<const UChar_t*>(expectedEndOfDarc+1) > start and
335  EventHandler::GetDarcEventType(*darcHeader) != 0x1
336  and *expectedEndOfDarc == fgkEndOfDarc
337  )
338  {
339  scalarEvent = true;
340  }
341  else
342  {
343  scalarEvent = false;
344  }
345  }
346 
347  // Detect how many regional blocks we expect. If we have no idea then
348  // just use what the maximum setting is.
349  UInt_t darkType = EventHandler::GetDarcType(*darcHeader);
350  if (darkType == fgkDarcVadorhType)
351  {
352  fNoRegionals = 1;
353  }
354  else if (darkType == fgkDarcDefaultType)
355  {
356  fNoRegionals = 8;
357  }
358  else
359  {
360  fNoRegionals = fMaxRegionals;
361  }
362 
363  // Check if the DARC header indicates we expect more regionals than we
364  // are allowed to decode according to our max regional structures count.
365  // If we do then this is an error and we should indicate it and exit
366  // if so requested by the user. Also we can fix the number of regionals
367  // to expect if we are trying to recover from errors.
368  if (fNoRegionals > fMaxRegionals)
369  {
370  fHandler.OnError(EventHandler::kTooManyRegionals, darcHeader);
371  fHadError = true;
372  if (fExitOnError) return;
373  if (fTryRecover)
374  {
375  fNoRegionals = fMaxRegionals;
376  }
377  }
378 
379  // Check that the DARC header indicates correctly if we are a scalar event or not.
380  bool darcShowsScalar = (EventHandler::GetDarcEventType(*darcHeader) != 0x1);
381  if (darcShowsScalar != scalarEvent)
382  {
383  // Indicate we had an error and stop the decoding if so requested
384  // by the user.
385  fHandler.OnError(EventHandler::kWrongEventType, darcHeader);
386  fHadError = true;
387  if (fExitOnError) return;
388  }
389 
390  // Decode the DARC scalars if this is a scalar event.
391  const AliMUONDarcScalarsStruct* darcScalars = NULL;
392  if (scalarEvent)
393  {
394  darcScalars = reinterpret_cast<const AliMUONDarcScalarsStruct*>(current);
395  current += sizeof(AliMUONDarcScalarsStruct);
396  if (current > end or current < start)
397  {
398  // If we overflowed the pointer and already had an error then
399  // we are clearly lost so just stop decoding before we segfault.
400  if (current < start and fHadError) return;
401 
402  // Indicate we had an error and stop the decoding because we
403  // hit the end of the buffer already.
404  fHandler.OnError(EventHandler::kNoDarcScalars, darcScalars);
405  fHadError = true;
406  return;
407  }
408  }
409 
410  // Now check that the end of DARC header marker is OK.
411  const UInt_t* endOfDarc = reinterpret_cast<const UInt_t*>(current);
412  current += sizeof(UInt_t);
413  if (current > end or current < start)
414  {
415  // If we overflowed the pointer and already had an error then
416  // we are clearly lost so just stop decoding before we segfault.
417  if (current < start and fHadError) return;
418 
419  // Indicate we had an error and stop the decoding because we
420  // hit the end of the buffer already.
421  fHandler.OnError(EventHandler::kNoEndOfDarc, endOfDarc);
422  fHadError = true;
423  return;
424  }
425  if (*endOfDarc != fgkEndOfDarc)
426  {
427  // Indicate we had an error and stop the decoding if so requested
428  // by the user.
429  fHandler.OnError(EventHandler::kBadEndOfDarc, endOfDarc);
430  fHadError = true;
431  if (fExitOnError) return;
432 
433  // If the user requested for us to try and recover from structure
434  // errors then we need to try locate the key in the data stream
435  // and continue decoding from there.
436  if (fTryRecover)
437  {
438  const UChar_t* keypos = FindKey(fgkEndOfDarc,
439  reinterpret_cast<const UChar_t*>(darcHeader),
440  end
441  );
442  if (keypos != NULL)
443  {
444  // remember to continue decoding just past the key.
445  current = keypos + sizeof(UInt_t);
446  }
447  }
448  }
449 
450  fHandler.OnDarcHeader(*darcHeader, darcScalars, current);
451 
452  // Next, we mark the Global header and check that we do not overrun the buffer.
453  const AliMUONGlobalHeaderStruct* globalHeader =
454  reinterpret_cast<const AliMUONGlobalHeaderStruct*>(current);
455  current += sizeof(AliMUONGlobalHeaderStruct);
456  if (current > end or current < start)
457  {
458  // If we overflowed the pointer and already had an error then
459  // we are clearly lost so just stop decoding before we segfault.
460  if (current < start and fHadError) return;
461 
462  // Indicate we had an error and stop the decoding because we
463  // hit the end of the buffer already.
464  fHandler.OnError(EventHandler::kNoGlobalHeader, globalHeader);
465  fHadError = true;
466  return;
467  }
468 
469  // Decode the global scalars if this is a scalar event.
470  const AliMUONGlobalScalarsStruct* globalScalars = NULL;
471  if (scalarEvent)
472  {
473  globalScalars = reinterpret_cast<const AliMUONGlobalScalarsStruct*>(current);
474  current += sizeof(AliMUONGlobalScalarsStruct);
475  if (current > end or current < start)
476  {
477  // If we overflowed the pointer and already had an error then
478  // we are clearly lost so just stop decoding before we segfault.
479  if (current < start and fHadError) return;
480 
481  // Indicate we had an error and stop the decoding because we
482  // hit the end of the buffer already.
483  fHandler.OnError(EventHandler::kNoGlobalScalars, globalScalars);
484  fHadError = true;
485  return;
486  }
487  }
488 
489  // Now check that the end of global header marker is OK.
490  const UInt_t* endOfGlobal = reinterpret_cast<const UInt_t*>(current);
491  current += sizeof(UInt_t);
492  if (current > end or current < start)
493  {
494  // If we overflowed the pointer and already had an error then
495  // we are clearly lost so just stop decoding before we segfault.
496  if (current < start and fHadError) return;
497 
498  // Indicate we had an error and stop the decoding because we
499  // hit the end of the buffer already.
500  fHandler.OnError(EventHandler::kNoEndOfGlobal, endOfGlobal);
501  fHadError = true;
502  return;
503  }
504  if (*endOfGlobal != fgkEndOfGlobal)
505  {
506  // Indicate we had an error and stop the decoding if so requested
507  // by the user.
508  fHandler.OnError(EventHandler::kBadEndOfGlobal, endOfGlobal);
509  fHadError = true;
510  if (fExitOnError) return;
511 
512  // If the user requested for us to try and recover from structure
513  // errors then we need to try locate the key in the data stream
514  // and continue decoding from there.
515  if (fTryRecover)
516  {
517  const UChar_t* keypos = FindKey(fgkEndOfGlobal,
518  reinterpret_cast<const UChar_t*>(globalHeader),
519  end
520  );
521  if (keypos != NULL)
522  {
523  // remember to continue decoding just past the key.
524  current = keypos + sizeof(UInt_t);
525  }
526  }
527  }
528 
529  fHandler.OnGlobalHeader(globalHeader, globalScalars, current);
530 
531  DecodeRegionalStructs(current, end, scalarEvent);
532 }
533 
534 
535 template <class EventHandler>
537  const UChar_t* start, const UChar_t* end, bool scalarEvent
538  )
539 {
556 
557  const UChar_t* current = start;
558 
559  for (UInt_t iReg = 0; iReg < fNoRegionals; iReg++)
560  {
561  const AliMUONRegionalHeaderStruct* regionalHeader =
562  reinterpret_cast<const AliMUONRegionalHeaderStruct*>(current);
563  current += sizeof(AliMUONRegionalHeaderStruct);
564 
565  if (current > end or current < start)
566  {
567  // If we overflowed the pointer and already had an error then
568  // we are clearly lost so just stop decoding before we segfault.
569  if (current < start and fHadError) return;
570 
571  // So we only got part of a regional header, nothing to do but
572  // report the error and exit.
573  fHandler.OnError(EventHandler::kNoRegionalHeader, regionalHeader);
574  fHadError = true;
575  return;
576  }
577 
578  // Skip empty regional board (not connected or with error reading).
579  if (regionalHeader->fDarcWord == fgkErrorWord)
580  {
581  //current += sizeof(AliMUONRegionalHeaderStruct); // already done above
582  if (scalarEvent)
583  current += sizeof(AliMUONRegionalScalarsStruct);
584  current += sizeof(UInt_t); // skip the end of regional structure key.
585 
586  // now also skip the local structure part:
587  current += fMaxLocals * sizeof(AliMUONLocalInfoStruct);
588  if (scalarEvent)
589  current += fMaxLocals * sizeof(AliMUONLocalScalarsStruct);
590  current += fMaxLocals * sizeof(UInt_t); // skip all the end of local structure keys.
591 
592  continue;
593  }
594 
595  // Decode the regional scalar words if this is a scalar event.
596  const AliMUONRegionalScalarsStruct* regionalScalars = NULL;
597  if (scalarEvent)
598  {
599  regionalScalars = reinterpret_cast<const AliMUONRegionalScalarsStruct*>(current);
600  current += sizeof(AliMUONRegionalScalarsStruct);
601  if (current > end or current < start)
602  {
603  // If we overflowed the pointer and already had an error then
604  // we are clearly lost so just stop decoding before we segfault.
605  if (current < start and fHadError) return;
606 
607  // Indicate we had an error and stop the decoding because we
608  // hit the end of the buffer already.
609  fHandler.OnError(EventHandler::kNoRegionalScalars, regionalScalars);
610  fHadError = true;
611  return;
612  }
613  }
614 
615  // Now check that the end of regional header marker is OK.
616  const UInt_t* endOfRegional = reinterpret_cast<const UInt_t*>(current);
617  current += sizeof(UInt_t);
618  if (current > end or current < start)
619  {
620  // If we overflowed the pointer and already had an error then
621  // we are clearly lost so just stop decoding before we segfault.
622  if (current < start and fHadError) return;
623 
624  // Indicate we had an error and stop the decoding because we
625  // hit the end of the buffer already.
626  fHandler.OnError(EventHandler::kNoEndOfRegional, endOfRegional);
627  fHadError = true;
628  return;
629  }
630  if (*endOfRegional != fgkEndOfReg)
631  {
632  // Indicate we had an error and stop the decoding if so requested
633  // by the user.
634  fHandler.OnError(EventHandler::kBadEndOfRegional, endOfRegional);
635  fHadError = true;
636  if (fExitOnError) return;
637 
638  // If the user requested for us to try and recover from structure
639  // errors then we need to try locate the key in the data stream
640  // and continue decoding from there.
641  if (fTryRecover)
642  {
643  const UChar_t* keypos = FindKey(fgkEndOfReg,
644  reinterpret_cast<const UChar_t*>(regionalHeader),
645  end
646  );
647 
648  // If the fgkEndOfReg key was found exactly one regional
649  // structure later then we should not adjust the current
650  // decoding position because it is more likely that the
651  // end of regional structure key was just corrupt rather
652  // than offset.
653  // If we could not find another good key then just continue.
654  size_t sizeOfRegional = sizeof(AliMUONRegionalHeaderStruct) + sizeof(UInt_t)
655  + fMaxLocals * (sizeof(AliMUONLocalInfoStruct) + sizeof(UInt_t));
656  if (scalarEvent)
657  {
658  sizeOfRegional += sizeof(AliMUONRegionalScalarsStruct)
659  + fMaxLocals * sizeof(AliMUONLocalScalarsStruct);
660  }
661 
662  if (keypos != NULL and keypos != current + sizeOfRegional)
663  {
664  current = keypos + sizeof(UInt_t);
665  }
666  }
667  }
668 
669  // Tell the handler that we have a new regional block and decode it.
670  // When done, tell the handler again.
671  // We call both versions of OnNewRegionalStruct so that user event
672  // handlers can implement the one they prefer to use.
673  const UChar_t* startOfLocals = current;
674  fHandler.OnNewRegionalStruct(regionalHeader, regionalScalars, startOfLocals);
675  fHandler.OnNewRegionalStructV2(iReg, regionalHeader, regionalScalars, startOfLocals);
676  current = DecodeLocalStructs(current, end, scalarEvent);
677  fHandler.OnEndOfRegionalStruct(regionalHeader, regionalScalars, startOfLocals);
678  fHandler.OnEndOfRegionalStructV2(iReg, regionalHeader, regionalScalars, startOfLocals);
679  }
680 
681  // Now just check that there is no extra rubbish at the end of the DDL.
682  if (current != end)
683  {
684  fHandler.OnError(EventHandler::kBufferTooBig, current);
685  fHadError = true;
686  }
687 }
688 
689 
690 template <class EventHandler>
692  const UChar_t* start, const UChar_t* end, bool scalarEvent
693  )
694 {
709 
710  const UChar_t* current = start;
711 
712  for (UInt_t iLocal = 0; iLocal < fMaxLocals; iLocal++)
713  {
714  const AliMUONLocalInfoStruct* localStruct =
715  reinterpret_cast<const AliMUONLocalInfoStruct*>(current);
716  current += sizeof(AliMUONLocalInfoStruct);
717 
718  if (current > end or current < start)
719  {
720  // If we overflowed the pointer and already had an error then
721  // we are clearly lost so just stop decoding before we segfault.
722  if (current < start and fHadError) return end;
723 
724  // So we only got part of a local structure, nothing to do but
725  // report the error and exit.
726  fHandler.OnError(EventHandler::kNoLocalStruct, localStruct);
727  fHadError = true;
728  return end;
729  }
730 
731  // Skip empty local board if card not notified.
732  if (localStruct->fX2X1 == fgkDisableWord and
733  localStruct->fX4X3 == fgkDisableWord and
734  localStruct->fY2Y1 == fgkDisableWord and
735  localStruct->fY4Y3 == fgkDisableWord and
736  localStruct->fTriggerBits == fgkDisableWord
737  )
738  {
739  //current += sizeof(AliMUONLocalInfoStruct); // already done above
740  if (scalarEvent)
741  current += sizeof(AliMUONLocalScalarsStruct);
742  current += sizeof(UInt_t); // skip the end of local structure key.
743  continue;
744  }
745 
746  // Decode the regional scalar words if this is a scalar event.
747  const AliMUONLocalScalarsStruct* localScalars = NULL;
748  if (scalarEvent)
749  {
750  localScalars = reinterpret_cast<const AliMUONLocalScalarsStruct*>(current);
751  current += sizeof(AliMUONLocalScalarsStruct);
752  if (current > end or current < start)
753  {
754  // If we overflowed the pointer and already had an error then
755  // we are clearly lost so just stop decoding before we segfault.
756  if (current < start and fHadError) return end;
757 
758  // Indicate we had an error and stop the decoding because we
759  // hit the end of the buffer already.
760  fHandler.OnError(EventHandler::kNoLocalScalars, localScalars);
761  fHadError = true;
762  return end;
763  }
764  }
765 
766  // Now check that the end of regional header marker is OK.
767  const UInt_t* endOfLocal = reinterpret_cast<const UInt_t*>(current);
768  current += sizeof(UInt_t);
769  if (current > end or current < start)
770  {
771  // If we overflowed the pointer and already had an error then
772  // we are clearly lost so just stop decoding before we segfault.
773  if (current < start and fHadError) return end;
774 
775  // Indicate we had an error and stop the decoding because we
776  // hit the end of the buffer already. We can however signal that
777  // we got a local structure, because the buffer contains enough
778  // data to potencially contain the real data of the structure.
779  fHandler.OnError(EventHandler::kNoEndOfLocal, endOfLocal);
780  if (not fExitOnError)
781  {
782  fHandler.OnLocalStruct(localStruct, localScalars);
783  }
784  fHadError = true;
785  return end;
786  }
787  if (*endOfLocal != fgkEndOfLocal)
788  {
789  // Indicate we had an error and stop the decoding if so requested
790  // by the user.
791  fHandler.OnError(EventHandler::kBadEndOfLocal, endOfLocal);
792  fHadError = true;
793  if (fExitOnError) return current;
794 
795  // If the user requested for us to try and recover from structure
796  // errors then we need to try locate the key in the data stream
797  // and continue decoding from there.
798  if (fTryRecover)
799  {
800  const UChar_t* searchPos = reinterpret_cast<const UChar_t*>(localStruct);
801  const UChar_t* firstLocalKey = FindKey(fgkEndOfLocal, searchPos, end);
802  const UChar_t* firstRegionalKey = FindKey(fgkEndOfReg, searchPos, end);
803 
804  // If a regional key was found first, then give up on
805  // anymore local structures from this regional block and
806  // continue decoding from the next regional block.
807  // Also if the fgkEndOfLocal key was found exactly one
808  // local structure later then we should not adjust the
809  // current decoding position because it is more likely that
810  // the end of local structure key was just corrupt rather
811  // than offset.
812  if (firstLocalKey != NULL and firstRegionalKey != NULL)
813  {
814  if (firstLocalKey < firstRegionalKey)
815  {
816  size_t sizeOflocalStruct = sizeof(AliMUONLocalInfoStruct) + sizeof(UInt_t);
817  if (scalarEvent)
818  sizeOflocalStruct += sizeof(AliMUONLocalScalarsStruct);
819 
820  if (firstLocalKey != current + sizeOflocalStruct)
821  current = firstLocalKey + sizeof(UInt_t);
822  }
823  else
824  {
825  // Adjust back to the start of the regional header.
826  current = firstRegionalKey - sizeof(AliMUONRegionalHeaderStruct);
827  if (scalarEvent)
828  current -= sizeof(AliMUONRegionalScalarsStruct);
829  break;
830  }
831  }
832 
833  // If we could not find another good key then just continue.
834  }
835  }
836 
837  // Call both handlers for local structures so that the user decoder event
838  // handler class can implement the one it prefers to use.
839  fHandler.OnLocalStruct(localStruct, localScalars);
840  fHandler.OnLocalStructV2(iLocal, localStruct, localScalars);
841  }
842 
843  return current;
844 }
845 
846 
847 template <class EventHandler>
849  UInt_t key, const UChar_t* start, const UChar_t* end
850  )
851 {
861 
862  if (end + sizeof(UInt_t) < start) return NULL; // check for pointer overflow.
863  const UChar_t* current = start;
864  while (current + sizeof(UInt_t) <= end)
865  {
866  UInt_t data = * reinterpret_cast<const UInt_t*>(current);
867  if (data == key) return current;
868  current++;
869  }
870  return NULL;
871 }
872 
873 #endif // ALIMUONTRIGGERDDLDECODER_H
The optional DARC board scalars.
bool fAutoDetectScalars
Flag to indicate if we should auto-detect if there are scalars in the data.
static const UInt_t fgkEndOfGlobal
Indicates the end of the global header just after the DARC header.
static UInt_t RegionalErrorWord()
Returns the regional error word.
void DecodeBuffer(const UChar_t *start, const UChar_t *end, bool scalarEvent)
UInt_t MaxRegionals() const
Returns the maximum regional structure count expected in the DDL payload.
bool fHadError
Indicates if we had an error decoding the data.
A high performance decoder class for MUON trigger DDL data.
The global input and output words just after the DARC header.
UInt_t fMaxRegionals
Maximum number of regional card structures allowed in a DDL stream.
void MaxRegionals(UInt_t n)
Sets the maximum regional structure count expected in the DDL payload.
static const UInt_t fgkEndOfLocal
Indicates the end of a local card structure.
Local card trigger information.
static const UInt_t fgkDisableWord
Word used to fill "empty" slots.
bool fExitOnError
Indicates if we should exit on the very first error.
const EventHandler & GetHandler() const
Constant method to return the event handler instance.
static UInt_t DarcDefaultType()
Returns value of default DARC type.
UInt_t fY2Y1
16 bits Y2 position in 16 most significant bits and 16 bits of Y1 in least significant bits...
static UInt_t EndOfGlobalWord()
Returns the end of global header marker key.
UInt_t fMaxLocals
Maximum number of local card structures per regional structure allowed in a DDL stream.
static const UInt_t fgkEndOfReg
Indicates the end of a regional card structure.
UInt_t fY4Y3
16 bits Y4 position in 16 most significant bits and 16 bits of Y3 in least significant bits...
UInt_t fX2X1
16 bits X2 position in 16 most significant bits and 16 bits of X1 in least significant bits...
EventHandler & GetHandler()
Returns the event handler instance.
The optional global card scalars.
UInt_t fNoRegionals
The number of regional card structures actually decoded.
UInt_t fX4X3
16 bits X4 position in 16 most significant bits and 16 bits of X3 in least significant bits...
EventHandler fHandler
The event handler which deals with the generated parsing events.
UInt_t RegionalsDecoded() const
Returns the number of regional structures we actually attempted to decode.
Implementation of the high performance trigger DDL decoder event handler.
static const UInt_t fgkDarcVadorhType
default type for DARC vadorh
static const UInt_t fgkDarcDefaultType
default type for DARC def.
static UInt_t EndOfLocalWord()
Returns the end of local structure marker key.
const UChar_t * DecodeLocalStructs(const UChar_t *start, const UChar_t *end, bool scalarEvent)
static UInt_t DarcVadorhType()
Returns value of Vadorh DARC type.
static const UInt_t fgkErrorWord
The error word when a regional board is missing.
static UInt_t EndOfDarcWord()
Returns the end of DARC marker key.
static UInt_t EndOfRegionalWord()
Returns the end of regional structure marker key.
void DecodeRegionalStructs(const UChar_t *start, const UChar_t *end, bool scalarEvent)
static const UInt_t fgkEndOfDarc
Indicates the end of the DARC header.
AliMUONTriggerDDLDecoder()
Default contructor.
static UInt_t LocalDisableWord()
Returns the local card disable word.
bool fTryRecover
Indicates if we should try recover from a corrupt structures.
bool Decode(const void *buffer, UInt_t bufferSize, bool scalarEvent=false)
This method decodes the DDL payload contained in the buffer.
const UChar_t * FindKey(UInt_t key, const UChar_t *start, const UChar_t *end)
UInt_t fTriggerBits
Trigger bits and deviation.