Branch data Line data Source code
1 : : // Copyright 2019-2026 David Robillard <d@drobilla.net> 2 : : // SPDX-License-Identifier: ISC 3 : : 4 : : #include "number_utils.h" 5 : : #include "read_utils.h" 6 : : #include "result.h" 7 : : #include "write_utils.h" 8 : : 9 : : #include <exess/exess.h> 10 : : 11 : : #include <stdbool.h> 12 : : #include <stdint.h> 13 : : #include <stdlib.h> 14 : : 15 : : EXESS_NONBLOCKING EXESS_NONBLOCKING ExessResult 16 : 116780 : exess_read_long(const char* const str, int64_t* const out) 17 : : { 18 : 116780 : *out = 0; 19 : : 20 : : // Skip leading whitespace and read sign if present 21 : 116780 : size_t i = skip_whitespace(str); 22 : 116780 : int sign = 1; 23 : 116780 : i += read_sign(&sign, &str[i]); 24 : : 25 : : // Read digits 26 : 116780 : uint64_t magnitude = 0; 27 : 116780 : ExessResult r = read_digits(&magnitude, str + i); 28 [ + + ]: 116780 : if (r.status) { 29 : 21 : return RESULT(r.status, i + r.count); 30 : : } 31 : : 32 : 116759 : i += r.count; 33 : : 34 [ + + ]: 116759 : if (sign > 0) { 35 [ + + ]: 75592 : if (magnitude > (uint64_t)INT64_MAX) { 36 : 2 : return RESULT(EXESS_OUT_OF_RANGE, i); 37 : : } 38 : : 39 : 75590 : *out = (int64_t)magnitude; 40 : 75590 : return RESULT(EXESS_SUCCESS, i); 41 : : } 42 : : 43 : 41167 : const uint64_t min_magnitude = (uint64_t)(-(INT64_MIN + 1)) + 1; 44 [ + + ]: 41167 : if (magnitude > min_magnitude) { 45 : 1 : return RESULT(EXESS_OUT_OF_RANGE, i); 46 : : } 47 : : 48 [ + + ]: 41166 : if (magnitude == min_magnitude) { 49 : 4 : *out = INT64_MIN; 50 : : } else { 51 : 41162 : *out = -(int64_t)magnitude; 52 : : } 53 : : 54 : 41166 : return RESULT(EXESS_SUCCESS, i); 55 : : } 56 : : 57 : : EXESS_NONBLOCKING EXESS_NONBLOCKING ExessResult 58 : 116925 : exess_write_long(const int64_t value, const size_t buf_size, char* const buf) 59 : : { 60 [ + + ]: 116925 : if (value == INT64_MIN) { 61 : 8 : return end_write( 62 : : EXESS_SUCCESS, 63 : : buf_size, 64 : : buf, 65 : : write_string(20, "-9223372036854775808", buf_size, buf, 0)); 66 : : } 67 : : 68 : 116917 : const bool is_negative = value < 0; 69 [ + + ]: 116917 : const uint64_t abs_value = (uint64_t)(is_negative ? -value : value); 70 : : 71 [ + + ]: 116917 : size_t i = is_negative ? write_char('-', buf_size, buf, 0) : 0; 72 : 116917 : ExessResult r = write_digits(abs_value, buf_size, buf, i); 73 : : 74 : 116917 : return end_write(r.status, buf_size, buf, i + r.count); 75 : : }