#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[];
};
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,
};
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)
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";
+}