Examples¶
The dynamic API and the generated API write the same bytes. Use the dynamic API when the shape is chosen at runtime. Use a generated struct when a schema already names the fields.
Dynamic struct¶
examples/main.c encodes a point and decodes it. Run it with make and
./build/example.
#include "kiln.h"
kiln_value fields[2];
fields[0].kind = KILN_I32;
fields[0].as.i64 = 1;
fields[1].kind = KILN_I32;
fields[1].as.i64 = 2;
The schema text is struct{x:i32,y:i32,}. The encoded buffer is eight bytes,
x then y, little-endian.
Generated Point¶
testdata/schema/point.json has required x and y and an optional label.
#include "point.h"
Point p;
uint8_t buf[64];
size_t n = 0;
memset(&p, 0, sizeof p);
p.x = 3;
p.y = -4;
p.label_present = 1;
p.label = "hi";
p.label_len = 2;
Point_encode(&p, buf, sizeof buf, &n);
Point_encoded_size reports n. Point_decode rejects a trailing byte and a
label that is not UTF-8. Point_free releases the label.
Message¶
testdata/schema/message.json nests Meta through #/$defs/Meta.
Message_encode writes the scalar fields and then the nested struct.
Meta_decode reads a standalone meta value. Message_decode_into reads a
message that is followed by more bytes in a larger buffer.
Tensor view¶
A decoded tensors value points data at the input buffer. The caller keeps
that buffer alive for as long as the view is used. Re-encoding copies those
bytes into a new canonical directory. The input itself is not modified.
kiln_list_load and kiln_tensor_load copy a borrowed numeric payload into
caller memory. Pass the same destination on the next decode. On a little-endian
host that copy is one memcpy of count * width. Width is 4 for f32 and 8
for f64 or i64, so a u32 list is not written into 8-byte slots.