1#include <mysqlxx/Value.h>
2#include <mysqlxx/ResultBase.h>
3#include <mysqlxx/Query.h>
4#include <mysqlxx/Exception.h>
5
6
7namespace mysqlxx
8{
9
10UInt64 Value::readUIntText(const char * buf, size_t length) const
11{
12 UInt64 x = 0;
13 const char * end = buf + length;
14
15 while (buf != end)
16 {
17 switch (*buf)
18 {
19 case '+':
20 break;
21 case '0':
22 case '1':
23 case '2':
24 case '3':
25 case '4':
26 case '5':
27 case '6':
28 case '7':
29 case '8':
30 case '9':
31 x *= 10;
32 x += *buf - '0';
33 break;
34 default:
35 throwException("Cannot parse unsigned integer");
36 }
37 ++buf;
38 }
39
40 return x;
41}
42
43
44Int64 Value::readIntText(const char * buf, size_t length) const
45{
46 bool negative = false;
47 UInt64 x = 0;
48 const char * end = buf + length;
49
50 while (buf != end)
51 {
52 switch (*buf)
53 {
54 case '+':
55 break;
56 case '-':
57 negative = true;
58 break;
59 case '0':
60 case '1':
61 case '2':
62 case '3':
63 case '4':
64 case '5':
65 case '6':
66 case '7':
67 case '8':
68 case '9':
69 x *= 10;
70 x += *buf - '0';
71 break;
72 default:
73 throwException("Cannot parse signed integer");
74 }
75 ++buf;
76 }
77
78 return negative ? -x : x;
79}
80
81
82double Value::readFloatText(const char * buf, size_t length) const
83{
84 bool negative = false;
85 double x = 0;
86 bool after_point = false;
87 double power_of_ten = 1;
88 const char * end = buf + length;
89
90 while (buf != end)
91 {
92 switch (*buf)
93 {
94 case '+':
95 break;
96 case '-':
97 negative = true;
98 break;
99 case '.':
100 after_point = true;
101 break;
102 case '0':
103 case '1':
104 case '2':
105 case '3':
106 case '4':
107 case '5':
108 case '6':
109 case '7':
110 case '8':
111 case '9':
112 if (after_point)
113 {
114 power_of_ten /= 10;
115 x += (*buf - '0') * power_of_ten;
116 }
117 else
118 {
119 x *= 10;
120 x += *buf - '0';
121 }
122 break;
123 case 'e':
124 case 'E':
125 {
126 ++buf;
127 Int32 exponent = readIntText(buf, end - buf);
128 x *= preciseExp10(exponent);
129 if (negative)
130 x = -x;
131 return x;
132 }
133 case 'i':
134 case 'I':
135 x = std::numeric_limits<double>::infinity();
136 if (negative)
137 x = -x;
138 return x;
139 case 'n':
140 case 'N':
141 x = std::numeric_limits<double>::quiet_NaN();
142 return x;
143 default:
144 throwException("Cannot parse floating point number");
145 }
146 ++buf;
147 }
148 if (negative)
149 x = -x;
150
151 return x;
152}
153
154
155void Value::throwException(const char * text) const
156{
157 static constexpr size_t MYSQLXX_QUERY_PREVIEW_LENGTH = 1000;
158
159 std::stringstream info;
160 info << text;
161
162 if (!isNull())
163 {
164 info << ": ";
165 info.write(m_data, m_length);
166 }
167
168 if (res && res->getQuery())
169 info << ", query: " << res->getQuery()->str().substr(0, MYSQLXX_QUERY_PREVIEW_LENGTH);
170
171 throw CannotParseValue(info.str());
172}
173
174}
175