firebird/common.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2006 Maciej Sobczak, Stephen Hutton, Rafal Bobrowski
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 
8 #ifndef SOCI_FIREBIRD_COMMON_H_INCLUDED
9 #define SOCI_FIREBIRD_COMMON_H_INCLUDED
10 
11 #include "soci-firebird.h"
12 #include <cstdlib>
13 #include <cstring>
14 #include <ctime>
15 #include <limits>
16 #include <sstream>
17 #include <iomanip>
18 #include <string>
19 #include <vector>
20 #include <algorithm>
21 
22 namespace soci
23 {
24 
25 namespace details
26 {
27 
28 namespace firebird
29 {
30 
31 char * allocBuffer(XSQLVAR* var);
32 
33 void tmEncode(short type, std::tm * src, void * dst);
34 
35 void tmDecode(short type, void * src, std::tm * dst);
36 
37 void setTextParam(char const * s, std::size_t size, char * buf_,
38  XSQLVAR * var);
39 
40 std::string getTextParam(XSQLVAR const *var);
41 
42 template <typename IntType>
43 const char *str2dec(const char * s, IntType &out, int &scale)
44 {
45  int sign = 1;
46  if ('+' == *s)
47  ++s;
48  else if ('-' == *s)
49  {
50  sign = -1;
51  ++s;
52  }
53  scale = 0;
54  bool period = false;
55  IntType res = 0;
56  for (out = 0; *s; ++s, out = res)
57  {
58  if (*s == '.')
59  {
60  if (period)
61  return s;
62  period = true;
63  continue;
64  }
65  int d = *s - '0';
66  if (d < 0 || d > 9)
67  return s;
68  res = res * 10 + d * sign;
69  if (1 == sign)
70  {
71  if (res < out)
72  return s;
73  }
74  else
75  {
76  if (res > out)
77  return s;
78  }
79  if (period)
80  ++scale;
81  }
82  return s;
83 }
84 
85 template<typename T1>
86 void to_isc(void * val, XSQLVAR * var, int x_scale = 0)
87 {
88  T1 value = *reinterpret_cast<T1*>(val);
89  short scale = var->sqlscale + x_scale;
90  short type = var->sqltype & ~1;
91  long long divisor = 1, multiplier = 1;
92 
93  if ((std::numeric_limits<T1>::is_integer == false) && scale >= 0 &&
94  (type == SQL_SHORT || type == SQL_LONG || type == SQL_INT64))
95  {
96  throw soci_error("Can't convert non-integral value to integral column type");
97  }
98 
99  for (int i = 0; i > scale; --i)
100  multiplier *= 10;
101  for (int i = 0; i < scale; ++i)
102  divisor *= 10;
103 
104  switch (type)
105  {
106  case SQL_SHORT:
107  {
108  short tmp = static_cast<short>(value*multiplier/divisor);
109  std::memcpy(var->sqldata, &tmp, sizeof(short));
110  }
111  break;
112  case SQL_LONG:
113  {
114  int tmp = static_cast<int>(value*multiplier/divisor);
115  std::memcpy(var->sqldata, &tmp, sizeof(int));
116  }
117  break;
118  case SQL_INT64:
119  {
120  long long tmp = static_cast<long long>(value*multiplier/divisor);
121  std::memcpy(var->sqldata, &tmp, sizeof(long long));
122  }
123  break;
124  case SQL_FLOAT:
125  {
126  float sql_value = static_cast<float>(value);
127  std::memcpy(var->sqldata, &sql_value, sizeof(float));
128  }
129  break;
130  case SQL_DOUBLE:
131  {
132  double sql_value = static_cast<double>(value);
133  std::memcpy(var->sqldata, &sql_value, sizeof(double));
134  }
135  break;
136  default:
137  throw soci_error("Incorrect data type for numeric conversion");
138  }
139 }
140 
141 template<typename IntType, typename UIntType>
142 void parse_decimal(void * val, XSQLVAR * var, const char * s)
143 {
144  int scale;
145  UIntType t1;
146  IntType t2;
147  if (!*str2dec(s, t1, scale))
148  std::memcpy(val, &t1, sizeof(t1));
149  else if (!*str2dec(s, t2, scale))
150  std::memcpy(val, &t2, sizeof(t2));
151  else
152  throw soci_error("Could not parse decimal value.");
153  to_isc<IntType>(val, var, scale);
154 }
155 
156 template<typename IntType>
157 std::string format_decimal(const void *sqldata, int sqlscale)
158 {
159  IntType x = *reinterpret_cast<const IntType *>(sqldata);
160  std::stringstream out;
161  out << x;
162  std::string r = out.str();
163  if (sqlscale < 0)
164  {
165  if (static_cast<int>(r.size()) - (x < 0) <= -sqlscale)
166  {
167  r = std::string(size_t(x < 0), '-') +
168  std::string(-sqlscale - (r.size() - (x < 0)) + 1, '0') +
169  r.substr(size_t(x < 0), std::string::npos);
170  }
171  return r.substr(0, r.size() + sqlscale) + '.' +
172  r.substr(r.size() + sqlscale, std::string::npos);
173  }
174  return r + std::string(sqlscale, '0');
175 }
176 
177 template<typename T1>
178 T1 from_isc(XSQLVAR * var)
179 {
180  short scale = var->sqlscale;
181  T1 tens = 1;
182 
183  if (scale < 0)
184  {
185  if (std::numeric_limits<T1>::is_integer)
186  {
187  std::ostringstream msg;
188  msg << "Can't convert value with scale " << -scale
189  << " to integral type";
190  throw soci_error(msg.str());
191  }
192 
193  for (int i = 0; i > scale; --i)
194  {
195  tens *= 10;
196  }
197  }
198 
199  switch (var->sqltype & ~1)
200  {
201  case SQL_SHORT:
202  return static_cast<T1>(*reinterpret_cast<short*>(var->sqldata)/tens);
203  case SQL_LONG:
204  return static_cast<T1>(*reinterpret_cast<int*>(var->sqldata)/tens);
205  case SQL_INT64:
206  return static_cast<T1>(*reinterpret_cast<long long*>(var->sqldata)/tens);
207  case SQL_FLOAT:
208  return static_cast<T1>(*reinterpret_cast<float*>(var->sqldata));
209  case SQL_DOUBLE:
210  return static_cast<T1>(*reinterpret_cast<double*>(var->sqldata));
211  default:
212  throw soci_error("Incorrect data type for numeric conversion");
213  }
214 }
215 
216 template <typename T>
217 std::size_t getVectorSize(void *p)
218 {
219  std::vector<T> *v = static_cast<std::vector<T> *>(p);
220  return v->size();
221 }
222 
223 template <typename T>
224 void resizeVector(void *p, std::size_t sz)
225 {
226  std::vector<T> *v = static_cast<std::vector<T> *>(p);
227  v->resize(sz);
228 }
229 
230 } // namespace firebird
231 
232 } // namespace details
233 
234 } // namespace soci
235 
236 #endif // SOCI_FIREBIRD_COMMON_H_INCLUDED
void tmEncode(short type, std::tm *src, void *dst)
void parse_decimal(void *val, XSQLVAR *var, const char *s)
void setTextParam(char const *s, std::size_t size, char *buf_, XSQLVAR *var)
const char * str2dec(const char *s, IntType &out, int &scale)
T1 from_isc(XSQLVAR *var)
std::string format_decimal(const void *sqldata, int sqlscale)
void to_isc(void *val, XSQLVAR *var, int x_scale=0)
void resizeVector(void *p, std::size_t sz)
char * allocBuffer(XSQLVAR *var)
SOCI_FIREBIRD_DECL firebird_backend_factory const firebird
void tmDecode(short type, void *src, std::tm *dst)
std::size_t getVectorSize(void *p)
std::string getTextParam(XSQLVAR const *var)


asr_lib_ism
Author(s): Hanselmann Fabian, Heller Florian, Heizmann Heinrich, Kübler Marcel, Mehlhaus Jonas, Meißner Pascal, Qattan Mohamad, Reckling Reno, Stroh Daniel
autogenerated on Wed Jan 8 2020 04:02:40