#include <sys/stat.h>
#include <sys/mman.h>
-#include "byteorder.h"
+#include "pack.h"
#include "misc.h"
#include "lbx.h"
-#define LBX_MAGIC 0x0000fead
+#define LBX_MAGIC 0x0000fead
+#define LBX_HDR_SIZE 8
int lbx_errno = 0;
uint32_t offsets[];
};
-struct lbx_state *lbx_fopen(FILE *f, const char *name)
+static struct lbx_state *lbx_init(unsigned char hdr[static LBX_HDR_SIZE])
{
- struct lbx_state *new = NULL;
- uint16_t nfiles, version;
- uint32_t magic;
-
- 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);
+ unsigned short nfiles = unpack_16_le(hdr+0);
+ unsigned long magic = unpack_32_le(hdr+2);
+ unsigned short version = unpack_16_le(hdr+6);
+ struct lbx_state *lbx;
if (magic != LBX_MAGIC) {
- lbx_errno = LBX_EMAGIC;
+ lbx_errno = -LBX_EMAGIC;
return NULL;
}
-
- new = malloc(sizeof *new + (nfiles+1)*(sizeof *new->offsets));
- if (!new) {
+
+ lbx = malloc(sizeof *lbx + sizeof lbx->offsets[0] * (nfiles+1));
+ if (!lbx) {
lbx_errno = -errno;
return NULL;
}
-
- *new = (struct lbx_state){
- .name = name,
+
+ *lbx = (struct lbx_state) {
.nfiles = nfiles,
- .f = f,
- .foff = sizeof nfiles + sizeof magic + sizeof version,
};
-
- if (fread(new->offsets, sizeof *new->offsets, nfiles+1, f) != nfiles+1)
- goto readerr;
- new->foff += sizeof *new->offsets * (nfiles+1);
- return new;
-readerr:
- if (feof(f)) {
- lbx_errno = LBX_EEOF;
- } else {
+ return lbx;
+}
+
+struct lbx_state *lbx_fopen(FILE *f, const char *name)
+{
+ unsigned char hdr_buf[LBX_HDR_SIZE];
+ struct lbx_state *lbx;
+
+ if (fread(hdr_buf, 1, sizeof hdr_buf, f) != sizeof hdr_buf) {
lbx_errno = -errno;
+ return NULL;
}
- free(new);
- return NULL;
+ lbx = lbx_init(hdr_buf);
+ if (!lbx)
+ return NULL;
+
+ lbx->name = name;
+ lbx->f = f;
+ lbx->foff = sizeof hdr_buf;
+
+ for (unsigned i = 0; i <= lbx->nfiles; i++) {
+ unsigned char buf[4];
+
+ if (fread(buf, 1, sizeof buf, f) != sizeof buf) {
+ lbx_errno = -errno;
+ if (feof(f))
+ lbx_errno = LBX_EEOF;
+ free(lbx);
+ return NULL;
+ }
+
+ lbx->offsets[i] = unpack_32_le(buf);
+ lbx->foff += sizeof buf;
+ }
+
+ return lbx;
}
static int _lbx_memcpy(void *dest, struct lbx_state *src, size_t size)
return NULL;
}
-struct lbx_state *lbx_open(const char *path)
-{
- struct lbx_state *new = NULL;
- FILE *f;
-
- if ((f = fopen(path, "rb"))) {
- const char *name = strrchr(path, '/');
- new = lbx_fopen(f, name ? name+1 : path);
- } else {
- lbx_errno = -errno;
- }
-
- return new;
-}
-
size_t lbx_numfiles(struct lbx_state *lbx)
{
return lbx->nfiles;