2026-06-19 19:12:20 -05:00
|
|
|

|
|
|
|
|
|
|
|
|
|
[](https://dock-it.dev/iDENTITY-Technology/iKv/actions?workflow=build.yml)
|
|
|
|
|
[](https://dock-it.dev/iDENTITY-Technology/iKv/releases/latest)
|
|
|
|
|
[](https://en.cppreference.com/w/c/language)
|
|
|
|
|
[](https://dock-it.dev/iDENTITY-Technology/iKv/src/branch/main/LICENSE)
|
2026-06-15 01:56:13 +00:00
|
|
|
|
2026-06-14 22:41:32 -05:00
|
|
|
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.
|
|
|
|
|
|
2026-06-19 19:12:20 -05:00
|
|
|
## Quick start
|
|
|
|
|
|
|
|
|
|
Build with CMake:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
cmake -S . -B build
|
|
|
|
|
cmake --build build
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Link it from another CMake project:
|
|
|
|
|
|
|
|
|
|
```cmake
|
|
|
|
|
add_subdirectory(path/to/iKv)
|
|
|
|
|
target_link_libraries(your_target PRIVATE ikv::ikv)
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-14 22:41:32 -05:00
|
|
|
## What it does
|
|
|
|
|
|
|
|
|
|
- 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`
|
|
|
|
|
|
|
|
|
|
## Syntax preview
|
|
|
|
|
|
|
|
|
|
```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
|
|
|
|
|
|
2026-06-17 10:37:32 -05:00
|
|
|
For the repo-local non-CMake build path:
|
2026-06-14 22:41:32 -05:00
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
./demo/build.sh
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-17 10:37:32 -05:00
|
|
|
On Windows:
|
|
|
|
|
|
|
|
|
|
```bat
|
|
|
|
|
demo\build.bat
|
|
|
|
|
```
|
|
|
|
|
|
2026-06-14 22:41:32 -05:00
|
|
|
## 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
|