o

obor

v906b870library

No description provided.

0 stars0 forksUnknownupdated 1 year ago
Open repo

OBOR - Odin Binary Object Representation

OBOR is a binary object format to encode and decode objects in the Odin Programming language. It supports two ways of encoding and decoding: schemaless and schemaful. With schemaful encoding, a type registry is built using RTTI and written to the start of the output bytes. This allows for decoding to a different type by diffing two schemas and figuring out migration policies. For example, you can encode a struct {bar: []Bar, a: f32, b: string, } and decode the resulting bytes into a struct {b: string, foo: Foo, a: f32 }. OBOR generates a policy table that makes sure the a: f32 and b: string fields are decoded to the right offsets in the decoded struct and the bar: []Bar field is skipped in the encoded bytes.

Here is how it works: Let's say I have this type Inventory:

Inventory :: struct {
	max_weight: u32,
	items: [dynamic]Item,
}
Item :: struct {
	name:     string,
	weight:   u32,
	is_magic: bool,
}

The constructed schema is like a lightweight version of the TypeInfo of all involved types:

0 -> size: 48, align: 48, is_copy: false, hash: 861660765213436421
   Kind: StructTy{fields = [StructField{ty_idx = 1, offset = 0, name = "max_weight"}, StructField{ty_idx = 2, offset = 8, name = "items"}]}
1 -> size: 4, align: 4, is_copy: true, hash: 2029349188714305344
   Kind: Int
2 -> size: 40, align: 40, is_copy: false, hash: 7409838414103185760
   Kind: SeqTy{elem_ty_idx = 3, is_dyn_arr = true}
3 -> size: 24, align: 24, is_copy: false, hash: 14661186651083965018
   Kind: StructTy{fields = [StructField{ty_idx = 4, offset = 0, name = "name"}, StructField{ty_idx = 1, offset = 16, name = "weight"}, StructField{ty_idx = 5, offset = 20, name = "is_magic"}]}
4 -> size: 16, align: 16, is_copy: false, hash: 3687799326438297182
   Kind: StringTy{is_cstring = false}
5 -> size: 1, align: 1, is_copy: true, hash: 15449794709565471098
   Kind: Bool

It is encoded to the output buffer first, to derive how the rest of the bytes are encoded. Imagine we have this example value:

Inventory {
    max_weight = 230,
    items = {
        Item{"sword", 8, false},
        Item{"apple", 3, false},
        Item{"magic stick", 4, true}
    },
}

Knowing the schema allows it to be pretty consicely encoded as these bytes:

[230, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 115, 119, 111, 114, 100, 8, 0, 0, 0, 0, 5, 0, 0, 0, 97, 112, 112, 108, 101, 1, 0, 0, 0, 0, 11, 0, 0, 0, 109, 97, 103, 105, 99, 32, 115, 116, 105, 99, 107, 4, 0, 0, 0, 1]

Here is a breakdown of the bytes:

max_weight:         230, 0, 0, 0
len(items):         3, 0, 0, 0, 0, 0, 0, 0
len("Sword"):       5, 0, 0, 0,
"Sword":            115, 119, 111, 114, 100,
weight:             8, 0, 0, 0
is_magic:           0
len("apple"):       5, 0, 0, 0,
"apple":            97, 112, 112, 108, 101,
weight:             1, 0, 0, 0
is_magic:           0
len("magic stick"): 11, 0, 0, 0,
"magic stick":      109, 97, 103, 105, 99, 32, 115, 116, 105, 99, 107,
weight:             4, 0, 0, 0
is_magic:           1
Package Info
Version
v906b870
License
Unknown
Author
@tadeohepperle
Type
library
Forks
0
Created
1 year ago
Updated
1 year ago
Health
maintained
has releases
has readme
has license
Activity
last 56 weeks