GFXprim
2D bitmap graphics library with emphasis on speed and correctness
Loading...
Searching...
No Matches
gp_strconv.h
Go to the documentation of this file.
1//SPDX-License-Identifier: LGPL-2.0-or-later
2
3/*
4
5 Copyright (c) 2025 Cyril Hrubis <metan@ucw.cz>
6
7 */
8
14#ifndef UTILS_GP_STRING_H
15#define UTILS_GP_STRING_H
16
17#include <stdbool.h>
18#include <stdint.h>
19#include <limits.h>
20#include <core/gp_common.h>
21
22#define GP_XXTOA_ADD(dst, pos, val) \
23do { \
24 if (dst) \
25 dst[pos] = val; \
26 pos++; \
27} while (0)
28
29#define GP_XXTOA_SWAP(dst, pos) \
30do { \
31 if (dst) { \
32 typeof(pos) i; \
33 for (i = 0; i < pos/2; i++) \
34 GP_SWAP(dst[i], dst[pos-1-i]); \
35 } \
36} while (0)
37
53static inline size_t gp_u32toa(char *dst, uint32_t val, bool null_terminate)
54{
55 size_t pos = 0;
56
57 if (!val) {
58 GP_XXTOA_ADD(dst, pos, '0');
59 goto ret;
60 }
61
62 while (val > 0) {
63 GP_XXTOA_ADD(dst, pos, '0' + (val % 10));
64 val /= 10;
65 }
66
67 GP_XXTOA_SWAP(dst, pos);
68
69ret:
70 if (null_terminate)
71 GP_XXTOA_ADD(dst, pos, 0);
72
73 return pos;
74}
75
91static inline size_t gp_u64toa(char *dst, uint64_t val, bool null_terminate)
92{
93 size_t pos = 0;
94
95 if (!val) {
96 GP_XXTOA_ADD(dst, pos, '0');
97 goto ret;
98 }
99
100 while (val > 0) {
101 GP_XXTOA_ADD(dst, pos, '0' + (val % 10));
102 val /= 10;
103 }
104
105 GP_XXTOA_SWAP(dst, pos);
106
107ret:
108 if (null_terminate)
109 GP_XXTOA_ADD(dst, pos, 0);
110
111 return pos;
112}
113
125static inline size_t gp_utoa(char *dst, unsigned int val, bool null_terminate)
126{
127#if UINT_MAX == UINT32_MAX
128 return gp_u32toa(dst, val, null_terminate);
129#elif UINT_MAX == UINT64_MAX
130 return gp_u64toa(dst, val, null_terminate);
131#else
132# error Unexpected unsigned int size
133#endif
134}
135
147static inline size_t gp_lutoa(char *dst, unsigned long val, bool null_terminate)
148{
149#if ULONG_MAX == UINT32_MAX
150 return gp_u32toa(dst, val, null_terminate);
151#elif ULONG_MAX == UINT64_MAX
152 return gp_u64toa(dst, val, null_terminate);
153#else
154# error Unexpected unsigned long size
155#endif
156}
157
169static inline size_t gp_llutoa(char *dst, unsigned long long val, bool null_terminate)
170{
171#if ULLONG_MAX == UINT32_MAX
172 return gp_u32toa(dst, val, null_terminate);
173#elif ULLONG_MAX == UINT64_MAX
174 return gp_u64toa(dst, val, null_terminate);
175#else
176# error Unexpected unsigned long long size
177#endif
178}
179
180#define GP_ATOXX_OVERFLOW(cur_val, digit, max) \
181 ((cur_val > max/10) || (cur_val == max/10 && digit > max%10))
182
196static inline ssize_t gp_atou32(const char *src, size_t src_len, uint32_t *dst)
197{
198 size_t pos = 0;
199 uint32_t digit;
200
201 *dst = 0;
202
203 while (src[pos] && (!src_len || pos < src_len)) {
204 switch (src[pos]) {
205 case '0' ... '9':
206 digit = src[pos++] - '0';
207
208 if (GP_ATOXX_OVERFLOW(*dst, digit, UINT32_MAX))
209 return -1;
210
211 *dst = 10 * (*dst) + digit;
212 break;
213 default:
214 return pos;
215 }
216 }
217
218 return pos;
219}
220
234static inline ssize_t gp_atou64(const char *src, size_t src_len, uint64_t *dst)
235{
236 size_t pos = 0;
237 uint64_t digit;
238
239 *dst = 0;
240
241 while (src[pos] && (!src_len || pos < src_len)) {
242 switch (src[pos]) {
243 case '0' ... '9':
244 digit = src[pos++] - '0';
245
246 if (GP_ATOXX_OVERFLOW(*dst, digit, UINT64_MAX))
247 return -1;
248
249 *dst = 10 * (*dst) + digit;
250 break;
251 default:
252 return pos;
253 }
254 }
255
256 return pos;
257}
258
272static inline ssize_t gp_atou(const char *src, size_t src_len, unsigned int *dst)
273{
274#if UINT_MAX == UINT32_MAX
275 return gp_atou32(src, src_len, (uint32_t*)dst);
276#elif UINT_MAX == UINT64_MAX
277 return gp_atou64(src, src_len, (uint64_t*)dst);
278#else
279# error Unexpected unsigned int size
280#endif
281}
282
296static inline ssize_t gp_atolu(const char *src, size_t src_len, unsigned long *dst)
297{
298#if ULONG_MAX == UINT32_MAX
299 return gp_atou32(src, src_len, (uint32_t*)dst);
300#elif ULONG_MAX == UINT64_MAX
301 return gp_atou64(src, src_len, (uint64_t*)dst);
302#else
303# error Unexpected unsigned long size
304#endif
305}
306
320static inline ssize_t gp_atollu(const char *src, size_t src_len, unsigned long long *dst)
321{
322#if ULLONG_MAX == UINT32_MAX
323 return gp_atou32(src, src_len, (uint32_t*)dst);
324#elif ULLONG_MAX == UINT64_MAX
325 return gp_atou64(src, src_len, (uint64_t*)dst);
326#else
327# error Unexpected unsigned long long size
328#endif
329}
330
331#endif /* UTILS_GP_STRING_H */
Common macros.
static size_t gp_utoa(char *dst, unsigned int val, bool null_terminate)
Converts an unsigned integer into an ascii representation.
Definition gp_strconv.h:125
static ssize_t gp_atou(const char *src, size_t src_len, unsigned int *dst)
Converts an ASCII string into an unsigned integer.
Definition gp_strconv.h:272
static size_t gp_lutoa(char *dst, unsigned long val, bool null_terminate)
Converts an unsigned long into an ascii representation.
Definition gp_strconv.h:147
static ssize_t gp_atolu(const char *src, size_t src_len, unsigned long *dst)
Converts an ASCII string into an unsigned long.
Definition gp_strconv.h:296
static ssize_t gp_atollu(const char *src, size_t src_len, unsigned long long *dst)
Converts an ASCII string into an unsigned long long.
Definition gp_strconv.h:320
static size_t gp_llutoa(char *dst, unsigned long long val, bool null_terminate)
Converts an unsigned long long into an ascii representation.
Definition gp_strconv.h:169
static size_t gp_u32toa(char *dst, uint32_t val, bool null_terminate)
Converts an unsigned 32bit integer into an ascii representation.
Definition gp_strconv.h:53
static ssize_t gp_atou64(const char *src, size_t src_len, uint64_t *dst)
Converts an ASCII string into an unsigned 64bit integer.
Definition gp_strconv.h:234
static ssize_t gp_atou32(const char *src, size_t src_len, uint32_t *dst)
Converts an ASCII string into an unsigned 32bit integer.
Definition gp_strconv.h:196
static size_t gp_u64toa(char *dst, uint64_t val, bool null_terminate)
Converts an unsigned 64bit integer into an ascii representation.
Definition gp_strconv.h:91