AmendHub

Download:

jcs

/

subtext

/

amendments

/

50

bile: Even more API changes


jcs made amendment 50 over 2 years ago
--- bile.c Thu Jan 6 17:07:39 2022 +++ bile.c Tue Jan 11 19:28:31 2022 @@ -18,21 +18,32 @@ #include "bile.h" #include "util.h" +/* for errors not specific to a bile */ static short _bile_error; -short bile_write_map(struct bile *bile); -void bile_sort_by_pos(struct bile *bile); -size_t bile_xwriteat(struct bile *bile, const size_t pos, const void *data, - const size_t len); +struct bile_object * bile_alloc(struct bile *bile, const OSType type, + const unsigned long id, const size_t size); +struct bile_object * bile_object_in_map(struct bile *bile, + const OSType type, const unsigned long id); +short bile_write_map(struct bile *bile); +void bile_sort_by_pos(struct bile *bile); +size_t bile_xwriteat(struct bile *bile, const size_t pos, + const void *data, const size_t len); +/* Public API */ + short -bile_error(void) +bile_error(struct bile *bile) { - return _bile_error; + if (bile == NULL) + return _bile_error; + + return bile->last_error; } struct bile * -bile_create(const Str255 filename, const OSType creator, const OSType type) +bile_create(const Str255 filename, short vrefnum, const OSType creator, + const OSType type) { struct bile *bile = NULL; size_t len; @@ -42,30 +53,31 @@ bile_create(const Str255 filename, const OSType creato _bile_error = 0; /* create file */ - _bile_error = Create(filename, 0, creator, type); + _bile_error = Create(filename, vrefnum, creator, type); if (_bile_error) return NULL; - _bile_error = FSOpen(filename, 0, &fh); + _bile_error = FSOpen(filename, vrefnum, &fh); if (_bile_error) return NULL; bile = xmalloczero(sizeof(struct bile)); - bile->vrefid = fh; + bile->vrefnum = vrefnum; + bile->frefnum = fh; bile->map_ptr.type = BILE_TYPE_MAPPTR; memcpy(bile->filename, filename, sizeof(bile->filename)); /* write magic */ len = BILE_MAGIC_LEN; magic = xstrdup(BILE_MAGIC); - _bile_error = FSWrite(bile->vrefid, &len, magic); + _bile_error = FSWrite(bile->frefnum, &len, magic); free(magic); if (_bile_error) goto create_bail; /* write header pointing to blank map */ len = sizeof(bile->map_ptr); - _bile_error = FSWrite(bile->vrefid, &len, &bile->map_ptr); + _bile_error = FSWrite(bile->frefnum, &len, &bile->map_ptr); if (_bile_error) goto create_bail; @@ -78,14 +90,14 @@ bile_create(const Str255 filename, const OSType creato return bile; create_bail: - FSClose(bile->vrefid); + FSClose(bile->frefnum); if (bile != NULL) free(bile); return NULL; } struct bile * -bile_open(const Str255 filename) +bile_open(const Str255 filename, short vrefnum) { struct bile *bile = NULL; struct bile_object map_obj; @@ -96,7 +108,7 @@ bile_open(const Str255 filename) _bile_error = 0; /* open file */ - _bile_error = FSOpen(filename, 0, &fh); + _bile_error = FSOpen(filename, vrefnum, &fh); if (_bile_error) return NULL; @@ -118,13 +130,14 @@ bile_open(const Str255 filename) } bile = xmalloczero(sizeof(struct bile)); - bile->vrefid = fh; - memcpy(bile->filename, filename, sizeof(filename)); + bile->vrefnum = vrefnum; + bile->frefnum = fh; + memcpy(bile->filename, filename, sizeof(bile->filename)); bile->file_size = file_size; /* load map pointer */ size = sizeof(bile->map_ptr); - _bile_error = FSRead(bile->vrefid, &size, &bile->map_ptr); + _bile_error = FSRead(bile->frefnum, &size, &bile->map_ptr); if (_bile_error) goto open_bail; @@ -137,12 +150,13 @@ bile_open(const Str255 filename) if (bile->map_ptr.size) { /* read and verify map object header map_ptr points to */ - _bile_error = SetFPos(bile->vrefid, fsFromStart, bile->map_ptr.pos); + _bile_error = SetFPos(bile->frefnum, fsFromStart, + bile->map_ptr.pos); if (_bile_error) goto open_bail; size = sizeof(struct bile_object); - _bile_error = FSRead(bile->vrefid, &size, &map_obj); + _bile_error = FSRead(bile->frefnum, &size, &map_obj); if (_bile_error) goto open_bail; @@ -156,7 +170,7 @@ bile_open(const Str255 filename) /* read entire map */ size = map_obj.size; bile->map = xmalloczero(size); - _bile_error = FSRead(bile->vrefid, &size, bile->map); + _bile_error = FSRead(bile->frefnum, &size, bile->map); if (_bile_error) goto open_bail; bile->nobjects = map_obj.size / BILE_OBJECT_SIZE; @@ -165,7 +179,7 @@ bile_open(const Str255 filename) return bile; open_bail: - FSClose(bile->vrefid); + FSClose(bile->frefnum); if (bile != NULL) free(bile); return NULL; @@ -179,31 +193,25 @@ bile_close(struct bile *bile) _bile_error = 0; - FSClose(bile->vrefid); + FSClose(bile->frefnum); if (bile->map != NULL) free(bile->map); } -/* XXX: these become invalid once we re-sort, should we return a copy? */ struct bile_object * bile_find(struct bile *bile, const OSType type, const unsigned long id) { - struct bile_object *o; + struct bile_object *o, *ocopy; unsigned long n; - if (bile == NULL) - panic("bile_find: bogus bile"); - - _bile_error = 0; + o = bile_object_in_map(bile, type, id); + if (o == NULL) + return NULL; - /* look backwards, optimizing for newer data */ - for (n = bile->nobjects; n > 0; n--) { - o = &bile->map[n - 1]; - if (o->type == type && o->id == id) - return o; - } + ocopy = xmalloc(BILE_OBJECT_SIZE); + memcpy(ocopy, o, BILE_OBJECT_SIZE); - return NULL; + return ocopy; } size_t @@ -215,7 +223,7 @@ bile_count_by_type(struct bile *bile, const OSType typ if (bile == NULL) panic("bile_count_by_type: bogus bile"); - _bile_error = 0; + _bile_error = bile->last_error = 0; for (n = 0; n < bile->nobjects; n++) { o = &bile->map[n - 1]; @@ -226,105 +234,70 @@ bile_count_by_type(struct bile *bile, const OSType typ return count; } -size_t -bile_next_id(struct bile *bile, const OSType type) +struct bile_object * +bile_get_nth_of_type(struct bile *bile, const size_t index, + const OSType type) { - struct bile_object *o; - size_t n, id = 1; - + struct bile_object *o, *ocopy; + size_t n, count = 0; + if (bile == NULL) - panic("bile_next_id: bogus bile"); + panic("bile_get_nth_of_type: bogus bile"); - _bile_error = 0; + _bile_error = bile->last_error = 0; for (n = 0; n < bile->nobjects; n++) { o = &bile->map[n - 1]; - if (o->type == type && o->id >= id) - id = o->id + 1; + if (o->type != type) + continue; + + if (count == index) { + ocopy = xmalloc(BILE_OBJECT_SIZE); + memcpy(ocopy, o, BILE_OBJECT_SIZE); + return ocopy; + } + count++; } - return id; + return NULL; } -struct bile_object * -bile_alloc(struct bile *bile, const OSType type, const unsigned long id, - const size_t size) +size_t +bile_next_id(struct bile *bile, const OSType type) { - struct bile_object *newo, *o; - size_t last_pos = BILE_HEADER_LEN; - short n; + struct bile_object *o; + size_t n, id = 1; if (bile == NULL) - panic("bile_alloc: bogus bile"); + panic("bile_next_id: bogus bile"); - _bile_error = 0; + _bile_error = bile->last_error = 0; - bile->map = xreallocarray(bile->map, bile->nobjects + 1, - BILE_OBJECT_SIZE); - - /* find a last_pos we can use */ for (n = 0; n < bile->nobjects; n++) { - if (bile->map[n].pos - last_pos >= (size + BILE_OBJECT_SIZE)) - break; - last_pos = bile->map[n].pos + BILE_OBJECT_SIZE + bile->map[n].size; - } - - newo = &bile->map[bile->nobjects]; - bile->nobjects++; - newo->pos = last_pos; - newo->size = size; - newo->type = type; - newo->id = id; - - bile_sort_by_pos(bile); - - /* find our new object pointer after sorting */ - for (n = bile->nobjects; n > 0; n--) { o = &bile->map[n - 1]; - if (o->type == type && o->pos == last_pos) - return o; + if (o->type == type && o->id >= id) + id = o->id + 1; } - panic("bile_alloc: couldn't find newly added object?"); + return id; } -void -bile_sort_by_pos(struct bile *bile) -{ - short i, j; - struct bile_object o; - if (bile == NULL) - panic("bile_sort_by_pos: bogus bile"); - - _bile_error = 0; - - for (i = 0; i < bile->nobjects; i++) { - for (j = 0; j < bile->nobjects - i - 1; j++) { - if (bile->map[j].pos > bile->map[j + 1].pos) { - o = bile->map[j]; - bile->map[j] = bile->map[j + 1]; - bile->map[j + 1] = o; - } - } - } -} - short bile_delete(struct bile *bile, const OSType type, const unsigned long id) { + static char zero[128] = { 0 }; struct bile_object *o; size_t pos, size, wsize; - char *zero; if (bile == NULL) panic("bile_delete: bogus bile"); - _bile_error = 0; + _bile_error = bile->last_error = 0; - o = bile_find(bile, type, id); + o = bile_object_in_map(bile, type, id); if (o == NULL) { - _bile_error = -1; + _bile_error = bile->last_error = -1; return -1; } @@ -336,16 +309,17 @@ bile_delete(struct bile *bile, const OSType type, cons if (_bile_error) return -1; - _bile_error = SetFPos(bile->vrefid, fsFromStart, pos); + _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromStart, + pos); if (_bile_error) return -1; - zero = xmalloczero(128); while (size > 0) { wsize = MIN(128, size); size -= wsize; - _bile_error = FSWrite(bile->vrefid, &wsize, zero); + _bile_error = bile->last_error = FSWrite(bile->frefnum, &wsize, + zero); if (_bile_error) return -1; } @@ -369,38 +343,38 @@ bile_read_object(struct bile *bile, const struct bile_ if (len == 0) panic("bile_read_object: zero len"); - _bile_error = 0; + _bile_error = bile->last_error = 0; if (o->pos + BILE_OBJECT_SIZE + o->size > bile->file_size) panic("bile_read_object: object %ld pos %ld size %ld > file size %ld", o->id, o->pos, o->size, bile->file_size); - _bile_error = SetFPos(bile->vrefid, fsFromStart, o->pos); + _bile_error = SetFPos(bile->frefnum, fsFromStart, o->pos); if (_bile_error) panic("bile_read_object: object %lu points to bogus position %lu", o->id, o->pos); rsize = BILE_OBJECT_SIZE; - _bile_error = FSRead(bile->vrefid, &rsize, &verify); + _bile_error = bile->last_error = FSRead(bile->frefnum, &rsize, &verify); if (_bile_error) return 0; if (verify.id != o->id) - panic("bile_read_object: object %ld pos %ld wrong id %ld, expected %ld", - o->id, o->pos, verify.id, o->id); + panic("bile_read_object: object %ld pos %ld wrong id %ld, " + "expected %ld", o->id, o->pos, verify.id, o->id); if (verify.type != o->type) - panic("bile_read_object: object %ld pos %ld wrong type %ld, expected %ld", - o->id, o->pos, verify.type, o->type); + panic("bile_read_object: object %ld pos %ld wrong type %ld, " + "expected %ld", o->id, o->pos, verify.type, o->type); if (verify.size != o->size) - panic("bile_read_object: object %ld pos %ld wrong size %ld, expected %ld", - o->id, o->pos, verify.size, o->size); + panic("bile_read_object: object %ld pos %ld wrong size %ld, " + "expected %ld", o->id, o->pos, verify.size, o->size); wantlen = len; if (wantlen > o->size) wantlen = o->size; rsize = wantlen; - _bile_error = FSRead(bile->vrefid, &rsize, data); + _bile_error = bile->last_error = FSRead(bile->frefnum, &rsize, data); if (_bile_error) return 0; @@ -415,21 +389,25 @@ bile_read(struct bile *bile, const OSType type, const char *data, const size_t len) { struct bile_object *o; - + size_t ret; + if (bile == NULL) panic("bile_read: bogus bile"); if (data == NULL) panic("bile_read: NULL data pointer passed"); - _bile_error = 0; + _bile_error = bile->last_error = 0; o = bile_find(bile, type, id); if (o == NULL) { - _bile_error = -1; + _bile_error = bile->last_error = -1; return 0; } - return bile_read_object(bile, o, data, len); + ret = bile_read_object(bile, o, data, len); + free(o); + + return ret; } size_t @@ -437,22 +415,26 @@ bile_read_alloc(struct bile *bile, const OSType type, const unsigned long id, char **data) { struct bile_object *o; + size_t ret; if (bile == NULL) panic("bile_read: bogus bile"); if (data == NULL) panic("bile_read: NULL data pointer passed"); - _bile_error = 0; + _bile_error = bile->last_error = 0; o = bile_find(bile, type, id); if (o == NULL) { - _bile_error = -1; + _bile_error = bile->last_error = -1; return 0; } *data = xmalloczero(o->size); - return bile_read_object(bile, o, *data, o->size); + ret = bile_read_object(bile, o, *data, o->size); + free(o); + + return ret; } size_t @@ -470,42 +452,127 @@ bile_write(struct bile *bile, const OSType type, const if (data == NULL) panic("bile_write: NULL data pointer passed"); - _bile_error = 0; + _bile_error = bile->last_error = 0; - old = bile_find(bile, type, id); - if (old) + if ((old = bile_object_in_map(bile, type, id)) != NULL) old->type = BILE_TYPE_PURGE; new_obj = bile_alloc(bile, type, id, len); bile_xwriteat(bile, new_obj->pos, new_obj, BILE_OBJECT_SIZE); - if (_bile_error) + if (bile->last_error) return 0; wrote = bile_xwriteat(bile, new_obj->pos + BILE_OBJECT_SIZE, data, len); - if (wrote == 0 || _bile_error) + if (wrote != len || bile->last_error) return 0; - SetFPos(bile->vrefid, fsFromLEOF, 0); - GetFPos(bile->vrefid, &bile->file_size); + SetFPos(bile->frefnum, fsFromLEOF, 0); + GetFPos(bile->frefnum, &bile->file_size); bile_write_map(bile); - if (_bile_error) + if (bile->last_error) return 0; return wrote; } + +void +bile_fsck(struct bile *bile) +{ + struct bile_object o; + size_t n; + char data; + + if (bile == NULL) + panic("bile_fsck: bogus bile"); + + _bile_error = bile->last_error = 0; + + for (n = 0; n < bile->nobjects; n++) + bile_read_object(bile, &bile->map[n], &data, 1); +} + +/* Private API */ + +struct bile_object * +bile_object_in_map(struct bile *bile, const OSType type, + const unsigned long id) +{ + struct bile_object *o; + size_t n; + + if (bile == NULL) + panic("bile_find: bogus bile"); + + _bile_error = bile->last_error = 0; + + /* look backwards, optimizing for newer data */ + for (n = bile->nobjects; n > 0; n--) { + o = &bile->map[n - 1]; + if (o->type == type && o->id == id) + return o; + } + + return NULL; +} + +struct bile_object * +bile_alloc(struct bile *bile, const OSType type, const unsigned long id, + const size_t size) +{ + struct bile_object *newo, *o; + size_t last_pos = BILE_HEADER_LEN; + size_t n; + + if (bile == NULL) + panic("bile_alloc: bogus bile"); + + _bile_error = bile->last_error = 0; + + bile->map = xreallocarray(bile->map, bile->nobjects + 1, + BILE_OBJECT_SIZE); + + /* find a last_pos we can use */ + for (n = 0; n < bile->nobjects; n++) { + if (bile->map[n].pos - last_pos >= (size + BILE_OBJECT_SIZE)) + break; + last_pos = bile->map[n].pos + BILE_OBJECT_SIZE + bile->map[n].size; + } + + newo = &bile->map[bile->nobjects]; + bile->nobjects++; + newo->pos = last_pos; + newo->size = size; + newo->type = type; + newo->id = id; + + bile_sort_by_pos(bile); + + /* find our new object pointer after sorting */ + for (n = bile->nobjects; n > 0; n--) { + o = &bile->map[n - 1]; + if (o->type == type && o->pos == last_pos) + return o; + } + + panic("bile_alloc: couldn't find newly added object?"); +} + short bile_write_map(struct bile *bile) { - struct bile_object *obj, *new_map_obj, *new_map; + IOParam pb; + struct bile_object *obj, *new_map_obj, *new_map, + *new_map_obj_in_new_map = NULL; size_t new_map_size, new_nobjects, new_map_id; size_t n; + short ret; if (bile == NULL) panic("bile_write_map: bogus bile"); - _bile_error = 0; + _bile_error = bile->last_error = 0; /* allocate a new map slightly larger than we need */ new_nobjects = bile->nobjects; @@ -520,7 +587,7 @@ bile_write_map(struct bile *bile) new_map_obj = bile_alloc(bile, BILE_TYPE_MAP, new_map_id, new_map_size); new_map = xmallocarray(BILE_OBJECT_SIZE, new_nobjects); - + for (n = 0, new_nobjects = 0; n < bile->nobjects; n++) { obj = &bile->map[n]; @@ -529,31 +596,39 @@ bile_write_map(struct bile *bile) continue; if (obj->type == BILE_TYPE_PURGE) continue; - + + if (obj->type == BILE_TYPE_MAP && obj->pos == new_map_obj->pos) + new_map_obj_in_new_map = &new_map[new_nobjects]; + new_map[new_nobjects++] = *obj; } /* shrink to new object count */ new_map_size = BILE_OBJECT_SIZE * new_nobjects; new_map_obj->size = new_map_size; - bile->nobjects = new_nobjects; + new_map_obj_in_new_map->size = new_map_size; /* write object header */ bile_xwriteat(bile, new_map_obj->pos, new_map_obj, BILE_OBJECT_SIZE); - if (_bile_error) + if (bile->last_error) return -1; /* and then the map contents */ bile_xwriteat(bile, new_map_obj->pos + BILE_OBJECT_SIZE, new_map, new_map_size); - if (_bile_error) + if (bile->last_error) return -1; - SetFPos(bile->vrefid, fsFromLEOF, 0); - GetFPos(bile->vrefid, &bile->file_size); + SetFPos(bile->frefnum, fsFromLEOF, 0); + GetFPos(bile->frefnum, &bile->file_size); + memset(&pb, 0, sizeof(pb)); + pb.ioRefNum = bile->frefnum; + PBFlushFile(&pb, false); + /* successfully wrote new map, switch over */ free(bile->map); + bile->nobjects = new_nobjects; bile->map = new_map; bile->map_ptr.pos = new_map_obj->pos; bile->map_ptr.size = new_map_obj->size; @@ -562,10 +637,10 @@ bile_write_map(struct bile *bile) /* write new pointer to point at new map object */ bile_xwriteat(bile, BILE_MAGIC_LEN, &bile->map_ptr, sizeof(bile->map_ptr)); - if (_bile_error) + if (bile->last_error) return -1; - - /* TODO: flush? */ + + PBFlushFile(&pb, false); return 0; } @@ -581,30 +656,58 @@ bile_xwriteat(struct bile *bile, const size_t pos, con if (bile == NULL) panic("bile_xwriteat: bogus bile"); - _bile_error = 0; + _bile_error = bile->last_error = 0; if (pos == bile->file_size) { - _bile_error = SetFPos(bile->vrefid, fsFromLEOF, 0); + _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromLEOF, + 0); } else if (pos > bile->file_size) { /* may as well allocate to cover len too */ asize = pos + len - bile->file_size; - _bile_error = Allocate(bile->vrefid, &asize); + _bile_error = Allocate(bile->frefnum, &asize); if (_bile_error) return 0; - _bile_error = SetFPos(bile->vrefid, fsFromLEOF, 0); + _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromLEOF, + 0); } else - _bile_error = SetFPos(bile->vrefid, fsFromStart, pos); + _bile_error = bile->last_error = SetFPos(bile->frefnum, + fsFromStart, pos); if (_bile_error) return 0; wsize = len; - _bile_error = FSWrite(bile->vrefid, &wsize, data); + _bile_error = bile->last_error = FSWrite(bile->frefnum, &wsize, data); if (_bile_error) return 0; if (wsize != len) panic("bile_xwriteat: short write of %lu at %lu to %s: %lu", len, pos, PtoCstr(bile->filename), wsize); + SetFPos(bile->frefnum, fsFromLEOF, 0); + GetFPos(bile->frefnum, &bile->file_size); + return wsize; -} +} + +void +bile_sort_by_pos(struct bile *bile) +{ + size_t n, j; + struct bile_object o; + + if (bile == NULL) + panic("bile_sort_by_pos: bogus bile"); + + _bile_error = bile->last_error = 0; + + for (n = 0; n < bile->nobjects; n++) { + for (j = 0; j < bile->nobjects - n - 1; j++) { + if (bile->map[j].pos > bile->map[j + 1].pos) { + o = bile->map[j]; + bile->map[j] = bile->map[j + 1]; + bile->map[j + 1] = o; + } + } + } +} --- bile.h Thu Jan 6 16:42:25 2022 +++ bile.h Mon Jan 10 21:07:52 2022 @@ -23,14 +23,11 @@ * File format: * [ bile header - BILE_HEADER_LEN ] * [ BILE_MAGIC - BILE_MAGIC_LEN ] - * [ map position - long ] - * [ map size - long ] - * [ map contents - (map_size) ] - * [ object[0] position - long ] - * [ object[0] size - long ] - * [ object[0] type - long ] - * [ object[0] id - long ] - * [ ... ] + * [ map pointer object ] + * [ pointer position - long ] + * [ pointer size - long ] + * [ pointer type (_BL>) - long ] + * [ pointer id - long ] * [ object[0] start (map points to this as its position) ] * [ object[0] position - long ] * [ object[0] size - long ] @@ -38,6 +35,12 @@ * [ object[0] id - long ] * [ object[1] start ] * [ .. ] + * [ map object - (pointed to by map pointer position) ] + * [ map position - long ] + * [ map size - long ] + * [ map type (_BLM) - long ] + * [ map id - long ] + * [ map contents ] */ #define BILE_MAGIC "BILE1" #define BILE_MAGIC_LEN 5 @@ -56,32 +59,41 @@ struct bile_object { struct bile { struct bile_object map_ptr; - short vrefid; + short vrefnum, frefnum, last_error; Str255 filename; size_t file_size; struct bile_object *map; /* array of bile_objects */ size_t nobjects; }; -short bile_error(void); -struct bile * bile_create(const Str255 filename, const OSType creator, - const OSType type); -struct bile * bile_open(const Str255 filename); -void bile_close(struct bile *bile); -struct bile_object * bile_find(struct bile *bile, const OSType type, - const unsigned long id); -size_t bile_count_by_type(struct bile *bile, const OSType type); -size_t bile_next_id(struct bile *bile, const OSType type); -struct bile_object * bile_alloc(struct bile *bile, const OSType type, - const unsigned long id, const size_t size); -short bile_delete(struct bile *bile, OSType type, const unsigned long id); -size_t bile_read_object(struct bile *bile, const struct bile_object *o, - char *data, const size_t len); -size_t bile_read(struct bile *bile, const OSType type, - const unsigned long id, char *data, const size_t len); -size_t bile_read_alloc(struct bile *bile, const OSType type, - const unsigned long id, char **data); -size_t bile_write(struct bile *bile, OSType type, const unsigned long id, - const void *data, const size_t len); +short bile_error(struct bile *bile); + +struct bile * bile_create(const Str255 filename, short vrefnum, + const OSType creator, const OSType type); +struct bile * bile_open(const Str255 filename, short vrefnum); +void bile_close(struct bile *bile); + +struct bile_object * bile_find(struct bile *bile, const OSType type, + const unsigned long id); +size_t bile_count_by_type(struct bile *bile, + const OSType type); +struct bile_object * bile_get_nth_of_type(struct bile *bile, + const size_t index, const OSType type); +size_t bile_next_id(struct bile *bile, const OSType type); +short bile_delete(struct bile *bile, const OSType type, + const unsigned long id); +size_t bile_read_object(struct bile *bile, + const struct bile_object *o, char *data, + const size_t len); +size_t bile_read(struct bile *bile, const OSType type, + const unsigned long id, char *data, + const size_t len); +size_t bile_read_alloc(struct bile *bile, + const OSType type, const unsigned long id, + char **data); +size_t bile_write(struct bile *bile, OSType type, + const unsigned long id, const void *data, + const size_t len); +void bile_fsck(struct bile *bile); #endif