[master] 3f6a25170 vnum: New VNUM_uint() and VNUM_hex() functions
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Tue Aug 31 10:23:07 UTC 2021
commit 3f6a25170488bb8bfca5f07a81e94cc1c5c35ade
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Tue Aug 31 11:57:38 2021 +0200
vnum: New VNUM_uint() and VNUM_hex() functions
With the hex table suggested by fgs.
diff --git a/include/vnum.h b/include/vnum.h
index cd08c3216..fe9e78bd1 100644
--- a/include/vnum.h
+++ b/include/vnum.h
@@ -37,6 +37,8 @@ vtim_dur VNUM_duration(const char *p);
int64_t VNUM_bytes_unit(double r, const char *b, const char *e, uintmax_t rel,
const char **errtxt);
const char *VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel);
+ssize_t VNUM_uint(const char *b, const char *e, const char **p);
+ssize_t VNUM_hex(const char *b, const char *e, const char **p);
int64_t SF_Parse_Integer(const char **ipp, const char **errtxt);
double SF_Parse_Decimal(const char **ipp, int strict, const char **errtxt);
diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c
index c6c59e0ba..fa3a8cc97 100644
--- a/lib/libvarnish/vnum.c
+++ b/lib/libvarnish/vnum.c
@@ -33,6 +33,9 @@
#include "config.h"
+#include <sys/types.h>
+
+#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
@@ -353,6 +356,66 @@ VNUM_2bytes(const char *p, uintmax_t *r, uintmax_t rel)
return (NULL);
}
+/**********************************************************************/
+
+static const uint8_t hex_table[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 127, 127, 127, 127, 127, 127, 127, 10, 11, 12,
+ 13, 14, 15, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 10,
+ 11, 12, 13, 14, 15
+};
+
+static ssize_t
+vnum_uint(const char *b, const char *e, const char **p, unsigned base)
+{
+ ssize_t u;
+ unsigned n;
+
+ AN(b);
+ AN(p);
+ if (e == NULL)
+ e = strchr(b, '\0');
+
+ u = 0;
+ if (!vct_ishex(*b) || hex_table[*b - '0'] >= base) {
+ *p = b;
+ return (-1);
+ }
+
+ for (; b < e && vct_ishex(*b) && hex_table[*b - '0'] < base; b++) {
+ if (u > (SSIZE_MAX / base)) {
+ u = -2;
+ break;
+ }
+ u *= base;
+ n = hex_table[*b - '0'];
+ if (u > (SSIZE_MAX - n)) {
+ u = -2;
+ break;
+ }
+ u += n;
+ }
+
+ *p = b;
+ return (u);
+}
+
+ssize_t
+VNUM_uint(const char *b, const char *e, const char **p)
+{
+
+ return (vnum_uint(b, e, p, 10));
+}
+
+ssize_t
+VNUM_hex(const char *b, const char *e, const char **p)
+{
+
+ return (vnum_uint(b, e, p, 16));
+}
+
#ifdef NUM_C_TEST
/*
* Compile with:
More information about the varnish-commit
mailing list