gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] 01/07: Added internal functions for printing decimal and


From: gnunet
Subject: [libmicrohttpd] 01/07: Added internal functions for printing decimal and hex numbers
Date: Wed, 28 Jul 2021 10:37:00 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd.

commit ee3f32220038303ebf1bfcf1494c9badf6d3adc4
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Mon Jun 7 19:46:46 2021 +0300

    Added internal functions for printing decimal and hex numbers
---
 src/microhttpd/.gitignore  |   1 +
 src/microhttpd/Makefile.am |   4 +
 src/microhttpd/mhd_str.c   |  68 ++++++++++
 src/microhttpd/mhd_str.h   |  30 +++++
 src/microhttpd/test_str.c  | 310 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 413 insertions(+)

diff --git a/src/microhttpd/.gitignore b/src/microhttpd/.gitignore
index 3b0d8ce4..11f4f587 100644
--- a/src/microhttpd/.gitignore
+++ b/src/microhttpd/.gitignore
@@ -48,6 +48,7 @@ test_http_reasons
 /test_shutdown_select_ignore
 /test_str_compare
 /test_str_to_value
+/test_str_from_value
 /test_upgrade
 /test_upgrade_ssl
 /test_options
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index e610c1df..fb10b0a2 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -157,6 +157,7 @@ endif
 check_PROGRAMS = \
   test_str_compare \
   test_str_to_value \
+  test_str_from_value \
   test_str_token \
   test_str_token_remove \
   test_str_tokens_remove \
@@ -358,6 +359,9 @@ test_str_compare_SOURCES = \
 test_str_to_value_SOURCES = \
   test_str.c test_helpers.h mhd_str.c mhd_str.h
 
+test_str_from_value_SOURCES = \
+  test_str.c test_helpers.h mhd_str.c mhd_str.h
+
 test_str_token_SOURCES = \
   test_str_token.c mhd_str.c mhd_str.h
 
diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c
index 60c198bc..1d4b9257 100644
--- a/src/microhttpd/mhd_str.c
+++ b/src/microhttpd/mhd_str.c
@@ -32,6 +32,7 @@
 
 #include "mhd_assert.h"
 #include "mhd_limits.h"
+#include "mhd_assert.h"
 
 #ifdef MHD_FAVOR_SMALL_CODE
 #ifdef _MHD_static_inline
