Skip to content

Commit b04cdea

Browse files
avargitster
authored andcommitted
object-file API: add a format_object_header() function
Add a convenience function to wrap the xsnprintf() command that generates loose object headers. This code was copy/pasted in various parts of the codebase, let's define it in one place and re-use it from there. All except one caller of it had a valid "enum object_type" for us, it's only write_object_file_prepare() which might need to deal with "git hash-object --literally" and a potential garbage type. Let's have the primary API use an "enum object_type", and define a *_literally() function that can take an arbitrary "const char *" for the type. See [1] for the discussion that prompted this patch, i.e. new code in object-file.c that wanted to copy/paste the xsnprintf() invocation. In the case of fast-import.c the callers unfortunately need to cast back & forth between "unsigned char *" and "char *", since format_object_header() ad encode_in_pack_object_header() take different signedness. 1. https://lore.kernel.org/git/[email protected]/ Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Jiang Xin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 63e05f9 commit b04cdea

File tree

6 files changed

+35
-11
lines changed

6 files changed

+35
-11
lines changed

builtin/fast-import.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -937,8 +937,8 @@ static int store_object(
937937
git_hash_ctx c;
938938
git_zstream s;
939939

940-
hdrlen = xsnprintf((char *)hdr, sizeof(hdr), "%s %lu",
941-
type_name(type), (unsigned long)dat->len) + 1;
940+
hdrlen = format_object_header((char *)hdr, sizeof(hdr), type,
941+
dat->len);
942942
the_hash_algo->init_fn(&c);
943943
the_hash_algo->update_fn(&c, hdr, hdrlen);
944944
the_hash_algo->update_fn(&c, dat->buf, dat->len);
@@ -1091,7 +1091,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
10911091
hashfile_checkpoint(pack_file, &checkpoint);
10921092
offset = checkpoint.offset;
10931093

1094-
hdrlen = xsnprintf((char *)out_buf, out_sz, "blob %" PRIuMAX, len) + 1;
1094+
hdrlen = format_object_header((char *)out_buf, out_sz, OBJ_BLOB, len);
10951095

10961096
the_hash_algo->init_fn(&c);
10971097
the_hash_algo->update_fn(&c, out_buf, hdrlen);

builtin/index-pack.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size,
449449
int hdrlen;
450450

451451
if (!is_delta_type(type)) {
452-
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX,
453-
type_name(type),(uintmax_t)size) + 1;
452+
hdrlen = format_object_header(hdr, sizeof(hdr), type, size);
454453
the_hash_algo->init_fn(&c);
455454
the_hash_algo->update_fn(&c, hdr, hdrlen);
456455
} else

bulk-checkin.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,8 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
220220
if (seekback == (off_t) -1)
221221
return error("cannot find the current offset");
222222

223-
header_len = xsnprintf((char *)obuf, sizeof(obuf), "%s %" PRIuMAX,
224-
type_name(type), (uintmax_t)size) + 1;
223+
header_len = format_object_header((char *)obuf, sizeof(obuf),
224+
type, size);
225225
the_hash_algo->init_fn(&ctx);
226226
the_hash_algo->update_fn(&ctx, obuf, header_len);
227227

http-push.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ static void start_put(struct transfer_request *request)
363363
git_zstream stream;
364364

365365
unpacked = read_object_file(&request->obj->oid, &type, &len);
366-
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
366+
hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
367367

368368
/* Set it up */
369369
git_deflate_init(&stream, zlib_compression_level);

object-file.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,23 @@ void *xmmap(void *start, size_t length,
10491049
return ret;
10501050
}
10511051

1052+
static int format_object_header_literally(char *str, size_t size,
1053+
const char *type, size_t objsize)
1054+
{
1055+
return xsnprintf(str, size, "%s %"PRIuMAX, type, (uintmax_t)objsize) + 1;
1056+
}
1057+
1058+
int format_object_header(char *str, size_t size, enum object_type type,
1059+
size_t objsize)
1060+
{
1061+
const char *name = type_name(type);
1062+
1063+
if (!name)
1064+
BUG("could not get a type name for 'enum object_type' value %d", type);
1065+
1066+
return format_object_header_literally(str, size, name, objsize);
1067+
}
1068+
10521069
/*
10531070
* With an in-core object data in "map", rehash it to make sure the
10541071
* object name actually matches "oid" to detect object corruption.
@@ -1077,7 +1094,7 @@ int check_object_signature(struct repository *r, const struct object_id *oid,
10771094
return -1;
10781095

10791096
/* Generate the header */
1080-
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(obj_type), (uintmax_t)size) + 1;
1097+
hdrlen = format_object_header(hdr, sizeof(hdr), obj_type, size);
10811098

10821099
/* Sha1.. */
10831100
r->hash_algo->init_fn(&c);
@@ -1777,7 +1794,7 @@ static void write_object_file_prepare(const struct git_hash_algo *algo,
17771794
git_hash_ctx c;
17781795

17791796
/* Generate the header */
1780-
*hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
1797+
*hdrlen = format_object_header_literally(hdr, *hdrlen, type, len);
17811798

17821799
/* Sha1.. */
17831800
algo->init_fn(&c);
@@ -2051,7 +2068,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
20512068
buf = read_object(the_repository, oid, &type, &len);
20522069
if (!buf)
20532070
return error(_("cannot read object for %s"), oid_to_hex(oid));
2054-
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
2071+
hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
20552072
ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0);
20562073
free(buf);
20572074

object-store.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,14 @@ int repo_has_object_file_with_flags(struct repository *r,
331331
*/
332332
int has_loose_object_nonlocal(const struct object_id *);
333333

334+
/**
335+
* format_object_header() is a thin wrapper around s xsnprintf() that
336+
* writes the initial "<type> <obj-len>" part of the loose object
337+
* header. It returns the size that snprintf() returns + 1.
338+
*/
339+
int format_object_header(char *str, size_t size, enum object_type type,
340+
size_t objsize);
341+
334342
void assert_oid_type(const struct object_id *oid, enum object_type expect);
335343

336344
/*

0 commit comments

Comments
 (0)