aboutsummaryrefslogtreecommitdiffstats
path: root/lib/strtoofft.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/strtoofft.c')
-rw-r--r--lib/strtoofft.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/lib/strtoofft.c b/lib/strtoofft.c
index c2adc728..36364773 100644
--- a/lib/strtoofft.c
+++ b/lib/strtoofft.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -20,6 +20,7 @@
*
***************************************************************************/
+#include <errno.h>
#include "curl_setup.h"
#include "strtoofft.h"
@@ -32,7 +33,29 @@
* https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
*/
-#ifdef NEED_CURL_STRTOLL
+#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG)
+# ifdef HAVE_STRTOLL
+# define strtooff strtoll
+# else
+# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
+# if defined(_SAL_VERSION)
+ _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
+ _In_z_ const char *_String,
+ _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
+# else
+ _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
+ char **_EndPtr, int _Radix);
+# endif
+# define strtooff _strtoi64
+# else
+# define PRIVATE_STRTOOFF 1
+# endif
+# endif
+#else
+# define strtooff strtol
+#endif
+
+#ifdef PRIVATE_STRTOOFF
/* Range tests can be used for alphanum decoding if characters are consecutive,
like in ASCII. Else an array is scanned. Determine this condition now. */
@@ -48,11 +71,10 @@ static const char valchars[] =
static int get_char(char c, int base);
/**
- * Emulated version of the strtoll function. This extracts a long long
+ * Custom version of the strtooff function. This extracts a curl_off_t
* value from the given input string and returns it.
*/
-curl_off_t
-curlx_strtoll(const char *nptr, char **endptr, int base)
+static curl_off_t strtooff(const char *nptr, char **endptr, int base)
{
char *end;
int is_negative = 0;
@@ -186,3 +208,37 @@ static int get_char(char c, int base)
return value;
}
#endif /* Only present if we need strtoll, but don't have it. */
+
+/*
+ * Parse a *positive* up to 64 bit number written in ascii.
+ */
+CURLofft curlx_strtoofft(const char *str, char **endp, int base,
+ curl_off_t *num)
+{
+ char *end;
+ curl_off_t number;
+ errno = 0;
+ *num = 0; /* clear by default */
+
+ DEBUGASSERT(str);
+
+ while(*str && ISSPACE(*str))
+ str++;
+ if('-' == *str) {
+ if(endp)
+ *endp = (char *)str; /* didn't actually move */
+ return CURL_OFFT_INVAL; /* nothing parsed */
+ }
+ number = strtooff(str, &end, base);
+ if(endp)
+ *endp = end;
+ if(errno == ERANGE)
+ /* overflow/underflow */
+ return CURL_OFFT_FLOW;
+ else if(str == end)
+ /* nothing parsed */
+ return CURL_OFFT_INVAL;
+
+ *num = number;
+ return CURL_OFFT_OK;
+}