AmendHub

Download:

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