File indexing completed on 2025-02-23 05:15:17

0001 //
0002 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef SOCI_MYSQL_COMMON_H_INCLUDED
0009 #define SOCI_MYSQL_COMMON_H_INCLUDED
0010 
0011 #include "soci/mysql/soci-mysql.h"
0012 #include "soci-cstrtod.h"
0013 #include "soci-compiler.h"
0014 // std
0015 #include <cstddef>
0016 #include <ctime>
0017 #include <locale>
0018 #include <sstream>
0019 #include <vector>
0020 
0021 namespace soci
0022 {
0023 
0024 namespace details
0025 {
0026 
0027 namespace mysql
0028 {
0029 
0030 // The idea is that infinity - infinity gives NaN, and NaN != NaN is true.
0031 //
0032 // This should work on any IEEE-754-compliant implementation, which is
0033 // another way of saying that it does not always work (in particular,
0034 // according to stackoverflow, it won't work with gcc with the --fast-math
0035 // option), but I know of no better way of testing this portably in C++ prior
0036 // to C++11.  When soci moves to C++11 this should be replaced
0037 // with std::isfinite().
0038 template <typename T>
0039 bool is_infinity_or_nan(T x)
0040 {
0041     T y = x - x;
0042 
0043     // We really need exact floating point comparison here.
0044     SOCI_GCC_WARNING_SUPPRESS(float-equal)
0045 
0046     return (y != y);
0047 
0048     SOCI_GCC_WARNING_RESTORE(float-equal)
0049 }
0050 
0051 template <typename T>
0052 void parse_num(char const *buf, T &x)
0053 {
0054     std::istringstream iss(buf);
0055     iss >> x;
0056     if (iss.fail() || (iss.eof() == false))
0057     {
0058         throw soci_error("Cannot convert data.");
0059     }
0060 }
0061 
0062 inline
0063 void parse_num(char const *buf, double &x)
0064 {
0065     x = cstring_to_double(buf);
0066 
0067     if (is_infinity_or_nan(x)) {
0068         throw soci_error(std::string("Cannot convert data: string \"") + buf +
0069                          "\" is not a finite number.");
0070     }
0071 }
0072 
0073 // helper for escaping strings
0074 char * quote(MYSQL * conn, const char *s, size_t len);
0075 
0076 // helper for vector operations
0077 template <typename T>
0078 std::size_t get_vector_size(void *p)
0079 {
0080     std::vector<T> *v = static_cast<std::vector<T> *>(p);
0081     return v->size();
0082 }
0083 
0084 } // namespace mysql
0085 
0086 } // namespace details
0087 
0088 } // namespace soci
0089 
0090 #endif // SOCI_MYSQL_COMMON_H_INCLUDED