[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