SATN Binary Format (BSATN)
The Spacetime Algebraic Type Notation binary (BSATN) format defines
how Spacetime AlgebraicValue
s and friends are encoded as byte strings.
Algebraic values and product values are BSATN-encoded for e.g., module-host communication and for storing row data in the database.
Notes on notation
In this reference, we give a formal definition of the format. To do this, we use inductive definitions, and define the following notation:
bsatn(x)
denotes a function converting some valuex
to a list of bytes.a: B
means thata
is of typeB
.Foo(x)
denotes extractingx
out of some variant or typeFoo
.a ++ b
denotes concatenating two byte listsa
andb
.bsatn(A) = bsatn(B) | ... | bsatn(Z)
whereB
toZ
are variants ofA
means thatbsatn(A)
is defined as e.g.,bsatn(B)
,bsatn(C)
, ..,bsatn(Z)
depending on what variant ofA
it was.[]
denotes the empty list of bytes.
Values
At a glance
Type | Description |
---|---|
AlgebraicValue |
A value of any type. |
SumValue |
A value of a sum type, i.e. an enum or tagged union. |
ProductValue |
A value of a product type, i.e. a struct or tuple. |
BuiltinValue |
A value of a builtin type, including numbers, booleans and sequences. |
`AlgebraicValue`
The BSATN encoding of an AlgebraicValue
defers to the encoding of each variant:
bsatn(AlgebraicValue) = bsatn(SumValue) | bsatn(ProductValue) | bsatn(BuiltinValue)
`SumValue`
An instance of a sum type, i.e. an enum or tagged union.
SumValue
s are binary-encoded as bsatn(tag) ++ bsatn(variant_data)
where tag: u8
is an index into the SumType.variants
array of the value's SumType
,
and where variant_data
is the data of the variant.
For variants holding no data, i.e., of some zero sized type,
bsatn(variant_data) = []
.
`ProductValue`
An instance of a product type, i.e. a struct or tuple.
ProductValue
s are binary encoded as:
bsatn(elems) = bsatn(elem_0) ++ .. ++ bsatn(elem_n)
Field names are not encoded.
`BuiltinValue`
An instance of a buil-in type.
Built-in types include booleans, integers, floats, strings and arrays.
The BSATN encoding of BuiltinValue
s defers to the encoding of each variant:
bsatn(BuiltinValue)
= bsatn(Bool)
| bsatn(U8) | bsatn(U16) | bsatn(U32) | bsatn(U64) | bsatn(U128)
| bsatn(I8) | bsatn(I16) | bsatn(I32) | bsatn(I64) | bsatn(I128)
| bsatn(F32) | bsatn(F64)
| bsatn(String)
| bsatn(Array)
bsatn(Bool(b)) = bsatn(b as u8)
bsatn(U8(x)) = [x]
bsatn(U16(x: u16)) = to_little_endian_bytes(x)
bsatn(U32(x: u32)) = to_little_endian_bytes(x)
bsatn(U64(x: u64)) = to_little_endian_bytes(x)
bsatn(U128(x: u128)) = to_little_endian_bytes(x)
bsatn(I8(x: i8)) = to_little_endian_bytes(x)
bsatn(I16(x: i16)) = to_little_endian_bytes(x)
bsatn(I32(x: i32)) = to_little_endian_bytes(x)
bsatn(I64(x: i64)) = to_little_endian_bytes(x)
bsatn(I128(x: i128)) = to_little_endian_bytes(x)
bsatn(F32(x: f32)) = bsatn(f32_to_raw_bits(x)) // lossless conversion
bsatn(F64(x: f64)) = bsatn(f64_to_raw_bits(x)) // lossless conversion
bsatn(String(s)) = bsatn(len(s) as u32) ++ bsatn(bytes(s))
bsatn(Array(a)) = bsatn(len(a) as u32)
++ bsatn(normalize(a)_0) ++ .. ++ bsatn(normalize(a)_n)
Where
f32_to_raw_bits(x)
is the raw transmute ofx: f32
tou32
f64_to_raw_bits(x)
is the raw transmute ofx: f64
tou64
normalize(a)
fora: ArrayValue
convertsa
to a list ofAlgebraicValue
s
Types
All SATS types are BSATN-encoded by converting them to an AlgebraicValue
,
then BSATN-encoding that meta-value.
See the SATN JSON Format for more details of the conversion to meta values. Note that these meta values are converted to BSATN and not JSON.