/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* numbers_to_str.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/16 18:15:57 by maiboyer #+# #+# */ /* Updated: 2024/10/10 18:49:27 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/convert/numbers_to_str.h" #include "me/mem/mem.h" #include "me/str/str.h" #include "me/types.h" #include #include static t_error _check_base(t_str base) { t_usize i; t_usize j; i = 0; if (base == NULL) return (ERROR); while (base[i] != '\0') { j = 1; while (base[i + j] != '\0') if (base[i + (j++)] == base[i]) return (ERROR); i++; } if (i <= 1) return (ERROR); return (NO_ERROR); } static void _set_modulus(t_num_str_state *s) { s->modulus = 0; s->base_len = str_len(s->base); if (s->base_len == 10) return ((void)(s->modulus = 10000000000000000000lu)); while (UINT64_MAX - s->modulus > s->base_len) s->modulus += s->base_len; } static char _get_char(t_u64 value, t_num_str_state *s) { if (value == 0) s->zero = true; else s->zero = false; return (s->base[value]); } static t_error _format_u64_base_innner(t_num_str_state *s) { char c; if (s->value == 0) return (s->buffer[s->idx++] = _get_char(0, s), NO_ERROR); while (s->modulus) { c = _get_char(s->value / s->modulus, s); if (s->zero || s->print) { s->buffer[s->idx++] = c; s->print = true; } s->value = s->value % s->modulus; s->modulus /= s->base_len; } return (NO_ERROR); } t_error _format_u64(t_num_str args, t_str *out) { t_num_str_state s; t_str res; if (_check_base(args.base)) return (ERROR); if (args.prefix == NULL) args.prefix = ""; mem_set_zero(&s, sizeof(s)); s.idx = 0; s.base = args.base; if (args.is_nonnegative) s.buffer[s.idx++] = '-'; _set_modulus(&s); s.print = false; if (_format_u64_base_innner(&s)) return (ERROR); res = str_join(args.prefix, s.buffer); if (res == NULL) return (ERROR); return (*out = res, NO_ERROR); }