* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
*
***************************************************************************/
+#include <errno.h>
#include "curl_setup.h"
#include "strtoofft.h"
*
* In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
* could use in case strtoll() doesn't exist... See
- * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
+ * 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. */
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;
else
value = CURL_OFF_T_MAX;
- SET_ERRNO(ERANGE);
+ errno = ERANGE;
}
if(endptr)
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;
+}