[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] 02/03: Added MHD_uint64_to_str() internal function
From: |
gnunet |
Subject: |
[libmicrohttpd] 02/03: Added MHD_uint64_to_str() internal function |
Date: |
Sun, 01 Aug 2021 12:28:05 +0200 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
commit 497a3546bc8e597373ee96c3e6d9849f053fa249
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Fri Jul 30 18:41:46 2021 +0300
Added MHD_uint64_to_str() internal function
---
src/microhttpd/mhd_str.c | 42 ++++++++++++++
src/microhttpd/mhd_str.h | 21 +++++++
src/microhttpd/test_str.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 203 insertions(+)
diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c
index 1d4b9257..b106859d 100644
--- a/src/microhttpd/mhd_str.c
+++ b/src/microhttpd/mhd_str.c
@@ -1216,6 +1216,7 @@ MHD_uint32_to_strx (uint32_t val,
}
+#ifndef MHD_FAVOR_SMALL_CODE
size_t
MHD_uint16_to_str (uint16_t val,
char *buf,
@@ -1252,3 +1253,44 @@ MHD_uint16_to_str (uint16_t val,
}
return 0; /* The buffer is too small */
}
+
+
+#endif /* !MHD_FAVOR_SMALL_CODE */
+
+
+size_t
+MHD_uint64_to_str (uint64_t val,
+ char *buf,
+ size_t buf_size)
+{
+ char *chr; /**< pointer to the current printed digit */
+ /* The biggest printable number is 18446744073709551615 */
+ uint64_t divisor = UINT64_C (10000000000000000000);
+ int digit;
+
+ chr = buf;
+ digit = (int) (val / divisor);
+ mhd_assert (digit < 10);
+
+ /* Do not print leading zeros */
+ while ((0 == digit) && (1 < divisor))
+ {
+ divisor /= 10;
+ digit = (int) (val / divisor);
+ mhd_assert (digit < 10);
+ }
+
+ while (0 != buf_size)
+ {
+ *chr = (char) digit + '0';
+ chr++;
+ buf_size--;
+ if (1 == divisor)
+ return (size_t) (chr - buf);
+ val %= divisor;
+ divisor /= 10;
+ digit = (int) (val / divisor);
+ mhd_assert (digit < 10);
+ }
+ return 0; /* The buffer is too small */
+}
diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h
index 91d5f46e..9cc4bb19 100644
--- a/src/microhttpd/mhd_str.h
+++ b/src/microhttpd/mhd_str.h
@@ -389,6 +389,7 @@ MHD_uint32_to_strx (uint32_t val,
size_t buf_size);
+#ifndef MHD_FAVOR_SMALL_CODE
/**
* Convert uint16_t value to decimal US-ASCII string.
* @note: result is NOT zero-terminated.
@@ -403,4 +404,24 @@ MHD_uint16_to_str (uint16_t val,
char *buf,
size_t buf_size);
+#else /* MHD_FAVOR_SMALL_CODE */
+#define MHD_uint16_to_str(v,b,s) MHD_uint64_to_str(v,b,s)
+#endif /* MHD_FAVOR_SMALL_CODE */
+
+
+/**
+ * Convert uint64_t value to decimal US-ASCII string.
+ * @note: result is NOT zero-terminated.
+ * @param val the value to convert
+ * @param buf the buffer to result to
+ * @param buf_size size of the @a buffer
+ * @return number of charters has been put to the @a buf,
+ * zero if buffer is too small (buffer may be modified).
+ */
+size_t
+MHD_uint64_to_str (uint64_t val,
+ char *buf,
+ size_t buf_size);
+
+
#endif /* MHD_STR_H */
diff --git a/src/microhttpd/test_str.c b/src/microhttpd/test_str.c
index 81ba378f..a65cb61d 100644
--- a/src/microhttpd/test_str.c
+++ b/src/microhttpd/test_str.c
@@ -3438,6 +3438,128 @@ check_str_from_uint16 (void)
}
+int
+check_str_from_uint64 (void)
+{
+ size_t t_failed = 0;
+ size_t i, j;
+ char buf[70];
+ const char *erase =
+ "-@=sd#+&(pdirenDSFGSe#@C&S!DAS*!AOIPUQWESAdFzxcvSs*()&#$%KH`"
+ "32452d098poiden45SADFFDA3S4D3SDFdfgsdfgsSADFzxdvs$*()द`"
+ "adsf##$$@&*^%*^&56qwe#3C@S!DAScFAOIP$#%#$Ad1zs3v1$*()ӌ`";
+ static const size_t n_checks = sizeof(dstrs_w_values)
+ / sizeof(dstrs_w_values[0]);
+ int c_failed[n_checks];
+
+ memset (c_failed, 0, sizeof(c_failed));
+
+ for (j = 0; j < locale_name_count; j++)
+ {
+ set_test_locale (j); /* setlocale() can be slow! */
+ for (i = 0; i < n_checks; i++)
+ {
+ const struct str_with_value *const t = dstrs_w_values + i;
+ size_t b_size;
+ size_t rs;
+
+ if (c_failed[i])
+ continue; /* skip already failed checks */
+
+ if (t->str.len < t->num_of_digt)
+ {
+ fprintf (stderr,
+ "ERROR: dstrs_w_values[%u] has wrong num_of_digt (%u):
num_of_digt is expected"
+ " to be less or equal to str.len (%u).\n",
+ (unsigned int) i, (unsigned int) t->num_of_digt, (unsigned
+ int) t->str.
+ len);
+ return -1;
+ }
+ if ('0' == t->str.str[0])
+ continue; /* Skip strings prefixed with zeros */
+ if (t->num_of_digt != t->str.len)
+ continue; /* Skip strings with suffixes */
+ if (sizeof(buf) < t->str.len + 1)
+ {
+ fprintf (stderr,
+ "ERROR: dstrs_w_values[%u] has too long (%u) string, "
+ "size of 'buf' should be increased.\n",
+ (unsigned int) i, (unsigned int) t->str.len);
+ return -1;
+ }
+ for (b_size = 0; b_size <= t->str.len + 1; ++b_size)
+ {
+ /* fill buffer with pseudo-random values */
+ memcpy (buf, erase, sizeof(buf));
+
+ rs = MHD_uint64_to_str (t->val, buf, b_size);
+
+ if (t->num_of_digt > b_size)
+ {
+ /* Must fail, buffer is too small for result */
+ if (0 != rs)
+ {
+ if (0 == c_failed[i])
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_uint64_to_str(%" PRIu64 ", -> buf,"
+ " %d) returned %" PRIuPTR
+ ", while expecting 0."
+ " Locale: %s\n", t->val, (int) b_size, (intptr_t) rs,
+ get_current_locale_str ());
+ }
+ }
+ else
+ {
+ if (t->num_of_digt != rs)
+ {
+ if (0 == c_failed[i])
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_uint64_to_str(%" PRIu64 ", -> buf,"
+ " %d) returned %" PRIuPTR
+ ", while expecting %d."
+ " Locale: %s\n", t->val, (int) b_size, (intptr_t) rs,
+ (int) t->num_of_digt, get_current_locale_str ());
+ }
+ else if (0 != memcmp (buf, t->str.str, t->num_of_digt))
+ {
+ if (0 == c_failed[i])
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_uint64_to_str(%" PRIu64 ", -> \"%.*s\","
+ " %d) returned %" PRIuPTR "."
+ " Locale: %s\n", t->val, (int) rs, buf, (int) b_size,
+ (intptr_t) rs, get_current_locale_str ());
+ }
+ else if (0 != memcmp (buf + rs, erase + rs, sizeof(buf) - rs))
+ {
+ if (0 == c_failed[i])
+ t_failed++;
+ c_failed[i] = ! 0;
+ fprintf (stderr,
+ "FAILED: MHD_uint64_to_str(%" PRIu64 ", -> \"%.*s\","
+ " %d) returned %" PRIuPTR
+ " and touched data after the resulting string."
+ " Locale: %s\n", t->val, (int) rs, buf, (int) b_size,
+ (intptr_t) rs, get_current_locale_str ());
+ }
+ }
+ }
+ if ((verbose > 1) && (j == locale_name_count - 1) && ! c_failed[i])
+ printf ("PASSED: MHD_uint64_to_str(%" PRIu64 ", -> \"%.*s\", %d) "
+ "== %" PRIuPTR "\n",
+ t->val, (int) rs, buf, (int) b_size - 1, (intptr_t) rs);
+ }
+ }
+ return t_failed;
+}
+
+
int
check_strx_from_uint32 (void)
{
@@ -3567,6 +3689,7 @@ int
run_str_from_X_tests (void)
{
int str_from_uint16;
+ int str_from_uint64;
int strx_from_uint32;
int failures;
@@ -3589,6 +3712,23 @@ run_str_from_X_tests (void)
printf (
"PASSED: testcase check_str_from_uint16() successfully passed.\n\n");
+ str_from_uint64 = check_str_from_uint64 ();
+ if (str_from_uint64 != 0)
+ {
+ if (str_from_uint64 < 0)
+ {
+ fprintf (stderr,
+ "ERROR: test internal error in check_str_from_uint16().\n");
+ return 99;
+ }
+ fprintf (stderr,
+ "FAILED: testcase check_str_from_uint16() failed.\n\n");
+ failures += str_from_uint64;
+ }
+ else if (verbose > 1)
+ printf (
+ "PASSED: testcase check_str_from_uint16() successfully passed.\n\n");
+
strx_from_uint32 = check_strx_from_uint32 ();
if (strx_from_uint32 != 0)
{
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.