Skip to content

Commit 3dac84d

Browse files
committed
using builtin decimal converter for unsigned int
1 parent 8ccbbf3 commit 3dac84d

4 files changed

Lines changed: 131 additions & 22 deletions

File tree

noson/src/private/builtin.c

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2014-2023 Jean-Luc Barriere
2+
* Copyright (C) 2014-2024 Jean-Luc Barriere
33
*
44
* This Program is free software; you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -215,6 +215,42 @@ int hex_to_num(const char *str, int *num)
215215
return 0;
216216
}
217217

218+
unsigned uint_to_strdec(unsigned u, char *str, unsigned len, int pad)
219+
{
220+
static const char g[10] = {
221+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
222+
};
223+
if (len)
224+
{
225+
char *ptr = str, *end = str + len;
226+
unsigned n = u, n10 = u / 10;
227+
do
228+
{
229+
*ptr++ = g[n - n10 * 10];
230+
n = n10;
231+
} while ((n10 = n / 10) > 0 && ptr < end);
232+
if (ptr < end)
233+
{
234+
/* push last digit */
235+
if (n > 0)
236+
*ptr++ = g[n];
237+
/* padding */
238+
if (pad)
239+
while (ptr < end) *ptr++ = '0';
240+
}
241+
len = ptr - str;
242+
/* reorder digits */
243+
while (--ptr > str)
244+
{
245+
char c = *str;
246+
*str = *ptr;
247+
*ptr = c;
248+
++str;
249+
}
250+
}
251+
return len;
252+
}
253+
218254
time_t __timegm(struct tm *utctime_tm)
219255
{
220256
time_t time;
@@ -384,13 +420,20 @@ void time_to_iso8601utc(time_t time, BUILTIN_BUFFER *str)
384420
str->data[0] = '\0';
385421
return;
386422
}
387-
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2dZ",
388-
time_tm.tm_year + 1900,
389-
time_tm.tm_mon + 1,
390-
time_tm.tm_mday,
391-
time_tm.tm_hour,
392-
time_tm.tm_min,
393-
time_tm.tm_sec);
423+
/* yyyy-MM-ddTHH:mm:ssZ */
424+
uint_to_strdec(time_tm.tm_year + 1900, str->data, 4, 1);
425+
str->data[4] = '-';
426+
uint_to_strdec(time_tm.tm_mon + 1, str->data + 5, 2, 1);
427+
str->data[7] = '-';
428+
uint_to_strdec(time_tm.tm_mday, str->data + 8, 2, 1);
429+
str->data[10] = 'T';
430+
uint_to_strdec(time_tm.tm_hour, str->data + 11, 2, 1);
431+
str->data[13] = ':';
432+
uint_to_strdec(time_tm.tm_min, str->data + 14, 2, 1);
433+
str->data[16] = ':';
434+
uint_to_strdec(time_tm.tm_sec, str->data + 17, 2, 1);
435+
str->data[19] = 'Z';
436+
str->data[20] = '\0';
394437
}
395438

396439
void time_to_iso8601(time_t time, BUILTIN_BUFFER *str)
@@ -402,13 +445,19 @@ void time_to_iso8601(time_t time, BUILTIN_BUFFER *str)
402445
str->data[0] = '\0';
403446
return;
404447
}
405-
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d",
406-
time_tm.tm_year + 1900,
407-
time_tm.tm_mon + 1,
408-
time_tm.tm_mday,
409-
time_tm.tm_hour,
410-
time_tm.tm_min,
411-
time_tm.tm_sec);
448+
/* yyyy-MM-ddTHH:mm:ss */
449+
uint_to_strdec(time_tm.tm_year + 1900, str->data, 4, 1);
450+
str->data[4] = '-';
451+
uint_to_strdec(time_tm.tm_mon + 1, str->data + 5, 2, 1);
452+
str->data[7] = '-';
453+
uint_to_strdec(time_tm.tm_mday, str->data + 8, 2, 1);
454+
str->data[10] = 'T';
455+
uint_to_strdec(time_tm.tm_hour, str->data + 11, 2, 1);
456+
str->data[13] = ':';
457+
uint_to_strdec(time_tm.tm_min, str->data + 14, 2, 1);
458+
str->data[16] = ':';
459+
uint_to_strdec(time_tm.tm_sec, str->data + 17, 2, 1);
460+
str->data[19] = '\0';
412461
}
413462

