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