Skip to content

Commit

Permalink
using builtin decimal converter for unsigned int
Browse files Browse the repository at this point in the history
  • Loading branch information
janbar committed Feb 19, 2024
1 parent 8ccbbf3 commit 3dac84d
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 22 deletions.
89 changes: 70 additions & 19 deletions noson/src/private/builtin.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014-2023 Jean-Luc Barriere
* Copyright (C) 2014-2024 Jean-Luc Barriere
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -215,6 +215,42 @@ int hex_to_num(const char *str, int *num)
return 0;
}

unsigned uint_to_strdec(unsigned u, char *str, unsigned len, int pad)
{
static const char g[10] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
if (len)
{
char *ptr = str, *end = str + len;
unsigned n = u, n10 = u / 10;
do
{
*ptr++ = g[n - n10 * 10];
n = n10;
} while ((n10 = n / 10) > 0 && ptr < end);
if (ptr < end)
{
/* push last digit */
if (n > 0)
*ptr++ = g[n];
/* padding */
if (pad)
while (ptr < end) *ptr++ = '0';
}
len = ptr - str;
/* reorder digits */
while (--ptr > str)
{
char c = *str;
*str = *ptr;
*ptr = c;
++str;
}
}
return len;
}

time_t __timegm(struct tm *utctime_tm)
{
time_t time;
Expand Down Expand Up @@ -384,13 +420,20 @@ void time_to_iso8601utc(time_t time, BUILTIN_BUFFER *str)
str->data[0] = '\0';
return;
}
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2dZ",
time_tm.tm_year + 1900,
time_tm.tm_mon + 1,
time_tm.tm_mday,
time_tm.tm_hour,
time_tm.tm_min,
time_tm.tm_sec);
/* yyyy-MM-ddTHH:mm:ssZ */
uint_to_strdec(time_tm.tm_year + 1900, str->data, 4, 1);
str->data[4] = '-';
uint_to_strdec(time_tm.tm_mon + 1, str->data + 5, 2, 1);
str->data[7] = '-';
uint_to_strdec(time_tm.tm_mday, str->data + 8, 2, 1);
str->data[10] = 'T';
uint_to_strdec(time_tm.tm_hour, str->data + 11, 2, 1);
str->data[13] = ':';
uint_to_strdec(time_tm.tm_min, str->data + 14, 2, 1);
str->data[16] = ':';
uint_to_strdec(time_tm.tm_sec, str->data + 17, 2, 1);
str->data[19] = 'Z';
str->data[20] = '\0';
}

void time_to_iso8601(time_t time, BUILTIN_BUFFER *str)
Expand All @@ -402,13 +445,19 @@ void time_to_iso8601(time_t time, BUILTIN_BUFFER *str)
str->data[0] = '\0';
return;
}
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d",
time_tm.tm_year + 1900,
time_tm.tm_mon + 1,
time_tm.tm_mday,
time_tm.tm_hour,
time_tm.tm_min,
time_tm.tm_sec);
/* yyyy-MM-ddTHH:mm:ss */
uint_to_strdec(time_tm.tm_year + 1900, str->data, 4, 1);
str->data[4] = '-';
uint_to_strdec(time_tm.tm_mon + 1, str->data + 5, 2, 1);
str->data[7] = '-';
uint_to_strdec(time_tm.tm_mday, str->data + 8, 2, 1);
str->data[10] = 'T';
uint_to_strdec(time_tm.tm_hour, str->data + 11, 2, 1);
str->data[13] = ':';
uint_to_strdec(time_tm.tm_min, str->data + 14, 2, 1);
str->data[16] = ':';
uint_to_strdec(time_tm.tm_sec, str->data + 17, 2, 1);
str->data[19] = '\0';
}

void time_to_isodate(time_t time, BUILTIN_BUFFER *str)
Expand All @@ -420,10 +469,12 @@ void time_to_isodate(time_t time, BUILTIN_BUFFER *str)
str->data[0] = '\0';
return;
}
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%4.4d-%2.2d-%2.2d",
time_tm.tm_year + 1900,
time_tm.tm_mon + 1,
time_tm.tm_mday);
uint_to_strdec(time_tm.tm_year + 1900, str->data, 4, 1);
str->data[4] = '-';
uint_to_strdec(time_tm.tm_mon + 1, str->data + 5, 2, 1);
str->data[7] = '-';
uint_to_strdec(time_tm.tm_mday, str->data + 8, 2, 1);
str->data[10] = '\0';
}

tz_t *time_tz(time_t time, tz_t* tz) {
Expand Down
12 changes: 9 additions & 3 deletions noson/src/private/builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,28 @@ static CC_INLINE void int8_to_string(int8_t num, BUILTIN_BUFFER *str)
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%d", num);
}

#define uint_to_strdec __uintstrdec
extern unsigned uint_to_strdec(unsigned u, char *str, unsigned len, int pad);

#define uint32_to_string __uint32str
static CC_INLINE void uint32_to_string(uint32_t num, BUILTIN_BUFFER *str)
{
snprintf(str->data, sizeof(BUILTIN_BUFFER), "%lu", (unsigned long)num);
unsigned len = uint_to_strdec(num, str->data, 10, 0);
str->data[len] = '\0';
}

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

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

#define double_to_string __doublestr
Expand Down
2 changes: 2 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ endif ()
unittest_project(NAME check_compressor SOURCES src/check_compressor.cpp TARGET noson)
unittest_project(NAME check_soap_parser SOURCES src/check_soap_parser.cpp TARGET noson)
unittest_project(NAME check_intrinsic SOURCES src/check_intrinsic.cpp TARGET noson)
unittest_project(NAME check_builtin SOURCES src/check_builtin.cpp TARGET noson)

50 changes: 50 additions & 0 deletions tests/src/check_builtin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <iostream>

#include "include/testmain.h"

#include <private/builtin.h>
#include <string.h>
#include <string>

TEST_CASE("Decimal converter")
{
BUILTIN_BUFFER buf;
memset(buf.data, '\0', sizeof(buf.data));

uint_to_strdec(1234567890, buf.data, 10, 0);
REQUIRE((strlen(buf.data) == 10));
std::cout << "DEC NO PADDING = " << std::string(buf.data) << std::endl;
REQUIRE((strncmp(buf.data, "1234567890", 10) == 0));

uint_to_strdec(987654321, buf.data, 16, 1);
REQUIRE((strlen(buf.data) == 16));
std::cout << "DEC PADDING 16 = " << std::string(buf.data) << std::endl;
REQUIRE((strncmp(buf.data, "0000000987654321", 16) == 0));
}

TEST_CASE("Time converters")
{
int r = 0;
time_t now = time(0);
time_t chk;

BUILTIN_BUFFER buf;
time_to_iso8601(now, &buf);
r = string_to_time(buf.data, &chk);
REQUIRE(r == 0);
std::cout << "ISO8601 LOC = " << std::string(buf.data) << std::endl;
REQUIRE(chk == now);

BUILTIN_BUFFER buf2;
time_to_isodate(now, &buf2);
REQUIRE((strlen(buf2.data) == 10));
std::cout << "ISODATE LOC = " << std::string(buf2.data) << std::endl;
REQUIRE((strncmp(buf2.data, buf.data, 10) == 0));

time_to_iso8601utc(now, &buf);
r = string_to_time(buf.data, &chk);
REQUIRE(r == 0);
std::cout << "ISO8601 UTC = " << std::string(buf.data) << std::endl;
REQUIRE(chk == now);
}

0 comments on commit 3dac84d

Please sign in to comment.