diff --git a/src/git/oid.h b/src/git/oid.h index 9e90ed0d1..6c1a2d8c3 100644 --- a/src/git/oid.h +++ b/src/git/oid.h @@ -13,11 +13,17 @@ */ GIT_BEGIN_DECL +/** Size (in bytes) of a raw/binary oid */ +#define GIT_OID_RAWSZ 20 + +/** Size (in bytes) of a hex formatted oid */ +#define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2) + /** Unique identity of any object (commit, tree, blob, tag). */ typedef struct { /** raw binary formatted id */ - unsigned char id[20]; + unsigned char id[GIT_OID_RAWSZ]; } git_oid; /** @@ -40,6 +46,40 @@ GIT_INLINE(void) git_oid_mkraw(git_oid *out, const unsigned char *raw) memcpy(out->id, raw, sizeof(out->id)); } +/** + * Format a git_oid into a hex string. + * @param str output hex string; must be pointing at the start of + * the hex sequence and have at least the number of bytes + * needed for an oid encoded in hex (40 bytes). Only the + * oid digits are written; a '\0' terminator must be added + * by the caller if it is required. + * @param oid oid structure to format. + */ +GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid); + +/** + * Format a git_oid into a loose-object path string. + *
+ * The resulting string is "aa/...", where "aa" is the first two
+ * hex digitis of the oid and "..." is the remaining 38 digits.
+ *
+ * @param str output hex string; must be pointing at the start of
+ * the hex sequence and have at least the number of bytes
+ * needed for an oid encoded in hex (41 bytes). Only the
+ * oid digits are written; a '\0' terminator must be added
+ * by the caller if it is required.
+ * @param oid oid structure to format.
+ */
+GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid);
+
+/**
+ * Format a gid_oid into a newly allocated c-string.
+ * @param oid theoid structure to format
+ * @return the c-string; NULL if memory is exhausted. Caller must
+ * deallocate the string with free().
+ */
+GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid);
+
/**
* Copy an oid from one structure to another.
* @param out oid structure the result is written into.
diff --git a/src/oid.c b/src/oid.c
index e235f89f5..5f3408511 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -44,6 +44,7 @@ static signed char from_hex[] = {
-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_mkstr(git_oid *out, const char *str)
{
@@ -57,3 +58,38 @@ int git_oid_mkstr(git_oid *out, const char *str)
}
return GIT_SUCCESS;
}
+
+static inline char *fmt_one(char *str, unsigned int val)
+{
+ *str++ = to_hex[val >> 4];
+ *str++ = to_hex[val & 0xf];
+ return str;
+}
+
+void git_oid_fmt(char *str, const git_oid *oid)
+{
+ int i;
+
+ for (i = 0; i < sizeof(oid->id); i++)
+ str = fmt_one(str, oid->id[i]);
+}
+
+void git_oid_pathfmt(char *str, const git_oid *oid)
+{
+ int i;
+
+ str = fmt_one(str, oid->id[0]);
+ *str++ = '/';
+ for (i = 1; i < sizeof(oid->id); i++)
+ str = fmt_one(str, oid->id[i]);
+}
+
+char *git_oid_allocfmt(const git_oid *oid)
+{
+ char *str = malloc(GIT_OID_HEXSZ + 1);
+ if (!str)
+ return NULL;
+ git_oid_fmt(str, oid);
+ str[GIT_OID_HEXSZ] = '\0';
+ return str;
+}
diff --git a/tests/t0000-oid.c b/tests/t0000-oid.c
index 624965525..e68231085 100644
--- a/tests/t0000-oid.c
+++ b/tests/t0000-oid.c
@@ -1,6 +1,14 @@
#include "test_lib.h"
#include