@@ -1184,3 +1185,70 @@ MHD_str_to_uvalue_n_ (const char *str,
 
 
 #endif /* MHD_FAVOR_SMALL_CODE */
+
+
+size_t
+MHD_uint32_to_strx (uint32_t val,
+                    char *buf,
+                    size_t buf_size)
+{
+  char *chr; /**< pointer to the current printed digit */
+  int digit_pos = 7; /** zero-based, digit position in @a 'val' */
+  int digit;
+
+  chr = buf;
+  digit = (int) (((val) >> (4 * digit_pos)) & 0xf);
+
+  /* Skip leading zeros */
+  while ((0 == digit) && (0 != digit_pos))
+    digit = (int) (((val) >> (4 * --digit_pos)) & 0xf);
+
+  while (0 != buf_size)
+  {
+    *chr = (digit <= 9) ? ('0' + (char) digit) : ('A' + (char) digit - 10);
+    chr++;
+    buf_size--;
+    if (0 == digit_pos)
+      return (size_t) (chr - buf);
+    digit = (int) (((val) >> (4 * --digit_pos)) & 0xf);
+  }
+  return 0; /* The buffer is too small */
+}
+
+
+size_t
+MHD_uint16_to_str (uint16_t val,
+                   char *buf,
+                   size_t buf_size)
+{
+  char *chr;  /**< pointer to the current printed digit */
+  /* The biggest printable number is 65535 */
+  uint16_t divisor = UINT16_C (10000);
+  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 0bd46444..27764f01 100644
--- a/src/microhttpd/mhd_str.h
+++ b/src/microhttpd/mhd_str.h
@@ -361,4 +361,34 @@ MHD_str_to_uvalue_n_ (const char *str,
 
 #endif /* MHD_FAVOR_SMALL_CODE */
 
+
+/**
+ * Convert uint32_t value to hexdecimal 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_uint32_to_strx (uint32_t val,
+                    char *buf,
+                    size_t buf_size);
+
+
+/**
+ * Convert uint16_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_uint16_to_str (uint16_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 1e140cb6..81ba378f 100644
--- a/src/microhttpd/test_str.c
+++ b/src/microhttpd/test_str.c
@@ -3314,6 +3314,313 @@ run_str_to_X_tests (void)
 }
 
 
+int
+check_str_from_uint16 (void)
+{
+  size_t t_failed = 0;
+  size_t i, j;
+  char buf[70];
+  const char *erase =
+    "-@=sd#+&(pdiren456qwe#@C3S!DAS45AOIPUQWESAdFzxcv1s*()&#$%34`"
+    "32452d098poiden45SADFFDA3S4D3SDFdfgsdfgsSADFzxdvs$*()&#2342`"
+    "adsf##$$@&*^%*^&56qwe#3C@S!DAScFAOIP$#%#$Ad1zs3v1$*()&#1228`";
+  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 (UINT16_MAX < t->val)
+        continue;  /* Too large value to convert */
+      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_uint16_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_uint16_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_uint16_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_uint16_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_uint16_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_uint16_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)
+{
+  size_t t_failed = 0;
+  size_t i, j;
+  char buf[70];
+  const char *erase =
+    "jrlkjssfhjfvrjntJHLJ$@%$#adsfdkj;k$##$%#$%FGDF%$#^FDFG%$#$D`"
+    ";skjdhjflsdkjhdjfalskdjhdfalkjdhf$%##%$$#%FSDGFSDDGDFSSDSDF`"
+    "#5#$%#$#$DFSFDDFSGSDFSDF354FDDSGFDFfdssfddfswqemn,.zxih,.sx`";
+  static const size_t n_checks = sizeof(xdstrs_w_values)
+                                 / sizeof(xdstrs_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 = xdstrs_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 (UINT32_MAX < t->val)
+        continue;  /* Too large value to convert */
+      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_uint32_to_strx (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_uint32_to_strx(0x%" PRIXPTR ", -> 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_uint32_to_strx(0x%" PRIXPTR ", -> 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 == MHD_str_equal_caseless_bin_n_ (buf, t->str.str,
+                                                       t->num_of_digt))
+          {
+            if (0 == c_failed[i])
+              t_failed++;
+            c_failed[i] = ! 0;
+            fprintf (stderr,
+                     "FAILED: MHD_uint32_to_strx(0x%" PRIXPTR ", -> \"%.*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_uint32_to_strx(0x%" PRIXPTR ", -> \"%.*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_uint32_to_strx(0x%" PRIXPTR ", -> \"%.*s\", %d) "
+                "== %" PRIuPTR "\n",
+                t->val, (int) rs, buf, (int) b_size - 1, (intptr_t) rs);
+    }
+  }
+  return t_failed;
+}
+
+
+int
+run_str_from_X_tests (void)
+{
+  int str_from_uint16;
+  int strx_from_uint32;
+  int failures;
+
+  failures = 0;
+
+  str_from_uint16 = check_str_from_uint16 ();
+  if (str_from_uint16 != 0)
+  {
+    if (str_from_uint16 < 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_uint16;
+  }
+  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)
+  {
+    if (strx_from_uint32 < 0)
+    {
+      fprintf (stderr,
+               "ERROR: test internal error in check_strx_from_uint32().\n");
+      return 99;
+    }
+    fprintf (stderr,
+             "FAILED: testcase check_strx_from_uint32() failed.\n\n");
+    failures += strx_from_uint32;
+  }
+  else if (verbose > 1)
+    printf (
+      "PASSED: testcase check_strx_from_uint32() successfully passed.\n\n");
+
+  if (failures)
+  {
+    if (verbose > 0)
+      printf ("At least one test failed.\n");
+
+    return 1;
+  }
+
+  if (verbose > 0)
+    printf ("All tests passed successfully.\n");
+
+  return 0;
+}
+
+
 int
 main (int argc, char *argv[])
 {
@@ -3328,5 +3635,8 @@ main (int argc, char *argv[])
   if (has_in_name (argv[0], "_to_value"))
     return run_str_to_X_tests ();
 
+  if (has_in_name (argv[0], "_from_value"))
+    return run_str_from_X_tests ();
+
   return run_eq_neq_str_tests ();
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]