DABC (Data Acquisition Backbone Core)  2.9.9
string.cxx
Go to the documentation of this file.
1 // $Id: string.cxx 4477 2020-04-15 14:19:58Z linev $
2 
3 /************************************************************
4  * The Data Acquisition Backbone Core (DABC) *
5  ************************************************************
6  * Copyright (C) 2009 - *
7  * GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
8  * Planckstr. 1, 64291 Darmstadt, Germany *
9  * Contact: http://dabc.gsi.de *
10  ************************************************************
11  * This software can be used under the GPL license *
12  * agreements as stated in LICENSE.txt file *
13  * which is part of the distribution. *
14  ************************************************************/
15 
16 #include "dabc/string.h"
17 
18 #include <cstring>
19 #include <cstdarg>
20 #include <cstdint>
21 #include <cstdio>
22 #include <clocale>
23 
24 #include "dabc/ConfigBase.h"
25 
26 void dabc::formats(std::string& sbuf, const char *fmt, ...)
27 {
28  if (!fmt || (strlen(fmt)==0)) return;
29 
30  va_list args;
31  int length(256), result(0);
32  char *buffer(0);
33  while (1) {
34  if (buffer) delete [] buffer;
35  buffer = new char [length];
36 
37  va_start(args, fmt);
38  result = vsnprintf(buffer, length, fmt, args);
39  va_end(args);
40 
41  if (result<0) length *= 2; else // this is error handling in glibc 2.0
42  if (result>=length) length = result + 1; else // this is error handling in glibc 2.1
43  break;
44  }
45  sbuf.assign(buffer);
46  delete [] buffer;
47 }
48 
49 std::string dabc::format(const char *fmt, ...)
50 {
51  if (!fmt || (strlen(fmt)==0)) return std::string("");
52 
53  va_list args;
54  int length(256), result(0);
55  char *buffer(0);
56  while (1) {
57  if (buffer) delete [] buffer;
58  buffer = new char [length];
59 
60  va_start(args, fmt);
61  result = vsnprintf(buffer, length, fmt, args);
62  va_end(args);
63 
64  if (result<0) length *= 2; else // this is error handling in glibc 2.0
65  if (result>=length) length = result + 1; else // this is error handling in glibc 2.1
66  break;
67  }
68 
69  std::string s(buffer);
70  delete [] buffer;
71  va_end(args);
72  return s;
73 }
74 
75 std::string dabc::size_to_str(unsigned long sz, int prec, int select)
76 {
77  if (select==0) {
78  unsigned long mult = prec<=0 ? 10 : 1;
79  if (sz < 0x1000LU) select = 1; else
80  if (sz < 0x100000LU*mult) select = 2; else
81  if (sz < 0x40000000LU*mult) select =3; else select = 4;
82  }
83 
84  switch (select) {
85  case 1:
86  return dabc::format("%lu B", sz);
87  case 2:
88  if (prec<=0)
89  return dabc::format("%lu KB", sz/1024);
90  else
91  return dabc::format("%*.*f KB", prec+2, prec, sz/1024.);
92  case 3:
93  if (prec<=0)
94  return dabc::format("%lu MB", sz/0x100000LU);
95  else
96  return dabc::format("%*.*f MB", prec+2, prec, sz/1024./1024.);
97  case 4:
98  if (prec<=0)
99  return dabc::format("%lu GB", sz/0x40000000LU);
100  else
101  return dabc::format("%*.*f GB", prec+2, prec, sz/1024./1024./1024.);
102  }
103 
104  return dabc::format("%lu B", sz);
105 }
106 
107 std::string dabc::number_to_str(unsigned long num, int prec, int select)
108 {
109  if (select==0) {
110  unsigned long mult = prec<=0 ? 10 : 1;
111  if (num < 10000LU) select = 1; else
112  if (num < 1000000LU*mult) select = 2; else
113  if (num < 1000000000LU*mult) select = 3; else select = 4;
114  }
115 
116  switch (select) {
117  case 1:
118  return dabc::format("%lu", num);
119  case 2:
120  if (prec<=0)
121  return dabc::format("%luk", num/1000);
122  else
123  return dabc::format("%*.*fk", prec+2, prec, num/1e3);
124  case 3:
125  if (prec<=0)
126  return dabc::format("%lum", num/1000000LU);
127  else
128  return dabc::format("%*.*fm", prec+2, prec, num/1e6);
129  case 4:
130  if (prec<=0)
131  return dabc::format("%lug", num/1000000000LU);
132  else
133  return dabc::format("%*.*fg", prec+2, prec, num/1e9);
134  }
135 
136  return dabc::format("%lu", num);
137 
138 }
139 
140 
141 
142 bool dabc::str_to_int(const char* val, int* res)
143 {
144  if ((val==0) || (res==0)) return false;
145 
146  while (*val==' ') val++;
147  if (*val==0) return false;
148  if ((strlen(val)>2) && (val[0]=='0') && ((val[1]=='x') || (val[1]=='X'))) {
149  unsigned ures(0);
150  if (sscanf(val+2, "%x", &ures) == 1) {
151  *res = ures;
152  return true;
153  }
154  return false;
155  }
156 
157  if (strpbrk(val,".,eE")!=0) return false; // avoid any float value
158 
159  return sscanf(val, "%d", res) == 1;
160 }
161 
162 bool dabc::str_to_lint(const char* val, long* res)
163 {
164  if ((val==0) || (res==0)) return false;
165 
166  while (*val==' ') val++;
167  if (*val==0) return false;
168 
169  if ((strlen(val)>2) && (val[0]=='0') && ((val[1]=='x') || (val[1]=='X'))) {
170  long unsigned ures = 0;
171  if (sscanf(val+2, "%lx", &ures) == 1) {
172  *res = ures;
173  return true;
174  }
175  return false;
176  }
177 
178  if (strpbrk(val,".,eE")!=0) return false; // avoid any float value
179 
180  return sscanf(val, "%ld", res) == 1;
181 }
182 
183 
184 bool dabc::str_to_uint(const char* val, unsigned* res)
185 {
186  if ((val==0) || (res==0)) return false;
187 
188  while (*val==' ') val++;
189  if (*val==0) return false;
190 
191  if ((strlen(val)>2) && (val[0]=='0') && ((val[1]=='x') || (val[1]=='X'))) {
192  return sscanf(val+2, "%x", res) == 1;
193  }
194 
195  if (strpbrk(val,".,eE")!=0) return false; // avoid any float value
196 
197  return sscanf(val, "%u", res) == 1;
198 }
199 
200 bool dabc::str_to_luint(const char* val, long unsigned* res)
201 {
202  if ((val==0) || (res==0)) return false;
203 
204  while (*val==' ') val++;
205  if (*val==0) return false;
206 
207  if ((strlen(val)>2) && (val[0]=='0') && ((val[1]=='x') || (val[1]=='X'))) {
208  return sscanf(val+2, "%lx", res) == 1;
209  }
210 
211  if (strpbrk(val,".,eE")!=0) return false; // avoid any float value
212 
213  return sscanf(val, "%lu", res) == 1;
214 }
215 
216 bool dabc::str_to_double(const char* val, double* res)
217 {
218  if ((val==0) || (res==0)) return false;
219 
220  if (sscanf(val, "%lf", res) == 1) return true;
221 
222  unsigned ures(0);
223 
224  if (str_to_uint(val, &ures)) { *res = ures; return true; }
225 
226  return false;
227 }
228 
229 bool dabc::str_to_bool(const char* val, bool* res)
230 {
231  if ((val==0) || (res==0)) return false;
232  if (strcmp(val, xmlTrueValue)==0) { *res = true; return true; }
233  if (strcmp(val, xmlFalseValue)==0) { *res = false; return true; }
234  return false;
235 }
236 
237 std::string dabc::replace_all(const std::string &str, const std::string &match, const std::string &replace)
238 {
239  if (match.empty()) return str;
240 
241  std::string res = str;
242  size_t last = 0, pos = 0;
243 
244  while ((pos = res.find(match, last)) != std::string::npos) {
245  res.erase(pos, match.length());
246  res.insert(pos, replace);
247  last = pos + replace.length();
248  }
249 
250  return res;
251 }
252 
254 {
255  char *loc = setlocale(LC_NUMERIC, NULL);
256  if (loc && (strcmp(loc, "C") != 0)) {
257  fPrev = loc;
258  setlocale(LC_NUMERIC, "C");
259  }
260 }
261 
263 {
264  if (!fPrev.empty())
265  setlocale(LC_NUMERIC, fPrev.c_str());
266 }
267 
268 
std::string fPrev
Definition: string.h:90
std::string replace_all(const std::string &str, const std::string &match, const std::string &replace)
Replace all matches in the string.
Definition: string.cxx:237
bool str_to_uint(const char *val, unsigned *res)
Convert string to unsigned integer value One could use hexadecimal (in form 0xabc100) or decimal form...
Definition: string.cxx:184
void formats(std::string &sbuf, const char *fmt,...)
Definition: string.cxx:26
bool str_to_double(const char *val, double *res)
Convert string to double value.
Definition: string.cxx:216
std::string format(const char *fmt,...)
Definition: string.cxx:49
std::string size_to_str(unsigned long sz, int prec=1, int select=0)
Convert size to string of form like 4.2 GB or 3.7 MB.
Definition: string.cxx:75
std::string number_to_str(unsigned long num, int prec=1, int select=0)
Convert number to string of form like 4.2G or 3.7M.
Definition: string.cxx:107
const char * xmlTrueValue
Definition: ConfigBase.cxx:90
bool str_to_lint(const char *val, long *res)
Convert string to long integer value.
Definition: string.cxx:162
bool str_to_luint(const char *val, long unsigned *res)
Convert string to long unsigned integer value One could use hexadecimal (in form 0xabc100) or decimal...
Definition: string.cxx:200
const char * xmlFalseValue
Definition: ConfigBase.cxx:91
bool str_to_bool(const char *val, bool *res)
Convert string to bool value.
Definition: string.cxx:229
bool str_to_int(const char *val, int *res)
Convert string to integer value.
Definition: string.cxx:142