conversions.c: Add conversions for largest max sized integer
[asterisk/asterisk.git] / main / conversions.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2017, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Conversion utility functions
20  */
21
22 /*** MODULEINFO
23         <support_level>core</support_level>
24  ***/
25
26 #include <ctype.h>
27 #include <errno.h>
28 #include <limits.h>
29 #include <inttypes.h>
30 #include <stdio.h>
31
32 #include "asterisk/conversions.h"
33
34 static int str_is_negative(const char **str)
35 {
36         /*
37          * Ignore any preceding white space. It's okay to move the pointer here
38          * since the converting function would do the same, i.e. skip white space.
39          */
40         while (isspace(**str)) ++*str;
41         return **str == '-';
42 }
43
44 int ast_str_to_uint(const char *str, unsigned int *res)
45 {
46         uintmax_t val;
47
48         if (ast_str_to_umax(str, &val) || val > UINT_MAX) {
49                 return -1;
50         }
51
52         *res = val;
53         return 0;
54 }
55
56 int ast_str_to_ulong(const char *str, unsigned long *res)
57 {
58         uintmax_t val;
59
60         if (ast_str_to_umax(str, &val) || val > ULONG_MAX) {
61                 return -1;
62         }
63
64         *res = val;
65         return 0;
66 }
67
68 int ast_str_to_umax(const char *str, uintmax_t *res)
69 {
70         char *end;
71         uintmax_t val;
72
73         if (!str || str_is_negative(&str)) {
74                 return -1;
75         }
76
77         errno = 0;
78         val = strtoumax(str, &end, 0);
79
80         /*
81          * If str equals end then no digits were found. If end is not pointing to
82          * a null character then the string contained some numbers that could be
83          * converted, but some characters that could not, which we'll consider
84          * invalid.
85          */
86         if ((str == end || *end != '\0' || (errno == ERANGE && val == UINTMAX_MAX))) {
87                 return -1;
88         }
89
90         *res = val;
91         return 0;
92 }