/root/doris/be/src/gutil/strtoint.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2008 Google Inc. All Rights Reserved. |
2 | | // |
3 | | // Architecture-neutral plug compatible replacements for strtol() friends. |
4 | | // |
5 | | // Long's have different lengths on ILP-32 and LP-64 platforms, and so overflow |
6 | | // behavior across the two varies when strtol() and similar are used to parse |
7 | | // 32-bit integers. Similar problems exist with atoi(), because although it |
8 | | // has an all-integer interface, it uses strtol() internally, and so suffers |
9 | | // from the same narrowing problems on assignments to int. |
10 | | // |
11 | | // Examples: |
12 | | // errno = 0; |
13 | | // i = strtol("3147483647", NULL, 10); |
14 | | // printf("%d, errno %d\n", i, errno); |
15 | | // // 32-bit platform: 2147483647, errno 34 |
16 | | // // 64-bit platform: -1147483649, errno 0 |
17 | | // |
18 | | // printf("%d\n", atoi("3147483647")); |
19 | | // // 32-bit platform: 2147483647 |
20 | | // // 64-bit platform: -1147483649 |
21 | | // |
22 | | // A way round this is to define local replacements for these, and use them |
23 | | // instead of the standard libc functions. |
24 | | // |
25 | | // In most 32-bit cases the replacements can be inlined away to a call to the |
26 | | // libc function. In a couple of 64-bit cases, however, adapters are required, |
27 | | // to provide the right overflow and errno behavior. |
28 | | // |
29 | | |
30 | | #pragma once |
31 | | |
32 | | #include <stdlib.h> // For strtol* functions. |
33 | | #include <string> |
34 | | |
35 | | using std::string; |
36 | | #include "gutil/integral_types.h" |
37 | | #include "butil/macros.h" |
38 | | |
39 | | // Adapter functions for handling overflow and errno. |
40 | | int32 strto32_adapter(const char* nptr, char** endptr, int base); |
41 | | uint32 strtou32_adapter(const char* nptr, char** endptr, int base); |
42 | | |
43 | | // Conversions to a 32-bit integer can pass the call to strto[u]l on 32-bit |
44 | | // platforms, but need a little extra work on 64-bit platforms. |
45 | 0 | inline int32 strto32(const char* nptr, char** endptr, int base) { |
46 | 0 | if (sizeof(int32) == sizeof(long)) |
47 | 0 | return static_cast<int32>(strtol(nptr, endptr, base)); |
48 | 0 | else |
49 | 0 | return strto32_adapter(nptr, endptr, base); |
50 | 0 | } |
51 | | |
52 | 0 | inline uint32 strtou32(const char* nptr, char** endptr, int base) { |
53 | 0 | if (sizeof(uint32) == sizeof(unsigned long)) |
54 | 0 | return static_cast<uint32>(strtoul(nptr, endptr, base)); |
55 | 0 | else |
56 | 0 | return strtou32_adapter(nptr, endptr, base); |
57 | 0 | } |
58 | | |
59 | | // For now, long long is 64-bit on all the platforms we care about, so these |
60 | | // functions can simply pass the call to strto[u]ll. |
61 | 0 | inline int64 strto64(const char* nptr, char** endptr, int base) { |
62 | 0 | COMPILE_ASSERT(sizeof(int64) == sizeof(long long), sizeof_int64_is_not_sizeof_long_long); |
63 | 0 | return strtoll(nptr, endptr, base); |
64 | 0 | } |
65 | | |
66 | 0 | inline uint64 strtou64(const char* nptr, char** endptr, int base) { |
67 | 0 | COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long), |
68 | 0 | sizeof_uint64_is_not_sizeof_long_long); |
69 | 0 | return strtoull(nptr, endptr, base); |
70 | 0 | } |
71 | | |
72 | | // Although it returns an int, atoi() is implemented in terms of strtol, and |
73 | | // so has differing overflow and underflow behavior. atol is the same. |
74 | 0 | inline int32 atoi32(const char* nptr) { |
75 | 0 | return strto32(nptr, NULL, 10); |
76 | 0 | } |
77 | | |
78 | 0 | inline int64 atoi64(const char* nptr) { |
79 | 0 | return strto64(nptr, NULL, 10); |
80 | 0 | } |
81 | | |
82 | | // Convenience versions of the above that take a string argument. |
83 | 0 | inline int32 atoi32(const string& s) { |
84 | 0 | return atoi32(s.c_str()); |
85 | 0 | } |
86 | | |
87 | 0 | inline int64 atoi64(const string& s) { |
88 | 0 | return atoi64(s.c_str()); |
89 | 0 | } |