Fix dependencies, implement integer packing.
This commit is contained in:
parent
d53c560f5d
commit
0b6be97e35
@ -7,6 +7,6 @@ edition = "2021"
|
|||||||
num = "0.4.3"
|
num = "0.4.3"
|
||||||
|
|
||||||
pack = { git = "https://git.tsukiyo.org/Utility/pack" }
|
pack = { git = "https://git.tsukiyo.org/Utility/pack" }
|
||||||
dict = { git = "https://git.tsukiyo.org/Utility/dictionary" }
|
dictionary = { git = "https://git.tsukiyo.org/Utility/dictionary" }
|
||||||
pool = { git = "https://git.tsukiyo.org/Utility/pool" }
|
pool = { git = "https://git.tsukiyo.org/Utility/pool" }
|
||||||
sparse = { git = "https://git.tsukiyo.org/Utility/sparse" }
|
sparse = { git = "https://git.tsukiyo.org/Utility/sparse" }
|
||||||
|
@ -1,44 +1,23 @@
|
|||||||
use szun::*;
|
use szun::*;
|
||||||
|
|
||||||
|
fn print_hex(data:&[u8])
|
||||||
|
{
|
||||||
|
for i in 0..data.len() {
|
||||||
|
print!("{:02x} ", data[i]);
|
||||||
|
} println!("");
|
||||||
|
}
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let data = Boolean::new().with(true);
|
println!("[TEST NATURAL]");
|
||||||
println!("bool {}", data.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
let data = 26;
|
||||||
let data = Natural::new().with(15);
|
println!(" = {}", data);
|
||||||
println!("nat {}", data.get::<u32>());
|
let mut v = Natural::new().with(data);
|
||||||
}
|
let b = v.encode();
|
||||||
|
print_hex(&b);
|
||||||
{
|
v.decode(&b, &mut 0).ok();
|
||||||
let data = Integer::new().with(-55);
|
println!(" = {}", v.get::<u64>());
|
||||||
println!("int {}", data.get::<i32>());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let (data, mut value) = Optional::<Integer>::new().with_default();
|
|
||||||
value.set(-1);
|
|
||||||
println!("opt {}", data.is_some());
|
|
||||||
|
|
||||||
if let Some(data) = data.get() {
|
|
||||||
println!("opt {}", data.get::<i32>());
|
|
||||||
}
|
|
||||||
|
|
||||||
data.unset();
|
|
||||||
println!("opt {}", data.is_some());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let seq = Sequence::new().with_str("Hello, world!");
|
|
||||||
println!("{} {} {}", seq.len(), seq.capacity(), seq.get_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let a = Integer::new().with(100);
|
|
||||||
let b = a.clone();
|
|
||||||
|
|
||||||
println!("100 <> {}, {}", a.get::<i32>(), b.get::<i32>());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ impl Szun for Any {
|
|||||||
fn typeid() -> usize { 0 }
|
fn typeid() -> usize { 0 }
|
||||||
|
|
||||||
fn encode(&self) -> Vec<u8> { Vec::new() }
|
fn encode(&self) -> Vec<u8> { Vec::new() }
|
||||||
fn decode(&mut self, _:&Vec<u8>, _:&mut usize) -> Result<(),()> { Err(()) }
|
fn decode(&mut self, _:&[u8], _:&mut usize) -> Result<(),()> { Err(()) }
|
||||||
}
|
}
|
||||||
impl internal::SzunInternal for Any {
|
impl internal::SzunInternal for Any {
|
||||||
fn to_ref(&self) -> Ref { self.refer }
|
fn to_ref(&self) -> Ref { self.refer }
|
||||||
|
@ -48,7 +48,8 @@ impl<T:Szun, const N:usize> Array<T,N> {
|
|||||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||||
|
|
||||||
let mut flag :u8 = 0;
|
let mut flag :u8 = 0;
|
||||||
Runtime::load(self.refer, &mut flag as _, types::size(inner_type), 1);
|
let (size, _) = types::size_align(inner_type);
|
||||||
|
Runtime::load(self.refer, &mut flag as _, size, 1);
|
||||||
if flag != 0 {
|
if flag != 0 {
|
||||||
let refer = self.refer;
|
let refer = self.refer;
|
||||||
Some(T::from_ref(refer.inner()))
|
Some(T::from_ref(refer.inner()))
|
||||||
@ -59,6 +60,14 @@ impl<T:Szun, const N:usize> Array<T,N> {
|
|||||||
}
|
}
|
||||||
impl<T:Szun, const N:usize> Szun for Array<T,N> {
|
impl<T:Szun, const N:usize> Szun for Array<T,N> {
|
||||||
fn typeid() -> usize { Runtime::type_from(T::typeid(), &[N, types::ARRAY]) }
|
fn typeid() -> usize { Runtime::type_from(T::typeid(), &[N, types::ARRAY]) }
|
||||||
|
|
||||||
|
fn encode(&self) -> Vec<u8> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode(&mut self, _bytes:&[u8], _index:&mut usize) -> Result<(),()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl<T:Szun, const N:usize> internal::SzunInternal for Array<T,N> {
|
impl<T:Szun, const N:usize> internal::SzunInternal for Array<T,N> {
|
||||||
fn to_ref(&self) -> Ref { self.refer }
|
fn to_ref(&self) -> Ref { self.refer }
|
||||||
|
@ -18,10 +18,12 @@ impl<const N:usize> Block<N> {
|
|||||||
|
|
||||||
pub fn set(&mut self, data:&[u8])
|
pub fn set(&mut self, data:&[u8])
|
||||||
{
|
{
|
||||||
let size = Runtime::type_of(Runtime::type_in(self.refer.typeid()));
|
let length = Runtime::type_of(Runtime::type_in(self.refer.typeid()));
|
||||||
let mut write = data.to_vec();
|
let mut write = data.to_vec();
|
||||||
write.resize(size, 0);
|
write.resize(length, 0);
|
||||||
Runtime::store(self.refer, write.as_ptr() as _, 0, types::size(self.refer.typeid()));
|
|
||||||
|
let (size, _) = types::size_align(self.refer.typeid());
|
||||||
|
Runtime::store(self.refer, write.as_ptr() as _, 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_byte(&mut self, index:usize, byte:u8)
|
pub fn set_byte(&mut self, index:usize, byte:u8)
|
||||||
@ -33,9 +35,11 @@ impl<const N:usize> Block<N> {
|
|||||||
|
|
||||||
pub fn get(&self) -> Vec<u8>
|
pub fn get(&self) -> Vec<u8>
|
||||||
{
|
{
|
||||||
let size = Runtime::type_of(Runtime::type_in(self.refer.typeid()));
|
let length = Runtime::type_of(Runtime::type_in(self.refer.typeid()));
|
||||||
let mut data = vec![0u8; size];
|
let mut data = vec![0u8; length];
|
||||||
Runtime::load(self.refer, data.as_mut_ptr() as _, 0, types::size(self.refer.typeid()));
|
|
||||||
|
let (size, _) = types::size_align(self.refer.typeid());
|
||||||
|
Runtime::load(self.refer, data.as_mut_ptr() as _, 0, size);
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +61,14 @@ impl<const N:usize> Block<N> {
|
|||||||
}
|
}
|
||||||
impl<const N:usize> Szun for Block<N> {
|
impl<const N:usize> Szun for Block<N> {
|
||||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[N, types::BLOCK]) }
|
fn typeid() -> usize { Runtime::type_from(types::ANY, &[N, types::BLOCK]) }
|
||||||
|
|
||||||
|
fn encode(&self) -> Vec<u8> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode(&mut self, _bytes:&[u8], _index:&mut usize) -> Result<(),()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl<const N:usize> SzunInternal for Block<N> {
|
impl<const N:usize> SzunInternal for Block<N> {
|
||||||
fn to_ref(&self) -> Ref { self.refer }
|
fn to_ref(&self) -> Ref { self.refer }
|
||||||
|
@ -39,7 +39,7 @@ impl Szun for Boolean {
|
|||||||
vec![self.get() as u8]
|
vec![self.get() as u8]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()> {
|
fn decode(&mut self, bytes:&[u8], index:&mut usize) -> Result<(),()> {
|
||||||
if bytes.len() - *index >= 1 {
|
if bytes.len() - *index >= 1 {
|
||||||
self.set(bytes[*index] != 0);
|
self.set(bytes[*index] != 0);
|
||||||
*index += 1;
|
*index += 1;
|
||||||
|
@ -35,6 +35,14 @@ impl Integer {
|
|||||||
}
|
}
|
||||||
impl Szun for Integer {
|
impl Szun for Integer {
|
||||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::INTEGER]) }
|
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::INTEGER]) }
|
||||||
|
|
||||||
|
fn encode(&self) -> Vec<u8> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode(&mut self, _bytes:&[u8], _index:&mut usize) -> Result<(),()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl SzunInternal for Integer {
|
impl SzunInternal for Integer {
|
||||||
fn to_ref(&self) -> Ref { self.refer }
|
fn to_ref(&self) -> Ref { self.refer }
|
||||||
|
@ -7,4 +7,5 @@ pub mod block; pub use block::Block;
|
|||||||
pub mod sequence; pub use sequence::Sequence;
|
pub mod sequence; pub use sequence::Sequence;
|
||||||
pub mod optional; pub use optional::Optional;
|
pub mod optional; pub use optional::Optional;
|
||||||
pub mod array; pub use array::Array;
|
pub mod array; pub use array::Array;
|
||||||
|
pub mod record; pub use record::Record;
|
||||||
pub mod schema; pub use schema::Schema;
|
pub mod schema; pub use schema::Schema;
|
||||||
|
@ -37,11 +37,12 @@ impl Szun for Natural {
|
|||||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::NATURAL]) }
|
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::NATURAL]) }
|
||||||
|
|
||||||
fn encode(&self) -> Vec<u8> {
|
fn encode(&self) -> Vec<u8> {
|
||||||
Vec::new()
|
crate::util::pack::pack_natural(self.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()> {
|
fn decode(&mut self, bytes:&[u8], index:&mut usize) -> Result<(),()> {
|
||||||
Err(())
|
self.set(crate::util::pack::unpack_natural(bytes, index));
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl SzunInternal for Natural {
|
impl SzunInternal for Natural {
|
||||||
|
@ -10,7 +10,7 @@ impl Szun for Null {
|
|||||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::BOOLEAN]) }
|
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::BOOLEAN]) }
|
||||||
|
|
||||||
fn encode(&self) -> Vec<u8> { Vec::new() }
|
fn encode(&self) -> Vec<u8> { Vec::new() }
|
||||||
fn decode(&mut self, _:&Vec<u8>, _:&mut usize) -> Result<(),()> { Err(()) }
|
fn decode(&mut self, _:&[u8], _:&mut usize) -> Result<(),()> { Err(()) }
|
||||||
}
|
}
|
||||||
impl SzunInternal for Null {
|
impl SzunInternal for Null {
|
||||||
fn to_ref(&self) -> Ref { Ref::null() }
|
fn to_ref(&self) -> Ref { Ref::null() }
|
||||||
|
@ -31,9 +31,9 @@ impl<T:Szun> Optional<T> {
|
|||||||
pub fn set(&self, data:&T)
|
pub fn set(&self, data:&T)
|
||||||
{
|
{
|
||||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||||
let inner_size = types::size(inner_type);
|
let (inner_size, _) = types::size_align(inner_type);
|
||||||
|
|
||||||
let mut bytes = vec![0u8; types::size(inner_type)];
|
let mut bytes = vec![0u8; inner_size];
|
||||||
|
|
||||||
Runtime::load(data.to_ref(), bytes.as_ptr() as _, 0, inner_size);
|
Runtime::load(data.to_ref(), bytes.as_ptr() as _, 0, inner_size);
|
||||||
|
|
||||||
@ -49,7 +49,8 @@ impl<T:Szun> Optional<T> {
|
|||||||
pub fn set_default(&self) -> T
|
pub fn set_default(&self) -> T
|
||||||
{
|
{
|
||||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||||
Runtime::write(self.refer, 0xFF, types::size(inner_type));
|
let (inner_size, _) = types::size_align(inner_type);
|
||||||
|
Runtime::write(self.refer, 0xFF, inner_size);
|
||||||
|
|
||||||
T::from_ref(self.refer.temporary())
|
T::from_ref(self.refer.temporary())
|
||||||
}
|
}
|
||||||
@ -57,8 +58,8 @@ impl<T:Szun> Optional<T> {
|
|||||||
pub fn unset(&self)
|
pub fn unset(&self)
|
||||||
{
|
{
|
||||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||||
let inner_size = types::size(inner_type);
|
let (inner_size, _) = types::size_align(inner_type);
|
||||||
let bytes = vec![0u8; types::size(inner_type)];
|
let bytes = vec![0u8; inner_size];
|
||||||
|
|
||||||
Runtime::store(self.refer, bytes.as_ptr() as _, 0, inner_size);
|
Runtime::store(self.refer, bytes.as_ptr() as _, 0, inner_size);
|
||||||
Runtime::write(self.refer, 0x00, inner_size);
|
Runtime::write(self.refer, 0x00, inner_size);
|
||||||
@ -67,9 +68,10 @@ impl<T:Szun> Optional<T> {
|
|||||||
pub fn get(&self) -> std::option::Option<T>
|
pub fn get(&self) -> std::option::Option<T>
|
||||||
{
|
{
|
||||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||||
|
let (inner_size, _) = types::size_align(inner_type);
|
||||||
|
|
||||||
let mut flag :u8 = 0;
|
let mut flag :u8 = 0;
|
||||||
Runtime::load(self.refer, &mut flag as _, types::size(inner_type), 1);
|
Runtime::load(self.refer, &mut flag as _, inner_size, 1);
|
||||||
if flag != 0 {
|
if flag != 0 {
|
||||||
let refer = self.refer;
|
let refer = self.refer;
|
||||||
Some(T::from_ref(refer.inner()))
|
Some(T::from_ref(refer.inner()))
|
||||||
@ -81,9 +83,10 @@ impl<T:Szun> Optional<T> {
|
|||||||
pub fn is_some(&self) -> bool
|
pub fn is_some(&self) -> bool
|
||||||
{
|
{
|
||||||
let inner_type = Runtime::type_in(self.refer.typeid());
|
let inner_type = Runtime::type_in(self.refer.typeid());
|
||||||
|
let (inner_size, _) = types::size_align(inner_type);
|
||||||
|
|
||||||
let mut flag :u8 = 0;
|
let mut flag :u8 = 0;
|
||||||
Runtime::load(self.refer, &mut flag as _, types::size(inner_type), 1);
|
Runtime::load(self.refer, &mut flag as _, inner_size, 1);
|
||||||
flag != 0
|
flag != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +109,7 @@ impl<T:Szun> Szun for Optional<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()> {
|
fn decode(&mut self, bytes:&[u8], index:&mut usize) -> Result<(),()> {
|
||||||
if bytes.len() - *index >= 1 {
|
if bytes.len() - *index >= 1 {
|
||||||
let some = bytes[*index];
|
let some = bytes[*index];
|
||||||
*index += 1;
|
*index += 1;
|
||||||
@ -141,7 +144,15 @@ impl<T:Szun> SzunInternal for Optional<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn mem_drop(refer:Ref) {
|
fn mem_drop(refer:Ref) {
|
||||||
drop(refer.inner())
|
let inner_type = Runtime::type_in(refer.typeid());
|
||||||
|
let (size, _) = types::size_align(inner_type);
|
||||||
|
|
||||||
|
let mut flag :u8 = 0;
|
||||||
|
Runtime::load(refer, &mut flag as _, size, 1);
|
||||||
|
|
||||||
|
if flag != 0 {
|
||||||
|
drop_memory(refer.inner())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::impl_szun_generic!(Optional<T>);
|
crate::impl_szun_generic!(Optional<T>);
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
||||||
|
|
||||||
|
pub struct Record {
|
||||||
|
refer:Ref,
|
||||||
|
}
|
||||||
|
impl Record {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
refer:Runtime::acquire(Self::typeid()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get<T:Szun>(&mut self, index:usize) -> T
|
||||||
|
{
|
||||||
|
if let Ok(member) = Runtime::member(Runtime::type_of(Runtime::type_in(self.refer.typeid())), index) {
|
||||||
|
if let Ok(data) = Any::from_ref(Ref::new(member.typeid, unsafe {self.refer.address().byte_add(member.offset)})).try_into() {
|
||||||
|
data
|
||||||
|
} else {
|
||||||
|
panic!("mismatched data type");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("invalid member index");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Szun for Record {
|
||||||
|
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::RECORD]) }
|
||||||
|
|
||||||
|
fn encode(&self) -> Vec<u8> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode(&mut self, _bytes:&[u8], _index:&mut usize) -> Result<(),()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl SzunInternal for Record {
|
||||||
|
fn to_ref(&self) -> Ref { self.refer }
|
||||||
|
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||||
|
}
|
||||||
|
crate::impl_szun!(Record);
|
@ -1,7 +1,14 @@
|
|||||||
use crate::{prelude::{*, internal::*}, Runtime, Any, types};
|
use crate::{prelude::{*, internal::*}, Runtime, Any, types, util::{DynList, DynListData}};
|
||||||
|
|
||||||
pub(crate) struct SchemaData {
|
#[derive(Clone, Copy)]
|
||||||
|
pub(crate) struct Member {
|
||||||
|
pub term:usize,
|
||||||
|
pub typeid:usize,
|
||||||
|
pub offset:usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct Data {
|
||||||
|
pub members:DynListData,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Schema {
|
pub struct Schema {
|
||||||
@ -14,16 +21,81 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build() -> Builder {
|
||||||
|
Builder {
|
||||||
|
data:Self::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add<T:Szun>(&mut self) -> Result<(),()>
|
pub fn add<T:Szun>(&mut self) -> Result<(),()>
|
||||||
{
|
{
|
||||||
|
let data = unsafe {&mut *(self.refer.address_mut() as *mut Data)};
|
||||||
|
let mut members = DynList::from_parts(
|
||||||
|
std::mem::size_of::<Member>(),
|
||||||
|
std::mem::align_of::<Member>(),
|
||||||
|
&mut data.members as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Ok(cell) = members.acquire() {
|
||||||
|
let member = unsafe {&mut *(cell as *mut Member)};
|
||||||
|
member.term = usize::MAX;
|
||||||
|
member.typeid = T::typeid();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_named<T:Szun>(&mut self, name:&str) -> Result<(),()>
|
pub fn add_named<T:Szun>(&mut self, name:&str) -> Result<(),()>
|
||||||
{
|
{
|
||||||
|
let data = unsafe {&mut *(self.refer.address_mut() as *mut Data)};
|
||||||
|
let mut members = DynList::from_parts(
|
||||||
|
std::mem::size_of::<Member>(),
|
||||||
|
std::mem::align_of::<Member>(),
|
||||||
|
&mut data.members as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Ok(cell) = members.acquire() {
|
||||||
|
let member = unsafe {&mut *(cell as *mut Member)};
|
||||||
|
member.term = Runtime::term(name);
|
||||||
|
member.typeid = T::typeid();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, _index:usize) -> Option<Member> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn length(&self) -> usize
|
||||||
|
{
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> usize
|
||||||
|
{
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn align(&self) -> usize
|
||||||
|
{
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(&self) -> Result<usize,()>
|
||||||
|
{
|
||||||
|
Runtime::bind(self, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_key(&self, key:usize) -> Result<usize,()>
|
||||||
|
{
|
||||||
|
Runtime::bind(self, Some(key))
|
||||||
|
}
|
||||||
|
}
|
||||||
impl Szun for Schema {
|
impl Szun for Schema {
|
||||||
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::SCHEMA]) }
|
fn typeid() -> usize { Runtime::type_from(types::ANY, &[types::SCHEMA]) }
|
||||||
|
|
||||||
@ -31,7 +103,7 @@ impl Szun for Schema {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()> {
|
fn decode(&mut self, _bytes:&[u8], _index:&mut usize) -> Result<(),()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,3 +112,33 @@ impl SzunInternal for Schema {
|
|||||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||||
}
|
}
|
||||||
crate::impl_szun!(Schema);
|
crate::impl_szun!(Schema);
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Builder {
|
||||||
|
data:Schema,
|
||||||
|
}
|
||||||
|
impl Builder {
|
||||||
|
pub fn build(self) -> Schema { self.data }
|
||||||
|
|
||||||
|
pub fn add<T:Szun>(mut self) -> Self
|
||||||
|
{
|
||||||
|
self.data.add::<T>();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_named<T:Szun>(mut self, name:&str) -> Self
|
||||||
|
{
|
||||||
|
self.data.add_named::<T>(name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(self) -> Result<usize,()>
|
||||||
|
{
|
||||||
|
self.data.bind()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_key(self, key:usize) -> Result<usize,()>
|
||||||
|
{
|
||||||
|
self.data.bind_key(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -106,12 +106,36 @@ impl Szun for Sequence {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()> {
|
fn decode(&mut self, _bytes:&[u8], _index:&mut usize) -> Result<(),()> {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl internal::SzunInternal for Sequence {
|
impl internal::SzunInternal for Sequence {
|
||||||
fn to_ref(&self) -> Ref { self.refer }
|
fn to_ref(&self) -> Ref { self.refer }
|
||||||
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
fn from_ref(refer:Ref) -> Self { Self { refer } }
|
||||||
|
|
||||||
|
fn mem_clone(refer:Ref, memory:Option<Ref>) -> Ref {
|
||||||
|
let memory = if let Some(memory) = memory {
|
||||||
|
memory
|
||||||
|
} else {
|
||||||
|
Runtime::acquire(Self::typeid())
|
||||||
|
};
|
||||||
|
|
||||||
|
let src = Sequence::from_ref(refer);
|
||||||
|
let mut dst = Sequence::from_ref(memory);
|
||||||
|
dst.set(&src.get());
|
||||||
|
|
||||||
|
memory
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mem_drop(refer:Ref) {
|
||||||
|
if let Some(header) = unsafe {(refer.address_mut() as *mut Data).as_mut()} {
|
||||||
|
if !header.data.is_null() {
|
||||||
|
if let Ok(layout) = std::alloc::Layout::from_size_align(header.capacity, 1) {
|
||||||
|
unsafe { std::alloc::dealloc(header.data as _, layout); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
crate::impl_szun!(Sequence);
|
crate::impl_szun!(Sequence);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::Ref;
|
use crate::Ref;
|
||||||
|
|
||||||
pub fn clone(refer:Ref, memory:Option<Ref>) -> Ref
|
pub(crate) fn clone(refer:Ref, memory:Option<Ref>) -> Ref
|
||||||
// Deep copy an object and return the copy's reference.
|
// Deep copy an object and return the copy's reference.
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{prelude::{*, internal::*}, types::*, implement::*};
|
use crate::{prelude::{*, internal::*}, types::*, implement::*};
|
||||||
|
|
||||||
pub fn drop(refer:Ref)
|
pub(crate) fn drop(refer:Ref)
|
||||||
{
|
{
|
||||||
if !refer.is_temporary() {
|
if !refer.is_temporary() {
|
||||||
drop_memory(refer);
|
drop_memory(refer);
|
||||||
@ -8,27 +8,23 @@ pub fn drop(refer:Ref)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_memory(refer:Ref)
|
pub(crate) fn drop_memory(refer:Ref)
|
||||||
{
|
{
|
||||||
|
if !refer.is_null() {
|
||||||
let typeid = refer.typeid();
|
let typeid = refer.typeid();
|
||||||
match typeid {
|
match typeid {
|
||||||
OPTIONAL => {
|
ANY => Any::mem_drop(refer),
|
||||||
let obj = crate::Optional::<Any>::from_ref(refer.temporary());
|
SEQUENCE => Sequence::mem_drop(refer),
|
||||||
if obj.is_some() {
|
//VAR => Var::mem_drop(refer),
|
||||||
drop_memory(refer.inner());
|
OPTIONAL => Optional::<Any>::mem_drop(refer),
|
||||||
}
|
ARRAY => Array::<Any, 0>::mem_drop(refer),
|
||||||
}
|
//LIST => List::<Any>::mem_drop(refer),
|
||||||
|
//RECORD => Record::<0>::mem_drop(refer),
|
||||||
|
SCHEMA => Schema::mem_drop(refer),
|
||||||
|
|
||||||
SEQUENCE => {
|
BOOLEAN | NATURAL | INTEGER | BLOCK => { }
|
||||||
if let Some(header) = unsafe {(refer.address_mut() as *mut sequence::Data).as_mut()} {
|
|
||||||
if !header.data.is_null() {
|
|
||||||
if let Ok(layout) = std::alloc::Layout::from_size_align(header.capacity, 1) {
|
|
||||||
unsafe { std::alloc::dealloc(header.data as _, layout); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => { }
|
_ => { panic!("drop_memory called for unhandled type"); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,10 @@ pub(crate) trait SzunInternal {
|
|||||||
Runtime::acquire(typeid)
|
Runtime::acquire(typeid)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (size, _) = types::size_align(typeid);
|
||||||
|
|
||||||
// Copy data to destination
|
// Copy data to destination
|
||||||
Runtime::copy(refer.address(), memory.address_mut(), types::size(typeid));
|
Runtime::copy(refer.address(), memory.address_mut(), size);
|
||||||
|
|
||||||
memory
|
memory
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ pub trait Szun : internal::SzunInternal + Clone + TryFrom<Any> + Into<Any> + Dro
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn encode(&self) -> Vec<u8>;
|
fn encode(&self) -> Vec<u8>;
|
||||||
fn decode(&mut self, bytes:&Vec<u8>, index:&mut usize) -> Result<(),()>;
|
fn decode(&mut self, bytes:&[u8], index:&mut usize) -> Result<(),()>;
|
||||||
|
|
||||||
fn tag(&self) -> Vec<u8>
|
fn tag(&self) -> Vec<u8>
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,11 @@ impl Ref {
|
|||||||
(self.typeid & (1 << (usize::BITS - 1))) != 0
|
(self.typeid & (1 << (usize::BITS - 1))) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_null(&self) -> bool
|
||||||
|
{
|
||||||
|
self.address.is_null()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn typeid(&self) -> usize
|
pub fn typeid(&self) -> usize
|
||||||
{
|
{
|
||||||
self.typeid & !(1 << (usize::BITS - 1))
|
self.typeid & !(1 << (usize::BITS - 1))
|
||||||
|
@ -1,26 +1,28 @@
|
|||||||
use crate::{prelude::*, types};
|
use crate::{prelude::{*, internal::SzunInternal}, types, util::DynList, Schema};
|
||||||
|
use dictionary::Dictionary;
|
||||||
use sparse::Sparse;
|
use sparse::Sparse;
|
||||||
use pool::Pool;
|
use pool::Pool;
|
||||||
|
|
||||||
mod typetree; use typetree::TypeTree;
|
mod typetree; use typetree::TypeTree;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
enum Binding {
|
enum Binding {
|
||||||
|
Temporary,
|
||||||
Schema {
|
Schema {
|
||||||
|
bind:usize,
|
||||||
length:usize,
|
length:usize,
|
||||||
size:usize,
|
size:usize,
|
||||||
align:usize,
|
align:usize,
|
||||||
next:usize,
|
next:usize,
|
||||||
},
|
},
|
||||||
Member {
|
Member {
|
||||||
term:usize,
|
data:crate::schema::Member,
|
||||||
typeid:usize,
|
|
||||||
offset:usize,
|
|
||||||
next:usize,
|
next:usize,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RuntimeData {
|
struct RuntimeData {
|
||||||
terms:dict::Dictionary,
|
terms:Dictionary,
|
||||||
types:TypeTree,
|
types:TypeTree,
|
||||||
bindings:Pool<Binding>,
|
bindings:Pool<Binding>,
|
||||||
bindings_ext:Sparse<usize>,
|
bindings_ext:Sparse<usize>,
|
||||||
@ -29,7 +31,7 @@ impl RuntimeData {
|
|||||||
const fn init() -> Self
|
const fn init() -> Self
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
terms:Vec::new(),
|
terms:Dictionary::new(),
|
||||||
types:TypeTree::new(),
|
types:TypeTree::new(),
|
||||||
bindings:Pool::new(),
|
bindings:Pool::new(),
|
||||||
bindings_ext:Sparse::new(),
|
bindings_ext:Sparse::new(),
|
||||||
@ -40,9 +42,9 @@ impl RuntimeData {
|
|||||||
{
|
{
|
||||||
use std::alloc::{alloc_zeroed, Layout};
|
use std::alloc::{alloc_zeroed, Layout};
|
||||||
|
|
||||||
let size = types::size(typeid);
|
let (size, align) = types::size_align(typeid);
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
if let Ok(layout) = Layout::from_size_align(size, types::align(typeid)) {
|
if let Ok(layout) = Layout::from_size_align(size, align) {
|
||||||
let address :*const u8;
|
let address :*const u8;
|
||||||
unsafe {
|
unsafe {
|
||||||
address = alloc_zeroed(layout) as _;
|
address = alloc_zeroed(layout) as _;
|
||||||
@ -61,9 +63,9 @@ impl RuntimeData {
|
|||||||
use std::alloc::{dealloc, Layout};
|
use std::alloc::{dealloc, Layout};
|
||||||
|
|
||||||
let typeid = refer.typeid();
|
let typeid = refer.typeid();
|
||||||
let size = types::size(typeid);
|
let (size, align) = types::size_align(typeid);
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
if let Ok(layout) = Layout::from_size_align(size, types::align(typeid)) {
|
if let Ok(layout) = Layout::from_size_align(size, align) {
|
||||||
unsafe {
|
unsafe {
|
||||||
dealloc(refer.address_mut(), layout);
|
dealloc(refer.address_mut(), layout);
|
||||||
}
|
}
|
||||||
@ -99,7 +101,7 @@ impl RuntimeData {
|
|||||||
|
|
||||||
fn zero(&mut self, refer:Ref)
|
fn zero(&mut self, refer:Ref)
|
||||||
{
|
{
|
||||||
let size = types::size(refer.typeid());
|
let (size, _) = types::size_align(refer.typeid());
|
||||||
for i in 0..size {
|
for i in 0..size {
|
||||||
unsafe { *refer.address_mut().byte_add(i) = 0; }
|
unsafe { *refer.address_mut().byte_add(i) = 0; }
|
||||||
}
|
}
|
||||||
@ -119,6 +121,134 @@ impl RuntimeData {
|
|||||||
{
|
{
|
||||||
self.types.value(typeid)
|
self.types.value(typeid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn term(&mut self, text:&str) -> usize
|
||||||
|
{
|
||||||
|
self.terms.set(text.as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind(&mut self, schema:&Schema, key:Option<usize>) -> Result<usize,()>
|
||||||
|
{
|
||||||
|
|
||||||
|
if let Some(schema_data) = unsafe {(schema.to_ref().address_mut() as *mut crate::schema::Data).as_mut()} {
|
||||||
|
|
||||||
|
let members = DynList::from_parts(
|
||||||
|
std::mem::size_of::<crate::schema::Member>(),
|
||||||
|
std::mem::align_of::<crate::schema::Member>(),
|
||||||
|
&mut schema_data.members as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Prepare bindings for schema and members.
|
||||||
|
let mut bindings = Vec::new();
|
||||||
|
bindings.push(Binding::Schema {
|
||||||
|
bind:if let Some(key) = key { key } else { usize::MAX },
|
||||||
|
length:members.size(),
|
||||||
|
size:0,
|
||||||
|
align:0,
|
||||||
|
next:0,
|
||||||
|
});
|
||||||
|
|
||||||
|
for i in 0..members.size() {
|
||||||
|
if let Ok(member) = members.cell_as::<crate::schema::Member>(i) {
|
||||||
|
bindings.push(Binding::Member {
|
||||||
|
data:member.clone(),
|
||||||
|
next:0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire binding allocations.
|
||||||
|
let mut slots = Vec::new();
|
||||||
|
for _ in 0..bindings.len() {
|
||||||
|
slots.push(self.bindings.add(Binding::Temporary));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill next pointers with allocations.
|
||||||
|
for i in 0..bindings.len() - 1 {
|
||||||
|
match &mut bindings[i] {
|
||||||
|
Binding::Schema {
|
||||||
|
bind:_,
|
||||||
|
length:_,
|
||||||
|
size:_,
|
||||||
|
align:_,
|
||||||
|
next
|
||||||
|
} => {
|
||||||
|
*next = slots[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding::Member {
|
||||||
|
data:_,
|
||||||
|
next
|
||||||
|
} => {
|
||||||
|
*next = slots[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write bindings to pool.
|
||||||
|
for i in 0..bindings.len() {
|
||||||
|
if let Some(cell) = self.bindings.get_mut(slots[i]) {
|
||||||
|
*cell = bindings[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map key to binding.
|
||||||
|
if let Some(key) = key {
|
||||||
|
self.bindings_ext.set(key as isize, slots[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(slots[0])
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member(&mut self, schema:usize, index:usize) -> Result<crate::schema::Member,()>
|
||||||
|
{
|
||||||
|
let mut bind_index = 0;
|
||||||
|
let bind_id = schema;
|
||||||
|
|
||||||
|
while bind_index < index {
|
||||||
|
if let Some(bind) = self.bindings.get(bind_id) {
|
||||||
|
match bind {
|
||||||
|
Binding::Schema {
|
||||||
|
bind:_,
|
||||||
|
length:_,
|
||||||
|
size:_,
|
||||||
|
align:_,
|
||||||
|
next:_,
|
||||||
|
} => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding::Member {
|
||||||
|
data:_,
|
||||||
|
next:_,
|
||||||
|
} => {
|
||||||
|
if index == bind_index {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
bind_index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => return Err(()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn member_name(&mut self, _schema:usize, _name:&str) -> Result<crate::schema::Member,()>
|
||||||
|
{
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static mut RUNTIME :RuntimeData = RuntimeData::init();
|
static mut RUNTIME :RuntimeData = RuntimeData::init();
|
||||||
|
|
||||||
@ -136,4 +266,9 @@ impl Runtime {
|
|||||||
pub fn type_in(typeid:usize) -> usize {unsafe{ RUNTIME.type_in(typeid).unwrap_or_default() }}
|
pub fn type_in(typeid:usize) -> usize {unsafe{ RUNTIME.type_in(typeid).unwrap_or_default() }}
|
||||||
pub fn type_in_opt(typeid:usize) -> Option<usize> {unsafe{ RUNTIME.type_in(typeid) }}
|
pub fn type_in_opt(typeid:usize) -> Option<usize> {unsafe{ RUNTIME.type_in(typeid) }}
|
||||||
pub fn type_from(typeid:usize, types:&[usize]) -> usize {unsafe{ RUNTIME.type_from(typeid, types) }}
|
pub fn type_from(typeid:usize, types:&[usize]) -> usize {unsafe{ RUNTIME.type_from(typeid, types) }}
|
||||||
|
|
||||||
|
pub fn term(text:&str) -> usize { unsafe { RUNTIME.term(text) } }
|
||||||
|
|
||||||
|
pub fn bind(schema:&Schema, key:Option<usize>) -> Result<usize,()> {unsafe{ RUNTIME.bind(schema, key) }}
|
||||||
|
pub fn member(schema:usize, index:usize) -> Result<crate::schema::Member,()> {unsafe { RUNTIME.member(schema, index) }}
|
||||||
}
|
}
|
||||||
|
102
src/types.rs
102
src/types.rs
@ -27,79 +27,51 @@ pub const ENUM :usize = 0x7D;
|
|||||||
pub const RECORD :usize = 0x7E;
|
pub const RECORD :usize = 0x7E;
|
||||||
pub const SCHEMA :usize = 0x7F;
|
pub const SCHEMA :usize = 0x7F;
|
||||||
|
|
||||||
pub fn size(typeid:usize) -> usize
|
pub fn size_align(typeid:usize) -> (usize, usize)
|
||||||
// Byte size of static data in memory.
|
// Byte size of static data in memory.
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
use std::mem::size_of;
|
use std::mem::{size_of, align_of};
|
||||||
|
|
||||||
match Runtime::type_of(typeid) {
|
match Runtime::type_of(typeid) {
|
||||||
ANY => 0,
|
ANY => (0, 0),
|
||||||
BOOLEAN => size_of::<bool>(),
|
BOOLEAN => (size_of::<bool>(), align_of::<bool>()),
|
||||||
BYTE => size_of::<u8>(),
|
BYTE => (size_of::<u8>(), align_of::<u8>()),
|
||||||
CHAR => size_of::<char>(),
|
CHAR => (size_of::<char>(), align_of::<char>()),
|
||||||
NATURAL => size_of::<u64>(),
|
NATURAL => (size_of::<u64>(), align_of::<u64>()),
|
||||||
INTEGER => size_of::<i64>(),
|
INTEGER => (size_of::<i64>(), align_of::<i64>()),
|
||||||
DECIMAL => size_of::<i64>(),
|
DECIMAL => (size_of::<i64>(), align_of::<i64>()),
|
||||||
SIGNIFICANT => size_of::<f64>(),
|
SIGNIFICANT => (size_of::<f64>(), align_of::<f64>()),
|
||||||
BLOCK => Runtime::type_of(Runtime::type_in(typeid)),
|
BLOCK => (Runtime::type_of(Runtime::type_in(typeid)), 1),
|
||||||
SEQUENCE => size_of::<crate::implement::sequence::Data>(),
|
SEQUENCE => (size_of::<crate::implement::sequence::Data>(), align_of::<crate::implement::sequence::Data>()),
|
||||||
VAR => 16,
|
VAR => (0, 0),
|
||||||
OPTIONAL => size(Runtime::type_in(typeid)) + 1,
|
OPTIONAL => {
|
||||||
|
let (size, align) = size_align(Runtime::type_of(Runtime::type_in(typeid)));
|
||||||
|
(
|
||||||
|
size + 1,
|
||||||
|
align,
|
||||||
|
)
|
||||||
|
},
|
||||||
ARRAY => {
|
ARRAY => {
|
||||||
let inner_size = Runtime::type_in(typeid);
|
let inner_size = Runtime::type_in(typeid);
|
||||||
let inner_type = Runtime::type_in(inner_size);
|
let inner_type = Runtime::type_in(inner_size);
|
||||||
Runtime::type_of(inner_size) * size(Runtime::type_of(inner_type))
|
let (size, align) = size_align(Runtime::type_of(inner_type));
|
||||||
|
(
|
||||||
|
Runtime::type_of(inner_size) * size,
|
||||||
|
align,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
LIST => 16,
|
LIST => (size_of::<crate::util::DynListData>(), align_of::<crate::util::DynListData>()),
|
||||||
GRAPH => 0,
|
GRAPH => (0, 0),
|
||||||
TRIE => 0,
|
TRIE => (0, 0),
|
||||||
MAP => 0,
|
MAP => (0, 0),
|
||||||
SPARSE => 0,
|
SPARSE => (0, 0),
|
||||||
POOL => 0,
|
POOL => (0, 0),
|
||||||
TABLE => 0,
|
TABLE => (0, 0),
|
||||||
ENUM => 0,
|
ENUM => (0, 0),
|
||||||
RECORD => 0,
|
RECORD => (0, 0),
|
||||||
SCHEMA => 0,
|
SCHEMA => (size_of::<crate::implement::schema::Data>(), align_of::<crate::implement::schema::Data>()),
|
||||||
_ => 0,
|
_ => (0, 0),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn align(typeid:usize) -> usize
|
|
||||||
// Byte alignment of type.
|
|
||||||
//
|
|
||||||
{
|
|
||||||
use std::mem::align_of;
|
|
||||||
|
|
||||||
match Runtime::type_of(typeid) {
|
|
||||||
ANY => 0,
|
|
||||||
BOOLEAN => align_of::<bool>(),
|
|
||||||
BYTE => align_of::<u8>(),
|
|
||||||
CHAR => align_of::<char>(),
|
|
||||||
NATURAL => align_of::<u64>(),
|
|
||||||
INTEGER => align_of::<i64>(),
|
|
||||||
DECIMAL => align_of::<i64>(),
|
|
||||||
SIGNIFICANT => align_of::<f64>(),
|
|
||||||
BLOCK => align_of::<u8>(),
|
|
||||||
SEQUENCE => align_of::<crate::implement::sequence::Data>(),
|
|
||||||
VAR => 8,
|
|
||||||
OPTIONAL => align(Runtime::type_in(typeid)),
|
|
||||||
ARRAY => {
|
|
||||||
let inner_size = Runtime::type_in(typeid);
|
|
||||||
let inner_type = Runtime::type_in(inner_size);
|
|
||||||
align(Runtime::type_of(inner_type))
|
|
||||||
},
|
|
||||||
LIST => 8,
|
|
||||||
GRAPH => 0,
|
|
||||||
TRIE => 0,
|
|
||||||
MAP => 0,
|
|
||||||
SPARSE => 0,
|
|
||||||
POOL => 0,
|
|
||||||
TABLE => 0,
|
|
||||||
ENUM => 0,
|
|
||||||
RECORD => 0,
|
|
||||||
SCHEMA => 0,
|
|
||||||
_ => 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +80,7 @@ pub fn primitive(typeid:usize) -> bool
|
|||||||
//
|
//
|
||||||
{
|
{
|
||||||
match Runtime::type_of(typeid) {
|
match Runtime::type_of(typeid) {
|
||||||
ANY | BOOLEAN
|
BOOLEAN
|
||||||
| BYTE | CHAR
|
| BYTE | CHAR
|
||||||
| NATURAL | INTEGER | DECIMAL | SIGNIFICANT
|
| NATURAL | INTEGER | DECIMAL | SIGNIFICANT
|
||||||
| BLOCK
|
| BLOCK
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) struct DynListData {
|
pub struct DynListData {
|
||||||
capacity:usize,
|
capacity:usize,
|
||||||
length:usize,
|
length:usize,
|
||||||
data:*mut u8,
|
data:*mut u8,
|
||||||
@ -9,56 +9,94 @@ pub(crate) struct DynListData {
|
|||||||
pub struct DynList {
|
pub struct DynList {
|
||||||
size:usize,
|
size:usize,
|
||||||
align:usize,
|
align:usize,
|
||||||
data:DynListData,
|
data:*mut DynListData,
|
||||||
}
|
}
|
||||||
impl DynList<Z> {
|
impl DynList {
|
||||||
pub fn from_parts(ptr:*const DynListData, size:usize, align:usize) -> Self {
|
pub fn from_parts(size:usize, align:usize, ptr:*mut DynListData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
size,
|
size,
|
||||||
align,
|
align,
|
||||||
data:unsafe {*ptr},
|
data:ptr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reserve(&mut self) -> Result<*mut u8,()>
|
pub fn acquire(&mut self) -> Result<*mut u8,()>
|
||||||
{
|
{
|
||||||
if self.length == self.capacity {
|
if let Some(data) = unsafe {self.data.as_mut()} {
|
||||||
self.resize(self.capacity * 2)?;
|
if data.length == data.capacity {
|
||||||
|
self.resize(data.capacity * 2)?;
|
||||||
}
|
}
|
||||||
self.length += 1;
|
data.length += 1;
|
||||||
cell(self.length - 1)
|
self.cell(data.length - 1)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cell(&self, index:usize) -> Result<*mut u8,()>
|
|
||||||
{
|
|
||||||
if index < self.length {
|
|
||||||
Ok(unsafe {self.data.byte_add(index * self.size)})
|
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, capacity:usize) -> Result<(),()>
|
pub fn cell(&self, index:usize) -> Result<*mut u8,()>
|
||||||
{
|
{
|
||||||
use std::alloc::{alloc_zeroed, Layout};
|
if let Some(data) = unsafe {self.data.as_mut()} {
|
||||||
|
if index < data.length {
|
||||||
|
return Ok(unsafe {self.data.byte_add(index * self.size)} as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cell_as<T>(&self, index:usize) -> Result<&mut T,()>
|
||||||
|
{
|
||||||
|
if let Some(data) = unsafe {self.data.as_mut()} {
|
||||||
|
if index < data.length {
|
||||||
|
if let Some(result) = unsafe {(self.data.byte_add(index * self.size) as *mut T).as_mut()} {
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, _capacity:usize) -> Result<(),()>
|
||||||
|
{
|
||||||
|
/*use std::alloc::{alloc_zeroed, Layout};
|
||||||
|
if let Some(data) = unsafe {self.data.as_mut()} {
|
||||||
let ptr = self.data;
|
let ptr = self.data;
|
||||||
|
|
||||||
if capacity > 0 {
|
if capacity > 0 {
|
||||||
if let Ok(layout) = Layout::from_size_align(size, types::align(typeid)) {
|
if let Ok(layout) = Layout::from_size_align(capacity * self.size, self.align) {
|
||||||
let address :*const u8;
|
//Ref::new(typeid, unsafe {alloc_zeroed(layout) as *const u8})
|
||||||
unsafe {
|
|
||||||
address = alloc_zeroed(layout) as _;
|
|
||||||
}
|
|
||||||
Ref::new(typeid, address)
|
|
||||||
} else {
|
} else {
|
||||||
Ref::null()
|
//Ref::null()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ref::null()
|
//Ref::null()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.capacity = capacity;
|
data.capacity = capacity;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(())
|
||||||
|
}*/
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn capacity(&self) -> usize
|
||||||
|
{
|
||||||
|
unsafe {(*self.data).capacity}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> usize
|
||||||
|
{
|
||||||
|
unsafe {(*self.data).length}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drop(&mut self)
|
||||||
|
{
|
||||||
|
use std::alloc::{dealloc, Layout};
|
||||||
|
if let Some(data) = unsafe {self.data.as_mut()} {
|
||||||
|
if let Ok(layout) = Layout::from_size_align(self.size * data.capacity, self.align) {
|
||||||
|
unsafe { dealloc(data.data, layout); }
|
||||||
|
data.data = std::ptr::null_mut();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
mod dynlist; pub use dynlist::RawList;
|
mod dynlist; pub use dynlist::*;
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod macros;
|
pub mod macros;
|
||||||
mod container; pub use container::*;
|
mod container; pub use container::*;
|
||||||
|
pub mod pack;
|
||||||
|
139
src/util/pack.rs
Normal file
139
src/util/pack.rs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
fn pack_size(data:u64, signed:bool) -> usize
|
||||||
|
{
|
||||||
|
let sign_bit = signed as u32;
|
||||||
|
1 + (data >= 1 << (7 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (14 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (21 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (28 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (35 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (42 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (49 - sign_bit)) as usize
|
||||||
|
+ (data >= 1 << (56 - sign_bit)) as usize
|
||||||
|
+ (signed && data >= 1 << 63) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pack_natural(data:u64) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut result = [0u8; 9];
|
||||||
|
let size = pack_size(data, false);
|
||||||
|
let tag = (0xFF00u32 >> (size - 1)) as u8;
|
||||||
|
|
||||||
|
match size {
|
||||||
|
1 => {
|
||||||
|
result[0] = data as u8;
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
result[0] = (data >> 8) as u8;
|
||||||
|
result[1] = data as u8;
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
result[0] = (data >> 16) as u8;
|
||||||
|
result[1] = (data >> 8) as u8;
|
||||||
|
result[2] = data as u8;
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[1] = (data >> 16) as u8;
|
||||||
|
result[2] = (data >> 8) as u8;
|
||||||
|
result[3] = data as u8;
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[1] = (data >> 16) as u8;
|
||||||
|
result[2] = (data >> 8) as u8;
|
||||||
|
result[3] = data as u8;
|
||||||
|
}
|
||||||
|
6 => {
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[1] = (data >> 16) as u8;
|
||||||
|
result[2] = (data >> 8) as u8;
|
||||||
|
result[3] = data as u8;
|
||||||
|
}
|
||||||
|
7 => {
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[0] = (data >> 24) as u8;
|
||||||
|
result[1] = (data >> 16) as u8;
|
||||||
|
result[2] = (data >> 8) as u8;
|
||||||
|
result[3] = data as u8;
|
||||||
|
}
|
||||||
|
8 => {
|
||||||
|
result[0] = (data >> 56) as u8;
|
||||||
|
result[1] = (data >> 48) as u8;
|
||||||
|
result[2] = (data >> 40) as u8;
|
||||||
|
result[3] = (data >> 32) as u8;
|
||||||
|
result[4] = (data >> 24) as u8;
|
||||||
|
result[5] = (data >> 16) as u8;
|
||||||
|
result[6] = (data >> 8) as u8;
|
||||||
|
result[7] = data as u8;
|
||||||
|
}
|
||||||
|
9 => {
|
||||||
|
result[1] = (data >> 56) as u8;
|
||||||
|
result[2] = (data >> 48) as u8;
|
||||||
|
result[3] = (data >> 40) as u8;
|
||||||
|
result[4] = (data >> 32) as u8;
|
||||||
|
result[5] = (data >> 24) as u8;
|
||||||
|
result[6] = (data >> 16) as u8;
|
||||||
|
result[7] = (data >> 8) as u8;
|
||||||
|
result[8] = data as u8;
|
||||||
|
}
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
|
||||||
|
result[0] |= tag;
|
||||||
|
result[0..size].to_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pack_integer(data:i64) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let negative = data < 0;
|
||||||
|
let data = ((negative as u64) * (!data as u64)) + ((!negative as u64) * data as u64);
|
||||||
|
let size = pack_size(data, true);
|
||||||
|
|
||||||
|
let sign = [
|
||||||
|
(((negative as u32) << 6) >> (size - 1)) as u8,
|
||||||
|
(((negative as u32) << 14) >> (size - 1)) as u8,
|
||||||
|
];
|
||||||
|
let sign_index = (size >= 6) as usize;
|
||||||
|
|
||||||
|
let mut result = pack_natural(data);
|
||||||
|
|
||||||
|
result[sign_index] |= sign[sign_index];
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack_natural(data:&[u8], index:&mut usize) -> u64
|
||||||
|
{
|
||||||
|
let size = data[*index].leading_ones();
|
||||||
|
let mut result = (data[*index] & (0x7F >> size)) as u64;
|
||||||
|
*index += 1;
|
||||||
|
|
||||||
|
for _ in 0..size {
|
||||||
|
result << 8;
|
||||||
|
result += data[*index] as u64;
|
||||||
|
*index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack_integer(data:&[u8], index:&mut usize) -> u64
|
||||||
|
{
|
||||||
|
let size = data[*index].leading_ones();
|
||||||
|
let sign = (data[*index + (size == 8) as usize] & (0x40 >> size)) != 0;
|
||||||
|
let mut result = (data[*index] & (0x3F >> size)) as u64;
|
||||||
|
*index += 1;
|
||||||
|
|
||||||
|
for _ in 0..size {
|
||||||
|
result << 8;
|
||||||
|
result += data[*index] as u64;
|
||||||
|
*index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
((sign) as u64 * (!result)) + ((!sign) as u64 * result)
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user