Imported Upstream version 7.59.0
[platform/upstream/curl.git] / lib / strtoofft.c
index b854bf4..3636477 100644 (file)
@@ -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"
  *
  * 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. */
@@ -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;
@@ -132,7 +154,7 @@ curlx_strtoll(const char *nptr, char **endptr, int base)
     else
       value = CURL_OFF_T_MAX;
 
-    SET_ERRNO(ERANGE);
+    errno = ERANGE;
   }
 
   if(endptr)
@@ -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;
+}