mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-21 12:24:58 +00:00
Add routines to convert git_oid to hex strings
[sp: Credit for some of this implementation goes to Pieter, I started off a patch he proposed for libgit2 but reworked enough of it that I don't want to blame him for any bugs.] Suggested-by: Pieter de Bie <pdebie@ai.rug.nl> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
b72ca26740
commit
af795e498d
@ -13,11 +13,17 @@
|
|||||||
*/
|
*/
|
||||||
GIT_BEGIN_DECL
|
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). */
|
/** Unique identity of any object (commit, tree, blob, tag). */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/** raw binary formatted id */
|
/** raw binary formatted id */
|
||||||
unsigned char id[20];
|
unsigned char id[GIT_OID_RAWSZ];
|
||||||
} git_oid;
|
} 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));
|
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.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
* Copy an oid from one structure to another.
|
||||||
* @param out oid structure the result is written into.
|
* @param out oid structure the result is written into.
|
||||||
|
36
src/oid.c
36
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, /* e0 */
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* f0 */
|
-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)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
#include "test_lib.h"
|
#include "test_lib.h"
|
||||||
#include <git/oid.h>
|
#include <git/oid.h>
|
||||||
|
|
||||||
|
BEGIN_TEST(oid_szs)
|
||||||
|
git_oid out;
|
||||||
|
must_be_true(20 == GIT_OID_RAWSZ);
|
||||||
|
must_be_true(40 == GIT_OID_HEXSZ);
|
||||||
|
must_be_true(sizeof(out) == GIT_OID_RAWSZ);
|
||||||
|
must_be_true(sizeof(out.id) == GIT_OID_RAWSZ);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
BEGIN_TEST(empty_string)
|
BEGIN_TEST(empty_string)
|
||||||
git_oid out;
|
git_oid out;
|
||||||
must_fail(git_oid_mkstr(&out, ""));
|
must_fail(git_oid_mkstr(&out, ""));
|
||||||
@ -150,3 +158,51 @@ BEGIN_TEST(cmp_oid_gt)
|
|||||||
git_oid_mkraw(&b, b_in);
|
git_oid_mkraw(&b, b_in);
|
||||||
must_be_true(git_oid_cmp(&a, &b) > 0);
|
must_be_true(git_oid_cmp(&a, &b) > 0);
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
BEGIN_TEST(cmp_oid_fmt)
|
||||||
|
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
|
||||||
|
git_oid in;
|
||||||
|
char out[GIT_OID_HEXSZ + 1];
|
||||||
|
|
||||||
|
must_pass(git_oid_mkstr(&in, exp));
|
||||||
|
|
||||||
|
/* Format doesn't touch the last byte */
|
||||||
|
out[GIT_OID_HEXSZ] = 'Z';
|
||||||
|
git_oid_fmt(out, &in);
|
||||||
|
must_be_true(out[GIT_OID_HEXSZ] == 'Z');
|
||||||
|
|
||||||
|
/* Format produced the right result */
|
||||||
|
out[GIT_OID_HEXSZ] = '\0';
|
||||||
|
must_pass(strcmp(exp, out));
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
BEGIN_TEST(cmp_oid_allocfmt)
|
||||||
|
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
|
||||||
|
git_oid in;
|
||||||
|
char *out;
|
||||||
|
|
||||||
|
must_pass(git_oid_mkstr(&in, exp));
|
||||||
|
|
||||||
|
out = git_oid_allocfmt(&in);
|
||||||
|
must_be_true(out);
|
||||||
|
must_pass(strcmp(exp, out));
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
BEGIN_TEST(cmp_oid_pathfmt)
|
||||||
|
const char *exp1 = "16a0123456789abcdef4b775213c23a8bd74f5e0";
|
||||||
|
const char *exp2 = "16/a0123456789abcdef4b775213c23a8bd74f5e0";
|
||||||
|
git_oid in;
|
||||||
|
char out[GIT_OID_HEXSZ + 2];
|
||||||
|
|
||||||
|
must_pass(git_oid_mkstr(&in, exp1));
|
||||||
|
|
||||||
|
/* Format doesn't touch the last byte */
|
||||||
|
out[GIT_OID_HEXSZ + 1] = 'Z';
|
||||||
|
git_oid_pathfmt(out, &in);
|
||||||
|
must_be_true(out[GIT_OID_HEXSZ + 1] == 'Z');
|
||||||
|
|
||||||
|
/* Format produced the right result */
|
||||||
|
out[GIT_OID_HEXSZ + 1] = '\0';
|
||||||
|
must_pass(strcmp(exp2, out));
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user