diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-11-03 21:10:27 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-11-03 21:10:27 +0000 |
commit | 236e47e55554310cc19b8c37c7b844d53a239f28 (patch) | |
tree | daeba73a49d600e9d7fb441fe67f32686e38415b | |
parent | f9b6dfb41e151628673595fd880318ec502ae4ed (diff) | |
download | gnunet-236e47e55554310cc19b8c37c7b844d53a239f28.tar.gz gnunet-236e47e55554310cc19b8c37c7b844d53a239f28.zip |
implementing time and size parsers for #1875
-rw-r--r-- | src/include/gnunet_configuration_lib.h | 19 | ||||
-rw-r--r-- | src/include/gnunet_strings_lib.h | 13 | ||||
-rw-r--r-- | src/util/configuration.c | 36 | ||||
-rw-r--r-- | src/util/strings.c | 126 | ||||
-rw-r--r-- | src/util/test_configuration.c | 11 | ||||
-rw-r--r-- | src/util/test_configuration_data.conf | 1 |
6 files changed, 197 insertions, 9 deletions
diff --git a/src/include/gnunet_configuration_lib.h b/src/include/gnunet_configuration_lib.h index 7167d8bd6..f8f302a18 100644 --- a/src/include/gnunet_configuration_lib.h +++ b/src/include/gnunet_configuration_lib.h | |||
@@ -226,6 +226,23 @@ GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle | |||
226 | struct GNUNET_TIME_Relative *time); | 226 | struct GNUNET_TIME_Relative *time); |
227 | 227 | ||
228 | 228 | ||
229 | |||
230 | /** | ||
231 | * Get a configuration value that should be a size in bytes. | ||
232 | * | ||
233 | * @param cfg configuration to inspect | ||
234 | * @param section section of interest | ||
235 | * @param option option of interest | ||
236 | * @param size set to the size in bytes as stored in the configuration | ||
237 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
238 | */ | ||
239 | int | ||
240 | GNUNET_CONFIGURATION_get_value_size (const struct GNUNET_CONFIGURATION_Handle | ||
241 | *cfg, const char *section, | ||
242 | const char *option, | ||
243 | unsigned long long *size); | ||
244 | |||
245 | |||
229 | /** | 246 | /** |
230 | * Test if we have a value for a particular option | 247 | * Test if we have a value for a particular option |
231 | * | 248 | * |
@@ -337,6 +354,7 @@ GNUNET_CONFIGURATION_get_value_yesno (const struct GNUNET_CONFIGURATION_Handle | |||
337 | *cfg, const char *section, | 354 | *cfg, const char *section, |
338 | const char *option); | 355 | const char *option); |
339 | 356 | ||
357 | |||
340 | /** | 358 | /** |
341 | * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" | 359 | * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" |
342 | * where either in the "PATHS" section or the environtment | 360 | * where either in the "PATHS" section or the environtment |
@@ -378,6 +396,7 @@ GNUNET_CONFIGURATION_set_value_string (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
378 | const char *section, const char *option, | 396 | const char *section, const char *option, |
379 | const char *value); | 397 | const char *value); |
380 | 398 | ||
399 | |||
381 | /** | 400 | /** |
382 | * Remove a filename from a configuration value that | 401 | * Remove a filename from a configuration value that |
383 | * represents a list of filenames | 402 | * represents a list of filenames |
diff --git a/src/include/gnunet_strings_lib.h b/src/include/gnunet_strings_lib.h index 6413fb102..637d4f7de 100644 --- a/src/include/gnunet_strings_lib.h +++ b/src/include/gnunet_strings_lib.h | |||
@@ -51,6 +51,18 @@ extern "C" | |||
51 | 51 | ||
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Convert a given fancy human-readable size to bytes. | ||
55 | * | ||
56 | * @param fancy_size human readable string (i.e. 1 MB) | ||
57 | * @param size set to the size in bytes | ||
58 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
59 | */ | ||
60 | int | ||
61 | GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | ||
62 | unsigned long long *size); | ||
63 | |||
64 | |||
65 | /** | ||
54 | * Convert a given filesize into a fancy human-readable format. | 66 | * Convert a given filesize into a fancy human-readable format. |
55 | * | 67 | * |
56 | * @param size number of bytes | 68 | * @param size number of bytes |
@@ -85,6 +97,7 @@ GNUNET_STRINGS_to_utf8 (const char *input, size_t len, const char *charset); | |||
85 | char * | 97 | char * |
86 | GNUNET_STRINGS_filename_expand (const char *fil); | 98 | GNUNET_STRINGS_filename_expand (const char *fil); |
87 | 99 | ||
100 | |||
88 | /** | 101 | /** |
89 | * Fill a buffer of the given size with | 102 | * Fill a buffer of the given size with |
90 | * count 0-terminated strings (given as varargs). | 103 | * count 0-terminated strings (given as varargs). |
diff --git a/src/util/configuration.c b/src/util/configuration.c index a269ed036..ba3aa7f45 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -731,16 +731,34 @@ GNUNET_CONFIGURATION_get_value_time (const struct GNUNET_CONFIGURATION_Handle | |||
731 | e = findEntry (cfg, section, option); | 731 | e = findEntry (cfg, section, option); |
732 | if (e == NULL) | 732 | if (e == NULL) |
733 | return GNUNET_SYSERR; | 733 | return GNUNET_SYSERR; |
734 | if ((0 == strcasecmp (e->val, "infinity")) || | 734 | |
735 | (0 == strcasecmp (e->val, "forever"))) | 735 | return GNUNET_STRINGS_fancy_time_to_relative (e->val, |
736 | { | 736 | time); |
737 | *time = GNUNET_TIME_UNIT_FOREVER_REL; | 737 | } |
738 | return GNUNET_OK; | 738 | |
739 | } | 739 | |
740 | if (1 != SSCANF (e->val, "%llu", &num)) | 740 | /** |
741 | * Get a configuration value that should be a size in bytes. | ||
742 | * | ||
743 | * @param cfg configuration to inspect | ||
744 | * @param section section of interest | ||
745 | * @param option option of interest | ||
746 | * @param size set to the size in bytes as stored in the configuration | ||
747 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
748 | */ | ||
749 | int | ||
750 | GNUNET_CONFIGURATION_get_value_size (const struct GNUNET_CONFIGURATION_Handle | ||
751 | *cfg, const char *section, | ||
752 | const char *option, | ||
753 | unsigned long long *size) | ||
754 | { | ||
755 | struct ConfigEntry *e; | ||
756 | |||
757 | e = findEntry (cfg, section, option); | ||
758 | if (e == NULL) | ||
741 | return GNUNET_SYSERR; | 759 | return GNUNET_SYSERR; |
742 | time->rel_value = (uint64_t) num; | 760 | return GNUNET_STRINGS_fancy_size_to_bytes (e->val, |
743 | return GNUNET_OK; | 761 | size); |
744 | } | 762 | } |
745 | 763 | ||
746 | 764 | ||
diff --git a/src/util/strings.c b/src/util/strings.c index 9e9aac3b1..63ebfc1e2 100644 --- a/src/util/strings.c +++ b/src/util/strings.c | |||
@@ -171,6 +171,132 @@ GNUNET_STRINGS_byte_size_fancy (unsigned long long size) | |||
171 | 171 | ||
172 | 172 | ||
173 | /** | 173 | /** |
174 | * Convert a given fancy human-readable size to bytes. | ||
175 | * | ||
176 | * @param fancy_size human readable string (i.e. 1 MB) | ||
177 | * @param size set to the size in bytes | ||
178 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
179 | */ | ||
180 | int | ||
181 | GNUNET_STRINGS_fancy_size_to_bytes (const char *fancy_size, | ||
182 | unsigned long long *size) | ||
183 | { | ||
184 | struct { | ||
185 | const char *name; | ||
186 | unsigned long long value; | ||
187 | } table[] = { | ||
188 | { "B", 1 }, | ||
189 | { "KiB", 1024 }, | ||
190 | { "kB", 1000 }, | ||
191 | { "MiB", 1024 * 1024 }, | ||
192 | { "MB", 1000 * 1000 }, | ||
193 | { "GiB", 1024 * 1024 * 1024 }, | ||
194 | { "GB", 1000 * 1000 * 1000 }, | ||
195 | { "TiB", 1024LL * 1024LL * 1024LL * 1024LL }, | ||
196 | { "TB", 1000LL * 1000LL * 1000LL * 1024LL }, | ||
197 | { "PiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL }, | ||
198 | { "PB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL}, | ||
199 | { "EiB", 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * 1024LL}, | ||
200 | { "EB", 1000LL * 1000LL * 1000LL * 1024LL * 1000LL * 1000LL }, | ||
201 | { NULL, 0 } | ||
202 | }; | ||
203 | unsigned long long ret; | ||
204 | char *in; | ||
205 | const char *tok; | ||
206 | unsigned long long last; | ||
207 | unsigned int i; | ||
208 | |||
209 | ret = 0; | ||
210 | last = 0; | ||
211 | in = GNUNET_strdup (fancy_size); | ||
212 | for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " ")) | ||
213 | { | ||
214 | fprintf (stderr, "%s - %llu %llu\n", tok, ret, last); | ||
215 | i=0; | ||
216 | while ( (table[i].name != NULL) && | ||
217 | (0 != strcasecmp (table[i].name, tok) ) ) | ||
218 | i++; | ||
219 | if (table[i].name != NULL) | ||
220 | last *= table[i].value; | ||
221 | else | ||
222 | { | ||
223 | ret += last; | ||
224 | last = 0; | ||
225 | if (1 != sscanf (tok, "%llu", &last)) | ||
226 | return GNUNET_SYSERR; /* expected number */ | ||
227 | } | ||
228 | } | ||
229 | ret += last; | ||
230 | *size = ret; | ||
231 | return GNUNET_OK; | ||
232 | } | ||
233 | |||
234 | |||
235 | /** | ||
236 | * Convert a given fancy human-readable time to our internal | ||
237 | * representation. | ||
238 | * | ||
239 | * @param fancy_size human readable string (i.e. 1 minute) | ||
240 | * @param rtime set to the relative time | ||
241 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
242 | */ | ||
243 | int | ||
244 | GNUNET_STRINGS_fancy_time_to_relative (const char *fancy_size, | ||
245 | struct GNUNET_TIME_Relative *rtime) | ||
246 | { | ||
247 | struct { | ||
248 | const char *name; | ||
249 | unsigned long long value; | ||
250 | } table[] = { | ||
251 | { "ms", 1 }, | ||
252 | { "s", 1000 }, | ||
253 | { "\"", 1000 }, | ||
254 | { "min", 60 * 1000 }, | ||
255 | { "minutes", 60 * 1000 }, | ||
256 | { "'", 60 * 1000 }, | ||
257 | { "h", 60 * 60 * 1000 }, | ||
258 | { "d", 24 * 60 * 60 * 1000 }, | ||
259 | { "a", 31557600 /* year */ }, | ||
260 | { NULL, 0 } | ||
261 | }; | ||
262 | unsigned long long ret; | ||
263 | char *in; | ||
264 | const char *tok; | ||
265 | unsigned long long last; | ||
266 | unsigned int i; | ||
267 | |||
268 | if ((0 == strcasecmp (fancy_size, "infinity")) || | ||
269 | (0 == strcasecmp (fancy_size, "forever"))) | ||
270 | { | ||
271 | *rtime = GNUNET_TIME_UNIT_FOREVER_REL; | ||
272 | return GNUNET_OK; | ||
273 | } | ||
274 | ret = 0; | ||
275 | last = 0; | ||
276 | in = GNUNET_strdup (fancy_size); | ||
277 | for (tok = strtok (in, " "); tok != NULL; tok = strtok (NULL, " ")) | ||
278 | { | ||
279 | i=0; | ||
280 | while ( (table[i].name != NULL) && | ||
281 | (0 != strcasecmp (table[i].name, tok) ) ) | ||
282 | i++; | ||
283 | if (table[i].name != NULL) | ||
284 | last *= table[i].value; | ||
285 | else | ||
286 | { | ||
287 | ret += last; | ||
288 | last = 0; | ||
289 | if (1 != sscanf (tok, "%llu", &last)) | ||
290 | return GNUNET_SYSERR; /* expected number */ | ||
291 | } | ||
292 | } | ||
293 | ret += last; | ||
294 | rtime->rel_value = (uint64_t) ret; | ||
295 | return GNUNET_OK; | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | ||
174 | * Convert the len characters long character sequence | 300 | * Convert the len characters long character sequence |
175 | * given in input that is in the given charset | 301 | * given in input that is in the given charset |
176 | * to UTF-8. | 302 | * to UTF-8. |
diff --git a/src/util/test_configuration.c b/src/util/test_configuration.c index 4a993923b..9deb4fc35 100644 --- a/src/util/test_configuration.c +++ b/src/util/test_configuration.c | |||
@@ -337,6 +337,17 @@ testConfig () | |||
337 | } | 337 | } |
338 | GNUNET_free (c); | 338 | GNUNET_free (c); |
339 | 339 | ||
340 | if (GNUNET_OK != | ||
341 | GNUNET_CONFIGURATION_get_value_size (cfg, "last", "size", &l)) | ||
342 | { | ||
343 | GNUNET_break (0); | ||
344 | return 10; | ||
345 | } | ||
346 | if (l != 512 * 1024) | ||
347 | { | ||
348 | GNUNET_break (0); | ||
349 | return 11; | ||
350 | } | ||
340 | return 0; | 351 | return 0; |
341 | } | 352 | } |
342 | 353 | ||
diff --git a/src/util/test_configuration_data.conf b/src/util/test_configuration_data.conf index c3452c381..517cbf0b0 100644 --- a/src/util/test_configuration_data.conf +++ b/src/util/test_configuration_data.conf | |||
@@ -19,6 +19,7 @@ five=42 | |||
19 | test = $SUBST/world | 19 | test = $SUBST/world |
20 | boom = "1 2 3 testing" | 20 | boom = "1 2 3 testing" |
21 | trailing = YES | 21 | trailing = YES |
22 | size = 512 KiB | ||
22 | 23 | ||
23 | [FILENAMES] | 24 | [FILENAMES] |
24 | test = "/Hello /File\ Name /World" | 25 | test = "/Hello /File\ Name /World" |