1 | #include <mysqlxx/Value.h> |
---|---|
2 | #include <mysqlxx/ResultBase.h> |
3 | #include <mysqlxx/Query.h> |
4 | #include <mysqlxx/Exception.h> |
5 | |
6 | |
7 | namespace mysqlxx |
8 | { |
9 | |
10 | UInt64 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 | |
44 | Int64 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 | |
82 | double 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 | |
155 | void 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 |