Commit eb8de7476b4d3caeac518ff9af459c49cfd78e35

nulltoken 2011-12-28T20:24:58

util: add git__fromhex()

diff --git a/src/oid.c b/src/oid.c
index 4b30804..61bf6da 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -11,24 +11,6 @@
 #include <string.h>
 #include <limits.h>
 
-static signed char from_hex[] = {
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20 */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 30 */
--1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 40 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 50 */
--1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 60 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* a0 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* b0 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* c0 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* d0 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* e0 */
--1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* f0 */
-};
 static char to_hex[] = "0123456789abcdef";
 
 int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
@@ -43,8 +25,8 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
 		length = GIT_OID_HEXSZ;
 
 	for (p = 0; p < length - 1; p += 2) {
-		v = (from_hex[(unsigned char)str[p + 0]] << 4)
-				| from_hex[(unsigned char)str[p + 1]];
+		v = (git__fromhex(str[p + 0]) << 4)
+				| git__fromhex(str[p + 1]);
 
 		if (v < 0)
 			return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is not a valid sha1 hash");
@@ -53,7 +35,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
 	}
 
 	if (length % 2) {
-		v = (from_hex[(unsigned char)str[p + 0]] << 4);
+		v = (git__fromhex(str[p + 0]) << 4);
 		if (v < 0)
 			return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is not a valid sha1 hash");
 
@@ -346,7 +328,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
 	is_leaf = 0;
 
 	for (i = 0; i < GIT_OID_HEXSZ; ++i) {
-		int c = from_hex[(int)text_oid[i]];
+		int c = git__fromhex(text_oid[i]);
 		trie_node *node;
 
 		if (c == -1)
@@ -360,7 +342,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
 			tail = node->tail;
 			node->tail = NULL;
 
-			node = push_leaf(os, idx, from_hex[(int)tail[0]], &tail[1]);
+			node = push_leaf(os, idx, git__fromhex(tail[0]), &tail[1]);
 			if (node == NULL)
 				return GIT_ENOMEM;
 		}
diff --git a/src/util.h b/src/util.h
index 4b1104b..ebc1ad0 100644
--- a/src/util.h
+++ b/src/util.h
@@ -133,5 +133,28 @@ typedef void (*git_refcount_freeptr)(void *r);
 
 #define GIT_REFCOUNT_OWNER(r) (((git_refcount *)(r))->owner)
 
+static signed char from_hex[] = {
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20 */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /* 30 */
+-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 40 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 50 */
+-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 60 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* a0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* b0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* c0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* d0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* e0 */
+-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* f0 */
+};
+
+GIT_INLINE(int) git__fromhex(char h)
+{
+	return from_hex[(unsigned char) h];
+}
 
 #endif /* INCLUDE_util_h__ */
diff --git a/tests-clay/clay.h b/tests-clay/clay.h
index c9fe4c1..c2b69c8 100644
--- a/tests-clay/clay.h
+++ b/tests-clay/clay.h
@@ -106,6 +106,7 @@ extern void test_core_filebuf__2(void);
 extern void test_core_filebuf__3(void);
 extern void test_core_filebuf__4(void);
 extern void test_core_filebuf__5(void);
+extern void test_core_hex__fromhex(void);
 extern void test_core_oid__initialize(void);
 extern void test_core_oid__streq(void);
 extern void test_core_path__0_dirname(void);
diff --git a/tests-clay/clay_main.c b/tests-clay/clay_main.c
index 318e096..7df342c 100644
--- a/tests-clay/clay_main.c
+++ b/tests-clay/clay_main.c
@@ -167,6 +167,9 @@ static const struct clay_func _clay_cb_core_filebuf[] = {
 	{"4", &test_core_filebuf__4},
 	{"5", &test_core_filebuf__5}
 };
+static const struct clay_func _clay_cb_core_hex[] = {
+    {"fromhex", &test_core_hex__fromhex}
+};
 static const struct clay_func _clay_cb_core_oid[] = {
     {"streq", &test_core_oid__streq}
 };
@@ -363,6 +366,12 @@ static const struct clay_suite _clay_suites[] = {
         _clay_cb_core_filebuf, 6
     },
 	{
+        "core::hex",
+        {NULL, NULL},
+        {NULL, NULL},
+        _clay_cb_core_hex, 1
+    },
+	{
         "core::oid",
         {"initialize", &test_core_oid__initialize},
         {NULL, NULL},
@@ -538,8 +547,8 @@ static const struct clay_suite _clay_suites[] = {
     }
 };
 
-static size_t _clay_suite_count = 38;
-static size_t _clay_callback_count = 122;
+static size_t _clay_suite_count = 39;
+static size_t _clay_callback_count = 123;
 
 /* Core test functions */
 static void
diff --git a/tests-clay/core/hex.c b/tests-clay/core/hex.c
new file mode 100644
index 0000000..391a286
--- /dev/null
+++ b/tests-clay/core/hex.c
@@ -0,0 +1,22 @@
+#include "clay_libgit2.h"
+#include "util.h"
+
+void test_core_hex__fromhex(void)
+{
+	/* Passing cases */
+	cl_assert(git__fromhex('0') == 0x0);
+	cl_assert(git__fromhex('1') == 0x1);
+	cl_assert(git__fromhex('3') == 0x3);
+	cl_assert(git__fromhex('9') == 0x9);
+	cl_assert(git__fromhex('A') == 0xa);
+	cl_assert(git__fromhex('C') == 0xc);
+	cl_assert(git__fromhex('F') == 0xf);
+	cl_assert(git__fromhex('a') == 0xa);
+	cl_assert(git__fromhex('c') == 0xc);
+	cl_assert(git__fromhex('f') == 0xf);
+
+	/* Failing cases */
+	cl_assert(git__fromhex('g') == -1);
+	cl_assert(git__fromhex('z') == -1);
+	cl_assert(git__fromhex('X') == -1);
+}
diff --git a/tests-clay/object/raw/chars.c b/tests-clay/object/raw/chars.c
index eba352b..83bcbeb 100644
--- a/tests-clay/object/raw/chars.c
+++ b/tests-clay/object/raw/chars.c
@@ -3,17 +3,6 @@
 
 #include "odb.h"
 
-static int from_hex(unsigned int i)
-{
-	if (i >= '0' && i <= '9')
-		return i - '0';
-	if (i >= 'a' && i <= 'f')
-		return 10 + (i - 'a');
-	if (i >= 'A' && i <= 'F')
-		return 10 + (i - 'A');
-	return -1;
-}
-
 void test_object_raw_chars__find_invalid_chars_in_oid(void)
 {
 	git_oid out;
@@ -28,8 +17,8 @@ void test_object_raw_chars__find_invalid_chars_in_oid(void)
 
 	for (i = 0; i < 256; i++) {
 		in[38] = (char)i;
-		if (from_hex(i) >= 0) {
-			exp[19] = (unsigned char)(from_hex(i) << 4);
+		if (git__fromhex(i) >= 0) {
+			exp[19] = (unsigned char)(git__fromhex(i) << 4);
 			cl_git_pass(git_oid_fromstr(&out, in));
 			cl_assert(memcmp(out.id, exp, sizeof(out.id)) == 0);
 		} else {
diff --git a/tests/t01-rawobj.c b/tests/t01-rawobj.c
index 8b05f33..7b9ca1e 100644
--- a/tests/t01-rawobj.c
+++ b/tests/t01-rawobj.c
@@ -52,17 +52,6 @@ BEGIN_TEST(oid2, "fail when parsing an invalid string as oid")
 	must_fail(git_oid_fromstr(&out, "moo"));
 END_TEST
 
-static int from_hex(unsigned int i)
-{
-	if (i >= '0' && i <= '9')
-		return i - '0';
-	if (i >= 'a' && i <= 'f')
-		return 10 + (i - 'a');
-	if (i >= 'A' && i <= 'F')
-		return 10 + (i - 'A');
-	return -1;
-}
-
 BEGIN_TEST(oid3, "find all invalid characters when parsing an oid")
 	git_oid out;
 	unsigned char exp[] = {
@@ -77,8 +66,8 @@ BEGIN_TEST(oid3, "find all invalid characters when parsing an oid")
 	for (i = 0; i < 256; i++) {
 		in[38] = (char)i;
 
-		if (from_hex(i) >= 0) {
-			exp[19] = (unsigned char)(from_hex(i) << 4);
+		if (git__fromhex(i) >= 0) {
+			exp[19] = (unsigned char)(git__fromhex(i) << 4);
 			must_pass(git_oid_fromstr(&out, in));
 			must_be_true(memcmp(out.id, exp, sizeof(out.id)) == 0);
 		} else {