]> git.draconx.ca Git - liblbx.git/blobdiff - src/lbx.c
Implement stub list operation.
[liblbx.git] / src / lbx.c
index 481123b5f774490ad4d517404ee9393bd7150081..73767305c4e3fb54690a3d09166612a5300ef4c8 100644 (file)
--- a/src/lbx.c
+++ b/src/lbx.c
@@ -1,14 +1,20 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <stdint.h>
+#include <errno.h>
 
 #include "byteorder.h"
 #include "lbx.h"
 
 #define LBX_MAGIC 0x0000fead
 
+int lbx_errno = 0;
+
 struct lbx_state {
        FILE *f;
+       long offset;
+
        uint16_t nfiles;
        uint32_t offsets[];
 };
@@ -19,20 +25,24 @@ struct lbx_state *lbx_fopen(FILE *f)
        uint16_t nfiles, version;
        uint32_t magic;
 
-       if (fread(&nfiles,  sizeof nfiles,  1, f) != 1) return NULL;
-       if (fread(&magic,   sizeof magic,   1, f) != 1) return NULL;
-       if (fread(&version, sizeof version, 1, f) != 1) return NULL;
+       if (fread(&nfiles,  sizeof nfiles,  1, f) != 1) goto readerr;
+       if (fread(&magic,   sizeof magic,   1, f) != 1) goto readerr;
+       if (fread(&version, sizeof version, 1, f) != 1) goto readerr;
 
        nfiles  = letohs(nfiles);
        magic   = letohl(magic);
        version = letohs(version);
 
-       if (magic != LBX_MAGIC)
+       if (magic != LBX_MAGIC) {
+               lbx_errno = LBX_EMAGIC;
                return NULL;
+       }
        
        new = malloc(sizeof *new + (nfiles+1)*(sizeof *new->offsets));
-       if (!new)
+       if (!new) {
+               lbx_errno = -errno;
                return NULL;
+       }
        
        *new = (struct lbx_state){
                .nfiles = nfiles,
@@ -40,9 +50,18 @@ struct lbx_state *lbx_fopen(FILE *f)
        };
        
        if (fread(new->offsets, sizeof *new->offsets, nfiles+1, f) != nfiles+1)
-               return free(new), NULL;
+               goto readerr;
 
        return new;
+readerr:
+       if (feof(f)) {
+               lbx_errno = LBX_EEOF;
+       } else {
+               lbx_errno = -errno;
+       }
+
+       free(new);
+       return NULL;
 }
 
 struct lbx_state *lbx_open(const char *path)
@@ -50,14 +69,38 @@ struct lbx_state *lbx_open(const char *path)
        struct lbx_state *new = NULL;
        FILE *f;
        
-       if ((f = fopen(path, "rb")))
+       if ((f = fopen(path, "rb"))) {
                new = lbx_fopen(f);
+       } else {
+               lbx_errno = -errno;
+       }
 
        return new;
 }
 
+size_t lbx_numfiles(struct lbx_state *lbx)
+{
+       return lbx->nfiles;
+}
+
 void lbx_close(struct lbx_state *lbx)
 {
+       if (!lbx) return;
+
        fclose(lbx->f);
        free(lbx);
 }
+
+const char *lbx_strerror(void)
+{
+       if (lbx_errno < 0)
+               return strerror(-lbx_errno);
+
+       switch (lbx_errno) {
+       case LBX_ESUCCESS: return "Success";
+       case LBX_EMAGIC:   return "Bad magic number";
+       case LBX_EEOF:     return "Unexpected end-of-file";
+       }
+
+       return "Unknown error";
+}