Supporting the noenc format requires (1) decoding authors slightly differently and (2) not attempting to read an encoding field for most hunks. The default encoding in such instances is UTF-8.
ZS3UJEZU4PZEYOXQNZWZGDNXTP5ESNPRAEHPJQ24O3TWZH746IBQC
XRGUHSC47YCVLCII7W7VDI3ZNZ4KT43GEQR2EL7Y5CH4SETUBOMQC
7NQTS36DJ6GRXMZDNMORKPWF7VBESQY4DH2XFI7VI2A2JVMFIK5AC
JAGXXSR7DR5FG77VKBF62BW7Q3JMVHCLHF4VB2PSLIZF4RLE553QC
Q7TKZCJP2Z75EICZYKCEZDHKGERSOKZGMTSU3UXETBHTF663T66AC
NZNIG2ULNMS5Z3OWEKRVOPLFA6CWYNF47U7UMXNZFSX256F2ZZVAC
YFBKBUKBX3JB7OCB4D3ZKSLWTP6QWZ36HEE5GZROJE55RK33MZCAC
TGT4VSMEWWTFYILTXVZWA5WHB2RCZZYNGZJ3UUKZ5OPD6JQD4G5QC
FMYCPGKDAPOUFLQOCXXKZ6TR75HT3TNCG4X3GAJDM4ARWKNWOSWAC
2YF4J5SJ2Z5EWPGJ4K57JGMRFAHIUL24ODELKRCXA4ILZDVS5LWQC
O7XAUFM6CCSFXSBTGOMVHRUQFJEWPO6YLNO52OT3AZ4GYN6JJONAC
7WA2F6RSQBGJJE5MZGQGAYJOWYEKQUWVI2MTZ4AMICEEQFENXANQC
RIWSVVASWLJQQTSVRHIIUPENOZWOMHQLZMTQVGJUS2ZUGDPSWWIQC
LCEKN25G5GFBUWWQAR4REIGPOL6JYNDWLNCDJGZQKOWIDHGIRMZAC
QYRJIOYPM7SAB3OHMALL67K44U5HPBRQ2AFNWUKATPXM6BUYRKBQC
JVU3TTT5T776LB2UNT5DCISJDWOITRSJPRG3CDTX4NDQEHC5VI3QC
2U7P5SFQG3AVALKMPJF4WMZE6PXIXXZYOMZ3RZKILBUJ4UMFXVIAC
XTKRT6OQYN4LARQRDLI2KBSAJTOFZNT4AMBZ46CPUDZXD7IDYYWQC
VXQYIOBXHTYEB62XSIAZGRNNIKXMDZLE5ANBGA7E7V3HOBVEMVSAC
YG4DZB3AW3Z3LB5CFBZZ4ORJOLZFN3G4CA2YTAMSUOQX3USVNVEAC
NEORNIZEGPZAVZV2J6TTCWPZAQM3N7MH7SMS3NDT4WKTXI34NSUAC
XTVLIC243WZF52NVTNRA3SV3WLE2ZZ5GTFQOK45IOLMXYQMTLOSAC
LPGHALLKCQRJUB7BNHABAG2VEEAFTUSN3WAPASM5B3V6JJ54GXJQC
OBKF6SIIFFHHY7YWKPPX75N23NAVUD5662DKIHXSSIDPKKXQ5ZDQC
5D2IYPL75HEP6JUEILEADSZRRSV72NECT6UQR3PORNDR35I2P5GQC
}
}
void
change_decode_author(struct bincode *bc, struct author *author)
{
size_t len, i;
len = bincode_getu64(bc);
author->len = len;
author->entries = xmalloc(sizeof(struct authorentry) * len);
for (i = 0; i < author->len; i++) {
len = bincode_getu64(bc);
author->entries[i].key = xmalloc(len + 1);
bincode_getstr(bc, author->entries[i].key, len);
len = bincode_getu64(bc);
author->entries[i].value = xmalloc(len + 1);
bincode_getstr(bc, author->entries[i].value, len);
}
}
void
change_decode_author_noenc(struct bincode *bc, struct author *author)
{
size_t len, i;
char *name, *full_name, *email;
i = 1;
full_name = email = NULL;
len = bincode_getu64(bc);
name = xmalloc(len + 1);
bincode_getstr(bc, name, len);
if (bincode_getu8(bc)) {
i++;
len = bincode_getu64(bc);
full_name = xmalloc(len + 1);
bincode_getstr(bc, full_name, len);
}
if (bincode_getu8(bc)) {
i++;
len = bincode_getu64(bc);
email = xmalloc(len + 1);
bincode_getstr(bc, email, len);
}
author->len = i;
author->entries = xmalloc(sizeof(struct authorentry) * i);
i = 0;
author->entries[i].key = xstrdup("name");
author->entries[i].value = name;
if (full_name) {
i++;
author->entries[i].key = xstrdup("full_name");
author->entries[i].value = full_name;
for (i = 0; i < hashed->header.authors.len; i++) {
size_t j;
len = bincode_getu64(&bc);
hashed->header.authors.map[i].entries =
xmalloc(sizeof(struct author) * len);
hashed->header.authors.map[i].len = len;
for (j = 0; j < hashed->header.authors.map[i].len; j++) {
// In VERSION_NOENC, the authors are a struct { name: str, full_name: maybe str, email: maybe str } instead of a more generic map
fn_change_decode_author = change_decode_author;
if (hashed->version == VERSION_NOENC)
fn_change_decode_author = change_decode_author_noenc;
// TODO switch on offsets.version to figure
// out how to decode the authors here
len = bincode_getu64(&bc);
hashed->header.authors.map[i].entries[j].key =
xmalloc(len + 1);
bincode_getstr(
&bc,
hashed->header.authors.map[i].entries[j].key,
len
);
len = bincode_getu64(&bc);
hashed->header.authors.map[i].entries[j].value =
xmalloc(len + 1);
bincode_getstr(
&bc,
hashed->header.authors.map[i].entries[j].value,
len
);
}
for (i = 0; i < hashed->header.authors.len; i++) {
fn_change_decode_author(&bc, &hashed->header.authors.map[i]);
/**
* In the VERSION_NOENC file metadata (for file additions), the
* filemetadata contains *only* the inodemetadata directly followed by
* the basename. The basename is not bincode-encoded, so we assume the
* length of the string is the given content length minus 2 (for the
* first two bytes used by the inodemetadata).
*/
static void
read_filemetadata_noenc(
struct filemetadata *m, uint8_t *contents, size_t contents_len
)
{
size_t len;
struct bincode bc = { .avail = contents_len, .buf = contents };
m->inodemetadata = bincode_getu16(&bc);
len = contents_len - 2;
m->basename = xmalloc(len + 1);
memcpy(m->basename, &contents[2], len);
m->basename[len] = '\0';
}
if (off->version != VERSION) {
if (off->version == VERSION_NOENC) {
printf("The NOENC version (%lu) is not yet supported, sorry (but it's planned)\n",
off->version);
} else {
printf("Version %lu is not yet supported, sorry.\n",
off->version);
}
if (off->version != VERSION && off->version != VERSION_NOENC) {
printf("Version %lu is not yet supported, sorry.\n",
off->version);
err = off->version;