From: Nick Bowler Date: Sat, 12 Mar 2011 01:55:50 +0000 (-0500) Subject: upkg: Embed struct upkg into the private structure. X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/commitdiff_plain/101802f109713394c6c8e0daea8129c6ee3c60d0 upkg: Embed struct upkg into the private structure. This avoids the need to store a pointer to the private struct inside the public struct and simplifies some code. --- diff --git a/src/libupkg.c b/src/libupkg.c index e861bcb..680faac 100644 --- a/src/libupkg.c +++ b/src/libupkg.c @@ -55,7 +55,9 @@ struct upkg_import { long package; }; -struct upkg_private { +struct upkg_priv { + struct upkg pub; + const struct upkg_file_ops *fops; int (*dtor)(void *handle); void *f; @@ -139,47 +141,42 @@ size_t upkg_decode_index(long *val, unsigned char *bytes, size_t n) return i; } -static struct upkg *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE]) +static struct upkg_priv *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE]) { - struct { - struct upkg pkg; - struct upkg_private priv; - } *alloc; + struct upkg_priv *pkg; - alloc = malloc(sizeof *alloc); - if (!alloc) { + pkg = malloc(sizeof *pkg); + if (!pkg) return NULL; - } - alloc->pkg = (struct upkg) { - .version = unpack_16_le(hdr+4), - .license = unpack_16_le(hdr+6), - .flags = unpack_32_le(hdr+8), - .name_count = unpack_32_le(hdr+12), - .export_count = unpack_32_le(hdr+20), - .import_count = unpack_32_le(hdr+28), - .priv = &alloc->priv, - }; + *pkg = (struct upkg_priv) { + .pub = { + .version = unpack_16_le(hdr+4), + .license = unpack_16_le(hdr+6), + .flags = unpack_32_le(hdr+8), + .name_count = unpack_32_le(hdr+12), + .export_count = unpack_32_le(hdr+20), + .import_count = unpack_32_le(hdr+28), + }, - alloc->priv = (struct upkg_private) { .name_offset = unpack_32_le(hdr+16), .export_offset = unpack_32_le(hdr+24), .import_offset = unpack_32_le(hdr+32), }; - return &alloc->pkg; + return pkg; } -static int pkg_init_guid(struct upkg *pkg) +static int pkg_init_guid(struct upkg_priv *pkg) { - const struct upkg_file_ops *fops = pkg->priv->fops; + const struct upkg_file_ops *fops = pkg->fops; size_t rc; - if (pkg->version < 68) { + if (pkg->pub.version < 68) { unsigned long heritage_count, heritage_offset; unsigned char buf[8]; - rc = fops->read(buf, sizeof buf, pkg->priv->f); + rc = fops->read(buf, sizeof buf, pkg->f); if (rc < 8) return -1; @@ -188,45 +185,45 @@ static int pkg_init_guid(struct upkg *pkg) if (heritage_count == 0) return -1; - if (fops->seek(pkg->priv->f, heritage_offset, SEEK_SET) != 0) + if (fops->seek(pkg->f, heritage_offset, SEEK_SET) != 0) return -1; } - rc = fops->read(pkg->guid, 16, pkg->priv->f); + rc = fops->read(pkg->pub.guid, 16, pkg->f); if (rc < 16) return -1; return 0; } -static int pkg_init_names(struct upkg *pkg) +static int pkg_init_names(struct upkg_priv *pkg) { - const struct upkg_file_ops *fops = pkg->priv->fops; - void *f = pkg->priv->f; + const struct upkg_file_ops *fops = pkg->fops; + void *f = pkg->f; size_t rc, len, nbuf = 0; unsigned long index = 0; unsigned char buf[512]; - if (fops->seek(f, pkg->priv->name_offset, SEEK_SET) != 0) + if (fops->seek(f, pkg->name_offset, SEEK_SET) != 0) return -1; - pkg->priv->names = malloc(pkg->name_count * sizeof *pkg->priv->names); - if (!pkg->priv->names) + pkg->names = malloc(pkg->pub.name_count * sizeof *pkg->names); + if (!pkg->names) return -1; - while (index < pkg->name_count) { - struct upkg_name *name = &pkg->priv->names[index]; + while (index < pkg->pub.name_count) { + struct upkg_name *name = &pkg->names[index]; /* Read some data into buffer. */ - if (!fops->eof(pkg->priv->f)) { + if (!fops->eof(pkg->f)) { rc = fops->read(buf+nbuf, sizeof buf-nbuf, f); if (rc == 0 && nbuf == 0) goto err; nbuf += rc; } - if (pkg->version >= 64) { + if (pkg->pub.version >= 64) { len = buf[0]; if (nbuf <= len + 4 || buf[len]) goto err; @@ -261,33 +258,33 @@ static int pkg_init_names(struct upkg *pkg) return 0; err: for (unsigned i = 0; i < index; i++) - free(pkg->priv->names[i].name); - free(pkg->priv->names); + free(pkg->names[i].name); + free(pkg->names); return -1; } -static int pkg_init_exports(struct upkg *pkg) +static int pkg_init_exports(struct upkg_priv *pkg) { - const struct upkg_file_ops *fops = pkg->priv->fops; - void *f = pkg->priv->f; + const struct upkg_file_ops *fops = pkg->fops; + void *f = pkg->f; size_t rc, len, nbuf = 0; unsigned long index = 0; unsigned char buf[512]; - if (fops->seek(f, pkg->priv->export_offset, SEEK_SET) != 0) + if (fops->seek(f, pkg->export_offset, SEEK_SET) != 0) return -1; - pkg->priv->exports = malloc(pkg->export_count * sizeof *pkg->priv->exports); - if (!pkg->priv->exports) + pkg->exports = malloc(pkg->pub.export_count * sizeof *pkg->exports); + if (!pkg->exports) return -1; - while (index < pkg->export_count) { - struct upkg_export_priv *export = &pkg->priv->exports[index]; + while (index < pkg->pub.export_count) { + struct upkg_export_priv *export = &pkg->exports[index]; long tmp; /* Read some data into buffer. */ - if (!fops->eof(pkg->priv->f)) { + if (!fops->eof(pkg->f)) { rc = fops->read(buf+nbuf, sizeof buf-nbuf, f); if (rc == 0 && nbuf == 0) goto err; @@ -308,8 +305,8 @@ static int pkg_init_exports(struct upkg *pkg) len += 4; rc = upkg_decode_index(&tmp, buf+len, nbuf-len); - if (rc == 0 || tmp < 0 || tmp >= pkg->name_count) goto err; - export->pub.name = pkg->priv->names[tmp].name; + if (rc == 0 || tmp < 0 || tmp >= pkg->pub.name_count) goto err; + export->pub.name = pkg->names[tmp].name; len += rc; if (nbuf-len < 4) goto err; @@ -335,32 +332,32 @@ static int pkg_init_exports(struct upkg *pkg) return 0; err: - free(pkg->priv->exports); + free(pkg->exports); return -1; } -static int pkg_init_imports(struct upkg *pkg) +static int pkg_init_imports(struct upkg_priv *pkg) { - const struct upkg_file_ops *fops = pkg->priv->fops; - void *f = pkg->priv->f; + const struct upkg_file_ops *fops = pkg->fops; + void *f = pkg->f; size_t rc, len, nbuf = 0; unsigned long index = 0; unsigned char buf[512]; - if (fops->seek(f, pkg->priv->import_offset, SEEK_SET) != 0) + if (fops->seek(f, pkg->import_offset, SEEK_SET) != 0) return -1; - pkg->priv->imports = malloc(pkg->import_count * sizeof *pkg->priv->imports); - if (!pkg->priv->imports) + pkg->imports = malloc(pkg->pub.import_count * sizeof *pkg->imports); + if (!pkg->imports) return -1; - while (index < pkg->import_count) { - struct upkg_import *import = &pkg->priv->imports[index]; + while (index < pkg->pub.import_count) { + struct upkg_import *import = &pkg->imports[index]; long tmp; /* Read some data into buffer. */ - if (!fops->eof(pkg->priv->f)) { + if (!fops->eof(pkg->f)) { rc = fops->read(buf+nbuf, sizeof buf-nbuf, f); if (rc == 0 && nbuf == 0) goto err; @@ -369,13 +366,13 @@ static int pkg_init_imports(struct upkg *pkg) len = 0; rc = upkg_decode_index(&tmp, buf+len, nbuf-len); - if (rc == 0 || len >= pkg->name_count) goto err; - import->class_package = pkg->priv->names[tmp].name; + if (rc == 0 || len >= pkg->pub.name_count) goto err; + import->class_package = pkg->names[tmp].name; len += rc; rc = upkg_decode_index(&tmp, buf+len, nbuf-len); - if (rc == 0 || len >= pkg->name_count) goto err; - import->class_name = pkg->priv->names[tmp].name; + if (rc == 0 || len >= pkg->pub.name_count) goto err; + import->class_name = pkg->names[tmp].name; len += rc; if (nbuf-len < 4) goto err; @@ -383,8 +380,8 @@ static int pkg_init_imports(struct upkg *pkg) len += 4; rc = upkg_decode_index(&tmp, buf+len, nbuf-len); - if (rc == 0 || len >= pkg->name_count) goto err; - import->object_name = pkg->priv->names[tmp].name; + if (rc == 0 || len >= pkg->pub.name_count) goto err; + import->object_name = pkg->names[tmp].name; len += rc; nbuf -= len; @@ -394,7 +391,7 @@ static int pkg_init_imports(struct upkg *pkg) return 0; err: - free(pkg->priv->imports); + free(pkg->imports); return -1; } @@ -402,7 +399,7 @@ struct upkg *upkg_open(void *f, const struct upkg_file_ops *fops, int (*destructor)(void *handle)) { unsigned char hdr_buf[UPKG_HDR_SIZE]; - struct upkg *pkg; + struct upkg_priv *pkg; if (fops->read(hdr_buf, sizeof hdr_buf, f) != sizeof hdr_buf) { return NULL; @@ -416,9 +413,9 @@ struct upkg *upkg_open(void *f, const struct upkg_file_ops *fops, if (!pkg) { return NULL; } - pkg->priv->fops = fops; - pkg->priv->dtor = destructor; - pkg->priv->f = f; + pkg->fops = fops; + pkg->dtor = destructor; + pkg->f = f; if (pkg_init_guid(pkg) != 0) { goto err1; @@ -436,13 +433,13 @@ struct upkg *upkg_open(void *f, const struct upkg_file_ops *fops, goto err3; } - return pkg; + return &pkg->pub; err3: - free(pkg->priv->exports); + free(pkg->exports); err2: - for (unsigned i = 0; i < pkg->name_count; i++) - free(pkg->priv->names[i].name); - free(pkg->priv->names); + for (unsigned i = 0; i < pkg->pub.name_count; i++) + free(pkg->names[i].name); + free(pkg->names); err1: free(pkg); return NULL; @@ -466,40 +463,45 @@ struct upkg *upkg_fopen(const char *path) return pkg; } -int upkg_close(struct upkg *pkg) +int upkg_close(struct upkg *pub) { + struct upkg_priv *pkg = (struct upkg_priv *)pub; int rc = 0; - if (pkg->priv->dtor) { - rc = pkg->priv->dtor(pkg->priv->f); + if (pkg->dtor) { + rc = pkg->dtor(pkg->f); } - for (unsigned i = 0; i < pkg->name_count; i++) { - free(pkg->priv->names[i].name); + for (unsigned i = 0; i < pkg->pub.name_count; i++) { + free(pkg->names[i].name); } - free(pkg->priv->imports); - free(pkg->priv->exports); - free(pkg->priv->names); + free(pkg->imports); + free(pkg->exports); + free(pkg->names); free(pkg); return rc; } -const char *upkg_get_name(struct upkg *pkg, unsigned long idx) +const char *upkg_get_name(struct upkg *pub, unsigned long idx) { - if (idx >= pkg->name_count) + struct upkg_priv *pkg = (struct upkg_priv *)pub; + + if (idx >= pkg->pub.name_count) return 0; - return pkg->priv->names[idx].name; + return pkg->names[idx].name; } -long upkg_export_find(struct upkg *pkg, long parent, const char *name) +long upkg_export_find(struct upkg *pub, long parent, const char *name) { + struct upkg_priv *pkg = (struct upkg_priv *)pub; + /* This only makes sense if the assertion below is not violated. */ long package = parent < 0 ? 0 : parent + 1; - for (unsigned long i = 0; i < pkg->export_count; i++) { - struct upkg_export_priv *e = &pkg->priv->exports[i]; + for (unsigned long i = 0; i < pkg->pub.export_count; i++) { + struct upkg_export_priv *e = &pkg->exports[i]; /* Assertion: an object's package is an export. */ format_assert(e->package >= 0, continue); @@ -511,24 +513,27 @@ long upkg_export_find(struct upkg *pkg, long parent, const char *name) return -1; } -const struct upkg_export *upkg_get_export(struct upkg *pkg, unsigned long idx) +const struct upkg_export *upkg_get_export(struct upkg *pub, unsigned long idx) { - if (idx < pkg->export_count) - return &pkg->priv->exports[idx].pub; + struct upkg_priv *pkg = (struct upkg_priv *)pub; + + if (idx < pkg->pub.export_count) + return &pkg->exports[idx].pub; return NULL; } -const char *upkg_export_class(struct upkg *pkg, unsigned long idx, +const char *upkg_export_class(struct upkg *pub, unsigned long idx, const char **package) { + struct upkg_priv *pkg = (struct upkg_priv *)pub; struct upkg_export_priv *export; struct upkg_import *iclass, *ipackage; unsigned long pkg_idx; - if (idx >= pkg->export_count) + if (idx >= pkg->pub.export_count) return NULL; - export = &pkg->priv->exports[idx]; + export = &pkg->exports[idx]; /* Assumption: class references are always imports. */ format_assert(export->class <= 0, return NULL); @@ -540,9 +545,9 @@ const char *upkg_export_class(struct upkg *pkg, unsigned long idx, } pkg_idx = -(export->class + 1); - if (pkg_idx >= pkg->import_count) + if (pkg_idx >= pkg->pub.import_count) return NULL; - iclass = &pkg->priv->imports[pkg_idx]; + iclass = &pkg->imports[pkg_idx]; /* Assumption: class references are always Core.Class. */ format_assert(!strcmp(iclass->class_package, "Core"), return NULL); @@ -553,9 +558,9 @@ const char *upkg_export_class(struct upkg *pkg, unsigned long idx, /* Get the package. */ pkg_idx = -(iclass->package + 1); - if (pkg_idx >= pkg->import_count) + if (pkg_idx >= pkg->pub.import_count) return NULL; - ipackage = &pkg->priv->imports[pkg_idx]; + ipackage = &pkg->imports[pkg_idx]; /* Assumption: package references are always Core.Package. */ format_assert(!strcmp(ipackage->class_package, "Core"), return NULL); @@ -565,11 +570,12 @@ const char *upkg_export_class(struct upkg *pkg, unsigned long idx, return iclass->object_name; } -struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx) +struct upkg_file *upkg_export_open(struct upkg *pub, unsigned long idx) { + struct upkg_priv *pkg = (struct upkg_priv *)pub; struct upkg_file *f; - if (idx >= pkg->export_count) + if (idx >= pkg->pub.export_count) return NULL; f = malloc(sizeof *f); @@ -578,9 +584,9 @@ struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx) *f = (struct upkg_file) { .pkg = pkg, - .base = pkg->priv->exports[idx].offset, - .len = pkg->priv->exports[idx].size, - .name = pkg->priv->exports[idx].pub.name, + .base = pkg->exports[idx].offset, + .len = pkg->exports[idx].size, + .name = pkg->exports[idx].pub.name, }; return f; @@ -588,8 +594,8 @@ struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx) void upkg_export_close(struct upkg_file *f) { - if (f->pkg->priv->last_file == f) - f->pkg->priv->last_file = NULL; + if (f->pkg->last_file == f) + f->pkg->last_file = NULL; free(f); } @@ -600,7 +606,7 @@ long upkg_export_tell(struct upkg_file *f) int upkg_export_seek(struct upkg_file *f, long offset, int whence) { - const struct upkg_file_ops *fops = f->pkg->priv->fops; + const struct upkg_file_ops *fops = f->pkg->fops; int rc = EOF; switch (whence) { @@ -609,23 +615,23 @@ int upkg_export_seek(struct upkg_file *f, long offset, int whence) case SEEK_SET: if (offset < 0 || offset > f->len) return EOF; - rc = fops->seek(f->pkg->priv->f, f->base + offset, SEEK_SET); + rc = fops->seek(f->pkg->f, f->base + offset, SEEK_SET); break; case SEEK_END: offset = -offset; if (offset < 0 || offset > f->len) return EOF; offset = f->len - offset; - rc = fops->seek(f->pkg->priv->f, f->base + offset, SEEK_SET); + rc = fops->seek(f->pkg->f, f->base + offset, SEEK_SET); break; } if (rc == 0) { - f->pkg->priv->last_file = f; + f->pkg->last_file = f; f->offset = offset; f->eof = 0; - } else if (f->pkg->priv->last_file == f) { - f->pkg->priv->last_file = NULL; + } else if (f->pkg->last_file == f) { + f->pkg->last_file = NULL; } return rc; @@ -633,7 +639,7 @@ int upkg_export_seek(struct upkg_file *f, long offset, int whence) size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n) { - const struct upkg_file_ops *fops = f->pkg->priv->fops; + const struct upkg_file_ops *fops = f->pkg->fops; size_t want = MIN(n, f->len - f->offset); size_t rc; @@ -641,15 +647,15 @@ size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n) return 0; } - if (f != f->pkg->priv->last_file) { - if (fops->seek(f->pkg->priv->f, f->base + f->offset, SEEK_SET)) + if (f != f->pkg->last_file) { + if (fops->seek(f->pkg->f, f->base + f->offset, SEEK_SET)) return 0; } - rc = fops->read(buf, want, f->pkg->priv->f); + rc = fops->read(buf, want, f->pkg->f); f->offset += rc; - if (want < n || (rc < want && fops->eof(f->pkg->priv->f))) + if (want < n || (rc < want && fops->eof(f->pkg->f))) f->eof = 1; return rc; } diff --git a/src/upkg.h b/src/upkg.h index f9193c5..044b107 100644 --- a/src/upkg.h +++ b/src/upkg.h @@ -75,8 +75,6 @@ struct upkg { unsigned long flags; unsigned long name_count, export_count, import_count; - - struct upkg_private *priv; }; struct upkg_export { @@ -89,7 +87,7 @@ struct upkg_file { int eof; - struct upkg *pkg; + struct upkg_priv *pkg; unsigned long base, offset, len; };