%% options copyright owner = Dirk Krause copyright year = 2015-xxxx SPDX-License-Identifier: BSD-3-Clause %% header /** @file Retrieve size_t value from wchar_t string in decimal notation. */ #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_wc_dec_size_t( size_t *rp, const wchar_t *src, const wchar_t **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_wc_dec_size_t_simple( size_t *rp, const wchar_t *src, const wchar_t **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 "dk4maiwddu.h" #include "dk4maiwdui.h" #include "dk4maiwdsz.h" #include "dk4numco.h" #include "dk4strw.h" int dk4ma_input_wc_dec_size_t( size_t *rp, const wchar_t *src, const wchar_t **endptr, int atg, dk4_er_t *erp ) { const wchar_t *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_wc_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; if (*myend <= (wchar_t)(0x00FFU)) { switch ((int)(*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 = dk4strw_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_wc_dec_size_t_simple( size_t *rp, const wchar_t *src, const wchar_t **endptr, int atg, dk4_er_t *erp ) { const wchar_t *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_wc_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; }