jcs
/subtext
/amendments
/120
bile: Sync with upstream, support in-place updates
jcs made amendment 120 over 2 years ago
--- bile.c Fri Jun 3 12:47:56 2022
+++ bile.c Mon Jun 6 09:43:38 2022
@@ -63,7 +63,12 @@ bile_create(const Str255 filename, short vrefnum, cons
_bile_error = FSOpen(filename, vrefnum, &fh);
if (_bile_error)
return NULL;
-
+
+ _bile_error = SetEOF(fh, BILE_ALLOCATE_SIZE);
+ if (_bile_error)
+ return NULL;
+ SetFPos(fh, fsFromStart, 0);
+
bile = xmalloczero(sizeof(struct bile));
bile->vrefnum = vrefnum;
bile->frefnum = fh;
@@ -220,7 +225,7 @@ bile_flush(struct bile *bile, short and_vol)
memset(&pb, 0, sizeof(pb));
pb.ioRefNum = bile->frefnum;
- ret = PBFlushFile(&pb, false);
+ ret = PBFlushFile(&pb, true);
if (ret != noErr)
return ret;
@@ -560,24 +565,37 @@ bile_write(struct bile *bile, const OSType type, const
_bile_error = bile->last_error = 0;
- if ((old = bile_object_in_map(bile, type, id)) != NULL)
+ old = bile_object_in_map(bile, type, id);
+ if (old != NULL && old->size != len)
old->type = BILE_TYPE_PURGE;
-
- new_obj = bile_alloc(bile, type, id, len);
- wrote = bile_xwriteat(bile, new_obj->pos, new_obj, BILE_OBJECT_SIZE);
- if (wrote != BILE_OBJECT_SIZE || bile->last_error)
- return 0;
- wrote = bile_xwriteat(bile, new_obj->pos + BILE_OBJECT_SIZE, data, len);
- if (wrote != len || bile->last_error)
- return 0;
+ if (old == NULL || old->size != len) {
+ new_obj = bile_alloc(bile, type, id, len);
+
+ wrote = bile_xwriteat(bile, new_obj->pos, new_obj,
+ BILE_OBJECT_SIZE);
+ if (wrote != BILE_OBJECT_SIZE || bile->last_error)
+ return 0;
+ wrote = bile_xwriteat(bile, new_obj->pos + BILE_OBJECT_SIZE, data,
+ len);
+ if (wrote != len || bile->last_error)
+ return 0;
+
+ /* update old object with PURGE type */
+ wrote = bile_xwriteat(bile, old->pos + BILE_OBJECT_SIZE, data,
+ len);
- SetFPos(bile->frefnum, fsFromLEOF, 0);
- GetFPos(bile->frefnum, &bile->file_size);
+ SetFPos(bile->frefnum, fsFromLEOF, 0);
+ GetFPos(bile->frefnum, &bile->file_size);
- bile_write_map(bile);
- if (bile->last_error)
- return 0;
+ bile_write_map(bile);
+ if (bile->last_error)
+ return 0;
+ } else {
+ wrote = bile_xwriteat(bile, old->pos + BILE_OBJECT_SIZE, data, len);
+ if (bile->last_error)
+ return 0;
+ }
return wrote;
}
@@ -908,13 +926,6 @@ bile_write_map(struct bile *bile)
SetFPos(bile->frefnum, fsFromLEOF, 0);
GetFPos(bile->frefnum, &bile->file_size);
- if (bile->autoflush) {
- if ((ret = bile_flush(bile, false)) != noErr) {
- warn("bile_write_map: flush failed: %d", ret);
- return -1;
- }
- }
-
/* successfully wrote new map, switch over */
free(bile->map);
bile->nobjects = new_nobjects;
@@ -936,11 +947,9 @@ bile_write_map(struct bile *bile)
if (bile->last_error)
return -1;
- if (bile->autoflush) {
- if ((ret = bile_flush(bile, false)) != noErr) {
- warn("bile_write_map: final flush failed: %d", ret);
- return -1;
- }
+ if ((ret = bile_flush(bile, false)) != noErr) {
+ warn("bile_write_map: flush failed: %d", ret);
+ return -1;
}
return 0;
@@ -951,29 +960,26 @@ bile_xwriteat(struct bile *bile, const size_t pos, con
const size_t len)
{
short error;
- size_t wsize;
- long asize;
+ size_t wsize, tsize;
if (bile == NULL)
panic("bile_xwriteat: bogus bile");
_bile_error = bile->last_error = 0;
- if (pos == bile->file_size) {
- _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->frefnum, &asize);
+ if (pos + len > bile->file_size) {
+ tsize = pos + len;
+ tsize += BILE_ALLOCATE_SIZE - (tsize % BILE_ALLOCATE_SIZE);
+ _bile_error = SetEOF(bile->frefnum, tsize);
if (_bile_error)
return 0;
- _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromLEOF,
- 0);
- } else
- _bile_error = bile->last_error = SetFPos(bile->frefnum,
- fsFromStart, pos);
-
+ _bile_error = bile->last_error = bile_flush(bile, true);
+ if (_bile_error)
+ return 0;
+ }
+
+ _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromStart,
+ pos);
if (_bile_error)
return 0;
--- bile.h Fri Jun 3 13:31:00 2022
+++ bile.h Mon Jun 6 09:43:43 2022
@@ -39,8 +39,10 @@
* [ object[0] size - long ]
* [ object[0] type - long ]
* [ object[0] id - long ]
+ * [ object[0] data ]
* [ object[1] start ]
* [ .. ]
+ * [ object[1] data ]
* [ map object - (pointed to by map pointer position) ]
* [ map position - long ]
* [ map size - long ]
@@ -62,6 +64,9 @@ struct bile_object {
};
#define BILE_OBJECT_SIZE (sizeof(struct bile_object))
#define BILE_HEADER_LEN 256
+
+/* allocate filesystem space in chunks of this */
+#define BILE_ALLOCATE_SIZE 8192
#ifndef BILE1_MAGIC
#define BILE1_MAGIC "BILE1"