414463
void time_to_isodate(time_t time, BUILTIN_BUFFER *str)
@@ -420,10 +469,12 @@ void time_to_isodate(time_t time, BUILTIN_BUFFER *str)
420469
str->data[0] = '\0';
421470
return;
422471
}
423-
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%4.4d-%2.2d-%2.2d",
424-
time_tm.tm_year + 1900,
425-
time_tm.tm_mon + 1,
426-
time_tm.tm_mday);
472+
uint_to_strdec(time_tm.tm_year + 1900, str->data, 4, 1);
473+
str->data[4] = '-';
474+
uint_to_strdec(time_tm.tm_mon + 1, str->data + 5, 2, 1);
475+
str->data[7] = '-';
476+
uint_to_strdec(time_tm.tm_mday, str->data + 8, 2, 1);
477+
str->data[10] = '\0';
427478
}
428479

429480
tz_t *time_tz(time_t time, tz_t* tz) {

noson/src/private/builtin.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,28 @@ static CC_INLINE void int8_to_string(int8_t num, BUILTIN_BUFFER *str)
100100
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%d", num);
101101
}
102102

103+
#define uint_to_strdec __uintstrdec
104+
extern unsigned uint_to_strdec(unsigned u, char *str, unsigned len, int pad);
105+
103106
#define uint32_to_string __uint32str
104107
static CC_INLINE void uint32_to_string(uint32_t num, BUILTIN_BUFFER *str)
105108
{
106-
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%lu", (unsigned long)num);
109+
unsigned len = uint_to_strdec(num, str->data, 10, 0);
110+
str->data[len] = '\0';
107111
}
108112

109113
#define uint16_to_string __uint16str
110114
static CC_INLINE void uint16_to_string(uint16_t num, BUILTIN_BUFFER *str)
111115
{
112-
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%u", num);
116+
unsigned len = uint_to_strdec(num, str->data, 5, 0);
117+
str->data[len] = '\0';
113118
}
114119

115120
#define uint8_to_string __uint8str
116121
static CC_INLINE void uint8_to_string(uint8_t num, BUILTIN_BUFFER *str)
117122
{
118-
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%u", num);
123+
unsigned len = uint_to_strdec(num, str->data, 3, 0);
124+
str->data[len] = '\0';
119125
}
120126

121127
#define double_to_string __doublestr

tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,5 @@ endif ()
6464
unittest_project(NAME check_compressor SOURCES src/check_compressor.cpp TARGET noson)
6565
unittest_project(NAME check_soap_parser SOURCES src/check_soap_parser.cpp TARGET noson)
6666
unittest_project(NAME check_intrinsic SOURCES src/check_intrinsic.cpp TARGET noson)
67+
unittest_project(NAME check_builtin SOURCES src/check_builtin.cpp TARGET noson)
68+

tests/src/check_builtin.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <iostream>
2+
3+
#include "include/testmain.h"
4+
5+
#include <private/builtin.h>
6+
#include <string.h>
7+
#include <string>
8+
9+
TEST_CASE("Decimal converter")
10+
{
11+
BUILTIN_BUFFER buf;
12+
memset(buf.data, '\0', sizeof(buf.data));
13+
14+
uint_to_strdec(1234567890, buf.data, 10, 0);
15+
REQUIRE((strlen(buf.data) == 10));
16+
std::cout << "DEC NO PADDING = " << std::string(buf.data) << std::endl;
17+
REQUIRE((strncmp(buf.data, "1234567890", 10) == 0));
18+
19+
uint_to_strdec(987654321, buf.data, 16, 1);
20+
REQUIRE((strlen(buf.data) == 16));
21+
std::cout << "DEC PADDING 16 = " << std::string(buf.data) << std::endl;
22+
REQUIRE((strncmp(buf.data, "0000000987654321", 16) == 0));
23+
}
24+
25+
TEST_CASE("Time converters")
26+
{
27+
int r = 0;
28+
time_t now = time(0);
29+
time_t chk;
30+
31+
BUILTIN_BUFFER buf;
32+
time_to_iso8601(now, &buf);
33+
r = string_to_time(buf.data, &chk);
34+
REQUIRE(r == 0);
35+
std::cout << "ISO8601 LOC = " << std::string(buf.data) << std::endl;
36+
REQUIRE(chk == now);
37+
38+
BUILTIN_BUFFER buf2;
39+
time_to_isodate(now, &buf2);
40+
REQUIRE((strlen(buf2.data) == 10));
41+
std::cout << "ISODATE LOC = " << std::string(buf2.data) << std::endl;
42+
REQUIRE((strncmp(buf2.data, buf.data, 10) == 0));
43+
44+
time_to_iso8601utc(now, &buf);
45+
r = string_to_time(buf.data, &chk);
46+
REQUIRE(r == 0);
47+
std::cout << "ISO8601 UTC = " << std::string(buf.data) << std::endl;
48+
REQUIRE(chk == now);
49+
}
50+

0 commit comments

Comments
 (0)