change.h
#ifndef ANI_CHANGE_H
#define ANI_CHANGE_H
/**
* Required headers
* * stdint.h
*/
#define VERSION 6
#define VERSION_NOENC 4
/**
* A table of contents for a change, indicating where each section is, to allow
* seeking inside a change file.
*/
struct offsets {
uint64_t version;
uint64_t hashed_len; /* length of hashed contents */
uint64_t unhashed_off;
uint64_t unhashed_len; /* length of unhashed contents */
uint64_t contents_off;
uint64_t contents_len; /* length of contents (uncompressed) */
uint64_t total; /* contents_off + length(compressed contents) */
};
/**
* Errors that can arise when working with change files
*/
enum error {
/* all good */
CHANGEFILE_OK,
/* .change file is too short */
CHANGEFILE_TOOSHORT,
/* .change file length mismatch */
CHANGEFILE_LENGTHMISMATCH,
/* version specified in file is not supported */
CHANGEFILE_UNSUPPORTEDVERSION,
/* hash mismatch */
CHANGEFILE_HASHMISMATCH,
};
enum error changefileoffsets(struct mbuf *, struct offsets *);
/* sizeof(struct offsets) */
#define OFFSETS_SIZE 56
struct authorentry {
str key;
str value;
};
/** An "author" is (strangely) a list of key-value pairs */
struct author {
size_t len;
struct authorentry *entries;
};
/**
* A list of key-value collections (BTreeMap)
*/
struct authors {
size_t len;
struct author *map;
};
void authorsfree(struct authors *);
struct changeheader {
str message; /* the "commit" message */
str description; /* the other undescribed part of a change */
str timestamp; /* yes, as a string */
struct authors authors; /* a list of "key"="value" collections */
};
/**
* The parts of a given change that is blake3-hashed.
*
* The actual hashing happens on the serialized (w/bincode) version of this
* struct. Decoding the 'changes' field will take quite a bit of doing, it's a
* fairly convoluted field.
*/
struct hashed {
uint64_t version; /* same as in offsets? here to be hashed! */
struct changeheader header;
struct hashlist dependencies; /* array of hashes */
struct hashlist extraknown; /* another array of hashes */
uint8_t *metadata;
struct hunklist hunks;
};
void hashedfree(struct hashed *);
/**
* Decode the 'struct offsets' from the given fd
*
* Return 0 if decoding completed successfully, a negative number indicates an
* error.
*/
int decode_offsets(int fd, struct offsets *);
/**
* Decompress and decode the hashed parts of a .change file. The
* struct hashed pointer argument is populated with the result.
*
*/
enum error change_decodehashed(u8 *, usize, u8 *, struct hashed *);
struct change {
struct offsets offsets;
struct hashed hashed;
uint8_t *contents;
};
struct changeentry {
size_t num;
struct hash hash;
struct change change;
};
/**
* structure for keeping track of multiple changes
*/
struct changestore {
char *repodir; /* absolute path to the changestore */
size_t len;
size_t cap;
struct changeentry *entries;
};
void changestoreinit(struct changestore *, size_t cap, const char *);
void changestorefree(struct changestore *);
/**
* either fetch a change that's already loaded, or load a change into
* the changestore.
*/
struct change *changestoreget(struct changestore *, struct hash *);
int changestoreload(struct changestore *, struct hash *);
#endif