Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:57

0001 // ----------------------------------------------------------------------
0002 // definition of type encoding/decoding functions
0003 // ----------------------------------------------------------------------
0004 
0005 // ----------------------------------------------------------------------
0006 // prerequisite source files and headers
0007 // ----------------------------------------------------------------------
0008 
0009 #include "FWCore/ParameterSet/interface/types.h"
0010 
0011 #include "FWCore/ParameterSet/src/split.h"
0012 #include "FWCore/Utilities/interface/Parse.h"
0013 #include <cctype>
0014 #include <cstdlib>
0015 #include <limits>
0016 #include <sstream>
0017 #include <stdexcept>
0018 #include <cassert>
0019 #include <optional>
0020 
0021 using namespace edm;
0022 
0023 // ----------------------------------------------------------------------
0024 // utility functions
0025 // ----------------------------------------------------------------------
0026 
0027 static char to_hex(unsigned int i) { return i + (i < 10u ? '0' : ('A' - 10)); }
0028 
0029 // ----------------------------------------------------------------------
0030 
0031 static unsigned int from_hex(char c) {
0032   switch (c) {
0033     case '0':
0034     case '1':
0035     case '2':
0036     case '3':
0037     case '4':
0038     case '5':
0039     case '6':
0040     case '7':
0041     case '8':
0042     case '9':
0043       return c - '0';
0044     case 'a':
0045     case 'b':
0046     case 'c':
0047     case 'd':
0048     case 'e':
0049     case 'f':
0050       return 10 + c - 'a';
0051     case 'A':
0052     case 'B':
0053     case 'C':
0054     case 'D':
0055     case 'E':
0056     case 'F':
0057       return 10 + c - 'A';
0058     default:
0059       return 0;
0060   }
0061 }  // from_hex()
0062 
0063 static void append_hex_rep(std::string& s, unsigned int c) {
0064   s += to_hex(c / 16u);
0065   s += to_hex(c % 16u);
0066 }  // append_hex_rep()
0067 
0068 // ----------------------------------------------------------------------
0069 // Bool
0070 // ----------------------------------------------------------------------
0071 
0072 bool edm::decode(bool& to, std::string_view from) {
0073   if (from == "true") {
0074     to = true;
0075     return true;
0076   } else if (from == "false") {
0077     to = false;
0078     return true;
0079   } else {
0080     return false;
0081   }
0082 }  // decode to bool
0083 
0084 // ----------------------------------------------------------------------
0085 
0086 bool edm::encode(std::string& to, bool from) {
0087   to = from ? "true" : "false";
0088   return true;
0089 }  // encode from bool
0090 
0091 // ----------------------------------------------------------------------
0092 // vBool
0093 // ----------------------------------------------------------------------
0094 
0095 bool edm::decode(std::vector<bool>& to, std::string_view from) {
0096   to.clear();
0097   to.reserve(std::count(from.begin(), from.end(), ','));
0098   return split(from, '{', ',', '}', [&to](auto t) {
0099     bool val = false;
0100     if (!decode(val, t)) {
0101       return false;
0102     }
0103     to.push_back(val);
0104     return true;
0105   });
0106 }  // decode to vector<bool>
0107 
0108 // ----------------------------------------------------------------------
0109 
0110 bool edm::encode(std::string& to, std::vector<bool> const& from) {
0111   to = "{";
0112 
0113   std::string converted;
0114   for (std::vector<bool>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
0115     if (!encode(converted, *b)) {
0116       return false;
0117     }
0118     if (b != from.begin()) {
0119       to += ",";
0120     }
0121     to += converted;
0122   }
0123   to += '}';
0124   return true;
0125 }  // encode from vector<bool>
0126 
0127 // ----------------------------------------------------------------------
0128 // Int32
0129 // ----------------------------------------------------------------------
0130 
0131 bool edm::decode(int& to, std::string_view from) {
0132   std::string_view::const_iterator b = from.begin(), e = from.end();
0133 
0134   if (*b != '+' && *b != '-') {
0135     return false;
0136   }
0137   int sign = (*b == '+') ? +1 : -1;
0138 
0139   to = 0;
0140   while (++b != e) {
0141     if (!std::isdigit(*b)) {
0142       return false;
0143     }
0144     to = 10 * to + (*b - '0');
0145   }
0146   to *= sign;
0147 
0148   return true;
0149 }  // decode to int
0150 
0151 // ----------------------------------------------------------------------
0152 
0153 bool edm::encode(std::string& to, int from) {
0154   bool is_negative = (from < 0);
0155   if (is_negative) {
0156     from = -from;  // TODO: work around this for most negative integer
0157   }
0158   to.clear();
0159   do {
0160     to = static_cast<char>(from % 10 + '0') + to;
0161     from /= 10;
0162   } while (from > 0);
0163   to = (is_negative ? '-' : '+') + to;
0164 
0165   return true;
0166 }  // encode from int
0167 
0168 // ----------------------------------------------------------------------
0169 // Int64
0170 // ----------------------------------------------------------------------
0171 
0172 bool edm::decode(long long& to, std::string_view from) {
0173   std::string_view::const_iterator b = from.begin(), e = from.end();
0174 
0175   if (*b != '+' && *b != '-') {
0176     return false;
0177   }
0178   int sign = (*b == '+') ? +1 : -1;
0179 
0180   to = 0;
0181   while (++b != e) {
0182     if (!std::isdigit(*b)) {
0183       return false;
0184     }
0185     to = 10 * to + (*b - '0');
0186   }
0187   to *= sign;
0188 
0189   return true;
0190 }  // decode to int
0191 
0192 // ----------------------------------------------------------------------
0193 
0194 bool edm::encode(std::string& to, long long from) {
0195   bool is_negative = (from < 0);
0196   if (is_negative) {
0197     from = -from;  // TODO: work around this for most negative integer
0198   }
0199 
0200   to.clear();
0201   do {
0202     to = static_cast<char>(from % 10 + '0') + to;
0203     from /= 10;
0204   } while (from > 0);
0205   to = (is_negative ? '-' : '+') + to;
0206 
0207   return true;
0208 }  // encode from int
0209 
0210 // ----------------------------------------------------------------------
0211 // vInt32
0212 // ----------------------------------------------------------------------
0213 
0214 bool edm::decode(std::vector<int>& to, std::string_view from) {
0215   to.clear();
0216   to.reserve(std::count(from.begin(), from.end(), ','));
0217   return split(from, '{', ',', '}', [&to](auto t) {
0218     int val = 0;
0219     if (!decode(val, t)) {
0220       return false;
0221     }
0222     to.push_back(val);
0223     return true;
0224   });
0225 }  // decode to vector<int>
0226 
0227 // ----------------------------------------------------------------------
0228 
0229 bool edm::encode(std::string& to, std::vector<int> const& from) {
0230   to = "{";
0231 
0232   std::string converted;
0233   for (std::vector<int>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
0234     if (!encode(converted, *b)) {
0235       return false;
0236     }
0237 
0238     if (b != from.begin()) {
0239       to += ",";
0240     }
0241     to += converted;
0242   }
0243 
0244   to += '}';
0245   return true;
0246 }  // encode from vector<int>
0247 
0248 // ----------------------------------------------------------------------
0249 // vInt64
0250 // ----------------------------------------------------------------------
0251 
0252 bool edm::decode(std::vector<long long>& to, std::string_view from) {
0253   std::vector<std::string_view> temp;
0254   if (!split(std::back_inserter(temp), from, '{', ',', '}')) {
0255     return false;
0256   }
0257 
0258   to.clear();
0259   for (auto t : temp) {
0260     long long val = 0LL;
0261     if (!decode(val, t)) {
0262       return false;
0263     }
0264     to.push_back(val);
0265   }
0266 
0267   return true;
0268 }  // decode to vector<int>
0269 
0270 // ----------------------------------------------------------------------
0271 
0272 bool edm::encode(std::string& to, std::vector<long long> const& from) {
0273   to = "{";
0274 
0275   std::string converted;
0276   for (std::vector<long long>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
0277     if (!encode(converted, *b)) {
0278       return false;
0279     }
0280     if (b != from.begin()) {
0281       to += ",";
0282     }
0283     to += converted;
0284   }
0285   to += '}';
0286   return true;
0287 }  // encode from vector<int>
0288 
0289 // ----------------------------------------------------------------------
0290 // Uint32
0291 // ----------------------------------------------------------------------
0292 
0293 bool edm::decode(unsigned int& to, std::string_view from) {
0294   std::string_view::const_iterator b = from.begin(), e = from.end();
0295 
0296   to = 0u;
0297   for (; b != e; ++b) {
0298     if (*b == 'u' || *b == 'U') {
0299       return true;
0300     }
0301     if (!std::isdigit(*b)) {
0302       return false;
0303     }
0304     to = 10u * to + (*b - '0');
0305   }
0306   return true;
0307 }  // decode to unsigned
0308 
0309 // ----------------------------------------------------------------------
0310 
0311 bool edm::encode(std::string& to, unsigned int from) {
0312   to.clear();
0313   do {
0314     to = static_cast<char>(from % 10 + '0') + to;
0315     from /= 10u;
0316   } while (from > 0u);
0317 
0318   return true;
0319 }  // encode from unsigned
0320 
0321 // ----------------------------------------------------------------------
0322 // Uint64
0323 // ----------------------------------------------------------------------
0324 
0325 bool edm::decode(unsigned long long& to, std::string_view from) {
0326   std::string_view::const_iterator b = from.begin(), e = from.end();
0327   to = 0u;
0328   for (; b != e; ++b) {
0329     if (*b == 'u' || *b == 'U') {
0330       return true;
0331     }
0332     if (!std::isdigit(*b)) {
0333       return false;
0334     }
0335     to = 10u * to + (*b - '0');
0336   }
0337   return true;
0338 }  // decode to unsigned
0339 
0340 // ----------------------------------------------------------------------
0341 
0342 bool edm::encode(std::string& to, unsigned long long from) {
0343   to.clear();
0344   do {
0345     to = static_cast<char>(from % 10 + '0') + to;
0346     from /= 10u;
0347   } while (from > 0u);
0348 
0349   return true;
0350 }  // encode from unsigned
0351 
0352 // ----------------------------------------------------------------------
0353 // vUint32
0354 // ----------------------------------------------------------------------
0355 
0356 bool edm::decode(std::vector<unsigned int>& to, std::string_view from) {
0357   to.clear();
0358   to.reserve(std::count(from.begin(), from.end(), ','));
0359   return split(from, '{', ',', '}', [&to](auto t) {
0360     unsigned int val = 0;
0361     if (!decode(val, t)) {
0362       return false;
0363     }
0364     to.push_back(val);
0365     return true;
0366   });
0367 }  // decode to vector<unsigned int>
0368 
0369 // ----------------------------------------------------------------------
0370 
0371 bool edm::encode(std::string& to, std::vector<unsigned int> const& from) {
0372   to = "{";
0373 
0374   std::string converted;
0375   for (std::vector<unsigned int>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
0376     if (!encode(converted, *b)) {
0377       return false;
0378     }
0379     if (b != from.begin()) {
0380       to += ",";
0381     }
0382     to += converted;
0383   }
0384 
0385   to += '}';
0386   return true;
0387 }  // encode from vector<unsigned int>
0388 
0389 // ----------------------------------------------------------------------
0390 // vUint64
0391 // ----------------------------------------------------------------------
0392 
0393 bool edm::decode(std::vector<unsigned long long>& to, std::string_view from) {
0394   to.clear();
0395   to.reserve(std::count(from.begin(), from.end(), ','));
0396   return split(from, '{', ',', '}', [&to](auto t) {
0397     unsigned long long val = 0ULL;
0398     if (!decode(val, t)) {
0399       return false;
0400     }
0401     to.push_back(val);
0402     return true;
0403   });
0404 }  // decode to vector<unsigned int>
0405 
0406 // ----------------------------------------------------------------------
0407 
0408 bool edm::encode(std::string& to, std::vector<unsigned long long> const& from) {
0409   to = "{";
0410 
0411   std::string converted;
0412   for (std::vector<unsigned long long>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
0413     if (!encode(converted, *b)) {
0414       return false;
0415     }
0416 
0417     if (b != from.begin()) {
0418       to += ",";
0419     }
0420     to += converted;
0421   }
0422 
0423   to += '}';
0424   return true;
0425 }  // encode from vector<unsigned int>
0426 
0427 // ----------------------------------------------------------------------
0428 // Double
0429 // ----------------------------------------------------------------------
0430 
0431 bool edm::decode(double& to, std::string_view from) {
0432   if (from == "NaN") {
0433     to = std::numeric_limits<double>::quiet_NaN();
0434   } else if (from == "+inf" || from == "inf") {
0435     to = std::numeric_limits<double>::has_infinity ? std::numeric_limits<double>::infinity()
0436                                                    : std::numeric_limits<double>::max();
0437   } else if (from == "-inf") {
0438     to = std::numeric_limits<double>::has_infinity ? -std::numeric_limits<double>::infinity()
0439                                                    : -std::numeric_limits<double>::max();
0440   }
0441 
0442   else {
0443     try {
0444       // std::cerr << "from:" << from << std::endl;
0445       to = std::stod(std::string(from));
0446       // std::cerr << "to:" << to << std::endl;
0447     } catch (const std::exception&) {
0448       return false;
0449     }
0450   }
0451   return true;
0452 }
0453 
0454 // ----------------------------------------------------------------------
0455 
0456 bool edm::encode(std::string& to, double from) {
0457   std::ostringstream ost;
0458   ost.precision(std::numeric_limits<double>::max_digits10);
0459   ost << from;
0460   if (!ost)
0461     return false;
0462   to = ost.str();
0463   return true;
0464 }
0465 
0466 // ----------------------------------------------------------------------
0467 // vDouble
0468 // ----------------------------------------------------------------------
0469 
0470 bool edm::decode(std::vector<double>& to, std::string_view from) {
0471   to.clear();
0472   to.reserve(std::count(from.begin(), from.end(), ','));
0473   return split(from, '{', ',', '}', [&to](auto t) {
0474     double val;
0475     if (!decode(val, t))
0476       return false;
0477     to.push_back(val);
0478     return true;
0479   });
0480 }  // decode to vector<double>
0481 
0482 // ----------------------------------------------------------------------
0483 
0484 bool edm::encode(std::string& to, std::vector<double> const& from) {
0485   to = "{";
0486 
0487   std::string converted;
0488   for (std::vector<double>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
0489     if (!encode(converted, *b))
0490       return false;
0491 
0492     if (b != from.begin())
0493       to += ",";
0494     to += converted;
0495   }
0496 
0497   to += '}';
0498   return true;
0499 }  // encode from vector<double>
0500 
0501 // ----------------------------------------------------------------------
0502 // String
0503 // ----------------------------------------------------------------------
0504 std::optional<std::string_view> edm::decode_string_extent(std::string_view from) {
0505   std::size_t searchIndex = 0;
0506   std::size_t indexEnd = 0;
0507   while (std::string_view::npos != (indexEnd = from.find_first_of('\0', searchIndex))) {
0508     if (indexEnd + 1 == from.size()) {
0509       return from;
0510     }
0511     if (from[indexEnd + 1] == '\0') {
0512       searchIndex = indexEnd + 2;
0513     } else {
0514       return from.substr(0, indexEnd + 1);
0515     }
0516   }
0517   //didn't find an unpaired '\0'
0518   return {};
0519 }
0520 
0521 bool edm::decode(std::string& to, std::string_view from) {
0522   if (from.empty() or from.back() != '\0') {
0523     return false;
0524   }
0525   to = from.substr(0, from.size() - 1);
0526 
0527   std::size_t searchIndex = 0;
0528   while (std::string::npos != (searchIndex = to.find_first_of('\0', searchIndex))) {
0529     if (searchIndex == to.size() - 1 or to[searchIndex + 1] != '\0') {
0530       //unpaired string
0531       return false;
0532     }
0533     to.erase(searchIndex, 1);
0534     ++searchIndex;
0535   }
0536   return true;
0537 }
0538 
0539 bool edm::decode_deprecated(std::string& to, std::string_view from) {
0540   /*std::cerr << "Decoding: " << from << '\n'; //DEBUG*/
0541   std::string_view::const_iterator b = from.begin(), e = from.end();
0542 
0543   to = "";
0544   to.reserve((e - b) / 2);
0545   char c = '\0';
0546   for (bool even_pos = true; b != e; ++b, even_pos = !even_pos) {
0547     if (even_pos) {
0548       /*std::cerr << "Even: |"
0549                   << *b
0550                   << "|   giving "
0551                   << from_hex(*b)
0552                   << "\n"; //DEBUG*/
0553       c = static_cast<char>(from_hex(*b));
0554     } else {
0555       /*std::cerr << "Odd:  |"
0556                   << *b
0557                   << "|   giving "
0558                   << from_hex(*b)
0559                   << "\n"; //DEBUG*/
0560       c = static_cast<char>(c * 16 + from_hex(*b));
0561       //      if(std::isalnum(c))  {
0562       /*std::cerr << "Ans:  |" << c << "|\n"; //DEBUG*/
0563       to += c;
0564       //}
0565       //else  { // keep all special chars encoded
0566       //to += "\\x";
0567       //to += to_hex_rep(c);
0568       //}
0569     }
0570   }
0571   /*std::cerr << "Decoded: " << to << '\n'; //DEBUG*/
0572   return true;
0573 }  // decode to String
0574 
0575 // ----------------------------------------------------------------------
0576 // FileInPath
0577 // ----------------------------------------------------------------------
0578 
0579 bool edm::decode(FileInPath& to, std::string_view from) {
0580   std::string sfrom{from};
0581   std::istringstream is(sfrom);
0582   FileInPath temp;
0583   temp.readFromParameterSetBlob(is);
0584   if (!is)
0585     return false;
0586   to = temp;
0587   return true;
0588 }  // decode to FileInPath
0589 
0590 bool edm::encode(std::string& to, FileInPath const& from) {
0591   std::ostringstream ost;
0592   ost << from;
0593   if (!ost)
0594     return false;
0595   to = ost.str();
0596   return true;
0597 }
0598 
0599 // ----------------------------------------------------------------------
0600 // InputTag
0601 // ----------------------------------------------------------------------
0602 
0603 bool edm::decode(InputTag& to, std::string_view from) {
0604   to = InputTag(std::string(from));
0605   return true;
0606 }  // decode to InputTag
0607 
0608 bool edm::encode(std::string& to, InputTag const& from) {
0609   to = from.encode();
0610   return true;
0611 }
0612 
0613 // ----------------------------------------------------------------------
0614 // VInputTag
0615 // ----------------------------------------------------------------------
0616 
0617 bool edm::decode(std::vector<InputTag>& to, std::string_view from) {
0618   std::vector<std::string> strings;
0619   decode(strings, from);
0620 
0621   for (std::vector<std::string>::const_iterator stringItr = strings.begin(), stringItrEnd = strings.end();
0622        stringItr != stringItrEnd;
0623        ++stringItr) {
0624     to.push_back(InputTag(*stringItr));
0625   }
0626   return true;
0627 }  // decode to VInputTag
0628 
0629 bool edm::encode(std::string& to, std::vector<InputTag> const& from) {
0630   std::vector<std::string> strings;
0631   for (std::vector<InputTag>::const_iterator tagItr = from.begin(), tagItrEnd = from.end(); tagItr != tagItrEnd;
0632        ++tagItr) {
0633     strings.push_back(tagItr->encode());
0634   }
0635   encode(to, strings);
0636   return true;
0637 }
0638 
0639 // ----------------------------------------------------------------------
0640 // ESInputTag
0641 // ----------------------------------------------------------------------
0642 
0643 bool edm::decode(ESInputTag& to, std::string_view from) {
0644   if (not from.empty() and from.npos == from.find(':')) {
0645     to = ESInputTag(std::string(from), "");
0646   } else {
0647     to = ESInputTag(std::string(from));
0648   }
0649   return true;
0650 }  // decode to InputTag
0651 
0652 bool edm::encode(std::string& to, ESInputTag const& from) {
0653   to = from.encode();
0654   if (not to.empty() and to.back() == ':') {
0655     to.pop_back();
0656   }
0657   return true;
0658 }
0659 
0660 // ----------------------------------------------------------------------
0661 // VESInputTag
0662 // ----------------------------------------------------------------------
0663 
0664 bool edm::decode(std::vector<ESInputTag>& to, std::string_view from) {
0665   std::vector<std::string> strings;
0666   decode(strings, from);
0667 
0668   for (std::vector<std::string>::const_iterator stringItr = strings.begin(), stringItrEnd = strings.end();
0669        stringItr != stringItrEnd;
0670        ++stringItr) {
0671     to.push_back(ESInputTag(*stringItr));
0672   }
0673   return true;
0674 }  // decode to VInputTag
0675 
0676 bool edm::encode(std::string& to, std::vector<ESInputTag> const& from) {
0677   std::vector<std::string> strings;
0678   for (std::vector<ESInputTag>::const_iterator tagItr = from.begin(), tagItrEnd = from.end(); tagItr != tagItrEnd;
0679        ++tagItr) {
0680     strings.push_back(tagItr->encode());
0681   }
0682   encode(to, strings);
0683   return true;
0684 }
0685 
0686 // ----------------------------------------------------------------------
0687 // EventID
0688 // ----------------------------------------------------------------------
0689 
0690 bool edm::decode(edm::EventID& to, std::string_view from) {
0691   std::vector<std::string> tokens = edm::tokenize(std::string(from), ":");
0692   assert(tokens.size() == 2 || tokens.size() == 3);
0693   unsigned int run = strtoul(tokens[0].c_str(), nullptr, 0);
0694   unsigned int lumi = (tokens.size() == 2 ? 0 : strtoul(tokens[1].c_str(), nullptr, 0));
0695   unsigned long long event = strtoull(tokens[tokens.size() - 1].c_str(), nullptr, 0);
0696   to = edm::EventID(run, lumi, event);
0697 
0698   return true;
0699 }  // decode to EventID
0700 
0701 bool edm::encode(std::string& to, edm::EventID const& from) {
0702   std::ostringstream os;
0703   if (from.luminosityBlock() == 0U) {
0704     os << from.run() << ":" << from.event();
0705   } else {
0706     os << from.run() << ":" << from.luminosityBlock() << ":" << from.event();
0707   }
0708   to = os.str();
0709   return true;
0710 }
0711 
0712 // ----------------------------------------------------------------------
0713 // VEventID
0714 // ----------------------------------------------------------------------
0715 
0716 bool edm::decode(std::vector<edm::EventID>& to, std::string_view from) {
0717   std::vector<std::string> strings;
0718   decode(strings, from);
0719 
0720   for (std::vector<std::string>::const_iterator stringItr = strings.begin(), stringItrEnd = strings.end();
0721        stringItr != stringItrEnd;
0722        ++stringItr) {
0723     edm::EventID eventID;
0724     decode(eventID, *stringItr);
0725     to.push_back(eventID);
0726   }
0727   return true;
0728 }  // decode to VInputTag
0729 
0730 bool edm::encode(std::string& to, std::vector<edm::EventID> const& from) {
0731   std::vector<std::string> strings;
0732   for (std::vector<edm::EventID>::const_iterator idItr = from.begin(), idItrEnd = from.end(); idItr != idItrEnd;
0733        ++idItr) {
0734     std::string encodedEventID;
0735     encode(encodedEventID, *idItr);
0736     strings.push_back(encodedEventID);
0737   }
0738   encode(to, strings);
0739   return true;
0740 }
0741 
0742 // ----------------------------------------------------------------------
0743 // LuminosityBlockID
0744 // ----------------------------------------------------------------------
0745 
0746 bool edm::decode(edm::LuminosityBlockID& to, std::string_view from) {
0747   std::vector<std::string> tokens = edm::tokenize(std::string(from), ":");
0748   assert(tokens.size() == 2);
0749   unsigned int run = strtoul(tokens[0].c_str(), nullptr, 0);
0750   unsigned int lumi = strtoul(tokens[1].c_str(), nullptr, 0);
0751   to = edm::LuminosityBlockID(run, lumi);
0752   return true;
0753 }  // decode to LuminosityBlockID
0754 
0755 bool edm::encode(std::string& to, edm::LuminosityBlockID const& from) {
0756   std::ostringstream os;
0757   os << from.run() << ":" << from.luminosityBlock();
0758   to = os.str();
0759   return true;
0760 }
0761 
0762 // ----------------------------------------------------------------------
0763 // VLuminosityBlockID
0764 // ----------------------------------------------------------------------
0765 
0766 bool edm::decode(std::vector<edm::LuminosityBlockID>& to, std::string_view from) {
0767   std::vector<std::string> strings;
0768   decode(strings, from);
0769 
0770   for (std::vector<std::string>::const_iterator stringItr = strings.begin(), stringItrEnd = strings.end();
0771        stringItr != stringItrEnd;
0772        ++stringItr) {
0773     edm::LuminosityBlockID lumiID;
0774     decode(lumiID, *stringItr);
0775     to.push_back(lumiID);
0776   }
0777   return true;
0778 }  // decode to VInputTag
0779 
0780 bool edm::encode(std::string& to, std::vector<edm::LuminosityBlockID> const& from) {
0781   std::vector<std::string> strings;
0782   for (std::vector<edm::LuminosityBlockID>::const_iterator idItr = from.begin(), idItrEnd = from.end();
0783        idItr != idItrEnd;
0784        ++idItr) {
0785     std::string encodedLuminosityBlockID;
0786     encode(encodedLuminosityBlockID, *idItr);
0787     strings.push_back(encodedLuminosityBlockID);
0788   }
0789   encode(to, strings);
0790   return true;
0791 }
0792 
0793 // ----------------------------------------------------------------------
0794 // LuminosityBlockRange
0795 // ----------------------------------------------------------------------
0796 
0797 bool edm::decode(edm::LuminosityBlockRange& to, std::string_view from) {
0798   std::vector<std::string> tokens = edm::tokenize(std::string(from), "-");
0799   assert(tokens.size() == 2);
0800   edm::LuminosityBlockID begin;
0801   edm::LuminosityBlockID end;
0802   edm::decode(begin, tokens[0]);
0803   edm::decode(end, tokens[1]);
0804   to = edm::LuminosityBlockRange(begin.run(), begin.luminosityBlock(), end.run(), end.luminosityBlock());
0805   return true;
0806 }  // decode to LuminosityBlockRange
0807 
0808 bool edm::encode(std::string& to, edm::LuminosityBlockRange const& from) {
0809   std::ostringstream os;
0810   os << from.startRun() << ":" << from.startLumi() << "-" << from.endRun() << ":" << from.endLumi();
0811   to = os.str();
0812   return true;
0813 }
0814 
0815 // ----------------------------------------------------------------------
0816 // VLuminosityBlockRange
0817 // ----------------------------------------------------------------------
0818 
0819 bool edm::decode(std::vector<edm::LuminosityBlockRange>& to, std::string_view from) {
0820   std::vector<std::string> strings;
0821   decode(strings, from);
0822 
0823   for (std::vector<std::string>::const_iterator stringItr = strings.begin(), stringItrEnd = strings.end();
0824        stringItr != stringItrEnd;
0825        ++stringItr) {
0826     edm::LuminosityBlockRange lumiRange;
0827     decode(lumiRange, *stringItr);
0828     to.push_back(lumiRange);
0829   }
0830   return true;
0831 }  // decode to VInputTag
0832 
0833 bool edm::encode(std::string& to, std::vector<edm::LuminosityBlockRange> const& from) {
0834   std::vector<std::string> strings;
0835   for (std::vector<edm::LuminosityBlockRange>::const_iterator idItr = from.begin(), idItrEnd = from.end();
0836        idItr != idItrEnd;
0837        ++idItr) {
0838     std::string encodedLuminosityBlockRange;
0839     encode(encodedLuminosityBlockRange, *idItr);
0840     strings.push_back(encodedLuminosityBlockRange);
0841   }
0842   encode(to, strings);
0843   return true;
0844 }
0845 
0846 // ----------------------------------------------------------------------
0847 // EventRange
0848 // ----------------------------------------------------------------------
0849 
0850 bool edm::decode(edm::EventRange& to, std::string_view from) {
0851   std::vector<std::string> tokens = edm::tokenize(std::string(from), "-");
0852   assert(tokens.size() == 2);
0853   edm::EventID begin;
0854   edm::EventID end;
0855   edm::decode(begin, tokens[0]);
0856   edm::decode(end, tokens[1]);
0857   assert((begin.luminosityBlock() == 0) == (end.luminosityBlock() == 0));
0858   to = edm::EventRange(
0859       begin.run(), begin.luminosityBlock(), begin.event(), end.run(), end.luminosityBlock(), end.event());
0860   return true;
0861 }  // decode to EventRange
0862 
0863 bool edm::encode(std::string& to, edm::EventRange const& from) {
0864   std::ostringstream os;
0865   if (from.startLumi() == 0) {
0866     assert(from.endLumi() == 0);
0867     os << from.startRun() << ":" << from.startEvent() << "-" << from.endRun() << ":" << from.endEvent();
0868   } else {
0869     assert(from.endLumi() != 0);
0870     os << from.startRun() << ":" << from.startLumi() << ":" << from.startEvent() << "-" << from.endRun() << ":"
0871        << from.endLumi() << ":" << from.endEvent();
0872   }
0873   to = os.str();
0874   return true;
0875 }
0876 
0877 // ----------------------------------------------------------------------
0878 // VEventRange
0879 // ----------------------------------------------------------------------
0880 
0881 bool edm::decode(std::vector<edm::EventRange>& to, std::string_view from) {
0882   std::vector<std::string> strings;
0883   decode(strings, from);
0884 
0885   for (std::vector<std::string>::const_iterator stringItr = strings.begin(), stringItrEnd = strings.end();
0886        stringItr != stringItrEnd;
0887        ++stringItr) {
0888     edm::EventRange eventRange;
0889     decode(eventRange, *stringItr);
0890     to.push_back(eventRange);
0891   }
0892   return true;
0893 }
0894 
0895 bool edm::encode(std::string& to, std::vector<edm::EventRange> const& from) {
0896   std::vector<std::string> strings;
0897   for (std::vector<edm::EventRange>::const_iterator idItr = from.begin(), idItrEnd = from.end(); idItr != idItrEnd;
0898        ++idItr) {
0899     std::string encodedEventRange;
0900     encode(encodedEventRange, *idItr);
0901     strings.push_back(encodedEventRange);
0902   }
0903   encode(to, strings);
0904   return true;
0905 }
0906 
0907 // ----------------------------------------------------------------------
0908 bool edm::encode(std::string& to, std::string const& from) {
0909   to = from;
0910   //need to escape any nulls by making them pairs
0911   std::size_t lastFound = 0;
0912   while (std::string::npos != (lastFound = to.find_first_of('\0', lastFound))) {
0913     to.insert(lastFound, 1, '\0');
0914     lastFound += 2;
0915   }
0916   to += '\0';
0917   return true;
0918 }
0919 
0920 bool edm::encode_deprecated(std::string& to, std::string const& from) {
0921   std::string::const_iterator b = from.begin(), e = from.end();
0922 
0923   enum escape_state { NONE, BACKSLASH, HEX, HEX1, OCT1, OCT2 };
0924 
0925   escape_state state = NONE;
0926   int code = 0;
0927   to = "";
0928   for (; b != e; ++b) {
0929     /*std::cerr << "State: " << state << "; char = " << *b << '\n'; //DEBUG*/
0930     switch (state) {
0931       case NONE: {
0932         if (*b == '\\')
0933           state = BACKSLASH;
0934         else
0935           append_hex_rep(to, *b);
0936         /*std::cerr << "To: |" << to << "|\n"; //DEBUG*/
0937         break;
0938       }
0939       case BACKSLASH: {
0940         code = 0;
0941         switch (*b) {
0942           case 'x':
0943           case 'X': {
0944             state = HEX;
0945             break;
0946           }
0947           case '0':
0948           case '1':
0949           case '2':
0950           case '3':
0951           case '4':
0952           case '5':
0953           case '6':
0954           case '7': {
0955             code = 8 * code + from_hex(*b);
0956             state = OCT1;
0957             break;
0958           }
0959           case 'n': {
0960             append_hex_rep(to, 10);
0961             state = NONE;
0962             break;
0963           }
0964           case 't': {
0965             append_hex_rep(to, 9);
0966             state = NONE;
0967             break;
0968           }
0969           default: {
0970             append_hex_rep(to, *b);
0971             state = NONE;
0972             break;
0973           }
0974         }
0975         break;
0976       }
0977       case HEX: {
0978         to += *b;
0979         state = HEX1;
0980         break;
0981       }
0982       case HEX1: {
0983         to += *b;
0984         state = NONE;
0985         break;
0986       }
0987       case OCT1: {
0988         switch (*b) {
0989           case '0':
0990           case '1':
0991           case '2':
0992           case '3':
0993           case '4':
0994           case '5':
0995           case '6':
0996           case '7': {
0997             code = 8 * code + from_hex(*b);
0998             state = OCT2;
0999             break;
1000           }
1001           default: {
1002             append_hex_rep(to, code);
1003             state = NONE;
1004             break;
1005           }
1006         }
1007         break;
1008       }
1009       case OCT2: {
1010         switch (*b) {
1011           case '0':
1012           case '1':
1013           case '2':
1014           case '3':
1015           case '4':
1016           case '5':
1017           case '6':
1018           case '7': {
1019             code = 8 * code + from_hex(*b);
1020             break;
1021           }
1022           default: {
1023             append_hex_rep(to, code);
1024             break;
1025           }
1026         }
1027         state = NONE;
1028         break;
1029       }
1030       default: {
1031         throw std::logic_error("can't happen");
1032         break;
1033       }
1034     }
1035   }  // for
1036 
1037   return true;
1038 }  // encode from String
1039 
1040 // ----------------------------------------------------------------------
1041 // vString
1042 // ----------------------------------------------------------------------
1043 
1044 bool edm::decode_deprecated(std::vector<std::string>& to, std::string_view from) {
1045   to.clear();
1046   to.reserve(std::count(from.begin(), from.end(), ','));
1047   return split(from, '{', ',', '}', [&to](auto t) {
1048     std::string val;
1049     // treat blank string specially
1050     if (t == "XXX") {
1051       val = "";
1052     } else if (!decode_deprecated(val, t)) {
1053       return false;
1054     }
1055     to.push_back(val);
1056     return true;
1057   });
1058 }  // decode to vector<string>
1059 
1060 std::optional<std::string_view> edm::decode_vstring_extent(std::string_view from) {
1061   if (from.size() < 2) {
1062     return {};
1063   }
1064   if (from.front() != '{') {
1065     return {};
1066   }
1067   if (from[1] == '}') {
1068     return from.substr(0, 2);
1069   }
1070   if (from.size() < 3) {
1071     return {};
1072   }
1073   if (from[1] != '\0') {
1074     return {};
1075   }
1076   auto remaining = from.substr(2);
1077   while (not remaining.empty()) {
1078     auto strng = decode_string_extent(remaining);
1079     if (not strng) {
1080       return {};
1081     }
1082     remaining = remaining.substr(strng->size());
1083     if (remaining.empty())
1084       return {};
1085     if (remaining.front() == '}') {
1086       return from.substr(0, from.size() - remaining.size() + 1);
1087     }
1088     if (remaining.front() == ',') {
1089       remaining = remaining.substr(1);
1090     } else {
1091       return {};
1092     }
1093   }
1094   return {};
1095 }
1096 
1097 bool edm::decode(std::vector<std::string>& to, std::string_view from) {
1098   if (from.size() < 2) {
1099     return false;
1100   }
1101   if (from.front() != '{') {
1102     return false;
1103   }
1104   if (from.back() != '}') {
1105     return false;
1106   }
1107   to.clear();
1108   if (from.size() == 2) {
1109     //an empty vector
1110     return true;
1111   }
1112   if (from[1] != '\0') {
1113     return false;
1114   }
1115   auto remaining = from.substr(2, from.size() - 2 /*leading {/0*/ - 1 /*trailing } */);
1116   while (not remaining.empty()) {
1117     auto strng = decode_string_extent(remaining);
1118     if (not strng) {
1119       return false;
1120     }
1121     std::string val;
1122     if (!decode_element(val, *strng)) {
1123       return false;
1124     }
1125     to.emplace_back(std::move(val));
1126 
1127     remaining = remaining.substr(strng->size());
1128     if (remaining.empty())
1129       break;
1130     if (remaining.front() == ',') {
1131       remaining = remaining.substr(1);
1132     } else {
1133       return false;
1134     }
1135   }
1136   return true;
1137 }  // decode to vector<string>
1138 
1139 bool edm::decode_element(std::string& to, std::string_view from) { return decode(to, from); }
1140 
1141 // ----------------------------------------------------------------------
1142 
1143 bool edm::encode(std::string& to, std::vector<std::string> const& from) {
1144   to = "{";
1145 
1146   //special cases
1147   // empty vector : "{}"
1148   // vector with one empty element: "{\0\0}"
1149   // vector with one '}' element: "{\0}\0}"
1150   // vector with two '}' elements: "{\0}\0,}\0}"
1151   //needed to tell an empty vector from one with the first string being "}"
1152   if (not from.empty()) {
1153     to += '\0';
1154   }
1155   std::string converted;
1156   for (std::vector<std::string>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
1157     if (!encode_element(converted, *b)) {
1158       return false;
1159     }
1160 
1161     if (b != from.begin())
1162       to += ",";
1163     to += converted;
1164   }
1165 
1166   to += '}';
1167   return true;
1168 }  // encode from vector<string>
1169 
1170 bool edm::encode_element(std::string& to, std::string const& from) { return encode(to, from); }
1171 
1172 bool edm::encode_deprecated(std::string& to, std::vector<std::string> const& from) {
1173   to = "{";
1174 
1175   std::string converted;
1176   for (std::vector<std::string>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
1177     if (!encode_deprecated(converted, *b)) {
1178       return false;
1179     }
1180 
1181     if (b != from.begin())
1182       to += ",";
1183     to += converted;
1184   }
1185 
1186   to += '}';
1187   return true;
1188 }  // encode from vector<string>
1189 // ----------------------------------------------------------------------
1190 // ParameterSet
1191 // ----------------------------------------------------------------------
1192 
1193 bool edm::decode(ParameterSet& to, std::string_view from) {
1194   to = ParameterSet(from);
1195   return true;
1196 }  // decode to ParameterSet
1197 
1198 // ----------------------------------------------------------------------
1199 
1200 bool edm::encode(std::string& to, ParameterSet const& from) {
1201   to = from.toString();
1202   return true;
1203 }  // encode from ParameterSet
1204 
1205 // ----------------------------------------------------------------------
1206 
1207 std::optional<std::string_view> edm::decode_pset_extent(std::string_view from) {
1208   auto e = ParameterSet::extent(from);
1209   if (e.empty()) {
1210     return {};
1211   }
1212   return e;
1213 }
1214 
1215 // ----------------------------------------------------------------------
1216 // vPSet
1217 // ----------------------------------------------------------------------
1218 bool edm::decode(std::vector<ParameterSet>& to, std::string_view from) {
1219   to.clear();
1220   if (from.size() < 2) {
1221     return false;
1222   }
1223   if (from[0] != '{') {
1224     return false;
1225   }
1226   if (from.back() != '}') {
1227     return false;
1228   }
1229 
1230   to.reserve(std::count(from.begin(), from.end(), ',') + 1);
1231 
1232   auto remaining = from.substr(1, from.size() - 2);
1233   while (not remaining.empty()) {
1234     auto extent = ParameterSet::extent(remaining);
1235     if (extent.empty()) {
1236       return false;
1237     }
1238     ParameterSet val;
1239     if (!decode(val, extent)) {
1240       return false;
1241     }
1242     to.push_back(std::move(val));
1243     remaining.remove_prefix(extent.size());
1244     if (not remaining.empty()) {
1245       if (remaining[0] != ',') {
1246         return false;
1247       }
1248       remaining.remove_prefix(1);
1249     }
1250   }
1251   return true;
1252 }  // decode to vector<ParameterSet>
1253 
1254 // ----------------------------------------------------------------------
1255 
1256 bool edm::encode(std::string& to, std::vector<ParameterSet> const& from) {
1257   to = "{";
1258 
1259   std::string converted;
1260   for (std::vector<ParameterSet>::const_iterator b = from.begin(), e = from.end(); b != e; ++b) {
1261     if (!encode(converted, *b)) {
1262       return false;
1263     }
1264     if (b != from.begin()) {
1265       to += ",";
1266     }
1267     to += converted;
1268   }
1269   to += '}';
1270   return true;
1271 }  // encode from vector<ParameterSet>
1272 
1273 // ----------------------------------------------------------------------
1274 
1275 std::optional<std::string_view> edm::decode_vpset_extent(std::string_view from) {
1276   if (from.size() < 2) {
1277     return {};
1278   }
1279   if (from.front() != '{') {
1280     return {};
1281   }
1282   if (from[1] == '}') {
1283     return from.substr(0, 2);
1284   }
1285   if (from.size() < 3) {
1286     return {};
1287   }
1288   auto remaining = from.substr(1);
1289   while (not remaining.empty()) {
1290     auto extent = decode_pset_extent(remaining);
1291     if (not extent) {
1292       return {};
1293     }
1294     remaining.remove_prefix(extent->size());
1295     if (remaining.empty())
1296       return {};
1297     if (remaining.front() == '}') {
1298       return from.substr(0, from.size() - remaining.size() + 1);
1299     }
1300     if (remaining.front() == ',') {
1301       remaining = remaining.substr(1);
1302     } else {
1303       return {};
1304     }
1305   }
1306   return {};
1307 }