feat: add public API header and format spec

This commit is contained in:
2026-09-14 23:20:32 +02:00
parent 4af011233d
commit 8287541447
4 changed files with 134 additions and 2 deletions
+3 -2
View File
@@ -21,8 +21,9 @@ funpack output.fpk [unpacked/] # dir defaults to "output" if omitted
```c ```c
#include <fpk/fpk.h> #include <fpk/fpk.h>
fpk_t *pak = fpk_open("assets.fpk"); struct fpk *pak = fpk_open("assets.fpk");
fpk_find(pak, "some/file.bin", &data, &size); fpk_entry_t *entry = fpk_find(pak, "some/file.bin");
void *data = fpk_read(pak, entry, &size);
fpk_close(pak); fpk_close(pak);
``` ```
+52
View File
@@ -0,0 +1,52 @@
# FPK1 format
```
[ header ][ data blobs ][ string table ][ directory entries ]
```
## Header (28 bytes)
| Field | Type | Size | Offset |
|-----------------|-----------|------|--------|
| `magic` | char[4] | 4 | 0 |
| `entry_count` | uint64_t | 8 | 4 |
| `dir_offset` | uint64_t | 8 | 12 |
| `strtab_offset` | uint64_t | 8 | 20 |
`magic` = `"FPK1"`.
`FPK_HEADER_SIZE` (28): field-by-field, not `sizeof()`.
## Data blobs
Raw bytes, back-to-back, no padding, writer add order.
## String table
Paths, `/`-separated, NUL-terminated, back-to-back, entry order.
`strtab_offset` points here.
## Directory (25 bytes per entry)
| Field | Type | Size | Offset |
|---------------|----------|------|--------|
| `path_offset` | uint64_t | 8 | 0 |
| `data_offset` | uint64_t | 8 | 8 |
| `data_size` | uint64_t | 8 | 16 |
| `method` | uint8_t | 1 | 24 |
`path_offset` relative to `strtab_offset`. `data_offset` absolute.
`FPK_DIR_ENTRY_SIZE` (25): field-by-field, not `sizeof()`.
`dir_offset` points here, last region. File size = `dir_offset +
entry_count * FPK_DIR_ENTRY_SIZE`.
## Compression
`method`: reserved, v1 = `FPK_METHOD_STORE` (0) only.
## Endianness
Little-endian on disk, always. Big-endian host swaps on read/write.
+63
View File
@@ -0,0 +1,63 @@
#ifndef FPK_H
#define FPK_H
#include <stddef.h>
#include <stdint.h>
#define FPK_MAGIC "FPK1"
#define FPK_MAGIC_SIZE 4
#define FPK_VERSION 1
#define FPK_HEADER_SIZE 28
/*
* magic 4
* entry_count 8
* dir_offset 8
* strtab_offset 8
* --
* 28
*/
#define FPK_DIR_ENTRY_SIZE 25
/*
* path_offset 8
* data_offset 8
* data_size 8
* method 1
* --
* 25
*/
#define FPK_METHOD_STORE 0
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
const char *path;
uint64_t data_offset;
uint64_t data_size;
uint8_t method;
} fpk_entry_t;
struct fpk;
struct fpk_writer;
struct fpk *fpk_open(const char *path);
void fpk_close(struct fpk *fpk);
fpk_entry_t *fpk_find(struct fpk *fpk, const char *path);
void *fpk_read(struct fpk *fpk, const fpk_entry_t *entry, size_t *out_size);
uint64_t fpk_entry_count(const struct fpk *fpk);
const fpk_entry_t *fpk_entry_at(const struct fpk *fpk, uint64_t index);
struct fpk_writer *fpk_writer_open(const char *path);
int fpk_writer_add(struct fpk_writer *w, const char *path, const void *data,
size_t size);
int fpk_writer_finalize(struct fpk_writer *w);
void fpk_writer_close(struct fpk_writer *w);
#ifdef __cplusplus
}
#endif
#endif /* FPK_H */
+16
View File
@@ -0,0 +1,16 @@
#ifndef FPK_VERSION_H
#define FPK_VERSION_H
#define FPK_VERSION_MAJOR 0
#define FPK_VERSION_MINOR 1
#define FPK_VERSION_PATCH 0
#define FPK_STRINGIFY_HELPER(x) #x
#define FPK_STRINGIFY(x) FPK_STRINGIFY_HELPER(x)
#define FPK_VERSION_STRING \
FPK_STRINGIFY(FPK_VERSION_MAJOR) \
"." FPK_STRINGIFY(FPK_VERSION_MINOR) "." FPK_STRINGIFY( \
FPK_VERSION_PATCH)
#endif /* FPK_VERSION_H */