Mercurial > hg > orthanc-stone
comparison OrthancStone/Sources/Toolbox/GenericToolbox.h @ 1512:244ad1e4e76a
reorganization of folders
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 07 Jul 2020 16:21:02 +0200 |
parents | Framework/Toolbox/GenericToolbox.h@30deba7bc8e2 |
children | 5887a4f8594b |
comparison
equal
deleted
inserted
replaced
1511:9dfeee74c1e6 | 1512:244ad1e4e76a |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 #pragma once | |
22 | |
23 #include <Compatibility.h> | |
24 #include <OrthancException.h> | |
25 | |
26 #include <boost/shared_ptr.hpp> | |
27 | |
28 #include <string> | |
29 #include <stdint.h> | |
30 #include <math.h> | |
31 | |
32 #include <memory> | |
33 | |
34 namespace OrthancStone | |
35 { | |
36 namespace GenericToolbox | |
37 { | |
38 /** | |
39 Fast floating point string validation. | |
40 No trimming applied, so the input must match regex | |
41 /^[-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/ | |
42 The following are allowed as edge cases: "" and "-" | |
43 */ | |
44 inline bool LegitDoubleString(const char* text) | |
45 { | |
46 const char* p = text; | |
47 if(*p == '-') | |
48 p++; | |
49 size_t period = 0; | |
50 while(*p != 0) | |
51 { | |
52 if (*p >= '0' && *p <= '9') | |
53 ++p; | |
54 else if(*p == '.') | |
55 { | |
56 if(period > 0) | |
57 return false; | |
58 else | |
59 period++; | |
60 ++p; | |
61 } | |
62 else if (*p == 'e' || *p == 'E') | |
63 { | |
64 ++p; | |
65 if (*p == '-' || *p == '+') | |
66 ++p; | |
67 // "e+"/"E+" "e-"/"E-" or "e"/"E" must be followed by a number | |
68 if (!(*p >= '0' && *p <= '9')) | |
69 return false; | |
70 | |
71 // these must be the last in the string | |
72 while(*p >= '0' && *p <= '9') | |
73 ++p; | |
74 | |
75 return (*p == 0); | |
76 } | |
77 else | |
78 { | |
79 return false; | |
80 } | |
81 } | |
82 return true; | |
83 } | |
84 | |
85 /** | |
86 Fast integer string validation. | |
87 No trimming applied, so the input must match regex /^-?[0-9]*$/ | |
88 The following are allowed as edge cases: "" and "-" | |
89 */ | |
90 inline bool LegitIntegerString(const char* text) | |
91 { | |
92 const char* p = text; | |
93 if (*p == '-') | |
94 p++; | |
95 while (*p != 0) | |
96 { | |
97 if (*p >= '0' && *p <= '9') | |
98 ++p; | |
99 else | |
100 return false; | |
101 } | |
102 return true; | |
103 } | |
104 | |
105 /* | |
106 Fast string --> double conversion. | |
107 Must pass the LegitDoubleString test | |
108 | |
109 String to doubles with at most 18 digits | |
110 */ | |
111 inline bool StringToDouble(double& r, const char* text) | |
112 { | |
113 if(!LegitDoubleString(text)) | |
114 return false; | |
115 | |
116 static const double FRAC_FACTORS[] = | |
117 { | |
118 1.0, | |
119 0.1, | |
120 0.01, | |
121 0.001, | |
122 0.0001, | |
123 0.00001, | |
124 0.000001, | |
125 0.0000001, | |
126 0.00000001, | |
127 0.000000001, | |
128 0.0000000001, | |
129 0.00000000001, | |
130 0.000000000001, | |
131 0.0000000000001, | |
132 0.00000000000001, | |
133 0.000000000000001, | |
134 0.0000000000000001, | |
135 0.00000000000000001, | |
136 0.000000000000000001, | |
137 0.0000000000000000001 | |
138 }; | |
139 const size_t FRAC_FACTORS_LEN = sizeof(FRAC_FACTORS)/sizeof(double); | |
140 | |
141 r = 0.0; | |
142 double neg = 1.0; | |
143 const char* p = text; | |
144 | |
145 if (*p == '-') | |
146 { | |
147 neg = -1.0; | |
148 ++p; | |
149 } | |
150 // 12345.67890 | |
151 while (*p >= '0' && *p <= '9') | |
152 { | |
153 r = (r*10.0) + (*p - '0'); // 1 12 123 123 12345 | |
154 ++p; | |
155 } | |
156 if (*p == '.') | |
157 { | |
158 double f = 0.0; | |
159 size_t n = 1; | |
160 ++p; | |
161 while (*p >= '0' && *p <= '9' && n < FRAC_FACTORS_LEN) | |
162 { | |
163 f += (*p - '0') * FRAC_FACTORS[n]; | |
164 ++p; | |
165 ++n; | |
166 } | |
167 r += f; | |
168 } | |
169 r *= neg; | |
170 | |
171 // skip the remaining numbers until we reach not-a-digit (either the | |
172 // end of the string OR the scientific notation symbol) | |
173 while ((*p >= '0' && *p <= '9')) | |
174 ++p; | |
175 | |
176 if (*p == 0 ) | |
177 { | |
178 return true; | |
179 } | |
180 else if ((*p == 'e') || (*p == 'E')) | |
181 { | |
182 // process the scientific notation | |
183 double sign; // no init is safe (read below) | |
184 ++p; | |
185 if (*p == '-') | |
186 { | |
187 sign = -1.0; | |
188 // point to first number | |
189 ++p; | |
190 } | |
191 else if (*p == '+') | |
192 { | |
193 sign = 1.0; | |
194 // point to first number | |
195 ++p; | |
196 } | |
197 else if (*p >= '0' && *p <= '9') | |
198 { | |
199 sign = 1.0; | |
200 } | |
201 else | |
202 { | |
203 // only a sign char or a number is allowed | |
204 return false; | |
205 } | |
206 // now p points to the absolute value of the exponent | |
207 double exp = 0; | |
208 while (*p >= '0' && *p <= '9') | |
209 { | |
210 exp = (exp * 10.0) + static_cast<double>(*p - '0'); // 1 12 123 123 12345 | |
211 ++p; | |
212 } | |
213 // now we have our exponent. put a sign on it. | |
214 exp *= sign; | |
215 double scFac = ::pow(10.0, exp); | |
216 r *= scFac; | |
217 | |
218 // only allowed symbol here is EOS | |
219 return (*p == 0); | |
220 } | |
221 else | |
222 { | |
223 // not allowed | |
224 return false; | |
225 } | |
226 } | |
227 | |
228 inline bool StringToDouble(double& r, const std::string& text) | |
229 { | |
230 return StringToDouble(r, text.c_str()); | |
231 } | |
232 | |
233 /** | |
234 Fast string to integer conversion. Leading zeroes and minus are accepted, | |
235 but a leading + sign is NOT. | |
236 Must pass the LegitIntegerString function test. | |
237 In addition, an empty string (or lone minus sign) yields 0. | |
238 */ | |
239 | |
240 template<typename T> | |
241 inline bool StringToInteger(T& r, const char* text) | |
242 { | |
243 if (!LegitIntegerString(text)) | |
244 return false; | |
245 | |
246 r = 0; | |
247 T neg = 1; | |
248 const char* p = text; | |
249 | |
250 if (*p == '-') | |
251 { | |
252 neg = -1; | |
253 ++p; | |
254 } | |
255 while (*p >= '0' && *p <= '9') | |
256 { | |
257 r = (r * 10) + (*p - '0'); // 1 12 123 123 12345 | |
258 ++p; | |
259 } | |
260 r *= neg; | |
261 if (*p == 0) | |
262 return true; | |
263 else | |
264 return false; | |
265 } | |
266 | |
267 template<typename T> | |
268 inline bool StringToInteger(T& r, const std::string& text) | |
269 { | |
270 return StringToInteger<T>(r, text.c_str()); | |
271 } | |
272 | |
273 /** | |
274 if input is "rgb(12,23,255)" --> function fills `red`, `green` and `blue` and returns true | |
275 else ("everything else") --> function returns false and leaves all values untouched | |
276 */ | |
277 bool GetRgbValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, const char* text); | |
278 | |
279 /** | |
280 See main overload | |
281 */ | |
282 inline bool GetRgbValuesFromString(uint8_t& red, uint8_t& green, uint8_t& blue, const std::string& text) | |
283 { | |
284 return GetRgbValuesFromString(red, green, blue, text.c_str()); | |
285 } | |
286 | |
287 /** | |
288 Same as GetRgbValuesFromString | |
289 */ | |
290 bool GetRgbaValuesFromString(uint8_t& red, | |
291 uint8_t& green, | |
292 uint8_t& blue, | |
293 uint8_t& alpha, | |
294 const char* text); | |
295 | |
296 /** | |
297 Same as GetRgbValuesFromString | |
298 */ | |
299 inline bool GetRgbaValuesFromString(uint8_t& red, | |
300 uint8_t& green, | |
301 uint8_t& blue, | |
302 uint8_t& alpha, | |
303 const std::string& text) | |
304 { | |
305 return GetRgbaValuesFromString(red, green, blue, alpha, text.c_str()); | |
306 } | |
307 } | |
308 } |