oid: add git_oid_fmt_substr Tidy up `nfmt` / `pathfmt`.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
diff --git a/src/libgit2/oid.c b/src/libgit2/oid.c
index d3284bd..7521dd2 100644
--- a/src/libgit2/oid.c
+++ b/src/libgit2/oid.c
@@ -22,8 +22,6 @@ const git_oid git_oid__empty_tree_sha1 =
{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
-static char to_hex[] = "0123456789abcdef";
-
static int oid_error_invalid(const char *msg)
{
git_error_set(GIT_ERROR_INVALID, "unable to parse OID - %s", msg);
@@ -75,16 +73,9 @@ int git_oid_fromstr(git_oid *out, const char *str, git_oid_t type)
return git_oid_fromstrn(out, str, git_oid_hexsize(type), type);
}
-GIT_INLINE(char) *fmt_one(char *str, unsigned int val)
-{
- *str++ = to_hex[val >> 4];
- *str++ = to_hex[val & 0xf];
- return str;
-}
-
int git_oid_nfmt(char *str, size_t n, const git_oid *oid)
{
- size_t hex_size, i, max_i;
+ size_t hex_size;
if (!oid) {
memset(str, 0, n);
@@ -99,14 +90,7 @@ int git_oid_nfmt(char *str, size_t n, const git_oid *oid)
n = hex_size;
}
- max_i = n / 2;
-
- for (i = 0; i < max_i; i++)
- str = fmt_one(str, oid->id[i]);
-
- if (n & 1)
- *str++ = to_hex[oid->id[i] >> 4];
-
+ git_oid_fmt_substr(str, oid, 0, n);
return 0;
}
@@ -117,16 +101,14 @@ int git_oid_fmt(char *str, const git_oid *oid)
int git_oid_pathfmt(char *str, const git_oid *oid)
{
- size_t size, i;
+ size_t hex_size;
- if (!(size = git_oid_size(oid->type)))
+ if (!(hex_size = git_oid_hexsize(oid->type)))
return oid_error_invalid("unknown type");
- str = fmt_one(str, oid->id[0]);
- *str++ = '/';
- for (i = 1; i < size; i++)
- str = fmt_one(str, oid->id[i]);
-
+ git_oid_fmt_substr(str, oid, 0, 2);
+ str[2] = '/';
+ git_oid_fmt_substr(&str[3], oid, 2, (hex_size - 2));
return 0;
}
diff --git a/src/libgit2/oid.h b/src/libgit2/oid.h
index ede9a16..64b6796 100644
--- a/src/libgit2/oid.h
+++ b/src/libgit2/oid.h
@@ -64,6 +64,35 @@ GIT_INLINE(git_hash_algorithm_t) git_oid_algorithm(git_oid_t type)
*/
char *git_oid_allocfmt(const git_oid *id);
+/**
+ * Format the requested nibbles of an object id.
+ *
+ * @param str the string to write into
+ * @param oid the oid structure to format
+ * @param start the starting number of nibbles
+ * @param count the number of nibbles to format
+ */
+GIT_INLINE(void) git_oid_fmt_substr(
+ char *str,
+ const git_oid *oid,
+ size_t start,
+ size_t count)
+{
+ static char hex[] = "0123456789abcdef";
+ size_t i, end = start + count, min = start / 2, max = end / 2;
+
+ if (start & 1)
+ *str++ = hex[oid->id[min++] & 0x0f];
+
+ for (i = min; i < max; i++) {
+ *str++ = hex[oid->id[i] >> 4];
+ *str++ = hex[oid->id[i] & 0x0f];
+ }
+
+ if (end & 1)
+ *str++ = hex[oid->id[i] >> 4];
+}
+
GIT_INLINE(int) git_oid_raw_ncmp(
const unsigned char *sha1,
const unsigned char *sha2,
diff --git a/tests/libgit2/core/oid.c b/tests/libgit2/core/oid.c
index ab00db0..f17054d 100644
--- a/tests/libgit2/core/oid.c
+++ b/tests/libgit2/core/oid.c
@@ -151,3 +151,28 @@ void test_core_oid__is_hexstr(void)
cl_assert(!git_oid__is_hexstr("zeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", GIT_OID_SHA1));
cl_assert(!git_oid__is_hexstr("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef1", GIT_OID_SHA1));
}
+
+void test_core_oid__fmt_substr_sha1(void)
+{
+ char buf[GIT_OID_MAX_HEXSIZE];
+
+ memset(buf, 0, GIT_OID_MAX_HEXSIZE);
+ git_oid_fmt_substr(buf, &id_sha1, 0, 40);
+ cl_assert_equal_s(buf, str_oid_sha1);
+
+ memset(buf, 0, GIT_OID_MAX_HEXSIZE);
+ git_oid_fmt_substr(buf, &id_sha1, 0, 18);
+ cl_assert_equal_s(buf, str_oid_sha1_p);
+
+ memset(buf, 0, GIT_OID_MAX_HEXSIZE);
+ git_oid_fmt_substr(buf, &id_sha1, 0, 5);
+ cl_assert_equal_s(buf, "ae90f");
+
+ memset(buf, 0, GIT_OID_MAX_HEXSIZE);
+ git_oid_fmt_substr(buf, &id_sha1, 5, 5);
+ cl_assert_equal_s(buf, "12eea");
+
+ memset(buf, 0, GIT_OID_MAX_HEXSIZE);
+ git_oid_fmt_substr(buf, &id_sha1, 5, 6);
+ cl_assert_equal_s(buf, "12eea6");
+}