00001 // $Id: InitMsgData.cc,v 1.8 2011/03/07 15:31:32 mommsen Exp $ 00003 00004 #include "EventFilter/StorageManager/src/ChainData.h" 00005 00006 #include "IOPool/Streamer/interface/InitMessage.h" 00007 00008 namespace stor 00009 { 00010 00011 namespace detail 00012 { 00013 00014 InitMsgData::InitMsgData(toolbox::mem::Reference* pRef) : 00015 ChainData(I2O_SM_PREAMBLE, Header::INIT), 00016 headerFieldsCached_(false) 00017 { 00018 addFirstFragment(pRef); 00019 parseI2OHeader(); 00020 } 00021 00022 inline size_t InitMsgData::do_i2oFrameSize() const 00023 { 00024 return sizeof(I2O_SM_PREAMBLE_MESSAGE_FRAME); 00025 } 00026 00027 unsigned long InitMsgData::do_headerSize() const 00028 { 00029 if ( !headerOkay() ) 00030 { 00031 return 0; 00032 } 00033 00034 if (! headerFieldsCached_) {cacheHeaderFields();} 00035 return headerSize_; 00036 } 00037 00038 unsigned char* InitMsgData::do_headerLocation() const 00039 { 00040 if ( !headerOkay() ) 00041 { 00042 return 0; 00043 } 00044 00045 if (! headerFieldsCached_) {cacheHeaderFields();} 00046 return headerLocation_; 00047 } 00048 00049 inline unsigned char* 00050 InitMsgData::do_fragmentLocation(unsigned char* dataLoc) const 00051 { 00052 if ( parsable() ) 00053 { 00054 I2O_SM_PREAMBLE_MESSAGE_FRAME *smMsg = 00055 (I2O_SM_PREAMBLE_MESSAGE_FRAME*) dataLoc; 00056 return (unsigned char*) smMsg->dataPtr(); 00057 } 00058 else 00059 { 00060 return dataLoc; 00061 } 00062 } 00063 00064 uint32_t InitMsgData::do_adler32Checksum() const 00065 { 00066 if ( !headerOkay() ) 00067 { 00068 std::stringstream msg; 00069 msg << "An adler32 checksum can not be determined from a "; 00070 msg << "faulty or incomplete INIT message."; 00071 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00072 } 00073 00074 if (! headerFieldsCached_) {cacheHeaderFields();} 00075 return adler32_; 00076 } 00077 00078 uint32_t InitMsgData::do_outputModuleId() const 00079 { 00080 if ( !headerOkay() ) 00081 { 00082 std::stringstream msg; 00083 msg << "An output module ID can not be determined from a "; 00084 msg << "faulty or incomplete INIT message."; 00085 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00086 } 00087 00088 if (! headerFieldsCached_) {cacheHeaderFields();} 00089 return outputModuleId_; 00090 } 00091 00092 std::string InitMsgData::do_outputModuleLabel() const 00093 { 00094 if ( !headerOkay() ) 00095 { 00096 std::stringstream msg; 00097 msg << "An output module label can not be determined from a "; 00098 msg << "faulty or incomplete INIT message."; 00099 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00100 } 00101 00102 if (! headerFieldsCached_) {cacheHeaderFields();} 00103 return outputModuleLabel_; 00104 } 00105 00106 void InitMsgData::do_hltTriggerNames(Strings& nameList) const 00107 { 00108 if ( !headerOkay() ) 00109 { 00110 std::stringstream msg; 00111 msg << "The HLT trigger names can not be determined from a "; 00112 msg << "faulty or incomplete INIT message."; 00113 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00114 } 00115 00116 if (! headerFieldsCached_) {cacheHeaderFields();} 00117 nameList = hltTriggerNames_; 00118 } 00119 00120 void InitMsgData::do_hltTriggerSelections(Strings& nameList) const 00121 { 00122 if ( !headerOkay() ) 00123 { 00124 std::stringstream msg; 00125 msg << "The HLT trigger selections can not be determined from a "; 00126 msg << "faulty or incomplete INIT message."; 00127 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00128 } 00129 00130 if (! headerFieldsCached_) {cacheHeaderFields();} 00131 nameList = hltTriggerSelections_; 00132 } 00133 00134 void InitMsgData::do_l1TriggerNames(Strings& nameList) const 00135 { 00136 if ( !headerOkay() ) 00137 { 00138 std::stringstream msg; 00139 msg << "The L1 trigger names can not be determined from a "; 00140 msg << "faulty or incomplete INIT message."; 00141 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00142 } 00143 00144 if (! headerFieldsCached_) {cacheHeaderFields();} 00145 nameList = l1TriggerNames_; 00146 } 00147 00148 inline void InitMsgData::parseI2OHeader() 00149 { 00150 if ( parsable() ) 00151 { 00152 I2O_SM_PREAMBLE_MESSAGE_FRAME *smMsg = 00153 (I2O_SM_PREAMBLE_MESSAGE_FRAME*) ref_->getDataLocation(); 00154 fragKey_.code_ = messageCode_; 00155 fragKey_.run_ = 0; 00156 fragKey_.event_ = smMsg->hltTid; 00157 fragKey_.secondaryId_ = smMsg->outModID; 00158 fragKey_.originatorPid_ = smMsg->fuProcID; 00159 fragKey_.originatorGuid_ = smMsg->fuGUID; 00160 rbBufferId_ = smMsg->rbBufferID; 00161 hltLocalId_ = smMsg->hltLocalId; 00162 hltInstance_ = smMsg->hltInstance; 00163 hltTid_ = smMsg->hltTid; 00164 fuProcessId_ = smMsg->fuProcID; 00165 fuGuid_ = smMsg->fuGUID; 00166 } 00167 } 00168 00169 void InitMsgData::cacheHeaderFields() const 00170 { 00171 unsigned char* firstFragLoc = dataLocation(0); 00172 unsigned long firstFragSize = dataSize(0); 00173 bool useFirstFrag = false; 00174 00175 // if there is only one fragment, use it 00176 if (fragmentCount_ == 1) 00177 { 00178 useFirstFrag = true; 00179 } 00180 // otherwise, check if the first fragment is large enough to hold 00181 // the full INIT message header (we require some minimal fixed 00182 // size in the hope that we don't parse garbage when we overlay 00183 // the InitMsgView on the buffer) 00184 else if (firstFragSize > (sizeof(InitHeader) + 16384)) 00185 { 00186 InitMsgView view(firstFragLoc); 00187 if (view.headerSize() <= firstFragSize) 00188 { 00189 useFirstFrag = true; 00190 } 00191 } 00192 00193 boost::shared_ptr<InitMsgView> msgView; 00194 if (useFirstFrag) 00195 { 00196 msgView.reset(new InitMsgView(firstFragLoc)); 00197 } 00198 else 00199 { 00200 copyFragmentsIntoBuffer(headerCopy_); 00201 msgView.reset(new InitMsgView(&headerCopy_[0])); 00202 } 00203 00204 headerSize_ = msgView->headerSize(); 00205 headerLocation_ = msgView->startAddress(); 00206 adler32_ = msgView->adler32_chksum(); 00207 outputModuleId_ = msgView->outputModuleId(); 00208 outputModuleLabel_ = msgView->outputModuleLabel(); 00209 msgView->hltTriggerNames(hltTriggerNames_); 00210 msgView->hltTriggerSelections(hltTriggerSelections_); 00211 msgView->l1TriggerNames(l1TriggerNames_); 00212 00213 headerFieldsCached_ = true; 00214 00215 #ifdef STOR_DEBUG_WRONG_ADLER 00216 double r = rand()/static_cast<double>(RAND_MAX); 00217 if (r < 0.01) 00218 { 00219 std::cout << "Simulating corrupt Adler calculation" << std::endl; 00220 headerSize_ += 3; 00221 } 00222 else if (r < 0.02) 00223 { 00224 std::cout << "Simulating corrupt Adler entry" << std::endl; 00225 adler32_ += r*10000; 00226 } 00227 #endif // STOR_DEBUG_WRONG_ADLER 00228 } 00229 00230 } // namespace detail 00231 00232 } // namespace stor 00233 00234