Add tests, add interface methods, updated README.
This commit is contained in:
parent
2d6f643373
commit
182bf00f71
224
README.md
224
README.md
@ -1,2 +1,226 @@
|
||||
# Suzu Runtime and Notation
|
||||
|
||||
# Documentation
|
||||
|
||||
## Conventions
|
||||
|
||||
### Namespacing
|
||||
Examples in this documentation will assume inclusion of the szun namespace.
|
||||
In practice, this is not recommended outside of limited scopes.
|
||||
```
|
||||
fn procedure()
|
||||
{
|
||||
use szun::*;
|
||||
|
||||
/* ... */
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Type Building
|
||||
Type building functions allow for the construction of identifiers representing complex data types. These identifiers are used to allocate typed
|
||||
```
|
||||
varying()
|
||||
boolean()
|
||||
natural()
|
||||
integer()
|
||||
block(size)
|
||||
sequence()
|
||||
array(size, type)
|
||||
list(type)
|
||||
schema()
|
||||
record(schema)
|
||||
```
|
||||
|
||||
### Example
|
||||
This example produces an identifier representing a list of blocks of 4 bytes each.
|
||||
```
|
||||
let type_id = list(block(4));
|
||||
```
|
||||
|
||||
## Global Functions
|
||||
|
||||
### allocate(type)
|
||||
```
|
||||
let ref = allocate(list(integer()));
|
||||
```
|
||||
|
||||
### encode(ref:Reference) -> vec<u8>
|
||||
|
||||
### decode(data:Vec<u8>) -> Reference
|
||||
|
||||
|
||||
## Language Compiler
|
||||
|
||||
|
||||
## Common Methods
|
||||
|
||||
### new() -> Self
|
||||
```
|
||||
let value = Integer::new();
|
||||
```
|
||||
|
||||
### from(ref:Reference) -> Result<Self,()>
|
||||
```
|
||||
match Integer::from(list.at(0)) {
|
||||
Ok(data) => { println!("Integer: {}", data); }
|
||||
Err(_) => { println!("Not Integer"); }
|
||||
}
|
||||
```
|
||||
|
||||
### with(value) -> Self
|
||||
```
|
||||
let b = Boolean::with(true);
|
||||
```
|
||||
|
||||
### Dereference
|
||||
```
|
||||
let ref = *Integer::new();
|
||||
```
|
||||
|
||||
|
||||
## Varying
|
||||
|
||||
### set(ref:Reference)
|
||||
```
|
||||
let var = Varying::new();
|
||||
var.set(*Sequence::with("Hello!"))
|
||||
```
|
||||
|
||||
### get() -> Reference
|
||||
```
|
||||
let var = Varying::with(*Boolean::with(true));
|
||||
let ref = var.get();
|
||||
```
|
||||
|
||||
|
||||
## Boolean
|
||||
Stores the value true or false.
|
||||
|
||||
### get() -> bool
|
||||
```
|
||||
let value = Boolean::with(true);
|
||||
if value.get() {
|
||||
println!("True");
|
||||
}
|
||||
```
|
||||
|
||||
### set(value:bool)
|
||||
```
|
||||
let mut value = Boolean::new();
|
||||
value.set(true);
|
||||
```
|
||||
|
||||
|
||||
## Natural
|
||||
Stores a non-negative integer value.
|
||||
|
||||
### get() -> u64
|
||||
```
|
||||
let value = Integer::with(-1);
|
||||
println!("{}", value.get());
|
||||
```
|
||||
|
||||
### set(value:u64)
|
||||
```
|
||||
let mut value = Integer::new();
|
||||
value.set(-273);
|
||||
```
|
||||
|
||||
|
||||
## Integer
|
||||
Stores a signed integer value.
|
||||
|
||||
### get() -> i64
|
||||
```
|
||||
let value = Integer::with(-1);
|
||||
println!("{}", value.get());
|
||||
```
|
||||
|
||||
### set(value:i64)
|
||||
```
|
||||
let mut value = Integer::new();
|
||||
value.set(-273);
|
||||
```
|
||||
|
||||
|
||||
## Block
|
||||
Constant-sized series of bytes.
|
||||
|
||||
|
||||
## Sequence
|
||||
Variable-sized series of bytes.
|
||||
|
||||
### get() -> String
|
||||
|
||||
### get_raw() -> Vec<u8>
|
||||
|
||||
### set(data:&str)
|
||||
|
||||
### set_raw(data:Vec<u8>)
|
||||
|
||||
|
||||
## Array
|
||||
Constant-sized, ordered collection of items.
|
||||
|
||||
### new(size:usize, type_id:usize)
|
||||
|
||||
### length() -> usize
|
||||
|
||||
### at(index:usize) -> Reference
|
||||
|
||||
### set(index:usize, ref:Reference)
|
||||
|
||||
|
||||
## List
|
||||
Variable-sized, ordered collection of items.
|
||||
|
||||
### new(type_id:usize)
|
||||
|
||||
### length() -> usize
|
||||
|
||||
### capacity() -> usize
|
||||
|
||||
### at(index:usize) -> Reference
|
||||
|
||||
### set(index:usize, ref:Reference)
|
||||
|
||||
### insert(index:usize, ref:Reference)
|
||||
|
||||
### remove(index:usize)
|
||||
|
||||
### reserve(capacity:usize)
|
||||
|
||||
### clear()
|
||||
|
||||
|
||||
## Schema
|
||||
Definition of an abstract structure composed of named items.
|
||||
|
||||
### get(index:usize) -> usize
|
||||
|
||||
### add(type_id:usize) -> usize
|
||||
|
||||
### remove(index:usize)
|
||||
|
||||
### assign(key:&str, type_id:usize) -> usize
|
||||
|
||||
### map(key:&str, index:usize)
|
||||
|
||||
### unmap(key:&str)
|
||||
|
||||
### clear()
|
||||
|
||||
### bind(id:usize)
|
||||
|
||||
|
||||
## Record
|
||||
Instance of a schema.
|
||||
|
||||
### at(index:usize) -> Reference
|
||||
|
||||
### set(index:usize, source:Reference)
|
||||
|
||||
### keyof(index:usize) -> String
|
||||
|
||||
### indexof(key:&str) -> usize
|
||||
|
@ -1,4 +1,4 @@
|
||||
fn main()
|
||||
{
|
||||
szun::test();
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ impl Array {
|
||||
{
|
||||
let mut obj = Self::new(length, class);
|
||||
for i in 0..usize::min(length, data.len()) {
|
||||
obj.update(i, data[i]);
|
||||
obj.set(i, data[i]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@ -44,7 +44,7 @@ impl Array {
|
||||
unsafe {array_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, index:usize, source:Reference)
|
||||
pub fn set(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe { array_update(self.addr, index, source); }
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_inner, type_key,
|
||||
block_set, block_get
|
||||
block_length,
|
||||
block_set, block_get,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::block;
|
||||
@ -30,6 +31,11 @@ impl Block {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {block_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data:Vec<u8>)
|
||||
{
|
||||
let length = unsafe {type_key(type_inner(self.addr.class))};
|
||||
|
@ -69,7 +69,7 @@ impl List {
|
||||
unsafe{list_insert(self.addr, index, source)};
|
||||
}
|
||||
|
||||
pub fn update(&mut self, index:usize, source:Reference)
|
||||
pub fn set(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe{list_update(self.addr, index, source)};
|
||||
}
|
||||
|
@ -40,35 +40,48 @@ impl Sequence {
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data:&str)
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {sequence_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn set_raw(&mut self, data:Vec<u8>)
|
||||
{
|
||||
unsafe { sequence_clear(self.addr); }
|
||||
let bytes = Vec::from(data.as_bytes());
|
||||
if bytes.len() > 0 {
|
||||
unsafe { sequence_reserve(self.addr, bytes.len()); }
|
||||
for i in 0..bytes.len() {
|
||||
unsafe { sequence_insert(self.addr, i, bytes[i]); }
|
||||
if data.len() > 0 {
|
||||
unsafe { sequence_reserve(self.addr, data.len()); }
|
||||
for i in 0..data.len() {
|
||||
unsafe { sequence_insert(self.addr, i, data[i]); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> String
|
||||
pub fn set(&mut self, data:&str)
|
||||
{
|
||||
self.set_raw(Vec::from(data.as_bytes()));
|
||||
}
|
||||
|
||||
pub fn get_raw(&self) -> Vec<u8>
|
||||
{
|
||||
let length = unsafe {sequence_length(self.addr)};
|
||||
let mut result = Vec::<u8>::new();
|
||||
|
||||
if length > 0 {
|
||||
let mut bytes = Vec::<u8>::with_capacity(length);
|
||||
result.reserve_exact(length);
|
||||
for i in 0..length {
|
||||
bytes.push(unsafe {sequence_get(self.addr, i)});
|
||||
result.push(unsafe {sequence_get(self.addr, i)});
|
||||
}
|
||||
return match String::from_utf8(bytes) {
|
||||
Ok(data) => data,
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn get(&self) -> String
|
||||
{
|
||||
match String::from_utf8(self.get_raw()) {
|
||||
Ok(s) => s,
|
||||
Err(_) => String::new(),
|
||||
}
|
||||
}
|
||||
else {
|
||||
return String::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Sequence {
|
||||
type Target = Reference;
|
||||
|
171
src/lib.rs
171
src/lib.rs
@ -5,61 +5,61 @@ mod util;
|
||||
mod runtime;
|
||||
mod interface; pub use interface::*;
|
||||
|
||||
fn assert<T>(expected:T, actual:T) where T:std::fmt::Display, T:std::cmp::PartialEq
|
||||
fn check<T>(expected:T, actual:T) where T:std::fmt::Display, T:std::cmp::PartialEq
|
||||
{
|
||||
print!(" ({}) ", if expected == actual { " " } else { "!" });
|
||||
println!("'{}' = '{}'", expected, actual);
|
||||
}
|
||||
|
||||
pub fn test()
|
||||
/*pub fn test()
|
||||
{
|
||||
{
|
||||
println!("Boolean");
|
||||
let mut dat = Boolean::new();
|
||||
assert::<bool>(false, dat.get());
|
||||
check(false, dat.get());
|
||||
dat.set(true);
|
||||
assert::<bool>(true, dat.get());
|
||||
check(true, dat.get());
|
||||
dat.set(false);
|
||||
assert::<bool>(false, dat.get());
|
||||
check(false, dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Natural");
|
||||
let mut dat = Natural::new();
|
||||
assert::<u64>(0, dat.get());
|
||||
check(0, dat.get());
|
||||
dat.set(50);
|
||||
assert::<u64>(50, dat.get());
|
||||
check(50, dat.get());
|
||||
dat.set(25000);
|
||||
assert::<u64>(25000, dat.get());
|
||||
check(25000, dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Integer");
|
||||
let mut dat = Integer::new();
|
||||
assert::<i64>(0, dat.get());
|
||||
check(0, dat.get());
|
||||
dat.set(-12);
|
||||
assert::<i64>(-12, dat.get());
|
||||
check(-12, dat.get());
|
||||
dat.set(38695);
|
||||
assert::<i64>(38695, dat.get());
|
||||
check(38695, dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Block");
|
||||
let mut dat = Block::new(4);
|
||||
dat.set(vec![1, 2, 3, 4]);
|
||||
assert::<usize>(4, dat.get().len());
|
||||
assert::<u8>(1, dat.get()[0]);
|
||||
assert::<u8>(2, dat.get()[1]);
|
||||
assert::<u8>(3, dat.get()[2]);
|
||||
assert::<u8>(4, dat.get()[3]);
|
||||
check(4, dat.get().len());
|
||||
check(1, dat.get()[0]);
|
||||
check(2, dat.get()[1]);
|
||||
check(3, dat.get()[2]);
|
||||
check(4, dat.get()[3]);
|
||||
}
|
||||
|
||||
{
|
||||
println!("Sequence");
|
||||
let mut dat = Sequence::new();
|
||||
assert::<String>(String::from(""), dat.get());
|
||||
check(String::from(""), dat.get());
|
||||
dat.set("hello");
|
||||
assert::<String>(String::from("hello"), dat.get());
|
||||
check(String::from("hello"), dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
@ -69,14 +69,14 @@ pub fn test()
|
||||
Natural::from(dat.at(1)).unwrap().set(500);
|
||||
Natural::from(dat.at(2)).unwrap().set(750);
|
||||
Natural::from(dat.at(3)).unwrap().set(1000);
|
||||
assert::<usize>(4, dat.length());
|
||||
assert::<u64>(250, Natural::from(dat.at(0)).unwrap().get());
|
||||
assert::<u64>(500, Natural::from(dat.at(1)).unwrap().get());
|
||||
assert::<u64>(750, Natural::from(dat.at(2)).unwrap().get());
|
||||
assert::<u64>(1000,Natural::from(dat.at(3)).unwrap().get());
|
||||
check(4, dat.length());
|
||||
check(250, Natural::from(dat.at(0)).unwrap().get());
|
||||
check(500, Natural::from(dat.at(1)).unwrap().get());
|
||||
check(750, Natural::from(dat.at(2)).unwrap().get());
|
||||
check(1000,Natural::from(dat.at(3)).unwrap().get());
|
||||
}
|
||||
|
||||
/* {
|
||||
{
|
||||
println!("List - Undefined");
|
||||
|
||||
println!("List - Variable");
|
||||
@ -97,20 +97,127 @@ pub fn test()
|
||||
dat.insert(usize::MAX, *Sequence::with("konbanwa"));
|
||||
dat.insert(usize::MAX, *Sequence::with("tasogare"));
|
||||
println!(" = {}", Integer::from(dat.at(0)).unwrap().get());
|
||||
} */
|
||||
}
|
||||
|
||||
/*{
|
||||
{
|
||||
println!("Sparse");
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
/*{
|
||||
{
|
||||
println!("Schema");
|
||||
let mut sch = Schema::new();
|
||||
sch.add(integer());
|
||||
sch.map("abc", 0);
|
||||
check(1, sch.length());
|
||||
check(0, sch.index("abc"));
|
||||
check(sch.length(), sch.index("def"));
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
/*{
|
||||
{
|
||||
println!("Record");
|
||||
|
||||
}*/
|
||||
}
|
||||
}*/
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn boolean_initialize()
|
||||
{
|
||||
let value = crate::Boolean::new();
|
||||
assert_eq!(false, value.get(), "Boolean::new() produces value of false.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn boolean_with()
|
||||
{
|
||||
assert_eq!(false, crate::Boolean::with(false).get(), "Boolean::with(false) produces value of false.");
|
||||
assert_eq!(true, crate::Boolean::with(true).get(), "Boolean::with(true) produces value of true.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn boolean_set_get()
|
||||
{
|
||||
let mut value = crate::Boolean::new();
|
||||
value.set(true);
|
||||
assert_eq!(true, value.get(), "Boolean.set(true) produces value of true.");
|
||||
value.set(false);
|
||||
assert_eq!(false, value.get(), "Boolean.set(false) produces value of false.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn natural_initialize()
|
||||
{
|
||||
let value = crate::Natural::new();
|
||||
assert_eq!(0, value.get(), "Natural::new() produces value of 0.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn natural_set_get()
|
||||
{
|
||||
let mut value = crate::Natural::new();
|
||||
value.set(12);
|
||||
assert_eq!(12, value.get(), "Natural.set(12) produces value of 12.");
|
||||
value.set(38695);
|
||||
assert_eq!(38695, value.get(), "Natural.set(38695) produces value of 38695.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integer_initialize()
|
||||
{
|
||||
let value = crate::Integer::new();
|
||||
assert_eq!(0, value.get(), "Integer::new() produces value of 0.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integer_set_get()
|
||||
{
|
||||
let mut value = crate::Integer::new();
|
||||
value.set(-273);
|
||||
assert_eq!(-273, value.get(), "Integer.set(-273) produces value of -273.");
|
||||
value.set(100);
|
||||
assert_eq!(100, value.get(), "Integer.set(100) produces value of 100.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_initialize()
|
||||
{
|
||||
let value = crate::Block::new(8);
|
||||
assert_eq!(8, value.length(), "Block::new(8) has length of 8.");
|
||||
assert_eq!(vec![0;8], value.get(), "Block::new(8) has value of 0.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_set_get()
|
||||
{
|
||||
let mut value = crate::Block::new(4);
|
||||
value.set(vec![1, 2, 3, 4]);
|
||||
assert_eq!(vec![1, 2, 3, 4], value.get(), "Block::set([1,2,3,4]) has value of [1,2,3,4].");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_initialize()
|
||||
{
|
||||
let value = crate::Sequence::new();
|
||||
assert_eq!(0, value.length(), "Sequence::new() has length 0.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_set_get_raw()
|
||||
{
|
||||
let mut value = crate::Sequence::new();
|
||||
value.set_raw(vec![0, 1, 2, 3, 2, 1]);
|
||||
assert_eq!(6, value.length(), "Sequence.set_raw([0,1,2,3,2,1]) has length 6.");
|
||||
assert_eq!(vec![0,1,2,3,2,1], value.get_raw(), "Sequence.set_raw([0,1,2,3,2,1]) produces value [0,1,2,3,2,1].");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_set_get_str()
|
||||
{
|
||||
let mut value = crate::Sequence::new();
|
||||
value.set("hello");
|
||||
assert_eq!(5, value.length(), "Sequence.set(hello) has length 5.");
|
||||
assert_eq!(String::from("hello"), value.get(), "Sequence.set(hello) produces value hello.");
|
||||
}
|
||||
}
|
||||
|
@ -293,6 +293,11 @@ extern "C" Type::Integer integer_get(Reference addr)
|
||||
|
||||
// Block //
|
||||
|
||||
extern "C" size_t block_length(Reference addr)
|
||||
{
|
||||
return type_key(type_inner(addr.type));
|
||||
}
|
||||
|
||||
extern "C" uint8_t block_get(Reference addr, size_t index)
|
||||
{
|
||||
size_t length = type_key(type_inner(addr.type));
|
||||
@ -681,7 +686,7 @@ extern "C" void schema_unmap(Reference addr, size_t key)
|
||||
extern "C" size_t schema_index(Reference addr, size_t key)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
for(size_t i; i < object.map.length; i++) {
|
||||
for(size_t i = 0; i < object.map.length; i++) {
|
||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
|
||||
if(cell != nullptr) {
|
||||
if(cell->key == key) {
|
||||
@ -700,11 +705,15 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
|
||||
// prepare binding
|
||||
binding.schema = object;
|
||||
binding.binding = id;
|
||||
//for(size_t type_id : object.data) {
|
||||
// binding.size += type_size(type_id);
|
||||
//}
|
||||
|
||||
printf("bind: (%zu) %zu\n", binding.binding, binding.size);
|
||||
for(size_t i = 0; i < object.data.length; ++i) {
|
||||
size_t type_id = *reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), i));
|
||||
size_t size = type_size(type_id);
|
||||
size_t alignment = size;
|
||||
binding.alignment = std::max(alignment, binding.alignment);
|
||||
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
|
||||
binding.size = size + position;
|
||||
}
|
||||
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
||||
|
||||
// add binding to pool
|
||||
//DB_SCHEMA.add(id, binding);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "type.h"
|
||||
#include "typetree.h"
|
||||
#include "nametree.h"
|
||||
//#include "sparselist.h"
|
||||
#include "rawlist.h"
|
||||
#include "pool.h"
|
||||
|
||||
@ -23,6 +24,8 @@ extern "C" size_t type_inner(size_t id);
|
||||
extern "C" size_t type_key(size_t id);
|
||||
extern "C" size_t type_size(size_t type_id);
|
||||
|
||||
//extern "C" size_t schema_bind(Reference addr, size_t id);
|
||||
|
||||
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length);
|
||||
std::string name_keyof_internal(size_t index);
|
||||
extern "C" Str name_keyof(size_t index);
|
||||
@ -50,6 +53,7 @@ extern "C" void integer_set(Reference addr, Type::Integer value);
|
||||
extern "C" Type::Integer integer_get(Reference addr);
|
||||
|
||||
// Block //
|
||||
extern "C" size_t block_length(Reference addr);
|
||||
extern "C" uint8_t block_get(Reference addr, size_t index);
|
||||
extern "C" void block_set(Reference addr, size_t index, uint8_t value);
|
||||
|
||||
|
@ -43,6 +43,7 @@ extern "C" {
|
||||
pub fn integer_set(addr:Reference, data:i64);
|
||||
pub fn integer_get(addr:Reference) -> i64;
|
||||
|
||||
pub fn block_length(addr:Reference) -> usize;
|
||||
pub fn block_set(addr:Reference, index:usize, data:u8);
|
||||
pub fn block_get(addr:Reference, index:usize) -> u8;
|
||||
|
||||
|
41
src/runtime/sparselist.h
Normal file
41
src/runtime/sparselist.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef H_SPARSELIST
|
||||
#define H_SPARSELIST
|
||||
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
class SparseList {
|
||||
public:
|
||||
SparseList()
|
||||
{ }
|
||||
|
||||
~SparseList()
|
||||
{ }
|
||||
|
||||
void set(size_t index, const T& value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void unset(size_t index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
T& get(size_t index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
struct Header {
|
||||
size_t start;
|
||||
size_t length;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
std::vector<Header> headers;
|
||||
std::vector<T> data;
|
||||
};
|
||||
|
||||
#endif
|
@ -67,6 +67,7 @@ struct Schema {
|
||||
|
||||
struct SchemaBinding {
|
||||
size_t binding;
|
||||
size_t alignment;
|
||||
size_t size;
|
||||
Schema schema;
|
||||
};
|
||||
|
Reference in New Issue
Block a user