| 182 | |
| 183 | |
| 184 | UCHAR CVT_get_numeric(const UCHAR* string, const USHORT length, SSHORT* scale, void* ptr) |
| 185 | { |
| 186 | /************************************** |
| 187 | * |
| 188 | * C V T _ g e t _ n u m e r i c |
| 189 | * |
| 190 | ************************************** |
| 191 | * |
| 192 | * Functional description |
| 193 | * Convert a numeric literal (string) to its binary value. |
| 194 | * |
| 195 | * According to the literal passed (contains an exponent or not, |
| 196 | * what datatype fits) returns long, int64, int128, double or decfloat. |
| 197 | * |
| 198 | * The return value from the function is set to dtype_decfloat, dtype_double, |
| 199 | * dtype_int128, dtype_int64 or dtype_long depending on the conversion performed. |
| 200 | * The binary value is stored at the address given by ptr. |
| 201 | * |
| 202 | **************************************/ |
| 203 | dsc desc; |
| 204 | |
| 205 | MOVE_CLEAR(&desc, sizeof(desc)); |
| 206 | desc.dsc_dtype = dtype_text; |
| 207 | desc.dsc_ttype() = ttype_ascii; |
| 208 | desc.dsc_length = length; |
| 209 | desc.dsc_address = const_cast<UCHAR*>(string); |
| 210 | // The above line allows the assignment, but "string" is treated as const |
| 211 | // for all the purposes here. |
| 212 | |
| 213 | SINT64 value = 0; |
| 214 | SSHORT local_scale = 0, sign = 0; |
| 215 | bool digit_seen = false, fraction = false, over = false; |
| 216 | |
| 217 | const UCHAR* p = string; |
| 218 | if (length > 2 && p[0] == '0' && p[1] == 'X') |
| 219 | { |
| 220 | *(Int128*) ptr = CVT_hex_to_int128(reinterpret_cast<const char*>(p + 2), length - 2); |
| 221 | *scale = 0; |
| 222 | return dtype_int128; |
| 223 | } |
| 224 | |
| 225 | const UCHAR* const end = p + length; |
| 226 | for (; p < end; p++) |
| 227 | { |
| 228 | if (DIGIT(*p)) |
| 229 | { |
| 230 | digit_seen = true; |
| 231 | |
| 232 | // Before computing the next value, make sure there will be |
| 233 | // no overflow. Trying to detect overflow after the fact is |
| 234 | // tricky: the value doesn't always become negative after an |
| 235 | // overflow! |
| 236 | |
| 237 | if (!over) |
| 238 | { |
| 239 | if (static_cast<FB_UINT64>(value) >= NUMERIC_LIMIT) |
| 240 | { |
| 241 | // possibility of an overflow |
no test coverage detected