| 2595 | static void hex_to_value(const char*& string, const char* end, RetPtr* retValue); |
| 2596 | |
| 2597 | static SSHORT cvt_decompose(const char* string, |
| 2598 | USHORT length, |
| 2599 | RetPtr* return_value, |
| 2600 | ErrorFunction err) |
| 2601 | { |
| 2602 | /************************************** |
| 2603 | * |
| 2604 | * d e c o m p o s e |
| 2605 | * |
| 2606 | ************************************** |
| 2607 | * |
| 2608 | * Functional description |
| 2609 | * Decompose a numeric string in mantissa and exponent, |
| 2610 | * or if it is in hexadecimal notation. |
| 2611 | * |
| 2612 | **************************************/ |
| 2613 | |
| 2614 | dsc errd; |
| 2615 | MOVE_CLEAR(&errd, sizeof(errd)); |
| 2616 | errd.dsc_dtype = dtype_text; |
| 2617 | errd.dsc_ttype() = ttype_ascii; |
| 2618 | errd.dsc_length = length; |
| 2619 | errd.dsc_address = reinterpret_cast<UCHAR*>(const_cast<char*>(string)); |
| 2620 | |
| 2621 | SSHORT scale = 0; |
| 2622 | int sign = 0; |
| 2623 | bool digit_seen = false, fraction = false; |
| 2624 | |
| 2625 | const char* p = string; |
| 2626 | const char* end = p + length; |
| 2627 | |
| 2628 | // skip initial spaces |
| 2629 | while (p < end && *p == ' ') |
| 2630 | ++p; |
| 2631 | |
| 2632 | // Check if this is a numeric hex string. Must start with 0x or 0X, and be |
| 2633 | // no longer than 16 hex digits + 2 (the length of the 0x prefix) = 18. |
| 2634 | if (p + 2 < end && p[0] == '0' && UPPER(p[1]) == 'X') |
| 2635 | { |
| 2636 | p += 2; // skip over 0x part |
| 2637 | |
| 2638 | // skip non spaces |
| 2639 | const char* q = p; |
| 2640 | while (q < end && *q && *q != ' ') |
| 2641 | ++q; |
| 2642 | |
| 2643 | const char* digits_end = q; |
| 2644 | |
| 2645 | // skip trailing spaces |
| 2646 | while (q < end && *q == ' ') |
| 2647 | q++; |
| 2648 | |
| 2649 | if (q != end || end - p == 0 || (end - p) * 4 > return_value->maxSize() * 8) |
| 2650 | { |
| 2651 | CVT_conversion_error(&errd, err); |
| 2652 | return 0; |
| 2653 | } |
| 2654 |
no test coverage detected