]> git.draconx.ca Git - upkg.git/commitdiff
Implement file reading API on exports.
authorNick Bowler <nbowler@draconx.ca>
Mon, 8 Jun 2009 16:53:53 +0000 (12:53 -0400)
committerNick Bowler <nbowler@draconx.ca>
Mon, 8 Jun 2009 19:27:52 +0000 (15:27 -0400)
src/libupkg.c
src/upkg.h

index 66546fd3dd80f3f1858f80d579a5f7ca7cd4b192..e2bcf2983adb0d614669b763b34d001a5d58d23d 100644 (file)
@@ -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;
+}
index 50793c5ef407d1be1b172bf3b23af28486e47650..ef6363ec0fc1378ab7037e4c0ef4fd4eb9215210 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef UPKG_H_
 #define UPKG_H_
 
+#include <stddef.h>
+
 #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