From 2a28d71fcf63deb44825b0996ee2a3958a1c0ccf Mon Sep 17 00:00:00 2001 From: yukirij Date: Thu, 24 Aug 2023 12:57:26 -0700 Subject: [PATCH] Update interface and README to match. --- README.md | 152 ++++++++++++++++++++++++++++++++++----- src/bin/main.rs | 64 ++++++++++++++++- src/interface/array.rs | 7 +- src/interface/list.rs | 24 +++++-- src/interface/schema.rs | 7 +- src/interface/sparse.rs | 15 ++-- src/interface/varying.rs | 5 ++ src/lib.rs | 4 +- src/runtime/lib.cc | 7 ++ src/runtime/lib.h | 1 + src/runtime/mod.rs | 6 ++ 11 files changed, 261 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 51d2b06..9fc69d5 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,9 @@ fn main() `acquire(type) -> Reference` Allocate a new instance of the provided type. + +> This method of allocation does not provide automatic memory management. + ``` let refer = acquire(list(integer())); ``` @@ -196,7 +199,7 @@ Encoding converts data between runtime memory and binary serialization. `encode(refer:Reference) -> Vec` `encode_raw(refer:Reference) -> Vec` -`encode_tag(refer:Reference) -> Vec` +`encode_tag(type_id:usize) -> Vec` Serializes an object into binary encoding. The raw variant does not produce a tag prefix for the root object. @@ -244,6 +247,22 @@ let refer = *Integer::new(); --- +## Reference +Identifier for an object in memory. + +`is_null() -> bool` + +Indicates whether the identifier represents a valid object. + +--- + +`kind() -> usize` + +Returns the type identifier of the referenced object. + +--- + + ## Varying Stores a value of any other type. @@ -279,6 +298,12 @@ Removes the contained object. --- +`kindof() -> usize` + +Returns the type identifier of the contained object. + +--- + ## Boolean Stores the value true or false. @@ -453,12 +478,20 @@ Returns the byte at the specified index or zero if out of bounds. Replaces the contents with the byte representation of a string. +``` +let text = Sequence::new(); +text.set("こんにちは"); +``` --- `set_raw(data:Vec)` Replaces the contents with a series of bytes. +``` +let bytes = Sequence::new(); +bytes.set_raw(vec![1, 2, 3, 4, 5, 6]); +``` --- `set_at(index:usize, data:u8)` @@ -501,7 +534,7 @@ Replaces the element at the given index with a copy of the source. --- -`kindof() -> usize` +`kind() -> usize` Returns the type identifier of the contents. @@ -517,6 +550,19 @@ Produces a new list of the given type. --- +`with(type_id:usize, data:Vec) -> List` + +Produces a new list with the provided contents. + +``` +let list = List::with(natural(), vec![ + *Natural::with(1), + *Natural::with(2), + *Natural::with(3), +]); +``` +--- + `capacity() -> usize` Returns the allocated capacity of the list. @@ -535,6 +581,12 @@ Returns the object at the given index or a null reference if out of bounds. --- +`get() -> Vec` + +Returns a vector containing references to the contents of the list. + +--- + `set(index:usize, source:Reference)` Replaces the object at the given index with a copy of the source. @@ -547,15 +599,21 @@ Inserts a copy of the source at a given index. --- -`remove(index:usize)` +`prepend(source:Reference)` -Removes the object at the given index from the list. +Adds an element to the start of the list. --- -`reserve(capacity:usize)` +`append(source:Reference)` -Reallocates the list to have capacity not less than the specified size. +Adds an element to the end of the list. + +--- + +`remove(index:usize)` + +Removes the object at the given index from the list. --- @@ -565,10 +623,42 @@ Removes all elements from the list. --- +`reserve(capacity:usize)` + +Reallocates the list to have capacity not less than the specified size. + +--- + +`kind() -> usize` + +Returns the type identifier of the contents. + +--- + ## Sparse List of discontinuous indicies. +`new(type_id:usize) -> Sparse` + +Produces a new sparse array of the specified type. + +--- + +`with(type_id:usize, data:Vec<(usize, Reference)>) -> Sparse` + +Produces a new sparse array with the specified contents. + +``` +let list = Sparse::with(natural(), vec![ + (1, *Natural::with(10)), + (5, *Natural::with(50)), + (6, *Natural::with(60)), + (10, *Natural::with(100)), +]); +``` +--- + `length() -> usize` Returns the number of elements in the collection. @@ -617,6 +707,12 @@ Returns the key of the element at the specified index. --- +`kind() -> usize` + +Returns the type identifier of the contents. + +--- + ## Schema Definition of an abstract structure composed of named items. @@ -635,6 +731,12 @@ let schema_rgba = Schema::with(vec![ ``` --- +`length() -> usize` + +Returns the number of members in the schema. + +--- + `get(index:usize) -> usize` Returns the type identifier of the given index or zero if out of bounds. @@ -647,18 +749,24 @@ Appends a member of the specified type to the schema. --- -`remove(index:usize)` - -Removes the member at the given index from the schema. - ---- - `assign(key:&str, type_id:usize) -> usize` Appends a member of the specified type to the schema and maps the provided string to that index. --- +`set(index:usize, type_id:usize)` + +Replaces the type identifier of the member at the specified index. + +--- + +`remove(index:usize)` + +Removes the member at the given index from the schema. + +--- + `map(key:&str, index:usize)` Maps a string to the specified index. @@ -684,7 +792,7 @@ Submits the template to the schema database under the provided identifier. > Note: zero is used as a wildcard identifier and is not a valid parameter. ``` -let vec3i = Schema::with(vec![ +let vec3i :usize = Schema::with(vec![ ("x", integer()), ("y", integer()), ("z", integer()), @@ -722,13 +830,25 @@ Returns the number of elements in the record. `at(index:usize) -> Reference` -Returns a reference to the member at the given index. +Returns a reference to the member at the specified index. --- -`set(index:usize, source:Reference)` +`get(key:&str) -> Reference` -Replaces the member at the given index with a copy of the source. +Returns a reference to the member with the specified key. + +--- + +`set_at(index:usize, source:Reference)` + +Replaces the member at the specified index with a copy of the source. + +--- + +`set(key:&str, source:Reference)` + +Replaces the member at the specified key with a copy of the source. --- diff --git a/src/bin/main.rs b/src/bin/main.rs index 2b3e77a..b32de57 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1 +1,63 @@ -fn main() { szun::test(); } +fn main() { + use std::fs::File; + use std::io::prelude::*; + + const MAGAZINE :usize = 0x100; + const MAGAZINE_ROW :usize = 0x101; + + // define schema "Magazine Row" + szun::Schema::with(vec![ + ("Content", szun::natural()), + ("Quantity", szun::natural()), + ]).bind(MAGAZINE_ROW); + + // define schema "Magazine" + let magazine = szun::Schema::with(vec![ + ("Capacity", szun::natural()), + ("Quantity", szun::natural()), + ("Content", szun::list(szun::record(MAGAZINE_ROW))), + ]); + magazine.bind(MAGAZINE); + + // create record "Magazine" + let _data = szun::Record::with(MAGAZINE, vec![ + ("Capacity", *szun::Natural::with(30)), + ("Quantity", *szun::Natural::with(25)), + ("Content", *szun::List::with(szun::record(MAGAZINE_ROW), vec![ + *szun::Record::with(MAGAZINE_ROW, vec![ + ("Content", *szun::Natural::with(15)), + ("Quantity", *szun::Natural::with(5)), + ]).unwrap(), + *szun::Record::with(MAGAZINE_ROW, vec![ + ("Content", *szun::Natural::with(16)), + ("Quantity", *szun::Natural::with(20)), + ]).unwrap(), + ])), + ]).unwrap(); + + // encode record + let out = szun::encode(*magazine); + + // write encoding to file + let mut file = File::create("target/dat.szn").unwrap(); + file.write_all(&out).ok(); + + // print hex series of encoding + print!("[{}]: ", out.len()); + for byte in &out { + print!("{:02x} ", *byte); + } println!(""); + + match szun::decode(&out, &mut 0) { + Ok(t) => match t { + szun::Type::Schema(data) => { + println!("len: {}", data.length()); + for i in 0..data.length() { + println!("'{}': {} ({:02x})", data.keyof(i).unwrap(), data.get(i).unwrap(), szun::kind(data.get(i).unwrap())); + } + } + _ => { println!("not expected"); } + } + Err(_) => { println!("failed"); } + } +} diff --git a/src/interface/array.rs b/src/interface/array.rs index 4ea1064..a2899f7 100644 --- a/src/interface/array.rs +++ b/src/interface/array.rs @@ -1,6 +1,6 @@ use crate::runtime::{ Reference, - type_key, + type_inner, type_key, acquire, release, array_length, array_at, array_update }; @@ -67,6 +67,11 @@ impl Array { { unsafe {array_at(self.addr, index)} } + + pub fn kind(&self) -> usize + { + unsafe {type_inner(self.addr.class)} + } } impl std::ops::Deref for Array { type Target = Reference; diff --git a/src/interface/list.rs b/src/interface/list.rs index fa54c46..4fbdbf1 100644 --- a/src/interface/list.rs +++ b/src/interface/list.rs @@ -1,7 +1,7 @@ use crate::runtime::{ Reference, acquire, release, - type_key, + type_inner, type_key, list_capacity, list_length, list_at, list_clear, @@ -17,11 +17,11 @@ pub struct List { addr:Reference, } impl List { - pub fn new(class:usize) -> Self + pub fn new(type_id:usize) -> Self { Self { managed:true, - addr:unsafe {acquire(list(class))}, + addr:unsafe {acquire(list(type_id))}, } } @@ -35,9 +35,9 @@ impl List { } } - pub fn with(class:usize, data:Vec) -> Self + pub fn with(type_id:usize, data:Vec) -> Self { - let mut obj = Self::new(class); + let mut obj = Self::new(type_id); for item in data { obj.insert(obj.length(), item); } @@ -59,6 +59,15 @@ impl List { unsafe {list_at(self.addr, index)} } + pub fn get(&self) -> Vec + { + let mut result = Vec::::with_capacity(self.length()); + for i in 0..self.length() { + result.push(self.at(i)); + } + return result; + } + pub fn clear(&mut self) { unsafe{list_clear(self.addr)}; @@ -93,6 +102,11 @@ impl List { { unsafe{list_reserve(self.addr, length)}; } + + pub fn kind(&self) -> usize + { + unsafe {type_inner(self.addr.class)} + } } impl std::ops::Deref for List { type Target = Reference; diff --git a/src/interface/schema.rs b/src/interface/schema.rs index 23f57b9..a9651fb 100644 --- a/src/interface/schema.rs +++ b/src/interface/schema.rs @@ -5,7 +5,7 @@ use crate::runtime::{ type_key, schema_length, schema_insert, schema_update, schema_get, - schema_remove, + schema_remove, schema_clear, schema_map, schema_unmap, schema_indexof, schema_keyof, schema_bind, }; @@ -50,6 +50,11 @@ impl Schema { unsafe {schema_length(self.addr)} } + pub fn clear(&mut self) + { + unsafe { schema_clear(self.addr); } + } + pub fn add(&mut self, type_id:usize) -> usize { unsafe {schema_insert(self.addr, usize::MAX, type_id)} diff --git a/src/interface/sparse.rs b/src/interface/sparse.rs index 613eda6..eabb4de 100644 --- a/src/interface/sparse.rs +++ b/src/interface/sparse.rs @@ -1,7 +1,7 @@ use crate::runtime::{ Reference, acquire, release, - type_key, + type_inner, type_key, sparse_length, sparse_at, sparse_get, sparse_clear, @@ -34,14 +34,14 @@ impl Sparse { } } - /* pub fn with(class:usize, data:Vec) -> Self + pub fn with(class:usize, data:Vec<(usize, Reference)>) -> Self { let mut obj = Self::new(class); - for item in data { - obj.insert(obj.length(), item); + for (key, item) in data { + obj.set(key, item); } return obj; - } */ + } pub fn length(&self) -> usize { @@ -82,6 +82,11 @@ impl Sparse { { unsafe{sparse_indexof(self.addr, index)} } + + pub fn kind(&self) -> usize + { + unsafe {type_inner(self.addr.class)} + } } impl std::ops::Deref for Sparse { type Target = Reference; diff --git a/src/interface/varying.rs b/src/interface/varying.rs index 010e51c..2be34bf 100644 --- a/src/interface/varying.rs +++ b/src/interface/varying.rs @@ -57,6 +57,11 @@ impl Varying { { unsafe { varying_get(self.addr) } } + + pub fn kindof(&self) -> usize + { + unsafe {varying_get(self.addr).class} + } } impl std::ops::Deref for Varying { type Target = Reference; diff --git a/src/lib.rs b/src/lib.rs index 2c22aa1..82f2726 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ mod runtime; mod interface; pub use interface::*; mod encoding; pub use encoding::*; -pub fn test() { +/* pub fn test() { use std::fs::File; use std::io::prelude::*; @@ -68,7 +68,7 @@ pub fn test() { } Err(_) => { println!("failed"); } } -} +} */ #[cfg(test)] mod tests; diff --git a/src/runtime/lib.cc b/src/runtime/lib.cc index df820f1..98cf4f4 100644 --- a/src/runtime/lib.cc +++ b/src/runtime/lib.cc @@ -1162,6 +1162,13 @@ extern "C" void schema_remove(Reference addr, size_t index) } } +extern "C" void schema_clear(Reference addr) +{ + auto& object = (*reinterpret_cast(addr.address)); + rawlist_clear(object.data); + rawlist_clear(object.map); +} + extern "C" void schema_map(Reference addr, size_t key, size_t index) { auto& object = (*reinterpret_cast(addr.address)); diff --git a/src/runtime/lib.h b/src/runtime/lib.h index be299ae..ce9f439 100644 --- a/src/runtime/lib.h +++ b/src/runtime/lib.h @@ -128,6 +128,7 @@ extern "C" size_t schema_insert(Reference addr, size_t index, size_t type_id); extern "C" void schema_update(Reference addr, size_t index, size_t type_id); extern "C" size_t schema_get(Reference addr, size_t index); extern "C" void schema_remove(Reference addr, size_t index); +extern "C" void schema_clear(Reference addr); //extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to); extern "C" void schema_map(Reference addr, size_t key, size_t index); extern "C" void schema_unmap(Reference addr, size_t key); diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 146c09e..5548ede 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -19,6 +19,11 @@ impl Reference { { self.address != 0 } + + pub fn kind(&self) -> usize + { + self.class + } } #[repr(C)] @@ -131,6 +136,7 @@ extern "C" { pub fn schema_update(addr:Reference, index:usize, type_id:usize); pub fn schema_get(addr:Reference, index:usize) -> usize; pub fn schema_remove(addr:Reference, index:usize); + pub fn schema_clear(addr:Reference); //pub fn schema_reorder(addr:Reference, from:usize, to:usize); pub fn schema_map(addr:Reference, key:usize, index:usize); pub fn schema_unmap(addr:Reference, key:usize);