summaryrefslogtreecommitdiff
path: root/src/ot_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ot_scan.c')
-rw-r--r--src/ot_scan.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/ot_scan.c b/src/ot_scan.c
new file mode 100644
index 0000000..3b8e87c
--- /dev/null
+++ b/src/ot_scan.c
@@ -0,0 +1,65 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4/* System */
5#include <errno.h>
6#include <stdint.h>
7#include <stdlib.h>
8
9/* Opentracker */
10#include "ot_scan.h"
11
12size_t scan_uint(const char *src, uint64_t *dest, uint64_t max) {
13 unsigned long long value;
14 char *end;
15
16 if (*src < '0' || *src > '9')
17 return 0;
18
19 errno = 0;
20 value = strtoull(src, &end, 10);
21
22 if (errno == ERANGE || value > (unsigned long long)max)
23 return 0;
24
25 *dest = (uint64_t)value;
26 return (size_t)(end - src);
27}
28
29size_t scan_uint_bencode(const char *src, uint64_t *dest, uint64_t max) {
30 uint64_t value;
31 size_t consumed = scan_uint(src, &value, max);
32
33 /* bencode writes no leading zeros, so anything longer than a single digit
34 must not begin with one. */
35 if (consumed > 1 && *src == '0')
36 return 0;
37
38 if (consumed)
39 *dest = value;
40
41 return consumed;
42}
43
44int scan_int(const char *src, size_t len, int64_t *dest) {
45 int64_t value = 0;
46 int negate = 0;
47
48 if (len && *src == '-')
49 --len, ++src, negate = 1;
50 if (!len)
51 return -1;
52
53 while (len--) {
54 if (*src < '0' || *src > '9')
55 return -1;
56 /* A twenty character field of nines does not fit, and silently wrapping
57 would magically heal a nonsense announce */
58 if (value > (INT64_MAX - (*src - '0')) / 10)
59 return -1;
60 value = 10 * value + (*src++ - '0');
61 }
62
63 *dest = negate ? -value : value;
64 return 0;
65}