change: support version = 4 (noenc) format

laumann
Oct 6, 2023, 9:09 AM
ZS3UJEZU4PZEYOXQNZWZGDNXTP5ESNPRAEHPJQ24O3TWZH746IBQC

Dependencies

  • [2] XRGUHSC4 change: fix some formatting issues
  • [3] 7NQTS36D bincode: change signature of getstr to receive str destination
  • [4] QSQNGA5K changestore: load changes on demand
  • [5] JAGXXSR7 change: initial work on decoding hunks
  • [6] YFBKBUKB change: rename binstat -> bc
  • [7] VXQYIOBX change: avoid crash on different format versions
  • [8] 7WA2F6RS change: decode resurrectzombies, addroot, delroot
  • [9] 5D2IYPL7 change: introduce changestore, print deleted lines
  • [10] XTKRT6OQ format the codebase
  • [11] 2U7P5SFQ Change struct names "struct foo -> typedef struct Foo"
  • [12] VKLGQREY change: add base32 decode, initial deconstruction of hashed
  • [13] ZKAOPMCH change: Implement decoding of edits, atoms, positions, among others
  • [14] NEORNIZE change: decode and print file moves
  • [15] LPGHALLK change: adjust printing of file adds
  • [16] OBKF6SII change: decompress the hashed section too
  • [17] TGT4VSME change: decode FILE_ADD
  • [18] Q7TKZCJP Add initial support for reading the offsets from a (fixed) change
  • [19] 2YF4J5SJ change: decode and print file undel
  • [20] QYRJIOYP change: separate decoding and printing of hashed struct
  • [21] JVU3TTT5 all: switch away from typedefing anonymous structs
  • [22] NZNIG2UL Fix lots of warnings, adjust build flags
  • [23] YG4DZB3A add representation of hash, decode dependencies
  • [24] FMYCPGKD change: extract hash list decoding into reused function
  • [25] LCEKN25G change: parse authors
  • [26] O7XAUFM6 change: decode and print {,un}solve order conflicts
  • [*] RIWSVVAS change: decompress the 'contents' with zstd_seekable
  • [*] XTVLIC24 change: refactor to print_change()

Change contents

  • edit in change.c at line 289
    [4.3757]
    [4.3757]
    static void
    change_decode_encoding_noenc(struct bincode *bc, char **encoding)
    {
    (void)bc;
    *encoding = xstrdup("UTF-8");
    }
  • edit in change.c at line 304
    [4.489]
    [4.3878]
    void (*fn_change_decode_encoding)(struct bincode *, char **);
    fn_change_decode_encoding = &change_decode_encoding;
    if (hashed->version == VERSION_NOENC)
    fn_change_decode_encoding = change_decode_encoding_noenc;
  • replacement in change.c at line 324
    [4.3181][4.3181:3235]()
    change_decode_encoding(bc, &bhunk->edit.encoding);
    [4.3181]
    [4.4305]
    fn_change_decode_encoding(bc, &bhunk->edit.encoding);
  • replacement in change.c at line 330
    [4.3406][4.3406:3467]()
    change_decode_encoding(bc, &bhunk->replacement.encoding);
    [4.3406]
    [4.0]
    fn_change_decode_encoding(
    bc, &bhunk->replacement.encoding
    );
  • replacement in change.c at line 342
    [3.238][4.3734:3791](),[4.3734][4.3734:3791]()
    change_decode_encoding(bc, &bhunk->fileadd.encoding);
    [3.238]
    [4.583]
    fn_change_decode_encoding(bc, &bhunk->fileadd.encoding);
  • replacement in change.c at line 359
    [3.430][4.4185:4242](),[4.4185][4.4185:4242]()
    change_decode_encoding(bc, &bhunk->filedel.encoding);
    [3.430]
    [4.58]
    fn_change_decode_encoding(bc, &bhunk->filedel.encoding);
  • replacement in change.c at line 370
    [3.529][4.4442:4501](),[4.4442][4.4442:4501]()
    change_decode_encoding(bc, &bhunk->fileundel.encoding);
    [3.529]
    [4.258]
    fn_change_decode_encoding(
    bc, &bhunk->fileundel.encoding
    );
  • replacement in change.c at line 407
    [4.5040][4.490:517](),[4.490][4.490:517]()
    change_decode_encoding(
    [4.5040]
    [4.5041]
    fn_change_decode_encoding(
  • edit in change.c at line 423
    [4.620]
    [4.620]
    }
    }
    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;
  • edit in change.c at line 486
    [4.623]
    [4.623]
    if (email) {
    i++;
    author->entries[i].key = xstrdup("email");
    author->entries[i].value = email;
    }
  • edit in change.c at line 508
    [4.5304]
    [28.2591]
    void (*fn_change_decode_author)(struct bincode *, struct author *);
  • replacement in change.c at line 566
    [4.514][4.427:479](),[4.479][4.490:502](),[4.502][4.5718:5747](),[4.5747][4.480:522](),[4.634][4.480:522](),[4.522][4.3897:3938](),[4.3169][4.523:626](),[4.3938][4.523:626](),[4.1331][4.523:626](),[4.626][4.43:176]()
    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
    [4.514]
    [4.176]
    fn_change_decode_author = change_decode_author;
    if (hashed->version == VERSION_NOENC)
    fn_change_decode_author = change_decode_author_noenc;
  • replacement in change.c at line 570
    [4.177][4.177:265](),[4.265][4.5748:5778](),[4.5778][4.627:677](),[4.849][4.627:677](),[4.677][3.1075:1189](),[3.1189][4.5809:5839](),[4.5809][4.5809:5839](),[4.5839][4.678:730](),[4.964][4.678:730](),[4.730][3.1190:1306](),[3.1306][4.1172:1176](),[4.1617][4.1172:1176](),[4.5870][4.1172:1176](),[4.1172][4.1172:1176]()
    // 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
    );
    }
    [4.177]
    [4.838]
    for (i = 0; i < hashed->header.authors.len; i++) {
    fn_change_decode_author(&bc, &hashed->header.authors.map[i]);
  • edit in change.c at line 807
    [4.765]
    [4.765]
  • edit in change.c at line 815
    [4.979]
    [29.253]
    /**
    * 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';
    }
  • edit in change.c at line 844
    [4.605]
    [29.316]
    void (*fn_read_filemetadata)(struct filemetadata *, uint8_t *, size_t);
  • edit in change.c at line 846
    [29.317]
    [29.317]
    fn_read_filemetadata = read_filemetadata;
    if (hashed->version == VERSION_NOENC)
    fn_read_filemetadata = read_filemetadata_noenc;
  • replacement in change.c at line 917
    [4.197][2.0:23]()
    read_filemetadata(
    [4.197]
    [2.23]
    fn_read_filemetadata(
  • replacement in change.c at line 944
    [4.1214][4.1214:1236]()
    read_filemetadata(
    [4.1214]
    [4.1236]
    fn_read_filemetadata(
  • replacement in change.c at line 1074
    [4.1874][4.7277:7348](),[4.7348][4.335:421](),[4.335][4.335:421](),[4.421][4.7349:7374](),[4.7374][4.445:512](),[4.445][4.445:512](),[4.512][4.7375:7400](),[4.7400][4.536:540](),[4.536][4.536:540]()
    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);
    }
    [4.1874]
    [4.540]
    if (off->version != VERSION && off->version != VERSION_NOENC) {
    printf("Version %lu is not yet supported, sorry.\n",
    off->version);
    err = off->version;
  • replacement in change.c at line 1232
    [4.8278][4.8278:8292]()
    size_t i, x;
    [4.8278]
    [4.8292]
    size_t x;