File indexing completed on 2025-10-30 08:54:57
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 #ifndef ROOT_StringConv
0013 #define ROOT_StringConv
0014 
0015 
0016 #include <string_view>
0017 #include "Rtypes.h"
0018 #include "RConfigure.h"
0019 #include <cmath>
0020 
0021 namespace ROOT {
0022 
0023    
0024    
0025    
0026    
0027    
0028    
0029    
0030 
0031 
0032 
0033 
0034 
0035 
0036 
0037 template <typename value_type>
0038 void ToHumanReadableSize(value_type bytes,
0039                          Bool_t si,
0040                          Double_t *coeff,
0041                          const char **units)
0042 {
0043    
0044    static const char *const suffix[][2] =
0045    { { "B",  "B"   },
0046      { "KB", "KiB" },
0047      { "MB", "MiB" },
0048      { "GB", "GiB" },
0049      { "TB", "TiB" },
0050      { "EB", "EiB" },
0051      { "ZB", "ZiB" },
0052      { "YB", "YiB" } };
0053    value_type unit = si ? 1000 : 1024;
0054    int exp = 0;
0055    if (bytes == unit) {
0056       
0057       
0058       
0059       
0060       exp = 1;
0061    } else if (bytes > 0) {
0062       exp = std::min( (int) (std::log(bytes) / std::log(unit)),
0063                      (int) (sizeof(suffix) / sizeof(suffix[0]) - 1));
0064    }
0065    *coeff = bytes / std::pow(unit, exp);
0066    *units  = suffix[exp][!si];
0067 }
0068 
0069 enum class EFromHumanReadableSize {
0070    kSuccess,
0071    kParseFail,
0072    kOverflow
0073 };
0074 
0075 
0076 
0077 
0078 
0079 
0080 
0081 
0082 
0083 
0084 
0085 template <typename T>
0086 EFromHumanReadableSize FromHumanReadableSize(std::string_view str, T &value)
0087 {
0088    try {
0089       size_t cur, size = str.size();
0090       
0091       const double coeff = stod(std::string(str.data(), str.size()), &cur);
0092 
0093       
0094       while (cur<size && isspace(str[cur])) ++cur;
0095 
0096       
0097       int exp = 0, unit = 1000;
0098 
0099       auto result = [coeff,&exp,&unit,&value]() {
0100          double v = exp ? coeff * std::pow(unit, exp / 3) : coeff;
0101          if (v < (double) std::numeric_limits<T>::max()) {
0102             value = (T)v;
0103             return EFromHumanReadableSize::kSuccess;
0104          } else {
0105             return EFromHumanReadableSize::kOverflow;
0106          }
0107       };
0108       if (cur==size) return result();
0109 
0110       switch (toupper(str[cur])) {
0111          case 'B':  exp =  0; break;
0112          case 'K':  exp =  3; break;
0113          case 'M':  exp =  6; break;
0114          case 'G':  exp =  9; break;
0115          case 'T':  exp = 12; break;
0116          case 'E':  exp = 15; break;
0117          case 'Z':  exp = 18; break;
0118          case 'Y':  exp = 21; break;
0119 
0120          default:   return EFromHumanReadableSize::kParseFail;
0121       }
0122       ++cur;
0123 
0124       
0125       if (cur<size && toupper(str[cur]) == 'I') {
0126          ++cur;
0127          unit = 1024;
0128       }
0129 
0130       if (cur==size) return result();
0131 
0132       
0133       switch (toupper(str[cur])) {
0134          case 'B':
0135          case ' ':
0136          case '\t': ++cur;  break;
0137 
0138          case '\0': return result();
0139 
0140          default:   return EFromHumanReadableSize::kParseFail;
0141       }
0142 
0143       
0144       
0145 
0146       
0147       
0148       
0149 
0150       return result();
0151    } catch (...) {
0152       return EFromHumanReadableSize::kParseFail;
0153    }
0154 
0155 }
0156 
0157 } 
0158 
0159 #endif