%% options copyright owner = Dirk Krause copyright year = 2015-xxxx SPDX-License-Identifier: BSD-3-Clause %% header /** @file Retrieve size_t value from 8 bit character string in decimal notation. CRT on Windows: Optional, disabling CRT degrades performance. */ #ifndef DK4CONF_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4conf.h" #else #include #endif #endif #ifndef DK4TYPES_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4types.h" #else #include #endif #endif #ifndef DK4ERROR_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4error.h" #else #include #endif #endif #ifdef __cplusplus extern "C" { #endif /** Retrieve numeric value from string, decimal notation. @param rp Pointer to result variable for the found value. @param src String to check for numeric value. In addition to the numeric value the string can contain a suffix 'K', 'M', 'G', 'T', 'P', 'E', 'Z' or 'Y' to indicate multiples of powers of 1024 (kibibytes, mibibytes...). Suffixes 'k', 'm', 'g', 't', 'p', 'e', 'z' or 'y' indicate multiples of powers of 1000 (kilobytes, megabytes...). @param endptr Address of pointer variable. A pointer to the first character not processed is stored here. The function may also store a NULL pointer in this variable. The variable points to the correct error position only if er.ec is DK4_E_SYNTAX. @param atg Allow trailing garbage: 0=no unprocessable trailing bytes allowed, 1=trailing whitespaces allowed, 2=any trailing characters allowed. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: DK4_E_INVALID_ARGUMENTS if rp or src is NULL, DK4_E_MATH_OVERFLOW if the number is out of range, or DK4_E_SYNTAX if src contains illegal characters. */ int dk4ma_input_c8_dec_size_t( size_t *rp, const char *src, const char **endptr, int atg, dk4_er_t *erp ); /** Retrieve numeric value from string, decimal notation. @param rp Pointer to result variable for the found value. @param src String to check for numeric value. No suffixes allowed. @param endptr Address of pointer variable. A pointer to the first character not processed is stored here. The function may also store a NULL pointer in this variable. The variable points to the correct error position only if er.ec is DK4_E_SYNTAX. @param atg Allow trailing garbage: 0=no unprocessable trailing bytes allowed, 1=trailing whitespaces allowed, 2=any trailing characters allowed. @param erp Error report, may be NULL. @return 1 on success, 0 on error. Error codes: DK4_E_INVALID_ARGUMENTS if rp or src is NULL, DK4_E_MATH_OVERFLOW if the number is out of range, or DK4_E_SYNTAX if src contains illegal characters. */ int dk4ma_input_c8_dec_size_t_simple( size_t *rp, const char *src, const char **endptr, int atg, dk4_er_t *erp ); #ifdef __cplusplus } #endif %% module #include "dk4conf.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #include "dk4mai8ddu.h" #include "dk4mai8dsz.h" #include "dk4maasz.h" #include "dk4numco.h" #include "dk4str8.h" int dk4ma_input_c8_dec_size_t( size_t *rp, const char *src, const char **endptr, int atg, dk4_er_t *erp ) { const char *myend = NULL; dk4_um_t um = (dk4_um_t)0UL; size_t res = 0; size_t xf = 1024; size_t factor = 1; size_t nloop = 0; int back = 0; #if DK4_USE_ASSERT assert(NULL != rp); assert(NULL != src); #endif if ((NULL != rp) && (NULL != src)) { if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, src, &myend, 2, erp)) { if (((dk4_um_t)(SIZE_MAX)) >= um) { res = (size_t)um; if (NULL != myend) { back = 1; switch (*myend) { case 'K': { nloop = 1; myend++; } break; case 'M': { nloop = 2; myend++; } break; case 'G': { nloop = 3; myend++; } break; case 'T': { nloop = 4; myend++; } break; case 'P': { nloop = 5; myend++; } break; case 'E': { nloop = 6; myend++; } break; case 'Z': { nloop = 7; myend++; } break; case 'Y': { nloop = 8; myend++; } break; case 'k': { nloop = 1; myend++; xf = 1000; } break; case 'm': { nloop = 2; myend++; xf = 1000; } break; case 'g': { nloop = 3; myend++; xf = 1000; } break; case 't': { nloop = 4; myend++; xf = 1000; } break; case 'p': { nloop = 5; myend++; xf = 1000; } break; case 'e': { nloop = 6; myend++; xf = 1000; } break; case 'z': { nloop = 7; myend++; xf = 1000; } break; case 'y': { nloop = 8; myend++; xf = 1000; } break; } while (nloop--) { if ((SIZE_MAX / xf) >= factor) { factor *= xf; } else { back = 0; dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } if (0 != back) { if ((SIZE_MAX / factor) >= res) { res *= factor; switch (atg) { case 2: { *rp = res; } break; case 1: { myend = dk4str8_start(myend, NULL); if (NULL != myend) { back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } else { *rp = res; } } break; default: { back = 0; dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } break; } } else { back = 0; dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } else { dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } else { *rp = res; back = 1; } } else { dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } if (NULL != endptr) { *endptr = myend; } return back; } int dk4ma_input_c8_dec_size_t_simple( size_t *rp, const char *src, const char **endptr, int atg, dk4_er_t *erp ) { const char *myend = NULL; dk4_um_t um = (dk4_um_t)0UL; int back = 0; #if DK4_USE_ASSERT assert(NULL != rp); assert(NULL != src); #endif if ((NULL != rp) && (NULL != src)) { if (0 != dk4ma_input_c8_dec_dk4_um_t(&um, src, &myend, atg, erp)) { if (((dk4_um_t)(SIZE_MAX)) >= um) { *rp = (size_t)um; back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW); } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } if (NULL != endptr) { *endptr = myend; } return back; }