reftable/basics: provide wrappers for big endian conversion

We're using a mixture of big endian conversion functions provided by
both the reftable library, but also by the Git codebase. Refactor the
code so that we exclusively use reftable-provided wrappers in order to
untangle us from the Git codebase.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Patrick Steinhardt 2025-02-18 10:20:45 +01:00 committed by Junio C Hamano
parent 6e3ea71639
commit e676694298
7 changed files with 127 additions and 58 deletions

View File

@ -147,25 +147,6 @@ char *reftable_buf_detach(struct reftable_buf *buf)
return result; return result;
} }


void put_be24(uint8_t *out, uint32_t i)
{
out[0] = (uint8_t)((i >> 16) & 0xff);
out[1] = (uint8_t)((i >> 8) & 0xff);
out[2] = (uint8_t)(i & 0xff);
}

uint32_t get_be24(uint8_t *in)
{
return (uint32_t)(in[0]) << 16 | (uint32_t)(in[1]) << 8 |
(uint32_t)(in[2]);
}

void put_be16(uint8_t *out, uint16_t i)
{
out[0] = (uint8_t)((i >> 8) & 0xff);
out[1] = (uint8_t)(i & 0xff);
}

size_t binsearch(size_t sz, int (*f)(size_t k, void *args), void *args) size_t binsearch(size_t sz, int (*f)(size_t k, void *args), void *args)
{ {
size_t lo = 0; size_t lo = 0;

View File

@ -76,9 +76,79 @@ char *reftable_buf_detach(struct reftable_buf *buf);


/* Bigendian en/decoding of integers */ /* Bigendian en/decoding of integers */


void put_be24(uint8_t *out, uint32_t i); static inline void reftable_put_be16(void *out, uint16_t i)
uint32_t get_be24(uint8_t *in); {
void put_be16(uint8_t *out, uint16_t i); unsigned char *p = out;
p[0] = (uint8_t)((i >> 8) & 0xff);
p[1] = (uint8_t)((i >> 0) & 0xff);
}

static inline void reftable_put_be24(void *out, uint32_t i)
{
unsigned char *p = out;
p[0] = (uint8_t)((i >> 16) & 0xff);
p[1] = (uint8_t)((i >> 8) & 0xff);
p[2] = (uint8_t)((i >> 0) & 0xff);
}

static inline void reftable_put_be32(void *out, uint32_t i)
{
unsigned char *p = out;
p[0] = (uint8_t)((i >> 24) & 0xff);
p[1] = (uint8_t)((i >> 16) & 0xff);
p[2] = (uint8_t)((i >> 8) & 0xff);
p[3] = (uint8_t)((i >> 0) & 0xff);
}

static inline void reftable_put_be64(void *out, uint64_t i)
{
unsigned char *p = out;
p[0] = (uint8_t)((i >> 56) & 0xff);
p[1] = (uint8_t)((i >> 48) & 0xff);
p[2] = (uint8_t)((i >> 40) & 0xff);
p[3] = (uint8_t)((i >> 32) & 0xff);
p[4] = (uint8_t)((i >> 24) & 0xff);
p[5] = (uint8_t)((i >> 16) & 0xff);
p[6] = (uint8_t)((i >> 8) & 0xff);
p[7] = (uint8_t)((i >> 0) & 0xff);
}

static inline uint16_t reftable_get_be16(const void *in)
{
const unsigned char *p = in;
return (uint16_t)(p[0]) << 8 |
(uint16_t)(p[1]) << 0;
}

static inline uint32_t reftable_get_be24(const void *in)
{
const unsigned char *p = in;
return (uint32_t)(p[0]) << 16 |
(uint32_t)(p[1]) << 8 |
(uint32_t)(p[2]) << 0;
}

static inline uint32_t reftable_get_be32(const void *in)
{
const unsigned char *p = in;
return (uint32_t)(p[0]) << 24 |
(uint32_t)(p[1]) << 16 |
(uint32_t)(p[2]) << 8|
(uint32_t)(p[3]) << 0;
}

static inline uint64_t reftable_get_be64(const void *in)
{
const unsigned char *p = in;
return (uint64_t)(p[0]) << 56 |
(uint64_t)(p[1]) << 48 |
(uint64_t)(p[2]) << 40 |
(uint64_t)(p[3]) << 32 |
(uint64_t)(p[4]) << 24 |
(uint64_t)(p[5]) << 16 |
(uint64_t)(p[6]) << 8 |
(uint64_t)(p[7]) << 0;
}


/* /*
* find smallest index i in [0, sz) at which `f(i) > 0`, assuming that f is * find smallest index i in [0, sz) at which `f(i) > 0`, assuming that f is

View File

@ -147,13 +147,13 @@ done:
int block_writer_finish(struct block_writer *w) int block_writer_finish(struct block_writer *w)
{ {
for (uint32_t i = 0; i < w->restart_len; i++) { for (uint32_t i = 0; i < w->restart_len; i++) {
put_be24(w->block + w->next, w->restarts[i]); reftable_put_be24(w->block + w->next, w->restarts[i]);
w->next += 3; w->next += 3;
} }


put_be16(w->block + w->next, w->restart_len); reftable_put_be16(w->block + w->next, w->restart_len);
w->next += 2; w->next += 2;
put_be24(w->block + 1 + w->header_off, w->next); reftable_put_be24(w->block + 1 + w->header_off, w->next);


/* /*
* Log records are stored zlib-compressed. Note that the compression * Log records are stored zlib-compressed. Note that the compression
@ -215,7 +215,7 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
{ {
uint32_t full_block_size = table_block_size; uint32_t full_block_size = table_block_size;
uint8_t typ = block->data[header_off]; uint8_t typ = block->data[header_off];
uint32_t sz = get_be24(block->data + header_off + 1); uint32_t sz = reftable_get_be24(block->data + header_off + 1);
int err = 0; int err = 0;
uint16_t restart_count = 0; uint16_t restart_count = 0;
uint32_t restart_start = 0; uint32_t restart_start = 0;
@ -299,7 +299,7 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
full_block_size = sz; full_block_size = sz;
} }


restart_count = get_be16(block->data + sz - 2); restart_count = reftable_get_be16(block->data + sz - 2);
restart_start = sz - 2 - 3 * restart_count; restart_start = sz - 2 - 3 * restart_count;
restart_bytes = block->data + restart_start; restart_bytes = block->data + restart_start;


@ -354,7 +354,7 @@ int block_reader_first_key(const struct block_reader *br, struct reftable_buf *k


static uint32_t block_reader_restart_offset(const struct block_reader *br, size_t idx) static uint32_t block_reader_restart_offset(const struct block_reader *br, size_t idx)
{ {
return get_be24(br->restart_bytes + 3 * idx); return reftable_get_be24(br->restart_bytes + 3 * idx);
} }


void block_iter_seek_start(struct block_iter *it, const struct block_reader *br) void block_iter_seek_start(struct block_iter *it, const struct block_reader *br)

View File

@ -101,18 +101,18 @@ static int parse_footer(struct reftable_reader *r, uint8_t *footer,
} }


f++; f++;
r->block_size = get_be24(f); r->block_size = reftable_get_be24(f);


f += 3; f += 3;
r->min_update_index = get_be64(f); r->min_update_index = reftable_get_be64(f);
f += 8; f += 8;
r->max_update_index = get_be64(f); r->max_update_index = reftable_get_be64(f);
f += 8; f += 8;


if (r->version == 1) { if (r->version == 1) {
r->hash_id = REFTABLE_HASH_SHA1; r->hash_id = REFTABLE_HASH_SHA1;
} else { } else {
switch (get_be32(f)) { switch (reftable_get_be32(f)) {
case REFTABLE_FORMAT_ID_SHA1: case REFTABLE_FORMAT_ID_SHA1:
r->hash_id = REFTABLE_HASH_SHA1; r->hash_id = REFTABLE_HASH_SHA1;
break; break;
@ -127,24 +127,24 @@ static int parse_footer(struct reftable_reader *r, uint8_t *footer,
f += 4; f += 4;
} }


r->ref_offsets.index_offset = get_be64(f); r->ref_offsets.index_offset = reftable_get_be64(f);
f += 8; f += 8;


r->obj_offsets.offset = get_be64(f); r->obj_offsets.offset = reftable_get_be64(f);
f += 8; f += 8;


r->object_id_len = r->obj_offsets.offset & ((1 << 5) - 1); r->object_id_len = r->obj_offsets.offset & ((1 << 5) - 1);
r->obj_offsets.offset >>= 5; r->obj_offsets.offset >>= 5;


r->obj_offsets.index_offset = get_be64(f); r->obj_offsets.index_offset = reftable_get_be64(f);
f += 8; f += 8;
r->log_offsets.offset = get_be64(f); r->log_offsets.offset = reftable_get_be64(f);
f += 8; f += 8;
r->log_offsets.index_offset = get_be64(f); r->log_offsets.index_offset = reftable_get_be64(f);
f += 8; f += 8;


computed_crc = crc32(0, footer, f - footer); computed_crc = crc32(0, footer, f - footer);
file_crc = get_be32(f); file_crc = reftable_get_be32(f);
f += 4; f += 4;
if (computed_crc != file_crc) { if (computed_crc != file_crc) {
err = REFTABLE_FORMAT_ERROR; err = REFTABLE_FORMAT_ERROR;
@ -214,7 +214,7 @@ static int32_t extract_block_size(uint8_t *data, uint8_t *typ, uint64_t off,


*typ = data[0]; *typ = data[0];
if (reftable_is_block_type(*typ)) { if (reftable_is_block_type(*typ)) {
result = get_be24(data + 1); result = reftable_get_be24(data + 1);
} }
return result; return result;
} }

View File

@ -689,7 +689,7 @@ static int reftable_log_record_key(const void *r, struct reftable_buf *dest)
return err; return err;


ts = (~ts) - rec->update_index; ts = (~ts) - rec->update_index;
put_be64(&i64[0], ts); reftable_put_be64(&i64[0], ts);


err = reftable_buf_add(dest, i64, sizeof(i64)); err = reftable_buf_add(dest, i64, sizeof(i64));
if (err < 0) if (err < 0)
@ -814,7 +814,7 @@ static int reftable_log_record_encode(const void *rec, struct string_view s,
if (s.len < 2) if (s.len < 2)
return -1; return -1;


put_be16(s.buf, r->value.update.tz_offset); reftable_put_be16(s.buf, r->value.update.tz_offset);
string_view_consume(&s, 2); string_view_consume(&s, 2);


n = encode_string( n = encode_string(
@ -846,7 +846,7 @@ static int reftable_log_record_decode(void *rec, struct reftable_buf key,
} }


memcpy(r->refname, key.buf, key.len - 8); memcpy(r->refname, key.buf, key.len - 8);
ts = get_be64(key.buf + key.len - 8); ts = reftable_get_be64((unsigned char *)key.buf + key.len - 8);


r->update_index = (~max) - ts; r->update_index = (~max) - ts;


@ -937,7 +937,7 @@ static int reftable_log_record_decode(void *rec, struct reftable_buf key,
goto done; goto done;
} }


r->value.update.tz_offset = get_be16(in.buf); r->value.update.tz_offset = reftable_get_be16(in.buf);
string_view_consume(&in, 2); string_view_consume(&in, 2);


n = decode_string(scratch, in); n = decode_string(scratch, in);

View File

@ -99,9 +99,9 @@ static int writer_write_header(struct reftable_writer *w, uint8_t *dest)


dest[4] = writer_version(w); dest[4] = writer_version(w);


put_be24(dest + 5, w->opts.block_size); reftable_put_be24(dest + 5, w->opts.block_size);
put_be64(dest + 8, w->min_update_index); reftable_put_be64(dest + 8, w->min_update_index);
put_be64(dest + 16, w->max_update_index); reftable_put_be64(dest + 16, w->max_update_index);
if (writer_version(w) == 2) { if (writer_version(w) == 2) {
uint32_t hash_id; uint32_t hash_id;


@ -116,7 +116,7 @@ static int writer_write_header(struct reftable_writer *w, uint8_t *dest)
return -1; return -1;
} }


put_be32(dest + 24, hash_id); reftable_put_be32(dest + 24, hash_id);
} }


return header_size(writer_version(w)); return header_size(writer_version(w));
@ -730,19 +730,19 @@ int reftable_writer_close(struct reftable_writer *w)
} }


p += writer_write_header(w, footer); p += writer_write_header(w, footer);
put_be64(p, w->stats.ref_stats.index_offset); reftable_put_be64(p, w->stats.ref_stats.index_offset);
p += 8; p += 8;
put_be64(p, (w->stats.obj_stats.offset) << 5 | w->stats.object_id_len); reftable_put_be64(p, (w->stats.obj_stats.offset) << 5 | w->stats.object_id_len);
p += 8; p += 8;
put_be64(p, w->stats.obj_stats.index_offset); reftable_put_be64(p, w->stats.obj_stats.index_offset);
p += 8; p += 8;


put_be64(p, w->stats.log_stats.offset); reftable_put_be64(p, w->stats.log_stats.offset);
p += 8; p += 8;
put_be64(p, w->stats.log_stats.index_offset); reftable_put_be64(p, w->stats.log_stats.index_offset);
p += 8; p += 8;


put_be32(p, crc32(0, footer, p - footer)); reftable_put_be32(p, crc32(0, footer, p - footer));
p += 4; p += 4;


err = w->flush(w->write_arg); err = w->flush(w->write_arg);

View File

@ -128,12 +128,30 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
reftable_buf_release(&b); reftable_buf_release(&b);
} }


if_test ("put_be24 and get_be24 work") { if_test ("reftable_put_be64 and reftable_get_be64 work") {
uint64_t in = 0x1122334455667788;
uint8_t dest[8];
uint64_t out;
reftable_put_be64(dest, in);
out = reftable_get_be64(dest);
check_int(in, ==, out);
}

if_test ("reftable_put_be32 and reftable_get_be32 work") {
uint32_t in = 0x11223344;
uint8_t dest[4];
uint32_t out;
reftable_put_be32(dest, in);
out = reftable_get_be32(dest);
check_int(in, ==, out);
}

if_test ("reftable_put_be24 and reftable_get_be24 work") {
uint32_t in = 0x112233; uint32_t in = 0x112233;
uint8_t dest[3]; uint8_t dest[3];
uint32_t out; uint32_t out;
put_be24(dest, in); reftable_put_be24(dest, in);
out = get_be24(dest); out = reftable_get_be24(dest);
check_int(in, ==, out); check_int(in, ==, out);
} }


@ -141,8 +159,8 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
uint32_t in = 0xfef1; uint32_t in = 0xfef1;
uint8_t dest[3]; uint8_t dest[3];
uint32_t out; uint32_t out;
put_be16(dest, in); reftable_put_be16(dest, in);
out = get_be16(dest); out = reftable_get_be16(dest);
check_int(in, ==, out); check_int(in, ==, out);
} }