00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "PSEvt/Source.h"
00017
00018
00019
00020
00021 #include <vector>
00022 #include <cassert>
00023 #include <map>
00024 #include <iostream>
00025 #include <boost/algorithm/string/trim.hpp>
00026 #include <boost/algorithm/string/split.hpp>
00027 #include <boost/algorithm/string/predicate.hpp>
00028 #include <boost/lexical_cast.hpp>
00029
00030
00031
00032
00033 #include "MsgLogger/MsgLogger.h"
00034 #include "PSEvt/Exceptions.h"
00035 #include "PSEvt/EventKey.h"
00036
00037
00038
00039
00040
00041 namespace {
00042
00043 const char* logger = "PSEvt::Source";
00044
00045
00046 Pds::Src parse(std::string spec);
00047
00048 std::map<std::string, Pds::DetInfo::Detector> initName2Det();
00049 const std::map<std::string, Pds::DetInfo::Detector> name2det = initName2Det();
00050
00051 std::map<std::string, Pds::DetInfo::Device> initName2Dev();
00052 const std::map<std::string, Pds::DetInfo::Device> name2dev = initName2Dev();
00053
00054 }
00055
00056
00057
00058
00059
00060 namespace PSEvt {
00061
00062
00063
00064
00065
00066
00067 Source::Source ()
00068 : m_src(Pds::Level::NumberOfLevels)
00069 , m_str()
00070 {
00071 }
00072
00073 Source::Source (const Pds::Src& src)
00074 : m_src(src)
00075 , m_str()
00076 {
00077 }
00078
00079
00080
00081
00082
00083
00084 Source::Source(Pds::DetInfo::Detector det, uint32_t detId, Pds::DetInfo::Device dev, uint32_t devId)
00085 : m_src(Pds::DetInfo(0, det, detId, dev, devId))
00086 , m_str()
00087 {
00088 }
00089
00090
00091
00092
00093
00094
00095 Source::Source(Pds::BldInfo::Type type)
00096 : m_src(Pds::BldInfo(0, type))
00097 , m_str()
00098 {
00099 }
00100
00101 Source::Source (const std::string& spec)
00102 : m_src(Pds::Src(Pds::Level::NumberOfLevels))
00103 , m_str(spec)
00104 {
00105 }
00106
00107 Source&
00108 Source::operator=(const std::string& spec)
00109 {
00110 m_src = Pds::Src();
00111 m_str = spec;
00112 return *this;
00113 }
00114
00115
00116
00117
00118 bool
00119 Source::SrcMatch::match(const Pds::Src& src) const
00120 {
00121 if (m_src == Pds::Src()) {
00122
00123
00124 return src == Pds::Src();
00125
00126 } else if (m_src.level() == Pds::Level::NumberOfLevels) {
00127
00128
00129 return true;
00130
00131 } else if (int(src.level()) > Pds::Level::NumberOfLevels) {
00132
00133
00134 return false;
00135
00136 } else if (m_src.level() == Pds::Level::Source) {
00137
00138
00139 if (src.level() != Pds::Level::Source) return false;
00140
00141 const Pds::DetInfo& minfo = static_cast<const Pds::DetInfo&>(m_src);
00142 const Pds::DetInfo& info = static_cast<const Pds::DetInfo&>(src);
00143
00144 if (int(minfo.detector()) != 255 and minfo.detector() != info.detector()) return false;
00145 if (int(minfo.device()) != 255 and minfo.device() != info.device()) return false;
00146 if (minfo.detId() != 255 and minfo.detId() != info.detId()) return false;
00147 if (minfo.devId() != 255 and minfo.devId() != info.devId()) return false;
00148 return true;
00149
00150 } else if (m_src.level() == Pds::Level::Reporter) {
00151
00152
00153 if (src.level() != Pds::Level::Reporter) return false;
00154
00155 const Pds::BldInfo& minfo = static_cast<const Pds::BldInfo&>(m_src);
00156 const Pds::BldInfo& info = static_cast<const Pds::BldInfo&>(src);
00157
00158 if (uint32_t(minfo.type()) != 0xffffffff and minfo.type() != info.type()) return false;
00159 return true;
00160
00161 } else {
00162
00163
00164 if (src.level() == Pds::Level::Source) return false;
00165 if (src.level() == Pds::Level::Reporter) return false;
00166
00167 const Pds::ProcInfo& minfo = static_cast<const Pds::ProcInfo&>(m_src);
00168 const Pds::ProcInfo& info = static_cast<const Pds::ProcInfo&>(src);
00169
00170 if (minfo.ipAddr() != 0xffffffff and minfo.ipAddr() != info.ipAddr()) return false;
00171 return true;
00172
00173 }
00174
00175 }
00176
00177
00178
00179 bool
00180 Source::SrcMatch::in(const SrcMatch& other) const
00181 {
00182
00183 if (other.src().level() == Pds::Level::NumberOfLevels) return true;
00184
00185 if (m_src == Pds::Src()) {
00186
00187
00188 return other.src() == Pds::Src();
00189
00190 } else if (m_src.level() == Pds::Level::NumberOfLevels) {
00191
00192
00193 return false;
00194
00195 } else if (int(other.src().level()) > Pds::Level::NumberOfLevels) {
00196
00197
00198 return false;
00199
00200 } else if (m_src.level() == Pds::Level::Source) {
00201
00202
00203 if (other.src().level() != Pds::Level::Source) return false;
00204
00205 const Pds::DetInfo& this_info = static_cast<const Pds::DetInfo&>(m_src);
00206 const Pds::DetInfo& other_info = static_cast<const Pds::DetInfo&>(other.src());
00207
00208 if (int(other_info.detector()) != 255 and this_info.detector() != other_info.detector()) return false;
00209 if (int(other_info.device()) != 255 and this_info.device() != other_info.device()) return false;
00210 if (other_info.detId() != 255 and this_info.detId() != other_info.detId()) return false;
00211 if (other_info.devId() != 255 and this_info.devId() != other_info.devId()) return false;
00212 return true;
00213
00214 } else if (m_src.level() == Pds::Level::Reporter) {
00215
00216
00217 if (other.src().level() != Pds::Level::Reporter) return false;
00218
00219 const Pds::BldInfo& this_info = static_cast<const Pds::BldInfo&>(m_src);
00220 const Pds::BldInfo& other_info = static_cast<const Pds::BldInfo&>(other.src());
00221
00222 if (uint32_t(other_info.type()) != 0xffffffff and this_info.type() != other_info.type()) return false;
00223 return true;
00224
00225 } else {
00226
00227
00228 if (other.src().level() == Pds::Level::Source) return false;
00229 if (other.src().level() == Pds::Level::Reporter) return false;
00230
00231 const Pds::ProcInfo& this_info = static_cast<const Pds::ProcInfo&>(m_src);
00232 const Pds::ProcInfo& other_info = static_cast<const Pds::ProcInfo&>(other.src());
00233
00234 if (other_info.ipAddr() != 0xffffffff and this_info.ipAddr() != other_info.ipAddr()) return false;
00235 return true;
00236
00237 }
00238
00239 }
00240
00241
00242 bool
00243 Source::SrcMatch::isExact() const
00244 {
00245 if (m_src.level() == Pds::Level::NumberOfLevels) {
00246
00247 return false;
00248 }
00249
00250 if (m_src == Pds::Src()) {
00251
00252 return true;
00253 }
00254
00255 if (m_src.level() == Pds::Level::Source) {
00256
00257 const Pds::DetInfo& info = static_cast<const Pds::DetInfo&>(m_src);
00258 return info.detector() != 255 and info.device() != 255 and
00259 info.detId() != 255 and info.devId() != 255;
00260
00261 } else if (m_src.level() == Pds::Level::Reporter) {
00262
00263 const Pds::BldInfo& info = static_cast<const Pds::BldInfo&>(m_src);
00264 return uint32_t(info.type()) != 0xffffffff;
00265
00266 } else {
00267
00268 const Pds::ProcInfo& info = static_cast<const Pds::ProcInfo&>(m_src);
00269 return info.ipAddr() != 0xffffffff;
00270
00271 }
00272
00273 }
00274
00275
00276 Source::SrcMatch
00277 Source::srcMatch(const AliasMap& amap) const
00278 {
00279 Pds::Src src = m_src;
00280 if (not m_str.empty()) {
00281
00282 src = amap.src(m_str);
00283 if (src == Pds::Src()) {
00284
00285 src = ::parse(m_str);
00286 }
00287 }
00288 return Source::SrcMatch(src);
00289 }
00290
00291
00292 void
00293 Source::print(std::ostream& out) const
00294 {
00295 if (not m_str.empty()) {
00296 out << m_str;
00297 } else {
00298 out << m_src;
00299 }
00300 }
00301
00302 }
00303
00304
00305 namespace {
00306
00307
00308
00309 std::string
00310 stripType(const std::string& spec, int typeLen)
00311 {
00312 std::string sspec(spec, typeLen);
00313 boost::algorithm::trim(sspec);
00314
00315 if (sspec.empty()) throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00316 if (sspec[0] != '(') throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00317
00318 std::string::size_type p2 = sspec.rfind(')');
00319 if (p2 == std::string::npos) {
00320 throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00321 }
00322
00323
00324 sspec.erase(p2);
00325
00326 sspec.erase(0, 1);
00327
00328
00329 boost::algorithm::trim(sspec);
00330 return sspec;
00331 }
00332
00333
00334
00335 bool parseBldInfo(std::string spec, Pds::Src *src)
00336 {
00337 MsgLog(logger, debug, "Source::parseBldInfo: spec = '" << spec << "'");
00338
00339 if (spec.empty()) {
00340 *src = Pds::BldInfo(0, Pds::BldInfo::Type(0xffffffff));
00341 return true;
00342 }
00343
00344
00345 for (int i = 0; i < Pds::BldInfo::NumberOf; ++ i) {
00346 Pds::BldInfo info(0, Pds::BldInfo::Type(i));
00347 if (spec == Pds::BldInfo::name(info)) {
00348 *src = info;
00349 return true;
00350 }
00351 }
00352
00353 return false;
00354 }
00355
00356
00357
00358 std::pair<std::string, unsigned> splitDetId(const std::string& spec, char sep)
00359 {
00360 std::pair<std::string, unsigned> res(std::string(), 255);
00361 std::string::size_type p1 = spec.find(sep);
00362 if(p1 == std::string::npos) {
00363 res.first = spec;
00364 } else {
00365 res.first = std::string(spec, 0, p1);
00366 std::string idStr = std::string(spec, p1+1);
00367 if (not (idStr.empty() or idStr == "*")) {
00368 res.second = boost::lexical_cast<unsigned>(idStr);
00369 }
00370 }
00371 if (res.first == "*") res.first.clear();
00372 return res;
00373 }
00374
00375
00376
00377 bool parseDetInfo(const std::string& spec, Pds::Src *src, char sep1, char sep2)
00378 {
00379
00380 assert(not spec.empty());
00381
00382 std::string detSpec;
00383 std::string devSpec;
00384 std::string::size_type p1 = spec.find(sep1);
00385 if(p1 == std::string::npos) {
00386 detSpec = spec;
00387 } else {
00388 detSpec = std::string(spec, 0, p1);
00389 devSpec = std::string(spec, p1+1);
00390 }
00391
00392 std::pair<std::string, unsigned> detPair;
00393 std::pair<std::string, unsigned> devPair;
00394 try {
00395 detPair = splitDetId(detSpec, sep2);
00396 devPair = splitDetId(devSpec, sep2);
00397 } catch (const boost::bad_lexical_cast& ex) {
00398 return false;
00399 }
00400
00401 Pds::DetInfo::Detector det = Pds::DetInfo::Detector(255);
00402 Pds::DetInfo::Device dev = Pds::DetInfo::Device(255);
00403 if (not detPair.first.empty()) {
00404 std::map<std::string, Pds::DetInfo::Detector>::const_iterator it = ::name2det.find(detPair.first);
00405 if (it != ::name2det.end()) {
00406 det = it->second;
00407 }
00408 if (det == 255) return false;
00409 }
00410 if (not devPair.first.empty()) {
00411 std::map<std::string, Pds::DetInfo::Device>::const_iterator it = ::name2dev.find(devPair.first);
00412 if (it != ::name2dev.end()) {
00413 dev = it->second;
00414 }
00415 if (dev == 255) return false;
00416 }
00417
00418 *src = Pds::DetInfo(0, det, detPair.second, dev, devPair.second);
00419 return true;
00420 }
00421
00422
00423
00424 bool parseDetInfo(std::string spec, Pds::Src *src)
00425 {
00426 MsgLog(logger, debug, "Source::parseDetInfo: spec = '" << spec << "'");
00427
00428 if (spec.empty()) {
00429 *src = Pds::DetInfo(0, Pds::DetInfo::Detector(0xff), 0xff, Pds::DetInfo::Device(0xff), 0xff);
00430 return true;
00431 }
00432
00433 if (parseDetInfo(spec, src, ':', '.')) return true;
00434 if (parseDetInfo(spec, src, '|', '-')) return true;
00435 return false;
00436 }
00437
00438
00439
00440 bool parseProcInfo(std::string spec, Pds::Src *src)
00441 {
00442 MsgLog(logger, debug, "Source::parseProcInfo: spec = '" << spec << "'");
00443
00444 if (spec.empty()) {
00445
00446 *src = Pds::ProcInfo(Pds::Level::Segment, 0, 0xffffffff);
00447 return true;
00448 }
00449
00450 std::vector<std::string> octets;
00451 boost::algorithm::split(octets, spec, boost::is_any_of("."));
00452 if (octets.size() != 4) return false;
00453
00454 uint32_t ip;
00455 try {
00456
00457 unsigned oct0 = boost::lexical_cast<unsigned>(octets[0]);
00458 unsigned oct1 = boost::lexical_cast<unsigned>(octets[1]);
00459 unsigned oct2 = boost::lexical_cast<unsigned>(octets[2]);
00460 unsigned oct3 = boost::lexical_cast<unsigned>(octets[3]);
00461 if (oct0 > 255 or oct1 > 255 or oct2 > 255 or oct3 > 255) return false;
00462 ip = (oct0 << 24) | (oct1 << 16) | (oct2 << 8) | oct3;
00463
00464 } catch (const boost::bad_lexical_cast& ex) {
00465 return false;
00466 }
00467
00468
00469 *src = Pds::ProcInfo(Pds::Level::Segment, 0, ip);
00470 return true;
00471 }
00472
00473
00474
00475 Pds::Src
00476 parse(std::string spec)
00477 {
00478
00479 boost::algorithm::trim(spec);
00480
00481 MsgLog(logger, debug, "Source::parse: spec = '" << spec << "'");
00482
00483
00484 if (spec.empty()) return Pds::Src(Pds::Level::NumberOfLevels);
00485
00486 if (boost::algorithm::starts_with(spec, "DetInfo")) {
00487
00488 Pds::Src src;
00489 if (not parseDetInfo(stripType(spec, 7), &src)) {
00490 throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00491 }
00492 return src;
00493
00494 } else if (boost::algorithm::starts_with(spec, "BldInfo")) {
00495
00496 Pds::Src src;
00497 if (not parseBldInfo(stripType(spec, 7), &src)) {
00498 throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00499 }
00500 return src;
00501
00502 } else if (boost::algorithm::starts_with(spec, "ProcInfo")) {
00503
00504 Pds::Src src;
00505 if (not parseProcInfo(stripType(spec, 8), &src)) {
00506 throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00507 }
00508 return src;
00509
00510 } else {
00511
00512 Pds::Src src;
00513 if (parseBldInfo(spec, &src)) return src;
00514 if (parseDetInfo(spec, &src)) return src;
00515 throw PSEvt::ExceptionSourceFormat(ERR_LOC, spec);
00516
00517 }
00518 }
00519
00520 std::map<std::string, Pds::DetInfo::Detector>
00521 initName2Det()
00522 {
00523 std::map<std::string, Pds::DetInfo::Detector> name2det;
00524
00525
00526 for(int i = 0; i < Pds::DetInfo::NumDetector; ++ i) {
00527 name2det[Pds::DetInfo::name(Pds::DetInfo::Detector(i))] = Pds::DetInfo::Detector(i);
00528 }
00529
00530
00531 name2det["AmoIms"] = Pds::DetInfo::AmoIms;
00532 name2det["amoIMS"] = Pds::DetInfo::AmoIms;
00533 name2det["AmoPem"] = Pds::DetInfo::AmoGasdet;
00534 name2det["amoGD"] = Pds::DetInfo::AmoGasdet;
00535 name2det["AmoGasdet"] = Pds::DetInfo::AmoGasdet;
00536 name2det["AmoETof"] = Pds::DetInfo::AmoETof;
00537 name2det["amoETOF"] = Pds::DetInfo::AmoETof;
00538 name2det["AmoITof"] = Pds::DetInfo::AmoITof;
00539 name2det["amoITOF"] = Pds::DetInfo::AmoITof;
00540 name2det["AmoMbs"] = Pds::DetInfo::AmoMbes;
00541 name2det["amoMBES"] = Pds::DetInfo::AmoMbes;
00542 name2det["AmoMbes"] = Pds::DetInfo::AmoMbes;
00543 name2det["AmoIis"] = Pds::DetInfo::AmoVmi;
00544 name2det["amoVMI"] = Pds::DetInfo::AmoVmi;
00545 name2det["AmoVMI"] = Pds::DetInfo::AmoVmi;
00546 name2det["AmoVmi"] = Pds::DetInfo::AmoVmi;
00547 name2det["AmoBps"] = Pds::DetInfo::AmoBps;
00548 name2det["amoBPS"] = Pds::DetInfo::AmoBps;
00549 name2det["epicsArch"] = Pds::DetInfo::EpicsArch;
00550
00551 return name2det;
00552 }
00553
00554 std::map<std::string, Pds::DetInfo::Device>
00555 initName2Dev()
00556 {
00557 std::map<std::string, Pds::DetInfo::Device> name2dev;
00558
00559
00560 for(int i = 0; i < Pds::DetInfo::NumDevice; ++ i) {
00561 name2dev[Pds::DetInfo::name(Pds::DetInfo::Device(i))] = Pds::DetInfo::Device(i);
00562 }
00563
00564
00565 name2dev["TM6740"] = Pds::DetInfo::TM6740;
00566
00567 return name2dev;
00568 }
00569
00570 }