feat: implement archive reader/writer with round-trip test

This commit is contained in:
2026-09-14 23:26:02 +02:00
parent 8287541447
commit 11675f8cd4
4 changed files with 469 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
CC ?= cc
CFLAGS = -Wall -Wpedantic -I../include -std=c89
LDFLAGS = -L../bin/debug -lfpk
.PHONY: all test clean
all: test
test_program: test.c
${CC} ${CFLAGS} -o ${.TARGET} test.c ${LDFLAGS}
test: test_program
@./test_program
clean:
rm -f test_program
+28
View File
@@ -0,0 +1,28 @@
CC := cc
CFLAGS = -Wall -Wpedantic -I../include -std=c89
LDFLAGS = -L../bin/debug -lfpk
ifeq ($(OS),Windows_NT)
SHELL := cmd.exe
.SHELLFLAGS := /c
EXE_EXT = .exe
else
EXE_EXT =
endif
.PHONY: all test clean
all: test
test_program$(EXE_EXT): test.c
$(CC) $(CFLAGS) -o $@ test.c $(LDFLAGS)
test: test_program$(EXE_EXT)
@./test_program$(EXE_EXT)
clean:
ifeq ($(OS),Windows_NT)
@del /Q test_program.exe 2>nul || true
else
@rm -f test_program
endif
+71
View File
@@ -0,0 +1,71 @@
#include <fpk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHECK(cond, msg) \
do { \
if (!(cond)) { \
fprintf(stderr, "FAIL: %s\n", msg); \
return EXIT_FAILURE; \
} \
} while (0)
static const char *PAK_PATH = "roundtrip.fpk";
int main(void)
{
struct fpk_writer *w;
struct fpk *r;
fpk_entry_t *entry;
void *data;
size_t out_size;
static const char hello[] = "hello, fpk";
static const char world[] = "world";
w = fpk_writer_open(PAK_PATH);
CHECK(w != NULL, "fpk_writer_open failed");
CHECK(fpk_writer_add(w, "a/hello.txt", hello, sizeof(hello)) == 0,
"fpk_writer_add(hello) failed");
CHECK(fpk_writer_add(w, "b/world.txt", world, sizeof(world)) == 0,
"fpk_writer_add(world) failed");
CHECK(fpk_writer_add(w, "c/empty.bin", NULL, 0) == 0,
"fpk_writer_add(empty) failed");
CHECK(fpk_writer_finalize(w) == 0, "fpk_writer_finalize failed");
fpk_writer_close(w);
r = fpk_open(PAK_PATH);
CHECK(r != NULL, "fpk_open failed");
CHECK(fpk_entry_count(r) == 3, "unexpected entry_count");
entry = fpk_find(r, "a/hello.txt");
CHECK(entry != NULL, "fpk_find(hello) failed");
CHECK(entry->data_size == sizeof(hello), "hello size mismatch");
data = fpk_read(r, entry, &out_size);
CHECK(data != NULL, "fpk_read(hello) failed");
CHECK(out_size == sizeof(hello), "hello read size mismatch");
CHECK(memcmp(data, hello, sizeof(hello)) == 0, "hello content mismatch");
free(data);
entry = fpk_find(r, "b/world.txt");
CHECK(entry != NULL, "fpk_find(world) failed");
data = fpk_read(r, entry, &out_size);
CHECK(data != NULL, "fpk_read(world) failed");
CHECK(out_size == sizeof(world), "world read size mismatch");
CHECK(memcmp(data, world, sizeof(world)) == 0, "world content mismatch");
free(data);
entry = fpk_find(r, "c/empty.bin");
CHECK(entry != NULL, "fpk_find(empty) failed");
CHECK(entry->data_size == 0, "empty size mismatch");
CHECK(fpk_find(r, "does/not/exist") == NULL,
"fpk_find(missing) should return NULL");
fpk_close(r);
remove(PAK_PATH);
printf("PASS\n");
return EXIT_SUCCESS;
}