From: Nick Bowler Date: Mon, 8 Jun 2009 16:53:53 +0000 (-0400) Subject: Implement file reading API on exports. X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/commitdiff_plain/fdfd7c7a49a780dedf2d8f0225d710b521ae87e3 Implement file reading API on exports. --- diff --git a/src/libupkg.c b/src/libupkg.c index 66546fd..e2bcf29 100644 --- a/src/libupkg.c +++ b/src/libupkg.c @@ -47,6 +47,8 @@ struct upkg_import { struct upkg_private { FILE *f; + struct upkg_file *last_file; + struct upkg_name *names; struct upkg_export *exports; struct upkg_import *imports; @@ -385,3 +387,49 @@ const char *upkg_get_name(struct upkg *pkg, unsigned long idx) return 0; return pkg->priv->names[idx].name; } + +struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx) +{ + struct upkg_file *f; + + if (idx >= pkg->export_count) + return NULL; + + f = malloc(sizeof *f); + if (f == NULL) + return NULL; + + *f = (struct upkg_file) { + .pkg = pkg, + .base = pkg->priv->exports[idx].offset, + .len = pkg->priv->exports[idx].size, + }; + + return f; +} + +void upkg_export_close(struct upkg_file *f) +{ + if (f->pkg->priv->last_file == f) + f->pkg->priv->last_file = NULL; + free(f); +} + +size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n) +{ + size_t want = MIN(n, f->len - f->offset); + size_t rc; + + if (want == 0) { + return 0; + } + + if (f != f->pkg->priv->last_file) { + if (fseek(f->pkg->priv->f, f->base + f->offset, SEEK_SET)) + return 0; + } + + rc = fread(buf, 1, want, f->pkg->priv->f); + f->offset += rc; + return rc; +} diff --git a/src/upkg.h b/src/upkg.h index 50793c5..ef6363e 100644 --- a/src/upkg.h +++ b/src/upkg.h @@ -20,6 +20,8 @@ #ifndef UPKG_H_ #define UPKG_H_ +#include + #define UPKG_FLAG_ALLOW_DOWNLOAD 0x0001 #define UPKG_FLAG_CLIENT_OPTIONAL 0x0002 #define UPKG_FLAG_SERVER_ONLY 0x0004 @@ -49,8 +51,18 @@ struct upkg { struct upkg_private *priv; }; +struct upkg_file { + struct upkg *pkg; + unsigned long base, offset, len; +}; + struct upkg *upkg_fopen(const char *path); int upkg_close(struct upkg *pkg); + const char *upkg_get_name(struct upkg *pkg, unsigned long idx); +struct upkg_file *upkg_export_open(struct upkg *pkg, unsigned long idx); +size_t upkg_export_read(struct upkg_file *f, void *buf, size_t n); +void upkg_export_close(struct upkg_file *f); + #endif