soci-cstrtoi.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //
  2. // Copyright (C) 2020 Vadim Zeitlin.
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED
  8. #define SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED
  9. #include "soci/error.h"
  10. #include <cstdlib>
  11. #include <limits>
  12. namespace soci
  13. {
  14. namespace details
  15. {
  16. // Convert string to a signed value of the given type, checking for overflow.
  17. //
  18. // Fill the provided result parameter and return true on success or false on
  19. // error, e.g. if the string couldn't be converted at all, if anything remains
  20. // in the string after conversion or if the value is out of range.
  21. template <typename T>
  22. bool cstring_to_integer(T& result, char const* buf)
  23. {
  24. char * end;
  25. // No strtoll() on MSVC versions prior to Visual Studio 2013
  26. #if !defined (_MSC_VER) || (_MSC_VER >= 1800)
  27. long long t = strtoll(buf, &end, 10);
  28. #else
  29. long long t = _strtoi64(buf, &end, 10);
  30. #endif
  31. if (end == buf || *end != '\0')
  32. return false;
  33. // successfully converted to long long
  34. // and no other characters were found in the buffer
  35. const T max = (std::numeric_limits<T>::max)();
  36. const T min = (std::numeric_limits<T>::min)();
  37. if (t > static_cast<long long>(max) || t < static_cast<long long>(min))
  38. return false;
  39. result = static_cast<T>(t);
  40. return true;
  41. }
  42. // Similar to the above, but for the unsigned integral types.
  43. template <typename T>
  44. bool cstring_to_unsigned(T& result, char const* buf)
  45. {
  46. char * end;
  47. // No strtoll() on MSVC versions prior to Visual Studio 2013
  48. #if !defined (_MSC_VER) || (_MSC_VER >= 1800)
  49. unsigned long long t = strtoull(buf, &end, 10);
  50. #else
  51. unsigned long long t = _strtoui64(buf, &end, 10);
  52. #endif
  53. if (end == buf || *end != '\0')
  54. return false;
  55. // successfully converted to unsigned long long
  56. // and no other characters were found in the buffer
  57. const T max = (std::numeric_limits<T>::max)();
  58. if (t > static_cast<unsigned long long>(max))
  59. return false;
  60. result = static_cast<T>(t);
  61. return true;
  62. }
  63. } // namespace details
  64. } // namespace soci
  65. #endif // SOCI_PRIVATE_SOCI_CSTRTOI_H_INCLUDED