File indexing completed on 2024-04-06 12:10:36
0001 #include "DCCBlockPrototype.h"
0002 #include "DCCDataParser.h"
0003 #include "DCCDataMapper.h"
0004 #include "ECALParserBlockException.h"
0005
0006 #include <cstdio>
0007 #include <sstream>
0008
0009 DCCTBBlockPrototype::DCCTBBlockPrototype(DCCTBDataParser *parser,
0010 std::string name,
0011 const uint32_t *buffer,
0012 uint32_t numbBytes,
0013 uint32_t wordsToEndOfEvent,
0014 uint32_t wordEventOffset) {
0015 blockError_ = false;
0016 parser_ = parser;
0017 name_ = name;
0018 dataP_ = buffer;
0019 beginOfBuffer_ = buffer;
0020 blockSize_ = numbBytes;
0021 wordEventOffset_ = wordEventOffset;
0022 wordsToEndOfEvent_ = wordsToEndOfEvent;
0023
0024 wordCounter_ = 0;
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 }
0037
0038 void DCCTBBlockPrototype::parseData() {
0039 std::set<DCCTBDataField *, DCCTBDataFieldComparator>::iterator it;
0040
0041
0042
0043
0044
0045
0046
0047 for (it = mapperFields_->begin(); it != mapperFields_->end(); it++) {
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 try {
0059 uint32_t data = getDataWord((*it)->wordPosition(), (*it)->bitPosition(), (*it)->mask());
0060 dataFields_[(*it)->name()] = data;
0061
0062 } catch (ECALTBParserBlockException &e) {
0063 std::string localString;
0064
0065 localString += "\n ======================================================================\n";
0066 localString += std::string(" ") + name_ + std::string(" :: out of scope Error :: Unable to get data field : ") +
0067 (*it)->name();
0068 localString += "\n Word position inside block : " + parser_->getDecString((*it)->wordPosition());
0069 localString +=
0070 "\n Word position inside event : " + parser_->getDecString((*it)->wordPosition() + wordEventOffset_);
0071 localString += "\n Block Size [bytes] : " + parser_->getDecString(blockSize_);
0072 localString += "\n Action -> Stop parsing this block !";
0073 localString += "\n ======================================================================";
0074
0075 std::string error("\n Last decoded fields until error : ");
0076
0077 std::ostringstream a;
0078
0079 try {
0080 displayData(a);
0081 } catch (ECALTBParserBlockException &e) {
0082 }
0083
0084 std::string outputErrorString(a.str());
0085 error += outputErrorString;
0086
0087 errorString_ += localString + error;
0088
0089 blockError_ = true;
0090
0091 throw(ECALTBParserBlockException(errorString_));
0092 }
0093 }
0094
0095
0096
0097 }
0098
0099 uint32_t DCCTBBlockPrototype::getDataWord(uint32_t wordPosition, uint32_t bitPosition, uint32_t mask) {
0100
0101
0102
0103
0104
0105
0106 if (wordPosition > wordCounter_) {
0107 increment(wordPosition - wordCounter_);
0108 }
0109
0110 return ((*dataP_) >> bitPosition) & mask;
0111 }
0112
0113 void DCCTBBlockPrototype::increment(uint32_t numb, std::string msg) {
0114 seeIfIsPossibleToIncrement(numb, msg);
0115 dataP_ += numb;
0116 wordCounter_ += numb;
0117 }
0118
0119 void DCCTBBlockPrototype::seeIfIsPossibleToIncrement(uint32_t numb, std::string msg) {
0120
0121
0122
0123
0124
0125
0126
0127 if ((((wordCounter_ + numb + 1) > blockSize_ / 4)) || (wordCounter_ + numb > wordsToEndOfEvent_)) {
0128 std::string error = std::string("\n Unable to get next block position (parser stoped!)") + msg;
0129 error += "\n Decoded fields untill error : ";
0130
0131 std::ostringstream a;
0132 std::string outputErrorString;
0133
0134 try {
0135 displayData(a);
0136 } catch (ECALTBParserBlockException &e) {
0137 }
0138 outputErrorString = a.str();
0139 error += outputErrorString;
0140
0141 throw ECALTBParserBlockException(error);
0142 blockError_ = true;
0143 }
0144 }
0145
0146 void DCCTBBlockPrototype::displayData(std::ostream &os) {
0147 std::set<DCCTBDataField *, DCCTBDataFieldComparator>::iterator it;
0148
0149 bool process(true);
0150 os << "\n ======================================================================\n";
0151 os << " Block name : " << name_ << ", size : " << std::dec << blockSize_
0152 << " bytes, event WOffset : " << wordEventOffset_;
0153 long currentPosition(0), position(-1);
0154
0155 std::string dataFieldName;
0156 for (it = mapperFields_->begin(); it != mapperFields_->end() && process; it++) {
0157 try {
0158 dataFieldName = (*it)->name();
0159 currentPosition = (*it)->wordPosition();
0160 if (currentPosition != position) {
0161 os << "\n W[" << std::setw(5) << std::setfill('0') << currentPosition << "]";
0162 position = currentPosition;
0163 }
0164 os << " " << formatString(dataFieldName, 14) << " = " << std::dec << std::setw(5) << getDataField(dataFieldName);
0165 } catch (ECALTBParserBlockException &e) {
0166 process = false;
0167 os << " not able to get data field..." << dataFieldName << std::endl;
0168 }
0169 }
0170 os << "\n ======================================================================\n";
0171 }
0172
0173 std::pair<bool, std::string> DCCTBBlockPrototype::checkDataField(std::string name, uint32_t data) {
0174 std::string output("");
0175 std::pair<bool, std::string> res;
0176 bool errorFound(false);
0177 uint32_t parsedData = getDataField(name);
0178 if (parsedData != data) {
0179 output += std::string("\n Field : ") + name + (" has value ") + parser_->getDecString(parsedData) +
0180 std::string(", while ") + parser_->getDecString(data) + std::string(" is expected");
0181
0182
0183
0184
0185
0186 blockError_ = true;
0187 errorFound = true;
0188 }
0189 res.first = !errorFound;
0190 res.second = output;
0191 return res;
0192 }
0193
0194 uint32_t DCCTBBlockPrototype::getDataField(std::string name) {
0195 std::map<std::string, uint32_t>::iterator it = dataFields_.find(name);
0196 if (it == dataFields_.end()) {
0197 throw ECALTBParserBlockException(std::string("\n field named : ") + name + std::string(" was not found in block ") +
0198 name_);
0199 blockError_ = true;
0200 }
0201
0202 return (*it).second;
0203 }
0204
0205 std::string DCCTBBlockPrototype::formatString(std::string myString, uint32_t minPositions) {
0206 std::string ret(myString);
0207 uint32_t stringSize = ret.size();
0208 if (minPositions > stringSize) {
0209 for (uint32_t i = 0; i < minPositions - stringSize; i++) {
0210 ret += " ";
0211 }
0212 }
0213 return ret;
0214 }
0215
0216 void DCCTBBlockPrototype::setDataField(std::string name, uint32_t data) {
0217 std::set<DCCTBDataField *, DCCTBDataFieldComparator>::iterator it;
0218 bool fieldFound(false);
0219 for (it = mapperFields_->begin(); it != mapperFields_->end(); it++) {
0220 if (!((*it)->name()).compare(name)) {
0221 fieldFound = true;
0222 }
0223 }
0224
0225 if (fieldFound) {
0226 dataFields_[name] = data;
0227 } else {
0228 throw ECALTBParserBlockException(std::string("\n field named : ") + name + std::string(" was not found in block ") +
0229 name_);
0230 }
0231 }
0232
0233 std::pair<bool, std::string> DCCTBBlockPrototype::compare(DCCTBBlockPrototype *block) {
0234 std::pair<bool, std::string> ret(true, "");
0235
0236 std::set<DCCTBDataField *, DCCTBDataFieldComparator>::iterator it;
0237 std::stringstream out;
0238
0239 out << "\n ======================================================================";
0240 out << "\n ORIGINAL BLOCK : ";
0241 out << "\n Block name : " << name_ << ", size : " << std::dec << blockSize_
0242 << " bytes, event WOffset : " << wordEventOffset_;
0243 out << "\n COMPARISION BLOCK : ";
0244 out << "\n Block name : " << (block->name()) << ", size : " << std::dec << (block->size())
0245 << " bytes, event WOffset : " << (block->wOffset());
0246 out << "\n =====================================================================";
0247
0248 if (block->name() != name_) {
0249 ret.first = false;
0250 out << "\n ERROR >> It is not possible to compare blocks with different names ! ";
0251 ret.second += out.str();
0252 return ret;
0253 }
0254
0255 if (block->size() != blockSize_) {
0256 ret.first = false;
0257 out << "\n WARNING >> Blocks have different sizes "
0258 << "\n WARNING >> Comparision will be carried on untill possible";
0259 }
0260
0261 if (block->wOffset() != wordEventOffset_) {
0262 ret.first = false;
0263 out << "\n WARNING >> Blocks have different word offset within the event ";
0264 }
0265
0266 std::string dataFieldName;
0267
0268 for (it = mapperFields_->begin(); it != mapperFields_->end(); it++) {
0269 dataFieldName = (*it)->name();
0270
0271 uint32_t aValue, bValue;
0272
0273
0274 try {
0275 aValue = getDataField(dataFieldName);
0276 }
0277
0278 catch (ECALTBParserBlockException &e) {
0279 ret.first = false;
0280 out << "\n ERROR ON ORIGINAL BLOCK unable to get data field :" << dataFieldName;
0281 out << "\n Comparision was stoped ! ";
0282 ret.second += out.str();
0283 return ret;
0284 }
0285
0286
0287
0288 try {
0289 bValue = block->getDataField(dataFieldName);
0290 } catch (ECALTBParserBlockException &e) {
0291 ret.first = false;
0292 out << "\n ERROR ON COMPARISION BLOCK unable to get data field :" << dataFieldName
0293 << "\n Comparision was stoped ! ";
0294 ret.second += out.str();
0295 return ret;
0296 }
0297
0298
0299
0300
0301
0302
0303
0304 if (aValue != bValue) {
0305 ret.first = false;
0306 out << "\n Data Field : " << dataFieldName << "\n ORIGINAL BLOCK value : " << std::dec << std::setw(5) << aValue
0307 << " , COMPARISION BLOCK value : " << std::dec << std::setw(5) << bValue;
0308
0309 }
0310 }
0311 out << "\n ======================================================================\n";
0312 ret.second = out.str();
0313
0314 return ret;
0315 }