jcs
/subtext
/amendments
/67
bile: Add object marshalling
jcs made amendment 67 over 2 years ago
--- bile.c Fri Jan 21 17:59:46 2022
+++ bile.c Sat Jan 29 14:33:45 2022
@@ -554,6 +554,103 @@ bile_write(struct bile *bile, const OSType type, const
}
short
+bile_marshall_object(struct bile *bile,
+ const struct bile_object_field *fields, const size_t nfields,
+ void *object, char **ret, size_t *retsize)
+{
+ char *data, *ptr;
+ size_t size = 0, fsize = 0, n;
+ bool write = 0;
+
+ if (ret == NULL)
+ panic("bile_pack_object invalid ret");
+
+ *ret = NULL;
+ *retsize = 0;
+
+iterate_fields:
+ for (n = 0; n < nfields; n++) {
+ if (fields[n].size == -1) {
+ /* dynamically-sized field, get length from its length field */
+ ptr = (char *)object + fields[n].object_len_off;
+ fsize = *(size_t *)ptr;
+ } else
+ fsize = fields[n].size;
+
+ if (write) {
+ if (fields[n].size == -1) {
+ /* field is dynamically allocated, first write size */
+ memcpy(data + size, &fsize, sizeof(fsize));
+ size += sizeof(fsize);
+ if (!fsize)
+ continue;
+ }
+
+ ptr = (char *)object + fields[n].struct_off;
+ if (fields[n].size == -1) {
+ ptr = (char *)*(unsigned long *)ptr;
+ if (ptr == 0)
+ panic("bile_pack_object field[%lu] points to NULL", n);
+ }
+
+ memcpy(data + size, ptr, fsize);
+ } else if (fields[n].size == -1) {
+ /* account for dynamic field length */
+ size += sizeof(fsize);
+ }
+
+ size += fsize;
+ }
+
+ if (!write) {
+ data = xmalloc(size);
+ write = 1;
+ size = 0;
+ goto iterate_fields;
+ }
+
+ *ret = data;
+ *retsize = size;
+
+ return 0;
+}
+
+short
+bile_unmarshall_object(struct bile *bile,
+ const struct bile_object_field *fields, const size_t nfields,
+ const char *data, const size_t size, void *object)
+{
+ size_t off, fsize = 0, n;
+ char *ptr, *dptr;
+
+ for (off = 0, n = 0; n < nfields; n++) {
+ if (fields[n].size == -1) {
+ /* dynamically-sized field, read length */
+ memcpy(&fsize, data + off, sizeof(fsize));
+ off += sizeof(fsize);
+ } else
+ fsize = fields[n].size;
+
+ if (off + fsize > size)
+ panic("bile_unpack_object: overflow at field %lu!", n);
+
+ ptr = (char *)object + fields[n].struct_off;
+
+ if (fields[n].size == -1) {
+ dptr = xmalloc(fsize);
+ memcpy(ptr, &dptr, sizeof(dptr));
+ ptr = dptr;
+ }
+
+ memcpy(ptr, data + off, fsize);
+ off += fsize;
+ }
+
+ return 0;
+}
+
+
+short
bile_verify(struct bile *bile)
{
struct bile_object o;
--- bile.h Fri Jan 21 17:58:40 2022
+++ bile.h Sat Jan 29 13:13:31 2022
@@ -84,6 +84,12 @@ struct bile {
short autoflush;
};
+struct bile_object_field {
+ size_t struct_off;
+ ssize_t size;
+ size_t object_len_off;
+};
+
short bile_error(struct bile *bile);
struct bile * bile_create(const Str255 filename, short vrefnum,
@@ -117,5 +123,14 @@ size_t bile_write(struct bile *bile, OSType type,
const unsigned long id, const void *data,
const size_t len);
short bile_verify(struct bile *bile);
+
+short bile_marshall_object(struct bile *bile,
+ const struct bile_object_field *fields,
+ const size_t nfields, void *object, char **ret,
+ size_t *retsize);
+short bile_unmarshall_object(struct bile *bile,
+ const struct bile_object_field *fields,
+ const size_t nfields, const char *data,
+ const size_t size, void *object);
#endif