jcs
/subtext
/amendments
/49
bile: More API changes
jcs made amendment 49 over 2 years ago
--- bile.c Wed Jan 5 20:45:19 2022
+++ bile.c Thu Jan 6 17:07:39 2022
@@ -22,8 +22,8 @@ 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 size_t len,
- const void *data);
+size_t bile_xwriteat(struct bile *bile, const size_t pos, const void *data,
+ const size_t len);
short
bile_error(void)
@@ -52,6 +52,7 @@ bile_create(const Str255 filename, const OSType creato
bile = xmalloczero(sizeof(struct bile));
bile->vrefid = fh;
+ bile->map_ptr.type = BILE_TYPE_MAPPTR;
memcpy(bile->filename, filename, sizeof(bile->filename));
/* write magic */
@@ -62,16 +63,11 @@ bile_create(const Str255 filename, const OSType creato
if (_bile_error)
goto create_bail;
- /* write empty map */
- len = sizeof(long);
- _bile_error = FSWrite(bile->vrefid, &len, &bile->map_pos);
+ /* write header pointing to blank map */
+ len = sizeof(bile->map_ptr);
+ _bile_error = FSWrite(bile->vrefid, &len, &bile->map_ptr);
if (_bile_error)
goto create_bail;
-
- len = sizeof(long);
- _bile_error = FSWrite(bile->vrefid, &len, &bile->map_size);
- if (_bile_error)
- goto create_bail;
GetFPos(fh, &bile->file_size);
@@ -92,6 +88,7 @@ struct bile *
bile_open(const Str255 filename)
{
struct bile *bile = NULL;
+ struct bile_object map_obj;
size_t file_size, map_size, size;
short fh;
char magic[BILE_MAGIC_LEN + 1];
@@ -125,34 +122,44 @@ bile_open(const Str255 filename)
memcpy(bile->filename, filename, sizeof(filename));
bile->file_size = file_size;
- /* load map */
- size = sizeof(long);
- _bile_error = FSRead(bile->vrefid, &size, &bile->map_pos);
+ /* load map pointer */
+ size = sizeof(bile->map_ptr);
+ _bile_error = FSRead(bile->vrefid, &size, &bile->map_ptr);
if (_bile_error)
goto open_bail;
-
- size = sizeof(long);
- _bile_error = FSRead(bile->vrefid, &size, &bile->map_size);
- if (_bile_error)
- goto open_bail;
- if (bile->map_pos + bile->map_size > file_size)
+ if (bile->map_ptr.pos + bile->map_ptr.size > file_size)
panic("bile_open: map points to %lu + %lu, but file is only %lu",
- bile->map_pos, bile->map_size, file_size);
+ bile->map_ptr.pos, bile->map_ptr.size, file_size);
+ if (bile->map_ptr.size % BILE_OBJECT_SIZE != 0)
+ panic("bile_open: map pointer size is not a multiple of object "
+ "size (%lu): %lu", BILE_OBJECT_SIZE, bile->map_ptr.size);
- if (bile->map_size) {
- _bile_error = SetFPos(bile->vrefid, fsFromStart, bile->map_pos +
- BILE_OBJECT_SIZE);
+ 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);
if (_bile_error)
goto open_bail;
- /* read size */
- size = bile->map_size;
- bile->map = xmalloczero(bile->map_size);
+ size = sizeof(struct bile_object);
+ _bile_error = FSRead(bile->vrefid, &size, &map_obj);
+ if (_bile_error)
+ goto open_bail;
+
+ if (map_obj.pos != bile->map_ptr.pos)
+ panic("bile_open: map pointer points to %lu but object there "
+ "has position %lu", bile->map_ptr.pos, map_obj.pos);
+ if (map_obj.size != bile->map_ptr.size)
+ panic("bile_open: map is supposed to have size %lu but object "
+ "pointed to has size %lu", bile->map_ptr.size, map_obj.size);
+
+ /* read entire map */
+ size = map_obj.size;
+ bile->map = xmalloczero(size);
_bile_error = FSRead(bile->vrefid, &size, bile->map);
if (_bile_error)
goto open_bail;
- bile->nobjects = bile->map_size / BILE_OBJECT_SIZE;
+ bile->nobjects = map_obj.size / BILE_OBJECT_SIZE;
}
return bile;
@@ -243,7 +250,7 @@ struct bile_object *
bile_alloc(struct bile *bile, const OSType type, const unsigned long id,
const size_t size)
{
- struct bile_object *new, *o;
+ struct bile_object *newo, *o;
size_t last_pos = BILE_HEADER_LEN;
short n;
@@ -262,12 +269,12 @@ bile_alloc(struct bile *bile, const OSType type, const
last_pos = bile->map[n].pos + BILE_OBJECT_SIZE + bile->map[n].size;
}
- new = &bile->map[bile->nobjects];
+ newo = &bile->map[bile->nobjects];
bile->nobjects++;
- new->pos = last_pos;
- new->size = size;
- new->type = type;
- new->id = id;
+ newo->pos = last_pos;
+ newo->size = size;
+ newo->type = type;
+ newo->id = id;
bile_sort_by_pos(bile);
@@ -321,7 +328,7 @@ bile_delete(struct bile *bile, const OSType type, cons
return -1;
}
- o->type = BILE_PURGE_TYPE;
+ o->type = BILE_TYPE_PURGE;
pos = o->pos;
size = o->size + BILE_OBJECT_SIZE;
@@ -467,15 +474,14 @@ bile_write(struct bile *bile, const OSType type, const
old = bile_find(bile, type, id);
if (old)
- old->type = BILE_PURGE_TYPE;
+ old->type = BILE_TYPE_PURGE;
new_obj = bile_alloc(bile, type, id, len);
- bile_xwriteat(bile, new_obj->pos, BILE_OBJECT_SIZE, new_obj);
+ bile_xwriteat(bile, new_obj->pos, new_obj, BILE_OBJECT_SIZE);
if (_bile_error)
return 0;
- wrote = bile_xwriteat(bile, new_obj->pos + BILE_OBJECT_SIZE, len,
- data);
+ wrote = bile_xwriteat(bile, new_obj->pos + BILE_OBJECT_SIZE, data, len);
if (wrote == 0 || _bile_error)
return 0;
@@ -493,7 +499,7 @@ short
bile_write_map(struct bile *bile)
{
struct bile_object *obj, *new_map_obj, *new_map;
- size_t new_map_size, new_nobjects;
+ size_t new_map_size, new_nobjects, new_map_id;
size_t n;
if (bile == NULL)
@@ -503,19 +509,25 @@ bile_write_map(struct bile *bile)
/* allocate a new map slightly larger than we need */
new_nobjects = bile->nobjects;
- if (!bile->map_pos)
+ if (bile->map_ptr.pos)
+ new_map_id = bile->map_ptr.id + 1;
+ else {
+ /* new file, map never written, allocate another object for map */
new_nobjects++;
+ new_map_id = 1;
+ }
new_map_size = BILE_OBJECT_SIZE * new_nobjects;
- new_map_obj = bile_alloc(bile, BILE_MAP_TYPE, 0, new_map_size);
+ 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];
- if (obj->type == BILE_MAP_TYPE && obj->pos == bile->map_pos)
+ if (obj->type == BILE_TYPE_MAP && obj->pos == bile->map_ptr.pos)
/* don't include old map in new one */
continue;
- if (obj->type == BILE_PURGE_TYPE)
+ if (obj->type == BILE_TYPE_PURGE)
continue;
new_map[new_nobjects++] = *obj;
@@ -526,11 +538,14 @@ bile_write_map(struct bile *bile)
new_map_obj->size = new_map_size;
bile->nobjects = new_nobjects;
- bile_xwriteat(bile, new_map_obj->pos, BILE_OBJECT_SIZE, &new_map_obj);
+ /* write object header */
+ bile_xwriteat(bile, new_map_obj->pos, new_map_obj, BILE_OBJECT_SIZE);
if (_bile_error)
return -1;
- bile_xwriteat(bile, new_map_obj->pos + BILE_OBJECT_SIZE, new_map_size,
- new_map);
+
+ /* and then the map contents */
+ bile_xwriteat(bile, new_map_obj->pos + BILE_OBJECT_SIZE, new_map,
+ new_map_size);
if (_bile_error)
return -1;
@@ -540,17 +555,15 @@ bile_write_map(struct bile *bile)
/* successfully wrote new map, switch over */
free(bile->map);
bile->map = new_map;
- bile->map_pos = new_map_obj->pos;
- bile->map_size = new_map_obj->size;
-
- /* write new header to point at new map object */
- bile_xwriteat(bile, BILE_MAGIC_LEN, sizeof(long), &bile->map_pos);
+ bile->map_ptr.pos = new_map_obj->pos;
+ bile->map_ptr.size = new_map_obj->size;
+ bile->map_ptr.id = new_map_obj->id;
+
+ /* 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)
return -1;
- bile_xwriteat(bile, BILE_MAGIC_LEN + sizeof(long), sizeof(long),
- &bile->map_size);
- if (_bile_error)
- return -1;
/* TODO: flush? */
@@ -558,8 +571,8 @@ bile_write_map(struct bile *bile)
}
size_t
-bile_xwriteat(struct bile *bile, const size_t pos, const size_t len,
- const void *data)
+bile_xwriteat(struct bile *bile, const size_t pos, const void *data,
+ const size_t len)
{
short error;
size_t wsize;
--- bile.h Wed Jan 5 20:41:23 2022
+++ bile.h Thu Jan 6 16:42:25 2022
@@ -41,9 +41,9 @@
*/
#define BILE_MAGIC "BILE1"
#define BILE_MAGIC_LEN 5
-#define BILE_HEADER_LEN (BILE_MAGIC_LEN + (sizeof(long) + sizeof(long)))
-#define BILE_MAP_TYPE '_BLM'
-#define BILE_PURGE_TYPE '_BLP'
+#define BILE_TYPE_MAP '_BLM'
+#define BILE_TYPE_MAPPTR '_BL>'
+#define BILE_TYPE_PURGE '_BLP'
struct bile_object {
unsigned long pos;
@@ -52,15 +52,14 @@ struct bile_object {
unsigned long id;
};
#define BILE_OBJECT_SIZE (sizeof(struct bile_object))
+#define BILE_HEADER_LEN (BILE_MAGIC_LEN + BILE_OBJECT_SIZE)
struct bile {
- unsigned long map_pos;
- unsigned long map_size;
-
+ struct bile_object map_ptr;
short vrefid;
Str255 filename;
size_t file_size;
- struct bile_object *map;
+ struct bile_object *map; /* array of bile_objects */
size_t nobjects;
};