mirror of
https://github.com/SOCI/soci.git
synced 2026-05-24 14:09:04 -05:00
Use cstring_to_integer() in other backends too
Replace all the other uses of sscanf("%lld") and "%llu" with the calls
to cstring_to_integer() and cstring_to_unsigned() respectively, which
should be faster and provide better error checking.
There should be no change in behaviour.
This commit is contained in:
@@ -8,10 +8,10 @@
|
||||
#define SOCI_ODBC_SOURCE
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/odbc/soci-odbc.h"
|
||||
#include "soci-cstrtoi.h"
|
||||
#include "soci-exchange-cast.h"
|
||||
#include "soci-mktime.h"
|
||||
#include <ctime>
|
||||
#include <stdio.h> // sscanf()
|
||||
|
||||
using namespace soci;
|
||||
using namespace soci::details;
|
||||
@@ -182,7 +182,7 @@ void odbc_standard_into_type_backend::post_fetch(
|
||||
else if (type_ == x_long_long && use_string_for_bigint())
|
||||
{
|
||||
long long& ll = exchange_type_cast<x_long_long>(data_);
|
||||
if (sscanf(buf_, "%" LL_FMT_FLAGS "d", &ll) != 1)
|
||||
if (!cstring_to_integer(ll, buf_))
|
||||
{
|
||||
throw soci_error("Failed to parse the returned 64-bit integer value");
|
||||
}
|
||||
@@ -190,7 +190,7 @@ void odbc_standard_into_type_backend::post_fetch(
|
||||
else if (type_ == x_unsigned_long_long && use_string_for_bigint())
|
||||
{
|
||||
unsigned long long& ll = exchange_type_cast<x_unsigned_long_long>(data_);
|
||||
if (sscanf(buf_, "%" LL_FMT_FLAGS "u", &ll) != 1)
|
||||
if (!cstring_to_unsigned(ll, buf_))
|
||||
{
|
||||
throw soci_error("Failed to parse the returned 64-bit integer value");
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define SOCI_ODBC_SOURCE
|
||||
#include "soci/soci-platform.h"
|
||||
#include "soci/odbc/soci-odbc.h"
|
||||
#include "soci-cstrtoi.h"
|
||||
#include "soci-mktime.h"
|
||||
#include "soci-static-assert.h"
|
||||
#include <cctype>
|
||||
@@ -15,7 +16,6 @@
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <stdio.h> // sscanf()
|
||||
|
||||
using namespace soci;
|
||||
using namespace soci::details;
|
||||
@@ -285,7 +285,7 @@ void odbc_vector_into_type_backend::post_fetch(bool gotData, indicator *ind)
|
||||
std::size_t const vsize = v.size();
|
||||
for (std::size_t i = 0; i != vsize; ++i)
|
||||
{
|
||||
if (sscanf(pos, "%" LL_FMT_FLAGS "d", &v[i]) != 1)
|
||||
if (!cstring_to_integer(v[i], pos))
|
||||
{
|
||||
throw soci_error("Failed to parse the returned 64-bit integer value");
|
||||
}
|
||||
@@ -301,7 +301,7 @@ void odbc_vector_into_type_backend::post_fetch(bool gotData, indicator *ind)
|
||||
std::size_t const vsize = v.size();
|
||||
for (std::size_t i = 0; i != vsize; ++i)
|
||||
{
|
||||
if (sscanf(pos, "%" LL_FMT_FLAGS "u", &v[i]) != 1)
|
||||
if (!cstring_to_unsigned(v[i], pos))
|
||||
{
|
||||
throw soci_error("Failed to parse the returned 64-bit integer value");
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
namespace soci { namespace details { namespace sqlite3 {
|
||||
|
||||
@@ -33,52 +32,6 @@ void resize_vector(void *p, std::size_t sz)
|
||||
v->resize(sz);
|
||||
}
|
||||
|
||||
// helper function for parsing integers
|
||||
template <typename T>
|
||||
T string_to_integer(char const * buf)
|
||||
{
|
||||
long long t(0);
|
||||
int n(0);
|
||||
int const converted = std::sscanf(buf, "%" LL_FMT_FLAGS "d%n", &t, &n);
|
||||
if (converted == 1 && static_cast<std::size_t>(n) == std::strlen(buf))
|
||||
{
|
||||
// successfully converted to long long
|
||||
// and no other characters were found in the buffer
|
||||
|
||||
const T max = (std::numeric_limits<T>::max)();
|
||||
const T min = (std::numeric_limits<T>::min)();
|
||||
if (t <= static_cast<long long>(max) &&
|
||||
t >= static_cast<long long>(min))
|
||||
{
|
||||
return static_cast<T>(t);
|
||||
}
|
||||
}
|
||||
|
||||
throw soci_error("Cannot convert data.");
|
||||
}
|
||||
|
||||
// helper function for parsing unsigned integers
|
||||
template <typename T>
|
||||
T string_to_unsigned_integer(char const * buf)
|
||||
{
|
||||
unsigned long long t(0);
|
||||
int n(0);
|
||||
int const converted = std::sscanf(buf, "%" LL_FMT_FLAGS "u%n", &t, &n);
|
||||
if (converted == 1 && static_cast<std::size_t>(n) == std::strlen(buf))
|
||||
{
|
||||
// successfully converted to unsigned long long
|
||||
// and no other characters were found in the buffer
|
||||
|
||||
T const max = (std::numeric_limits<T>::max)();
|
||||
if (t <= static_cast<unsigned long long>(max))
|
||||
{
|
||||
return static_cast<T>(t);
|
||||
}
|
||||
}
|
||||
|
||||
throw soci_error("Cannot convert data.");
|
||||
}
|
||||
|
||||
}}} // namespace soci::details::sqlite3
|
||||
|
||||
#endif // SOCI_SQLITE3_COMMON_H_INCLUDED
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#define SOCI_SQLITE3_SOURCE
|
||||
#include "soci-cstrtoi.h"
|
||||
#include "soci-dtocstr.h"
|
||||
#include "soci-exchange-cast.h"
|
||||
#include "soci/blob.h"
|
||||
@@ -64,7 +65,13 @@ void set_number_in_vector(void *p, int idx, const sqlite3_column &col)
|
||||
case dt_date:
|
||||
case dt_string:
|
||||
case dt_blob:
|
||||
set_in_vector(p, idx, string_to_integer<T>(col.buffer_.size_ > 0 ? col.buffer_.constData_ : ""));
|
||||
{
|
||||
T value;
|
||||
if (!details::cstring_to_integer(value, col.buffer_.size_ > 0 ? col.buffer_.constData_ : ""))
|
||||
throw soci_error("Cannot convert data");
|
||||
|
||||
set_in_vector(p, idx, value);
|
||||
}
|
||||
break;
|
||||
|
||||
case dt_double:
|
||||
|
||||
Reference in New Issue
Block a user