diff --git a/README.md b/README.md index 7ec455b..b3eed4e 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,124 @@ # iKv -Standalone iKv C library. +iKv is a small standalone C library for reading, writing, and building iKv data trees. +It supports both text and binary formats, keeps the public API in a single header, and +handles multiple on-disk versions behind one interface. -Build: -- CMake: `cmake -S . -B build && cmake --build build` -- Scripted local build on Linux runners: `./demo/build.sh` +## What it does -Layout: -- `include/ikv.h`: public API only. -- `src/ikv.c`: shared implementation and loader dispatch. -- `src/loaders/ikv1.c`: iKv1 loader. -- `src/loaders/ikv2.c`: iKv2 loader. -- `src/internal/ikv_internal.h`: private node layout and loader interface. +- Parse iKv text from strings or files +- Parse iKv binary blobs from memory or files +- Build object and array trees in memory +- Write text or binary output +- Auto-detect `iKv1` vs `iKv2` for generic parse calls +- Write the current format version by default, which is `iKv2` -Behavior: -- The generic parse APIs auto-detect iKv1 vs iKv2 and choose the correct loader. -- The generic write APIs emit the current format version, which is `iKv2`. -- Public callers do not depend on loader-specific headers or internal structs. -- `iKv2` binary files now use an indexed root layout with a key table and payload offsets. -- Parsing an `iKv2` binary file reads the root index first and loads individual top-level values on demand. -- `iKv1` binary files still use the legacy full-tree format for compatibility. +## Syntax preview -Adding a new version: -1. Add `src/loaders/ikv3.h` and `src/loaders/ikv3.c` exporting an `ikv_loader_t`. -2. Implement that loader using the shared internal helpers or custom logic. -3. Register the loader in `src/ikv.c`. -4. Add the new version constant to `include/ikv.h` if it is part of the public API. +```ikv +ikv2 "player_save" +{ + "title" "iKv demo" + "version" 2 + "player" { + "name" "jondoe" + "alive" true + "speed" 12.5 + } + "inventory" [ + "wrench" + "battery" + "map" + ] +} +``` + +## Library example + +```c +#include "ikv.h" + +ikv_node_t *root = ikv_create_object("demo"); +ikv_node_t *player = ikv_object_add_object(root, "player"); + +ikv_object_set_string(root, "title", "iKv demo"); +ikv_object_set_int(root, "version", 2); +ikv_object_set_string(player, "name", "jondoe"); +ikv_object_set_bool(player, "alive", true); + +ikv_write_file("demo_output.ikv", root); +ikv_free(root); +``` + +## Build + +### CMake + +```sh +cmake -S . -B build +cmake --build build +``` + +This produces the reusable static library target: +- `ikv` +- `ikv::ikv` for CMake consumers + +Example consumer usage: + +```cmake +add_subdirectory(path/to/iKv) +target_link_libraries(your_target PRIVATE ikv::ikv) +``` + +### Script build + +For the repo-local non-CMake build path used in CI: + +```sh +./demo/build.sh +``` + +## Project layout + +- `include/ikv.h`: public API +- `src/ikv.c`: shared implementation and loader dispatch +- `src/loaders/ikv1.c`: iKv1 loader +- `src/loaders/ikv2.c`: iKv2 loader +- `src/internal/ikv_internal.h`: private internals and loader interface +- `demo/main.c`: small usage example +- `demo/unit_test.c`: unit tests + +## Format behavior + +- Generic parse APIs auto-detect `iKv1` and `iKv2` +- Generic write APIs default to `iKv2` +- Public callers do not need loader-specific headers +- `iKv2` binary files use an indexed root layout with key tables and payload offsets +- `iKv1` binary files remain supported for compatibility + +## Public API + +The public interface is declared in [`include/ikv.h`](./include/ikv.h). +Key areas include: + +- node creation and cleanup +- object and array mutation +- scalar accessors +- text parse/write APIs +- binary parse/write APIs +- explicit versioned APIs when auto-detection is not desired + +## License + +This repository currently ships with the license text in [`LICENSE`](./LICENSE): + +- Creative Commons Attribution-ShareAlike 4.0 International (`CC BY-SA 4.0`) + +## Extending the format + +To add a new format version: + +1. Add `src/loaders/ikv3.h` and `src/loaders/ikv3.c` exporting an `ikv_loader_t` +2. Implement the loader +3. Register it in `src/ikv.c` +4. Add a public version constant to `include/ikv.h` if needed