mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-02 22:49:04 +00:00
Add git_oid_nfmt - a flexible OID formatter
I frequently want to the the first N digits of an OID formatted as a string and I'd like it to be efficient. This function makes that easy and I could rewrite the OID formatters in terms of it.
This commit is contained in:
parent
c2d282cfd8
commit
660d59caa9
@ -89,6 +89,17 @@ GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw);
|
||||
*/
|
||||
GIT_EXTERN(void) git_oid_fmt(char *out, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a partial hex string.
|
||||
*
|
||||
* @param out output hex string; you say how many bytes to write.
|
||||
* If the number of bytes is > GIT_OID_HEXSZ, extra bytes
|
||||
* will be zeroed; if not, a '\0' terminator is NOT added.
|
||||
* @param n number of characters to write into out string
|
||||
* @param oid oid structure to format.
|
||||
*/
|
||||
GIT_EXTERN(void) git_oid_nfmt(char *out, size_t n, const git_oid *id);
|
||||
|
||||
/**
|
||||
* Format a git_oid into a loose-object path string.
|
||||
*
|
||||
@ -117,10 +128,12 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *id);
|
||||
* Format a git_oid into a buffer as a hex format c-string.
|
||||
*
|
||||
* If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting
|
||||
* oid c-string will be truncated to n-1 characters. If there are
|
||||
* any input parameter errors (out == NULL, n == 0, oid == NULL),
|
||||
* then a pointer to an empty string is returned, so that the return
|
||||
* value can always be printed.
|
||||
* oid c-string will be truncated to n-1 characters (but will still be
|
||||
* NUL-byte terminated).
|
||||
*
|
||||
* If there are any input parameter errors (out == NULL, n == 0, oid ==
|
||||
* NULL), then a pointer to an empty string is returned, so that the
|
||||
* return value can always be printed.
|
||||
*
|
||||
* @param out the buffer into which the oid string is output.
|
||||
* @param n the size of the out buffer.
|
||||
|
48
src/oid.c
48
src/oid.c
@ -68,12 +68,31 @@ GIT_INLINE(char) *fmt_one(char *str, unsigned int val)
|
||||
return str;
|
||||
}
|
||||
|
||||
void git_oid_nfmt(char *str, size_t n, const git_oid *oid)
|
||||
{
|
||||
size_t i, max_i;
|
||||
|
||||
if (!oid) {
|
||||
memset(str, 0, n);
|
||||
return;
|
||||
}
|
||||
if (n > GIT_OID_HEXSZ) {
|
||||
memset(&str[GIT_OID_HEXSZ], 0, n - GIT_OID_HEXSZ);
|
||||
n = GIT_OID_HEXSZ;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
void git_oid_fmt(char *str, const git_oid *oid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(oid->id); i++)
|
||||
str = fmt_one(str, oid->id[i]);
|
||||
git_oid_nfmt(str, GIT_OID_HEXSZ, oid);
|
||||
}
|
||||
|
||||
void git_oid_pathfmt(char *str, const git_oid *oid)
|
||||
@ -91,31 +110,20 @@ char *git_oid_allocfmt(const git_oid *oid)
|
||||
char *str = git__malloc(GIT_OID_HEXSZ + 1);
|
||||
if (!str)
|
||||
return NULL;
|
||||
git_oid_fmt(str, oid);
|
||||
str[GIT_OID_HEXSZ] = '\0';
|
||||
git_oid_nfmt(str, GIT_OID_HEXSZ + 1, oid);
|
||||
return str;
|
||||
}
|
||||
|
||||
char *git_oid_tostr(char *out, size_t n, const git_oid *oid)
|
||||
{
|
||||
char str[GIT_OID_HEXSZ];
|
||||
|
||||
if (!out || n == 0)
|
||||
return "";
|
||||
|
||||
n--; /* allow room for terminating NUL */
|
||||
if (n > GIT_OID_HEXSZ + 1)
|
||||
n = GIT_OID_HEXSZ + 1;
|
||||
|
||||
if (oid == NULL)
|
||||
n = 0;
|
||||
|
||||
if (n > 0) {
|
||||
git_oid_fmt(str, oid);
|
||||
if (n > GIT_OID_HEXSZ)
|
||||
n = GIT_OID_HEXSZ;
|
||||
memcpy(out, str, n);
|
||||
}
|
||||
|
||||
out[n] = '\0';
|
||||
git_oid_nfmt(out, n - 1, oid); /* allow room for terminating NUL */
|
||||
out[n - 1] = '\0';
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -73,3 +73,41 @@ void test_object_raw_convert__succeed_on_oid_to_string_conversion_big(void)
|
||||
cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+2) == 'Y');
|
||||
cl_assert(str && str == big && *(str+GIT_OID_HEXSZ+3) == 'Z');
|
||||
}
|
||||
|
||||
static void check_partial_oid(
|
||||
char *buffer, size_t count, const git_oid *oid, const char *expected)
|
||||
{
|
||||
git_oid_nfmt(buffer, count, oid);
|
||||
buffer[count] = '\0';
|
||||
cl_assert_equal_s(expected, buffer);
|
||||
}
|
||||
|
||||
void test_object_raw_convert__convert_oid_partially(void)
|
||||
{
|
||||
const char *exp = "16a0123456789abcdef4b775213c23a8bd74f5e0";
|
||||
git_oid in;
|
||||
char big[GIT_OID_HEXSZ + 1 + 3]; /* note + 4 => big buffer */
|
||||
char *str;
|
||||
|
||||
cl_git_pass(git_oid_fromstr(&in, exp));
|
||||
|
||||
git_oid_nfmt(big, sizeof(big), &in);
|
||||
cl_assert_equal_s(exp, big);
|
||||
|
||||
git_oid_nfmt(big, GIT_OID_HEXSZ + 1, &in);
|
||||
cl_assert_equal_s(exp, big);
|
||||
|
||||
check_partial_oid(big, 1, &in, "1");
|
||||
check_partial_oid(big, 2, &in, "16");
|
||||
check_partial_oid(big, 3, &in, "16a");
|
||||
check_partial_oid(big, 4, &in, "16a0");
|
||||
check_partial_oid(big, 5, &in, "16a01");
|
||||
|
||||
check_partial_oid(big, GIT_OID_HEXSZ, &in, exp);
|
||||
check_partial_oid(
|
||||
big, GIT_OID_HEXSZ - 1, &in, "16a0123456789abcdef4b775213c23a8bd74f5e");
|
||||
check_partial_oid(
|
||||
big, GIT_OID_HEXSZ - 2, &in, "16a0123456789abcdef4b775213c23a8bd74f5");
|
||||
check_partial_oid(
|
||||
big, GIT_OID_HEXSZ - 3, &in, "16a0123456789abcdef4b775213c23a8bd74f");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user