00001 #ifndef TDataContainer_hxx_seen 00002 #define TDataContainer_hxx_seen 00003 00004 #include <stdio.h> 00005 #include <vector> 00006 #include <exception> 00007 00008 #include "TMidasEvent.h" 00009 #include "TGenericData.hxx" 00010 #include <typeinfo> 00011 00012 /// 00013 class failed_midas_bank_cast: public std::exception 00014 { 00015 virtual const char* what() const throw() 00016 { 00017 return "Incorrect bank cast"; 00018 } 00019 }; 00020 00021 00022 /// This class is what will get passed back to users for each midas event. 00023 /// It will contain a pointer to the midas event, which the user can access. 00024 /// It will also contain routines that the user can call to access decoded 00025 /// versions of the midas banks. 00026 /// Generally the decoded information will be cleaned out at the end of each 00027 /// event; but there will be options to allow this information to persist. 00028 class TDataContainer 00029 { 00030 00031 00032 public: 00033 00034 TDataContainer(): 00035 fMidasEventPointer(0), fOwnMidasEventMemory(false) 00036 {} 00037 00038 TDataContainer(const TDataContainer &dataContainer); 00039 00040 ~TDataContainer(); 00041 00042 /// Get the MIDAS data for this event, in TMidasEvent format 00043 TMidasEvent& GetMidasData() const; 00044 TMidasEvent& GetMidasEvent() const{ return GetMidasData(); } 00045 00046 00047 /// Add a templated function that returns event data in the format that we want. 00048 template <typename T> T* GetEventData(const char* name){ 00049 00050 // Try to find a cached version of this bank 00051 for(unsigned int ibank = 0; ibank < fEventDataList.size(); ibank++){ 00052 if(fEventDataList[ibank]->GetName().compare(name) == 0){ 00053 // Found bank. Now check it has correct type. 00054 T* cast_bank = dynamic_cast<T*>(fEventDataList[ibank]); 00055 // Throw exception if cached bank is of different type. 00056 if(!cast_bank){ 00057 std::cout << "TMidasEvent::GetMidasBank: ERROR: you requested bank with name=" << name << std::endl 00058 << "A cached version of this bank (of type " << typeid(fEventDataList[ibank]).name() 00059 << ") already exists in event; cannot create bank class of new type " 00060 << typeid(T).name()<<std::endl; 00061 throw failed_midas_bank_cast(); 00062 } 00063 return cast_bank; 00064 } 00065 00066 } 00067 00068 void *ptr; 00069 int bklen,bktype; 00070 int status = GetMidasData().FindBank(name, &bklen, &bktype, &ptr); 00071 00072 /// If we couldn't find bank, return null. 00073 if(status == 0) return 0; 00074 00075 T *bank = new T(bklen,bktype,name, ptr); 00076 00077 // Cache a version of this bank... 00078 fEventDataList.push_back(bank); 00079 00080 return bank; 00081 00082 } 00083 00084 00085 /// Method to clean up the current events list of event data. 00086 /// Generally this will delete all the existing information, 00087 /// but this behaviour may be modified in some cases. 00088 void CleanupEvent(); 00089 00090 /// This is the ugly function where we de-reference to get pointer for a TMidasEvent (ugly!). 00091 /// In this case TDataContainer does not own the memory referenced by fMidasEventPointer. 00092 void SetMidasEventPointer(TMidasEvent& event); 00093 00094 private: 00095 00096 /// Pointer to the TMidasEvent; 00097 /// In some cases we own the memory referenced by pointer; other cases not 00098 TMidasEvent *fMidasEventPointer; 00099 00100 /// Do we own the memory pointed to by TMidasEvent pointer? 00101 bool fOwnMidasEventMemory; 00102 00103 00104 /// For the moment make empty assign operator 00105 TDataContainer& operator= (const TDataContainer &event); 00106 00107 /// This is the list of banks associated with this event. 00108 /// The event owns these banks and needs to take care of 00109 /// deleting them. 00110 std::vector<TGenericData*> fEventDataList; 00111 00112 00113 }; 00114 00115 00116 #endif