Rework of interface.
This commit is contained in:
parent
8116af305f
commit
7c64312323
@ -1,34 +1,29 @@
|
||||
use szun::*;
|
||||
|
||||
fn main() {
|
||||
let mut int = Integer::new().with(512);
|
||||
let boo = Boolean::new().with(false);
|
||||
let mut var = Var::new();
|
||||
var.set(&int);
|
||||
|
||||
let int2 :Integer = var.get();
|
||||
println!("{}", int2.get::<i32>());
|
||||
|
||||
int.set(1024);
|
||||
let mut lst = List::<Var>::new();
|
||||
lst.push(&int);
|
||||
lst.push(&boo);
|
||||
|
||||
int.set(20); lst.push(&int);
|
||||
|
||||
for i in 0..lst.len() {
|
||||
if let Ok(int) = lst.get(i).try_get::<Integer>() {
|
||||
println!("{}", int.get::<i32>());
|
||||
fn hex_str(data:Vec<u8>) -> String
|
||||
{
|
||||
fn nibble(byte:u8) -> char
|
||||
{
|
||||
if byte < 10 {
|
||||
char::from_u32('0' as u32 + byte as u32).unwrap_or('?')
|
||||
} else {
|
||||
char::from_u32('a' as u32 + (byte as u32 - 10)).unwrap_or('?')
|
||||
}
|
||||
}
|
||||
|
||||
let mut arr = Array::<2, Var>::new();
|
||||
int.set(30); arr.set(0, &int);
|
||||
arr.set(1, &boo);
|
||||
|
||||
for i in 0..arr.len() {
|
||||
if let Ok(int) = arr.get(i).try_get::<Integer>() {
|
||||
println!("{}", int.get::<i32>());
|
||||
}
|
||||
let mut result = String::with_capacity(data.len() * 2);
|
||||
for byte in data {
|
||||
result.push(nibble((byte >> 4) & 0x0F));
|
||||
result.push(nibble(byte & 0x0F));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut list = List::<Any>::new();
|
||||
list.push(&Natural::new().with(10));
|
||||
list.push(&Natural::new().with(20));
|
||||
list.push(&Integer::new().with(-1));
|
||||
|
||||
println!("{}", hex_str(list.encode()));
|
||||
}
|
||||
|
@ -1,363 +1,371 @@
|
||||
use crate::{
|
||||
runtime,
|
||||
runtime::{
|
||||
Reference,
|
||||
kind_hasinner, type_hasinner, type_inner, type_outer,
|
||||
type_key, type_innerkey, SparseHeader,
|
||||
},
|
||||
types,
|
||||
Object,
|
||||
util::*,
|
||||
};
|
||||
use crate::kind;
|
||||
use crate::{
|
||||
Varying,
|
||||
Boolean,
|
||||
Natural, Integer,
|
||||
Decimal, //Significant,
|
||||
Block, Sequence,
|
||||
Array, List,
|
||||
Record,
|
||||
Schema,
|
||||
};
|
||||
use crate::util;
|
||||
|
||||
pub fn encode_tag(type_id:usize) -> Vec<u8>
|
||||
{
|
||||
let mut tid = type_id;
|
||||
let mut result = Vec::<u8>::new();
|
||||
let mut remaining :usize = 1;
|
||||
while remaining > 0 {
|
||||
result.append(&mut util::pack_natural(unsafe {type_key(tid)} as u64));
|
||||
|
||||
remaining -= 1;
|
||||
if remaining == 0 {
|
||||
remaining += unsafe {type_hasinner(tid)};
|
||||
}
|
||||
tid = unsafe {type_inner(tid)};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn encode_data(addr:Reference) -> Vec<u8>
|
||||
{
|
||||
let mut result = Vec::<u8>::new();
|
||||
match unsafe {type_key(addr.class)} {
|
||||
types::VARYING => {
|
||||
let data = Varying::try_from(addr).unwrap();
|
||||
result.append(&mut encode(data.get()));
|
||||
}
|
||||
types::BOOLEAN => {
|
||||
result.append(&mut util::pack_natural(Boolean::try_from(addr).unwrap().get() as u64));
|
||||
}
|
||||
types::NATURAL => {
|
||||
result.append(&mut util::pack_natural(Natural::try_from(addr).unwrap().get() as u64));
|
||||
}
|
||||
types::INTEGER => {
|
||||
result.append(&mut &mut util::pack_integer(Integer::try_from(addr).unwrap().get() as i64));
|
||||
}
|
||||
types::DECIMAL => {
|
||||
let mantissa = unsafe {type_innerkey(addr.class)};
|
||||
let raw = Decimal::try_from(addr).unwrap().get_raw();
|
||||
let whole = raw >> mantissa;
|
||||
let fract = (raw as u64 & ((1u64 << mantissa) - 1)).reverse_bits() >> (u64::BITS as usize - mantissa);
|
||||
result.append(&mut &mut util::pack_integer(whole));
|
||||
result.append(&mut &mut util::pack_natural(fract));
|
||||
}
|
||||
types::SIGNIFICANT => {
|
||||
result.append(&mut vec![0]);
|
||||
}
|
||||
types::BLOCK => {
|
||||
result.append(&mut Block::try_from(addr).unwrap().get());
|
||||
}
|
||||
types::SEQUENCE => {
|
||||
let data = Sequence::try_from(addr).unwrap();
|
||||
result.append(&mut util::pack_natural(data.size() as u64));
|
||||
result.append(&mut data.get_raw());
|
||||
}
|
||||
types::ARRAY => {
|
||||
let data = Array::try_from(addr).unwrap();
|
||||
for i in 0..data.length() {
|
||||
if unsafe {type_innerkey(addr.class)} == types::VARYING {
|
||||
result.append(&mut encode(data.at(i)));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(data.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
types::LIST => {
|
||||
let data = List::try_from(addr).unwrap();
|
||||
result.append(&mut util::pack_natural(data.length() as u64));
|
||||
for i in 0..data.length() {
|
||||
if unsafe {type_innerkey(addr.class)} == types::VARYING {
|
||||
result.append(&mut encode(data.at(i)));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(data.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
types::SPARSE => {
|
||||
let data = crate::Sparse::try_from(addr).unwrap();
|
||||
|
||||
let header_length = unsafe {runtime::sparse_header_length(addr)};
|
||||
|
||||
result.append(&mut util::pack_natural(header_length as u64));
|
||||
|
||||
for i in 0..header_length {
|
||||
let header = unsafe {runtime::sparse_header_data(addr, i)};
|
||||
result.append(&mut util::pack_natural(header.start as u64));
|
||||
result.append(&mut util::pack_natural(header.length as u64));
|
||||
result.append(&mut util::pack_natural(header.index as u64));
|
||||
}
|
||||
|
||||
for i in 0..data.length() {
|
||||
if unsafe {type_innerkey(addr.class)} == types::VARYING {
|
||||
result.append(&mut encode(data.at(i)));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(data.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
types::RECORD => {
|
||||
let data = Record::try_from(addr).unwrap();
|
||||
for i in 0..data.length() {
|
||||
if kind(data.kindof(i)) == types::VARYING {
|
||||
result.append(&mut encode(data.at(i)));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(data.at(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
types::SCHEMA => {
|
||||
let data = Schema::try_from(addr).unwrap();
|
||||
|
||||
result.append(&mut util::pack_natural(data.length() as u64));
|
||||
|
||||
for i in 0..data.length() {
|
||||
result.append(&mut encode_tag(data.get(i).unwrap()));
|
||||
|
||||
let mut key = Vec::from(data.keyof(i).unwrap().as_bytes());
|
||||
result.append(&mut util::pack_natural(key.len() as u64));
|
||||
result.append(&mut key);
|
||||
}
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn encode(addr:Reference) -> Vec<u8>
|
||||
{
|
||||
let mut result = encode_tag(addr.class);
|
||||
result.append(&mut encode_data(addr));
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn decode_tag(data:&Vec<u8>, index:&mut usize) -> Result<usize,()>
|
||||
{
|
||||
let mut tags = Vec::<usize>::new();
|
||||
let mut remaining :usize = 1;
|
||||
while remaining > 0 && *index < data.len() {
|
||||
let kind = util::unpack_natural(&data, index) as usize;
|
||||
tags.push(kind);
|
||||
|
||||
remaining -= 1;
|
||||
if remaining == 0 {
|
||||
remaining += unsafe {kind_hasinner(kind)};
|
||||
}
|
||||
}
|
||||
let mut type_id = 0;
|
||||
for i in (0..tags.len()).rev() {
|
||||
type_id = unsafe {type_outer(type_id, tags[i])};
|
||||
}
|
||||
|
||||
return if remaining == 0 { Ok(type_id) }
|
||||
else { Err(()) }
|
||||
}
|
||||
|
||||
pub fn decode_data(data:&Vec<u8>, type_id:usize, index:&mut usize) -> Result<Object,()>
|
||||
{
|
||||
match unsafe {type_key(type_id)} {
|
||||
types::VARYING => {
|
||||
return match decode(data, index) {
|
||||
Ok(value) => {
|
||||
Ok(Object::Varying(Varying::with(value.get())))
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
}
|
||||
types::BOOLEAN => {
|
||||
return Ok(Object::Boolean(Boolean::with(unpack_natural(data, index) == 1)));
|
||||
}
|
||||
types::NATURAL => {
|
||||
return Ok(Object::Natural(Natural::with(unpack_natural(data, index))));
|
||||
}
|
||||
types::INTEGER => {
|
||||
return Ok(Object::Integer(Integer::with(unpack_integer(data, index))));
|
||||
}
|
||||
types::DECIMAL => {
|
||||
let mantissa = unsafe {type_innerkey(type_id)};
|
||||
let whole = unpack_integer(data, index);
|
||||
let fract = unpack_natural(data, index).reverse_bits() >> (u64::BITS as usize - mantissa);
|
||||
let raw = (whole << mantissa) | fract as i64;
|
||||
|
||||
return Ok(Object::Decimal(Decimal::with_raw(unsafe {type_innerkey(type_id)}, raw)));
|
||||
}
|
||||
types::SIGNIFICANT => {
|
||||
return Err(())
|
||||
}
|
||||
types::BLOCK => {
|
||||
let size = unsafe {type_innerkey(type_id)};
|
||||
let mut bytes = Vec::<u8>::with_capacity(size);
|
||||
if *index + size <= data.len() {
|
||||
for _ in 0..size {
|
||||
bytes.push(data[*index]);
|
||||
*index += 1;
|
||||
}
|
||||
}
|
||||
return Ok(Object::Block(Block::with(size, bytes)));
|
||||
}
|
||||
types::SEQUENCE => {
|
||||
let size = unpack_natural(data, index) as usize;
|
||||
let mut bytes = Vec::<u8>::with_capacity(size);
|
||||
if *index + size <= data.len() {
|
||||
for _ in 0..size {
|
||||
bytes.push(data[*index]);
|
||||
*index += 1;
|
||||
}
|
||||
}
|
||||
return Ok(Object::Sequence(Sequence::with_raw(bytes)));
|
||||
}
|
||||
types::ARRAY => {
|
||||
let length = unsafe {type_innerkey(type_id)};
|
||||
let inner = unsafe {type_inner(type_inner(type_id))};
|
||||
|
||||
let mut result = Array::new(length, inner);
|
||||
for i in 0..length {
|
||||
match if unsafe {type_key(inner)} == types::VARYING {
|
||||
decode(data, index)
|
||||
} else {
|
||||
decode_data(data, inner, index)
|
||||
} {
|
||||
Ok(data) => { result.set(i, data.get()); }
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Object::Array(result));
|
||||
}
|
||||
types::LIST => {
|
||||
let inner = unsafe {type_inner(type_id)};
|
||||
let length = util::unpack_natural(data, index) as usize;
|
||||
|
||||
let mut result = List::new(inner);
|
||||
result.reserve(length);
|
||||
|
||||
for _ in 0..length {
|
||||
match if unsafe {type_key(inner)} == types::VARYING {
|
||||
decode(data, index)
|
||||
} else {
|
||||
decode_data(data, inner, index)
|
||||
} {
|
||||
Ok(data) => { result.append(data.get()); }
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Object::List(result));
|
||||
}
|
||||
types::SPARSE => {
|
||||
let inner = unsafe {type_inner(type_id)};
|
||||
let mut result = crate::Sparse::new(inner);
|
||||
|
||||
let header_length = util::unpack_natural(data, index) as usize;
|
||||
let mut headers = Vec::<SparseHeader>::with_capacity(header_length);
|
||||
|
||||
for _ in 0..header_length {
|
||||
headers.push(runtime::SparseHeader {
|
||||
start:util::unpack_natural(data, index) as usize,
|
||||
length:util::unpack_natural(data, index) as usize,
|
||||
index:util::unpack_natural(data, index) as usize,
|
||||
});
|
||||
}
|
||||
|
||||
for header in headers {
|
||||
for i in 0..header.length {
|
||||
match if unsafe {type_key(inner)} == types::VARYING {
|
||||
decode(data, index)
|
||||
} else {
|
||||
decode_data(data, inner, index)
|
||||
} {
|
||||
Ok(data) => {
|
||||
result.set(header.start + i, data.get());
|
||||
}
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Object::Sparse(result));
|
||||
}
|
||||
types::RECORD => {
|
||||
return match Record::new(unsafe {type_innerkey(type_id)}) {
|
||||
Ok(mut value) => {
|
||||
for i in 0..value.length() {
|
||||
match decode_data(data, value.kindof(i), index) {
|
||||
Ok(refer) => {
|
||||
value.set_at(i, refer.get());
|
||||
}
|
||||
Err(_) => return Err(())
|
||||
}
|
||||
}
|
||||
Ok(Object::Record(value))
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
}
|
||||
types::SCHEMA => {
|
||||
let mut result = Schema::new();
|
||||
|
||||
let length = util::unpack_natural(data, index) as usize;
|
||||
|
||||
for _ in 0..length {
|
||||
let class :usize;
|
||||
match decode_tag(data, index) {
|
||||
Ok(tag) => { class = tag; }
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
|
||||
let key_length = util::unpack_natural(data, index) as usize;
|
||||
let mut key_bytes = Vec::<u8>::with_capacity(key_length);
|
||||
for _ in 0..key_length {
|
||||
if *index < data.len() {
|
||||
key_bytes.push(data[*index]);
|
||||
*index += 1;
|
||||
}
|
||||
else {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
let key = String::from_utf8(key_bytes).unwrap();
|
||||
|
||||
result.assign(&key, class);
|
||||
}
|
||||
|
||||
return Ok(Object::Schema(result));
|
||||
}
|
||||
_ => { }
|
||||
}
|
||||
|
||||
return Err(());
|
||||
}
|
||||
|
||||
pub fn decode(data:&Vec<u8>, index:&mut usize) -> Result<Object,()>
|
||||
{
|
||||
return match decode_tag(data, index) {
|
||||
Ok(type_id) => decode_data(data, type_id, index),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
use crate::{
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
util::binary,
|
||||
};
|
||||
use crate::interface::*;
|
||||
|
||||
pub fn encode_tag(type_id:usize) -> Vec<u8>
|
||||
{
|
||||
let mut tid = type_id;
|
||||
let mut result = Vec::<u8>::new();
|
||||
let mut remaining :usize = 1;
|
||||
while remaining > 0 {
|
||||
result.append(&mut binary::pack_natural(unsafe {runtime::type_key(tid)} as u64));
|
||||
|
||||
remaining -= 1;
|
||||
if remaining == 0 {
|
||||
remaining += unsafe {runtime::type_hasinner(tid)};
|
||||
}
|
||||
tid = unsafe {runtime::type_inner(tid)};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn encode_data(addr:Ref) -> Vec<u8>
|
||||
{
|
||||
match unsafe {runtime::type_key(addr.class)} {
|
||||
types::TYPE_VAR => {
|
||||
encode(Var::__from_ref(addr).get_any().__to_ref())
|
||||
}
|
||||
types::TYPE_BOOLEAN => {
|
||||
binary::pack_natural(unsafe {runtime::bool_get(addr)} as u64)
|
||||
}
|
||||
types::TYPE_NATURAL => {
|
||||
binary::pack_natural(unsafe {runtime::natural_get(addr)})
|
||||
}
|
||||
types::TYPE_INTEGER => {
|
||||
binary::pack_integer(unsafe {runtime::integer_get(addr)})
|
||||
}
|
||||
/*types::TYPE_DECIMAL => {
|
||||
let mantissa = unsafe {type_innerkey(addr.class)};
|
||||
let raw = Decimal::try_from(addr).unwrap().get_raw();
|
||||
let whole = raw >> mantissa;
|
||||
let fract = (raw as u64 & ((1u64 << mantissa) - 1)).reverse_bits() >> (u64::BITS as usize - mantissa);
|
||||
result.append(&mut &mut binary::pack_integer(whole));
|
||||
result.append(&mut &mut binary::pack_natural(fract));
|
||||
}*/
|
||||
/*types::TYPE_SIGNIFICANT => {
|
||||
result.append(&mut vec![0]);
|
||||
}*/
|
||||
types::TYPE_BLOCK => {
|
||||
let length = unsafe {runtime::type_innerkey(addr.class)};
|
||||
let mut result = Vec::new();
|
||||
for i in 0..length {
|
||||
result.push(unsafe {runtime::block_get(addr, i)});
|
||||
}
|
||||
result
|
||||
}
|
||||
types::TYPE_SEQUENCE => {
|
||||
let length = unsafe {runtime::sequence_length(addr)};
|
||||
|
||||
let mut result = binary::pack_natural(length as u64);
|
||||
for i in 0..length {
|
||||
result.push(unsafe {runtime::sequence_get(addr, i)});
|
||||
}
|
||||
result
|
||||
}
|
||||
types::TYPE_ARRAY => {
|
||||
let len_type = unsafe {runtime::type_inner(addr.class)};
|
||||
let length = unsafe {runtime::type_key(len_type)};
|
||||
|
||||
let mut result = Vec::new();
|
||||
for i in 0..length {
|
||||
let refr = unsafe {runtime::array_at(addr, i)};
|
||||
|
||||
if unsafe {runtime::type_key(refr.class)} == types::TYPE_VAR {
|
||||
result.append(&mut encode(unsafe {runtime::var_get(refr)}));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(refr));
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
types::TYPE_LIST => {
|
||||
let length = unsafe {runtime::list_length(addr)};
|
||||
|
||||
let mut result = Vec::new();
|
||||
for i in 0..length {
|
||||
let refr = unsafe {runtime::list_at(addr, i)};
|
||||
|
||||
if unsafe {runtime::type_key(refr.class)} == types::TYPE_VAR {
|
||||
result.append(&mut encode(unsafe {runtime::var_get(refr)}));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(refr));
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
types::TYPE_SPARSE => {
|
||||
let result = Vec::new();
|
||||
/*let data = crate::Sparse::try_from(addr).unwrap();
|
||||
|
||||
let header_length = unsafe {runtime::sparse_header_length(addr)};
|
||||
|
||||
result.append(&mut binary::pack_natural(header_length as u64));
|
||||
|
||||
for i in 0..header_length {
|
||||
let header = unsafe {runtime::sparse_header_data(addr, i)};
|
||||
result.append(&mut binary::pack_natural(header.start as u64));
|
||||
result.append(&mut binary::pack_natural(header.length as u64));
|
||||
result.append(&mut binary::pack_natural(header.index as u64));
|
||||
}
|
||||
|
||||
for i in 0..data.length() {
|
||||
if unsafe {type_innerkey(addr.class)} == types::TYPE_VAR {
|
||||
result.append(&mut encode(data.at(i)));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(data.at(i)));
|
||||
}
|
||||
}*/
|
||||
result
|
||||
}
|
||||
types::TYPE_RECORD => {
|
||||
let _schema = unsafe {runtime::type_innerkey(addr.class)};
|
||||
/*let length = unsafe {runtime::schema_length(schema)};
|
||||
|
||||
let data = Record::try_from(addr).unwrap();
|
||||
for i in 0..data.length() {
|
||||
if kind(data.kindof(i)) == types::TYPE_VAR {
|
||||
result.append(&mut encode(data.at(i)));
|
||||
}
|
||||
else {
|
||||
result.append(&mut encode_data(data.at(i)));
|
||||
}
|
||||
}*/
|
||||
Vec::new()
|
||||
}
|
||||
types::TYPE_SCHEMA => {
|
||||
/*let data = Schema::try_from(addr).unwrap();
|
||||
|
||||
result.append(&mut binary::pack_natural(data.length() as u64));
|
||||
|
||||
for i in 0..data.length() {
|
||||
result.append(&mut encode_tag(data.get(i).unwrap()));
|
||||
|
||||
let mut key = Vec::from(data.keyof(i).unwrap().as_bytes());
|
||||
result.append(&mut binary::pack_natural(key.len() as u64));
|
||||
result.append(&mut key);
|
||||
}*/
|
||||
Vec::new()
|
||||
}
|
||||
_ => { panic!("szun encode not implemented"); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode(addr:Ref) -> Vec<u8>
|
||||
{
|
||||
let mut result = encode_tag(addr.class);
|
||||
result.append(&mut encode_data(addr));
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn decode_tag(data:&Vec<u8>, index:&mut usize) -> Result<usize,SzunError>
|
||||
{
|
||||
let mut tags = Vec::<usize>::new();
|
||||
let mut remaining :usize = 1;
|
||||
while remaining > 0 && *index < data.len() {
|
||||
let kind = match binary::unpack_natural(&data, index) {
|
||||
Ok(id) => id as usize,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
tags.push(kind);
|
||||
|
||||
remaining -= 1;
|
||||
if remaining == 0 {
|
||||
remaining += unsafe {runtime::kind_hasinner(kind)};
|
||||
}
|
||||
}
|
||||
let mut type_id = 0;
|
||||
for i in (0..tags.len()).rev() {
|
||||
type_id = unsafe {runtime::type_outer(type_id, tags[i])};
|
||||
}
|
||||
|
||||
return if remaining == 0 { Ok(type_id) }
|
||||
else { Err(SzunError::BadData) }
|
||||
}
|
||||
|
||||
pub fn decode_data(_data:&Vec<u8>, type_id:usize, _index:&mut usize) -> Result<Any,()>
|
||||
{
|
||||
match unsafe {runtime::type_key(type_id)} {
|
||||
/*types::TYPE_VAR => {
|
||||
return match decode(data, index) {
|
||||
Ok(value) => {
|
||||
Ok(Object::Var(Var::with(value.get())))
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
}
|
||||
types::TYPE_BOOLEAN => {
|
||||
return Ok(Object::Boolean(Boolean::with(unpack_natural(data, index) == 1)));
|
||||
}
|
||||
types::TYPE_NATURAL => {
|
||||
return Ok(Object::Natural(Natural::with(unpack_natural(data, index))));
|
||||
}
|
||||
types::TYPE_INTEGER => {
|
||||
return Ok(Object::Integer(Integer::with(unpack_integer(data, index))));
|
||||
}
|
||||
types::TYPE_DECIMAL => {
|
||||
let mantissa = unsafe {type_innerkey(type_id)};
|
||||
let whole = unpack_integer(data, index);
|
||||
let fract = unpack_natural(data, index).reverse_bits() >> (u64::BITS as usize - mantissa);
|
||||
let raw = (whole << mantissa) | fract as i64;
|
||||
|
||||
return Ok(Object::Decimal(Decimal::with_raw(unsafe {type_innerkey(type_id)}, raw)));
|
||||
}
|
||||
types::TYPE_SIGNIFICANT => {
|
||||
return Err(())
|
||||
}
|
||||
types::TYPE_BLOCK => {
|
||||
let size = unsafe {type_innerkey(type_id)};
|
||||
let mut bytes = Vec::<u8>::with_capacity(size);
|
||||
if *index + size <= data.len() {
|
||||
for _ in 0..size {
|
||||
bytes.push(data[*index]);
|
||||
*index += 1;
|
||||
}
|
||||
}
|
||||
return Ok(Object::Block(Block::with(size, bytes)));
|
||||
}
|
||||
types::TYPE_SEQUENCE => {
|
||||
let size = unpack_natural(data, index) as usize;
|
||||
let mut bytes = Vec::<u8>::with_capacity(size);
|
||||
if *index + size <= data.len() {
|
||||
for _ in 0..size {
|
||||
bytes.push(data[*index]);
|
||||
*index += 1;
|
||||
}
|
||||
}
|
||||
return Ok(Object::Sequence(Sequence::with_raw(bytes)));
|
||||
}
|
||||
types::TYPE_ARRAY => {
|
||||
let length = unsafe {type_innerkey(type_id)};
|
||||
let inner = unsafe {type_inner(type_inner(type_id))};
|
||||
|
||||
let mut result = Array::new(length, inner);
|
||||
for i in 0..length {
|
||||
match if unsafe {type_key(inner)} == types::TYPE_VAR {
|
||||
decode(data, index)
|
||||
} else {
|
||||
decode_data(data, inner, index)
|
||||
} {
|
||||
Ok(data) => { result.set(i, data.get()); }
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Object::Array(result));
|
||||
}
|
||||
types::TYPE_LIST => {
|
||||
let inner = unsafe {type_inner(type_id)};
|
||||
let length = binary::unpack_natural(data, index) as usize;
|
||||
|
||||
let mut result = List::new(inner);
|
||||
result.reserve(length);
|
||||
|
||||
for _ in 0..length {
|
||||
match if unsafe {type_key(inner)} == types::TYPE_VAR {
|
||||
decode(data, index)
|
||||
} else {
|
||||
decode_data(data, inner, index)
|
||||
} {
|
||||
Ok(data) => { result.append(data.get()); }
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Object::List(result));
|
||||
}
|
||||
types::TYPE_SPARSE => {
|
||||
let inner = unsafe {type_inner(type_id)};
|
||||
let mut result = crate::Sparse::new(inner);
|
||||
|
||||
let header_length = binary::unpack_natural(data, index) as usize;
|
||||
let mut headers = Vec::<SparseHeader>::with_capacity(header_length);
|
||||
|
||||
for _ in 0..header_length {
|
||||
headers.push(runtime::SparseHeader {
|
||||
start:binary::unpack_natural(data, index) as usize,
|
||||
length:binary::unpack_natural(data, index) as usize,
|
||||
index:binary::unpack_natural(data, index) as usize,
|
||||
});
|
||||
}
|
||||
|
||||
for header in headers {
|
||||
for i in 0..header.length {
|
||||
match if unsafe {type_key(inner)} == types::TYPE_VAR {
|
||||
decode(data, index)
|
||||
} else {
|
||||
decode_data(data, inner, index)
|
||||
} {
|
||||
Ok(data) => {
|
||||
result.set(header.start + i, data.get());
|
||||
}
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Object::Sparse(result));
|
||||
}
|
||||
types::TYPE_RECORD => {
|
||||
return match Record::new(unsafe {type_innerkey(type_id)}) {
|
||||
Ok(mut value) => {
|
||||
for i in 0..value.length() {
|
||||
match decode_data(data, value.kindof(i), index) {
|
||||
Ok(refer) => {
|
||||
value.set_at(i, refer.get());
|
||||
}
|
||||
Err(_) => return Err(())
|
||||
}
|
||||
}
|
||||
Ok(Object::Record(value))
|
||||
}
|
||||
Err(_) => Err(()),
|
||||
}
|
||||
}
|
||||
types::TYPE_SCHEMA => {
|
||||
let mut result = Schema::new();
|
||||
|
||||
let length = binary::unpack_natural(data, index) as usize;
|
||||
|
||||
for _ in 0..length {
|
||||
let class :usize;
|
||||
match decode_tag(data, index) {
|
||||
Ok(tag) => { class = tag; }
|
||||
Err(_) => { return Err(()); }
|
||||
}
|
||||
|
||||
let key_length = binary::unpack_natural(data, index) as usize;
|
||||
let mut key_bytes = Vec::<u8>::with_capacity(key_length);
|
||||
for _ in 0..key_length {
|
||||
if *index < data.len() {
|
||||
key_bytes.push(data[*index]);
|
||||
*index += 1;
|
||||
}
|
||||
else {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
let key = String::from_utf8(key_bytes).unwrap();
|
||||
|
||||
result.assign(&key, class);
|
||||
}
|
||||
|
||||
return Ok(Any::__from_ref(result));
|
||||
}*/
|
||||
_ => { panic!("szun decode not implemented"); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode(data:&Vec<u8>, index:&mut usize) -> Result<Any,()>
|
||||
{
|
||||
return match decode_tag(data, index) {
|
||||
Ok(type_id) => decode_data(data, type_id, index),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
type_inner, type_key,
|
||||
acquire, release,
|
||||
array_length, array_at, array_update
|
||||
};
|
||||
use crate::tag;
|
||||
use super::array;
|
||||
|
||||
/// Constant-sized, indexed, ordered collection.
|
||||
pub struct Array {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Array {
|
||||
/// Allocates a new array of a given size and type.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `length` - number of elements in the array
|
||||
/// * `class` - type identifier of the array contents
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// // Produces an array of 8 integers.
|
||||
/// let int_array = szun::Array::new(8, szun::integer());
|
||||
/// ```
|
||||
pub fn new(length:usize, class:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(array(length, class))},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(length:usize, class:usize, data:Vec<Reference>) -> Self
|
||||
{
|
||||
let mut obj = Self::new(length, class);
|
||||
for i in 0..usize::min(length, data.len()) {
|
||||
obj.set(i, data[i]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {array_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe { array_update(self.addr, index, source); }
|
||||
}
|
||||
|
||||
pub fn at(&self, index:usize) -> Reference
|
||||
{
|
||||
unsafe {array_at(self.addr, index)}
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> usize
|
||||
{
|
||||
unsafe {type_inner(self.addr.class)}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Array {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::ARRAY) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Array {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Array {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_inner, type_key,
|
||||
block_length,
|
||||
block_set, block_get,
|
||||
block_set_natural, block_get_natural,
|
||||
block_set_integer, block_get_integer,
|
||||
block_set_field, block_get_field,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::block;
|
||||
|
||||
pub struct Block {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Block {
|
||||
pub fn new(size:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(block(size))},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(size:usize, data:Vec<u8>) -> Self
|
||||
{
|
||||
let mut obj = Self::new(size);
|
||||
obj.set(data);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn size(&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))};
|
||||
for index in 0..usize::min(data.len(), length) {
|
||||
unsafe {block_set(self.addr, index, data[index])};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_u64(&self, data:u64)
|
||||
{
|
||||
unsafe {block_set_natural(self.addr, data)}
|
||||
}
|
||||
|
||||
pub fn set_i64(&self, data:i64)
|
||||
{
|
||||
unsafe {block_set_integer(self.addr, data)}
|
||||
}
|
||||
|
||||
pub fn set_field(&mut self, index:usize, length:usize, data:u64)
|
||||
{
|
||||
unsafe { block_set_field(self.addr, index, length, data); }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Vec<u8>
|
||||
{
|
||||
let mut result = Vec::<u8>::new();
|
||||
let length = unsafe {type_key(type_inner(self.addr.class))};
|
||||
if length > 0 {
|
||||
result.resize(length, 0);
|
||||
for index in 0..length {
|
||||
result[index] = unsafe {block_get(self.addr, index)};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn get_u64(&self) -> u64
|
||||
{
|
||||
unsafe {block_get_natural(self.addr)}
|
||||
}
|
||||
|
||||
pub fn get_i64(&self) -> i64
|
||||
{
|
||||
unsafe {block_get_integer(self.addr)}
|
||||
}
|
||||
|
||||
pub fn get_field(&self, index:usize, length:usize) -> u64
|
||||
{
|
||||
unsafe {block_get_field(self.addr, index, length)}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Block {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::BLOCK) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Block {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Block {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
bool_get, bool_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::boolean;
|
||||
|
||||
pub struct Boolean {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Boolean {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(boolean())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:bool) -> Self
|
||||
{
|
||||
let mut result = Self::new();
|
||||
result.set(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value:bool)
|
||||
{
|
||||
unsafe { bool_set(self.addr, value) };
|
||||
}
|
||||
|
||||
pub fn get(&self) -> bool
|
||||
{
|
||||
unsafe { bool_get(self.addr) }
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Boolean {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::BOOLEAN) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Boolean {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Boolean {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
||||
impl Into<bool> for Boolean {
|
||||
fn into(self) -> bool {
|
||||
self.get()
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
use crate::tag;
|
||||
use crate::runtime;
|
||||
|
||||
pub fn inner(type_id:usize) -> usize { unsafe {runtime::type_inner(type_id)} }
|
||||
pub fn kind(type_id:usize) -> usize { unsafe {runtime::type_key(type_id)} }
|
||||
|
||||
pub fn null() -> usize { 0 }
|
||||
pub fn varying() -> usize { unsafe { runtime::type_outer(0, tag::VARYING) } }
|
||||
pub fn boolean() -> usize { unsafe { runtime::type_outer(0, tag::BOOLEAN) } }
|
||||
pub fn natural() -> usize { unsafe { runtime::type_outer(0, tag::NATURAL) } }
|
||||
pub fn integer() -> usize { unsafe { runtime::type_outer(0, tag::INTEGER) } }
|
||||
pub fn significant() -> usize { unsafe { runtime::type_outer(0, tag::SIGNIFICANT) } }
|
||||
|
||||
pub fn decimal(mantissa:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(0, mantissa);
|
||||
runtime::type_outer(inner_node, tag::DECIMAL)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block(size:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(0, size);
|
||||
runtime::type_outer(inner_node, tag::BLOCK)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sequence() -> usize { unsafe { runtime::type_outer(0, tag::SEQUENCE) } }
|
||||
|
||||
pub fn array(size:usize, type_id:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(type_id, size);
|
||||
runtime::type_outer(inner_node, tag::ARRAY)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn list(type_id:usize) -> usize { unsafe { runtime::type_outer(type_id, tag::LIST) } }
|
||||
pub fn sparse(type_id:usize) -> usize { unsafe { runtime::type_outer(type_id, tag::SPARSE) } }
|
||||
|
||||
pub fn record(schema_id:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(0, schema_id);
|
||||
runtime::type_outer(inner_node, tag::RECORD)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn schema() -> usize { unsafe { runtime::type_outer(0, tag::SCHEMA) } }
|
@ -1,228 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
decimal_get, decimal_set, type_innerkey,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::decimal;
|
||||
|
||||
pub struct Decimal {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Decimal {
|
||||
pub fn new(mantissa:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(decimal(mantissa))},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_raw(mantissa:usize, data:i64) -> Self
|
||||
{
|
||||
let mut obj = Self::new(mantissa);
|
||||
obj.set_raw(data);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn with(mantissa:usize, value:f64) -> Self
|
||||
{
|
||||
let mut obj = Self::new(mantissa);
|
||||
obj.set(value);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn copy(&self) -> Self
|
||||
{
|
||||
Decimal::try_from(self.addr).unwrap()
|
||||
}
|
||||
|
||||
pub fn set_raw(&mut self, data:i64)
|
||||
{
|
||||
unsafe { decimal_set(self.addr, data) };
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value:f64)
|
||||
{
|
||||
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||
let whole = value as i64;
|
||||
let decimal = ((value - value.trunc()).abs() * (1i64 << mantissa) as f64).floor() as i64;
|
||||
let data = (whole << mantissa) + (decimal as i64);
|
||||
self.set_raw(data);
|
||||
}
|
||||
|
||||
pub fn get_raw(&self) -> i64
|
||||
{
|
||||
unsafe {decimal_get(self.addr)}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> f64
|
||||
{
|
||||
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||
let data = self.get_raw();
|
||||
(data >> mantissa) as f64 + ((data & ((1i64 << mantissa) - 1)) as f64 / (1i64 << mantissa) as f64)
|
||||
}
|
||||
|
||||
fn rebase(to:usize, from:usize, data:i64) -> i64
|
||||
{
|
||||
return if to > from {
|
||||
data << (to - from) as i64
|
||||
} else if to < from {
|
||||
data >> (from - to) as i64
|
||||
} else { data }
|
||||
}
|
||||
|
||||
pub fn to_base(&self, mantissa:usize) -> Self
|
||||
{
|
||||
let mut result = Decimal::new(mantissa);
|
||||
result.set_raw(Self::rebase(mantissa, self.mantissa(), self.get_raw()));
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn mantissa(&self) -> usize
|
||||
{
|
||||
unsafe {type_innerkey(self.addr.class)}
|
||||
}
|
||||
}
|
||||
impl Clone for Decimal {
|
||||
fn clone(&self) -> Self {
|
||||
Decimal::with_raw(self.mantissa(), self.get_raw())
|
||||
}
|
||||
}
|
||||
impl std::ops::Add for Decimal {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
Decimal::with_raw(lhe, lhd + rhd)
|
||||
}
|
||||
}
|
||||
impl std::ops::AddAssign for Decimal {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
self.set_raw(lhd + rhd);
|
||||
}
|
||||
}
|
||||
impl std::ops::Sub for Decimal {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
Decimal::with_raw(lhe, lhd - rhd)
|
||||
}
|
||||
}
|
||||
impl std::ops::SubAssign for Decimal {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
self.set_raw(lhd - rhd);
|
||||
}
|
||||
}
|
||||
impl std::ops::Mul for Decimal {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
Decimal::with_raw(lhe, ((lhd as i128 * rhd as i128) >> lhe) as i64)
|
||||
}
|
||||
}
|
||||
impl std::ops::MulAssign for Decimal {
|
||||
fn mul_assign(&mut self, rhs: Self) {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
self.set_raw(((lhd as i128 * rhd as i128) >> lhe) as i64);
|
||||
}
|
||||
}
|
||||
impl std::ops::Div for Decimal {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: Self) -> Self::Output {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
Decimal::with_raw(lhe, ((lhd as i128 * (1i64 << lhe) as i128) / rhd as i128) as i64)
|
||||
}
|
||||
}
|
||||
impl std::ops::DivAssign for Decimal {
|
||||
fn div_assign(&mut self, rhs: Self) {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
self.set_raw(((lhd as i128 * (1i64 << lhe) as i128) / rhd as i128) as i64);
|
||||
}
|
||||
}
|
||||
impl std::ops::Rem for Decimal {
|
||||
type Output = Self;
|
||||
fn rem(self, rhs: Self) -> Self::Output {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
Decimal::with_raw(lhe, (lhd as i128 % rhd as i128) as i64)
|
||||
}
|
||||
}
|
||||
impl std::ops::RemAssign for Decimal {
|
||||
fn rem_assign(&mut self, rhs: Self) {
|
||||
let lhe = unsafe {type_innerkey(self.addr.class)};
|
||||
let rhe = unsafe {type_innerkey(rhs.addr.class)};
|
||||
let lhd = self.get_raw();
|
||||
let rhd = Self::rebase(lhe, rhe, rhs.get_raw());
|
||||
|
||||
self.set_raw(((lhd as i128 * (1i64 << lhe) as i128) % rhd as i128) as i64);
|
||||
}
|
||||
}
|
||||
impl std::ops::Neg for Decimal {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self::Output {
|
||||
let mantissa = unsafe {type_innerkey(self.addr.class)};
|
||||
Decimal::with_raw(mantissa, -self.get_raw())
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Decimal {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Decimal {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
||||
impl TryFrom<Reference> for Decimal {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::DECIMAL) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Into<f64> for Decimal {
|
||||
fn into(self) -> f64 {
|
||||
self.get()
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
integer_get, integer_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::integer;
|
||||
|
||||
pub struct Integer {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Integer {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(integer())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:i64) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
obj.set(value);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value:i64)
|
||||
{
|
||||
unsafe { integer_set(self.addr, value) };
|
||||
}
|
||||
|
||||
pub fn get(&self) -> i64
|
||||
{
|
||||
unsafe { integer_get(self.addr) }
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Integer {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::INTEGER) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Integer {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Integer {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
||||
|
@ -1,118 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_inner, type_key,
|
||||
list_capacity, list_length,
|
||||
list_at,
|
||||
list_clear,
|
||||
list_insert, list_prepend, list_append, list_update,
|
||||
list_remove,
|
||||
list_reserve,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::list;
|
||||
|
||||
pub struct List {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl List {
|
||||
pub fn new(type_id:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(list(type_id))},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(type_id:usize, data:Vec<Reference>) -> Self
|
||||
{
|
||||
let mut obj = Self::new(type_id);
|
||||
for item in data {
|
||||
obj.insert(obj.length(), item);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize
|
||||
{
|
||||
unsafe {list_capacity(self.addr)}
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {list_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn at(&self, index:usize) -> Reference
|
||||
{
|
||||
unsafe {list_at(self.addr, index)}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Vec<Reference>
|
||||
{
|
||||
let mut result = Vec::<Reference>::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)};
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe{list_insert(self.addr, index, source)};
|
||||
}
|
||||
|
||||
pub fn prepend(&mut self, source:Reference)
|
||||
{
|
||||
unsafe{list_prepend(self.addr, source)};
|
||||
}
|
||||
|
||||
pub fn append(&mut self, source:Reference)
|
||||
{
|
||||
unsafe{list_append(self.addr, source)};
|
||||
}
|
||||
|
||||
pub fn set(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe{list_update(self.addr, index, source)};
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index:usize)
|
||||
{
|
||||
unsafe{list_remove(self.addr, index)};
|
||||
}
|
||||
|
||||
pub fn reserve(&mut self, length:usize)
|
||||
{
|
||||
unsafe{list_reserve(self.addr, length)};
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> usize
|
||||
{
|
||||
unsafe {type_inner(self.addr.class)}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for List {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::LIST) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for List {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for List {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
use crate::runtime::{Reference, type_key};
|
||||
use crate::tag;
|
||||
|
||||
mod builder; pub use builder::*;
|
||||
mod util; pub use util::*;
|
||||
|
||||
mod varying; pub use varying::Varying;
|
||||
mod boolean; pub use boolean::Boolean;
|
||||
mod natural; pub use natural::Natural;
|
||||
mod integer; pub use integer::Integer;
|
||||
mod decimal; pub use decimal::Decimal;
|
||||
mod signficant; pub use signficant::Significant;
|
||||
mod block; pub use block::Block;
|
||||
mod sequence; pub use sequence::Sequence;
|
||||
mod array; pub use array::Array;
|
||||
mod list; pub use list::List;
|
||||
mod sparse; pub use sparse::Sparse;
|
||||
mod schema; pub use schema::Schema;
|
||||
mod record; pub use record::Record;
|
||||
|
||||
pub enum Object {
|
||||
Null,
|
||||
Varying(Varying),
|
||||
Boolean(Boolean),
|
||||
Natural(Natural),
|
||||
Integer(Integer),
|
||||
Decimal(Decimal),
|
||||
Significant(Significant),
|
||||
Block(Block),
|
||||
Sequence(Sequence),
|
||||
Array(Array),
|
||||
List(List),
|
||||
Sparse(Sparse),
|
||||
Record(Record),
|
||||
Schema(Schema),
|
||||
}
|
||||
impl Object {
|
||||
pub fn from(addr:Reference) -> Self
|
||||
{
|
||||
match unsafe {type_key(addr.class)} {
|
||||
tag::NULL => Object::Null,
|
||||
tag::VARYING => Object::Varying(Varying::try_from(addr).unwrap()),
|
||||
tag::BOOLEAN => Object::Boolean(Boolean::try_from(addr).unwrap()),
|
||||
tag::NATURAL => Object::Natural(Natural::try_from(addr).unwrap()),
|
||||
tag::INTEGER => Object::Integer(Integer::try_from(addr).unwrap()),
|
||||
tag::DECIMAL => Object::Decimal(Decimal::try_from(addr).unwrap()),
|
||||
tag::SIGNIFICANT => Object::Significant(Significant::try_from(addr).unwrap()),
|
||||
tag::BLOCK => Object::Block(Block::try_from(addr).unwrap()),
|
||||
tag::SEQUENCE => Object::Sequence(Sequence::try_from(addr).unwrap()),
|
||||
tag::ARRAY => Object::Array(Array::try_from(addr).unwrap()),
|
||||
tag::LIST => Object::List(List::try_from(addr).unwrap()),
|
||||
tag::SPARSE => Object::Sparse(Sparse::try_from(addr).unwrap()),
|
||||
tag::RECORD => Object::Record(Record::try_from(addr).unwrap()),
|
||||
_ => Object::Null,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Reference
|
||||
{
|
||||
match &self {
|
||||
Object::Varying(obj) => **obj,
|
||||
Object::Boolean(obj) => **obj,
|
||||
Object::Natural(obj) => **obj,
|
||||
Object::Integer(obj) => **obj,
|
||||
Object::Decimal(obj) => **obj,
|
||||
Object::Significant(obj) => **obj,
|
||||
Object::Block(obj) => **obj,
|
||||
Object::Sequence(obj) => **obj,
|
||||
Object::Array(obj) => **obj,
|
||||
Object::List(obj) => **obj,
|
||||
Object::Sparse(obj) => **obj,
|
||||
Object::Record(obj) => **obj,
|
||||
_ => Reference::null(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
natural_get, natural_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::natural;
|
||||
|
||||
pub struct Natural {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Natural {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(natural())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:u64) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
obj.set(value);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value:u64)
|
||||
{
|
||||
unsafe { natural_set(self.addr, value) };
|
||||
}
|
||||
|
||||
pub fn get(&self) -> u64
|
||||
{
|
||||
unsafe { natural_get(self.addr) }
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Natural {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::NATURAL) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Natural {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Natural {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
use crate::runtime::{
|
||||
util::{name_indexof, name_keyof},
|
||||
Reference,
|
||||
acquire, release,
|
||||
schema_has,
|
||||
type_key,
|
||||
record_length,
|
||||
record_at, record_update,
|
||||
record_indexof, record_keyof,
|
||||
record_type,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::record;
|
||||
|
||||
pub struct Record {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Record {
|
||||
pub fn new(schema:usize) -> Result<Self,()>
|
||||
{
|
||||
if unsafe {schema_has(schema)} {
|
||||
Ok(Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(record(schema))},
|
||||
})
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(schema:usize, data:Vec<(&str, Reference)>) -> Result<Self,()>
|
||||
{
|
||||
match Self::new(schema) {
|
||||
Ok(mut obj) => {
|
||||
for (key, value) in data {
|
||||
obj.set(key, value);
|
||||
}
|
||||
Ok(obj)
|
||||
}
|
||||
Err(_) => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_values(schema:usize, data:Vec<Reference>) -> Result<Self,()>
|
||||
{
|
||||
match Self::new(schema) {
|
||||
Ok(mut obj) => {
|
||||
for index in 0..data.len() {
|
||||
obj.set_at(index, data[index]);
|
||||
}
|
||||
Ok(obj)
|
||||
}
|
||||
Err(_) => Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {record_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn set_at(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe { record_update(self.addr, index, source); }
|
||||
}
|
||||
|
||||
pub fn set(&mut self, key:&str, source:Reference)
|
||||
{
|
||||
match self.indexof(key) {
|
||||
Some(index) => {
|
||||
unsafe { record_update(self.addr, index, source); }
|
||||
}
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn at(&self, index:usize) -> Reference
|
||||
{
|
||||
unsafe {record_at(self.addr, index)}
|
||||
}
|
||||
|
||||
pub fn get(&self, key:&str) -> Reference
|
||||
{
|
||||
match self.indexof(key) {
|
||||
Some(index) => {
|
||||
unsafe {record_at(self.addr, index)}
|
||||
}
|
||||
None => Reference::null()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indexof(&self, key:&str) -> Option<usize>
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
let result = unsafe {record_indexof(self.addr, key_index)};
|
||||
if result != self.length() {
|
||||
Some(result)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn keyof(&self, index:usize) -> Option<String>
|
||||
{
|
||||
let result = unsafe {record_keyof(self.addr, index)};
|
||||
if result != 0 {
|
||||
Some(name_keyof(result))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kindof(&self, index:usize) -> usize
|
||||
{
|
||||
unsafe {record_type(self.addr, index)}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Record {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::RECORD) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Record {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Record {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
use crate::runtime::{
|
||||
util::{name_indexof, name_keyof},
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
schema_length,
|
||||
schema_insert, schema_update, schema_get,
|
||||
schema_remove, schema_clear,
|
||||
schema_map, schema_unmap, schema_indexof, schema_keyof,
|
||||
schema_bind,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::schema;
|
||||
|
||||
pub struct Schema {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Schema {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(schema())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(members:Vec<(&str, usize)>) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
for binding in members {
|
||||
let (key, type_id) = binding;
|
||||
obj.assign(key, type_id);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
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)}
|
||||
}
|
||||
|
||||
pub fn assign(&mut self, key:&str, type_id:usize)
|
||||
{
|
||||
if key.len() > 0 {
|
||||
let key_index = name_indexof(key);
|
||||
unsafe {
|
||||
schema_map(
|
||||
self.addr,
|
||||
key_index,
|
||||
schema_insert(self.addr, usize::MAX, type_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.add(type_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, index:usize, type_id:usize)
|
||||
{
|
||||
unsafe { schema_update(self.addr, index, type_id); }
|
||||
}
|
||||
|
||||
pub fn get(&self, index:usize) -> Option<usize>
|
||||
{
|
||||
match unsafe {schema_get(self.addr, index)} {
|
||||
0 => None,
|
||||
value => Some(value),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index:usize)
|
||||
{
|
||||
unsafe { schema_remove(self.addr, index); }
|
||||
}
|
||||
|
||||
pub fn map(&mut self, key:&str, index:usize)
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
unsafe { schema_map(self.addr, key_index, index); }
|
||||
}
|
||||
|
||||
pub fn unmap(&mut self, key:&str)
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
unsafe { schema_unmap(self.addr, key_index); }
|
||||
}
|
||||
|
||||
pub fn indexof(&self, key:&str) -> Option<usize>
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
let result = unsafe {schema_indexof(self.addr, key_index)};
|
||||
if result != self.length() {
|
||||
Some(result)
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn keyof(&self, index:usize) -> Option<String>
|
||||
{
|
||||
let result = unsafe {schema_keyof(self.addr, index)};
|
||||
if result != 0 {
|
||||
Some(name_keyof(result))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind(&self, id:usize) -> usize
|
||||
{
|
||||
unsafe {schema_bind(self.addr, id)}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Schema {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::SCHEMA) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Schema {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Schema {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
sequence_capacity, sequence_length,
|
||||
sequence_clear, sequence_reserve,
|
||||
sequence_get,
|
||||
sequence_insert, sequence_set,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::sequence;
|
||||
|
||||
pub struct Sequence {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Sequence {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(sequence())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_raw(data:Vec<u8>) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
obj.set_raw(data);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn with(data:&str) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
obj.set(data);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize
|
||||
{
|
||||
unsafe {sequence_capacity(self.addr)}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize
|
||||
{
|
||||
unsafe {sequence_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn set_at(&mut self, index:usize, value:u8)
|
||||
{
|
||||
unsafe { sequence_set(self.addr, index, value); }
|
||||
}
|
||||
|
||||
pub fn set_raw(&mut self, data:Vec<u8>)
|
||||
{
|
||||
unsafe { sequence_clear(self.addr); }
|
||||
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 set(&mut self, data:&str)
|
||||
{
|
||||
self.set_raw(Vec::from(data.as_bytes()));
|
||||
}
|
||||
|
||||
pub fn get_at(&self, index:usize) -> u8
|
||||
{
|
||||
unsafe {sequence_get(self.addr, index)}
|
||||
}
|
||||
|
||||
pub fn get_raw(&self) -> Vec<u8>
|
||||
{
|
||||
let length = unsafe {sequence_length(self.addr)};
|
||||
let mut result = Vec::<u8>::new();
|
||||
|
||||
if length > 0 {
|
||||
result.reserve_exact(length);
|
||||
for i in 0..length {
|
||||
result.push(unsafe {sequence_get(self.addr, i)});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn get(&self) -> String
|
||||
{
|
||||
match String::from_utf8(self.get_raw()) {
|
||||
Ok(s) => s,
|
||||
Err(_) => String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Sequence {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::SEQUENCE) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Sequence {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Sequence {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
significant_get, significant_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::significant;
|
||||
|
||||
pub struct Significant {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Significant {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(significant())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:f64) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
obj.set(value);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value:f64)
|
||||
{
|
||||
unsafe { significant_set(self.addr, value) };
|
||||
}
|
||||
|
||||
pub fn get(&self) -> f64
|
||||
{
|
||||
unsafe { significant_get(self.addr) }
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Significant {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::SIGNIFICANT) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Significant {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Significant {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_inner, type_key,
|
||||
sparse_length,
|
||||
sparse_first, sparse_next, sparse_last,
|
||||
sparse_at, sparse_get,
|
||||
sparse_clear,
|
||||
sparse_set, sparse_unset,
|
||||
sparse_indexof,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::sparse;
|
||||
|
||||
pub struct Sparse {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Sparse {
|
||||
pub fn new(class:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(sparse(class))},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(class:usize, data:Vec<(usize, Reference)>) -> Self
|
||||
{
|
||||
let mut obj = Self::new(class);
|
||||
for (key, item) in data {
|
||||
obj.set(key, item);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {sparse_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn first(&self) -> usize
|
||||
{
|
||||
unsafe {sparse_first(self.addr)}
|
||||
}
|
||||
|
||||
pub fn next(&self) -> usize
|
||||
{
|
||||
unsafe {sparse_next(self.addr)}
|
||||
}
|
||||
|
||||
pub fn last(&self) -> usize
|
||||
{
|
||||
unsafe {sparse_last(self.addr)}
|
||||
}
|
||||
|
||||
pub fn at(&self, index:usize) -> Reference
|
||||
{
|
||||
unsafe {sparse_at(self.addr, index)}
|
||||
}
|
||||
|
||||
pub fn has(&self, key:usize) -> bool
|
||||
{
|
||||
unsafe {sparse_get(self.addr, key)}.address != 0
|
||||
}
|
||||
|
||||
pub fn get(&self, key:usize) -> Reference
|
||||
{
|
||||
unsafe {sparse_get(self.addr, key)}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
unsafe{sparse_clear(self.addr)};
|
||||
}
|
||||
|
||||
pub fn set(&mut self, key:usize, source:Reference)
|
||||
{
|
||||
unsafe{sparse_set(self.addr, key, source)};
|
||||
}
|
||||
|
||||
pub fn unset(&mut self, key:usize)
|
||||
{
|
||||
unsafe{sparse_unset(self.addr, key)};
|
||||
}
|
||||
|
||||
pub fn indexof(&self, index:usize) -> usize
|
||||
{
|
||||
unsafe{sparse_indexof(self.addr, index)}
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> usize
|
||||
{
|
||||
unsafe {type_inner(self.addr.class)}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Sparse {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::SPARSE) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Sparse {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Sparse {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
use crate::runtime;
|
||||
|
||||
pub fn acquire(type_id:usize) -> runtime::Reference
|
||||
{
|
||||
unsafe {runtime::acquire(type_id)}
|
||||
}
|
||||
|
||||
pub fn release(addr:runtime::Reference)
|
||||
{
|
||||
unsafe {runtime::release(addr)}
|
||||
}
|
||||
|
||||
pub fn copy(dst:runtime::Reference, src:runtime::Reference) -> Result<(),()>
|
||||
{
|
||||
if unsafe {runtime::copy(dst, src)} { Ok(()) }
|
||||
else { Err(()) }
|
||||
}
|
||||
|
||||
pub fn transfer(dst:runtime::Reference, src:runtime::Reference) -> Result<(),()>
|
||||
{
|
||||
if unsafe {runtime::transfer(dst, src)} { Ok(()) }
|
||||
else { Err(()) }
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
varying_get, varying_set,
|
||||
varying_clear,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::varying;
|
||||
|
||||
pub struct Varying {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Varying {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(varying())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(addr:Reference) -> Self
|
||||
{
|
||||
let mut obj = Varying::new();
|
||||
obj.set(addr);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn is_null(&self) -> bool
|
||||
{
|
||||
(unsafe {varying_get(self.addr)}).address == 0
|
||||
}
|
||||
|
||||
pub fn set(&mut self, source:Reference)
|
||||
{
|
||||
unsafe { varying_set(self.addr, source); }
|
||||
}
|
||||
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
unsafe { varying_clear(self.addr); }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Reference
|
||||
{
|
||||
unsafe { varying_get(self.addr) }
|
||||
}
|
||||
|
||||
pub fn kindof(&self) -> usize
|
||||
{
|
||||
unsafe {varying_get(self.addr).class}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Reference> for Varying {
|
||||
type Error = ();
|
||||
fn try_from(addr:Reference) -> Result<Self, Self::Error> {
|
||||
return if(unsafe {type_key(addr.class)} == tag::VARYING) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Varying {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Varying {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
32
src/interface/any.rs
Normal file
32
src/interface/any.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use crate::{
|
||||
prelude::*,
|
||||
runtime,
|
||||
Var,
|
||||
};
|
||||
|
||||
pub struct Any {
|
||||
address:Ref,
|
||||
}
|
||||
impl Any {
|
||||
pub fn type_id(&self) -> usize { self.address.type_id() }
|
||||
}
|
||||
impl SzunType for Any {
|
||||
fn type_id() -> usize { Var::type_id() }
|
||||
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
impl Clone for Any {
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl Drop for Any {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
use std::marker::PhantomData;
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer, type_key,
|
||||
clone,
|
||||
array_set, array_at,
|
||||
},
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
Any,
|
||||
};
|
||||
|
||||
pub struct Array<const N :usize, T: SzunType> {
|
||||
@ -16,19 +13,19 @@ pub struct Array<const N :usize, T: SzunType> {
|
||||
impl<const N :usize, T: SzunType> Array<N,T> {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {acquire(Self::type_id())}, _data:PhantomData }
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())}, _data:PhantomData }
|
||||
}
|
||||
|
||||
pub fn set<D: SzunType>(&mut self, index:usize, data:&D)
|
||||
{
|
||||
if self.compatible(data) {
|
||||
unsafe {array_set(self.address.clone(), index, data.__to_ref())};
|
||||
unsafe {runtime::array_set(self.address.clone(), index, data.__to_ref())};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, index:usize) -> T
|
||||
{
|
||||
let refr = unsafe {array_at(self.address.clone(), index)};
|
||||
let refr = unsafe {runtime::array_at(self.address.clone(), index)};
|
||||
if refr.is_some() {
|
||||
T::__from_ref(refr)
|
||||
} else { panic!("array index out of bounds"); }
|
||||
@ -40,39 +37,39 @@ impl<const N :usize, T: SzunType> Array<N,T> {
|
||||
}
|
||||
}
|
||||
impl<const N :usize, T: SzunType> SzunType for Array<N,T> {
|
||||
fn type_id() -> usize {
|
||||
let inner = unsafe {type_outer(T::type_id(), N)};
|
||||
unsafe {type_outer(inner, types::TYPE_ARRAY)}
|
||||
fn type_id() -> usize
|
||||
{
|
||||
let inner = unsafe {runtime::type_outer(T::type_id(), N)};
|
||||
unsafe {runtime::type_outer(inner, types::TYPE_ARRAY)}
|
||||
}
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool {
|
||||
R::type_id() == T::type_id() || unsafe {type_key(T::type_id())} == types::TYPE_VARYING
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool
|
||||
{
|
||||
R::type_id() == T::type_id() || unsafe {runtime::type_key(T::type_id())} == types::TYPE_VAR
|
||||
}
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr, _data:PhantomData } }
|
||||
}
|
||||
|
||||
impl<const N :usize, T: SzunType> Clone for Array<N,T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())}, _data:PhantomData }
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N :usize, T: SzunType> TryFrom<Ref> for Array<N,T> {
|
||||
impl<const N :usize, T: SzunType> TryFrom<Any> for Array<N,T> {
|
||||
type Error = SzunError;
|
||||
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error> {
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr, _data:PhantomData })
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<const N :usize, T: SzunType> Into<Ref> for Array<N,T> { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl<const N :usize, T: SzunType> Into<Any> for Array<N,T> { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl<const N :usize, T: SzunType> Drop for Array<N,T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,6 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer,
|
||||
clone,
|
||||
block_set, block_get,
|
||||
},
|
||||
runtime,
|
||||
};
|
||||
|
||||
pub struct Block<const N :usize> {
|
||||
@ -14,7 +9,7 @@ pub struct Block<const N :usize> {
|
||||
impl<const N :usize> Block<N> {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {acquire(Self::type_id())} }
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
|
||||
pub fn with(mut self, data:&[u8; N]) -> Self
|
||||
@ -26,7 +21,7 @@ impl<const N :usize> Block<N> {
|
||||
pub fn set(&mut self, data:&[u8; N])
|
||||
{
|
||||
for i in 0..data.len() {
|
||||
unsafe {block_set(self.address.clone(), i, data[i])};
|
||||
unsafe {runtime::block_set(self.address.clone(), i, data[i])};
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,19 +29,19 @@ impl<const N :usize> Block<N> {
|
||||
{
|
||||
let mut data = [0; N];
|
||||
for i in 0..data.len() {
|
||||
data[i] = unsafe {block_get(self.address.clone(), i)};
|
||||
data[i] = unsafe {runtime::block_get(self.address.clone(), i)};
|
||||
}
|
||||
data
|
||||
}
|
||||
|
||||
pub fn set_at(&mut self, index:usize, data:u8)
|
||||
{
|
||||
unsafe {block_set(self.address.clone(), index, data)}
|
||||
unsafe {runtime::block_set(self.address.clone(), index, data)}
|
||||
}
|
||||
|
||||
pub fn get_at(&self, index:usize) -> u8
|
||||
{
|
||||
unsafe {block_get(self.address.clone(), index)}
|
||||
unsafe {runtime::block_get(self.address.clone(), index)}
|
||||
}
|
||||
|
||||
pub fn set_unsigned<T: num::Num + num::NumCast>(&mut self, data:T)
|
||||
@ -54,7 +49,7 @@ impl<const N :usize> Block<N> {
|
||||
let mut value :u128 = num::NumCast::from(data).unwrap();
|
||||
let n = N - 1;
|
||||
for i in 0..N {
|
||||
unsafe {block_set(self.address.clone(), n - i, (value & 0xFF) as u8)};
|
||||
unsafe {runtime::block_set(self.address.clone(), n - i, (value & 0xFF) as u8)};
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
@ -64,53 +59,64 @@ impl<const N :usize> Block<N> {
|
||||
let mut value :u128 = 0;
|
||||
for i in 0..N {
|
||||
value <<= 8;
|
||||
value |= unsafe {block_get(self.address.clone(), i)} as u128;
|
||||
value |= unsafe {runtime::block_get(self.address.clone(), i)} as u128;
|
||||
}
|
||||
num::NumCast::from(value).unwrap()
|
||||
}
|
||||
|
||||
pub fn set_bits(&mut self, _index:usize, _length:usize, _data:usize)
|
||||
{
|
||||
panic!("block.set_bits not implemented");
|
||||
//unsafe {block_set_bits(self.address.clone(), index, length, data)}
|
||||
}
|
||||
|
||||
pub fn get_bits(&self, _index:usize, _length:usize) -> usize
|
||||
{
|
||||
panic!("block.get_bits not implemented");
|
||||
//unsafe {block_get_bits(self.address.clone(), index, length)}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
N
|
||||
}
|
||||
}
|
||||
impl<const N :usize> SzunType for Block<N> {
|
||||
fn type_id() -> usize {
|
||||
let inner = unsafe {type_outer(0, N)};
|
||||
unsafe {type_outer(inner, types::TYPE_BLOCK)}
|
||||
fn type_id() -> usize
|
||||
{
|
||||
let inner = unsafe {runtime::type_outer(0, N)};
|
||||
unsafe {runtime::type_outer(inner, types::TYPE_BLOCK)}
|
||||
}
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
impl<const N :usize> Clone for Block<N> {
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl<const N :usize> TryFrom<Any> for Block<N> {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<const N :usize> Into<Any> for Block<N> { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl<const N :usize> Drop for Block<N> {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block<const N :usize>(data:&[u8; N]) -> Block<N>
|
||||
{
|
||||
Block::new().with(data)
|
||||
}
|
||||
|
||||
impl<const N :usize> Clone for Block<N> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())} }
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N :usize> TryFrom<Ref> for Block<N> {
|
||||
type Error = SzunError;
|
||||
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error> {
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr })
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<const N :usize> Into<Ref> for Block<N> { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl<const N :usize> Drop for Block<N> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer,
|
||||
clone,
|
||||
bool_set, bool_get,
|
||||
},
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct Boolean {
|
||||
@ -14,7 +10,7 @@ pub struct Boolean {
|
||||
impl Boolean {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {acquire(Self::type_id())} }
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
|
||||
pub fn with(mut self, data:bool) -> Self
|
||||
@ -25,58 +21,57 @@ impl Boolean {
|
||||
|
||||
pub fn set(&mut self, data:bool)
|
||||
{
|
||||
unsafe {bool_set(self.address.clone(), data)}
|
||||
unsafe {runtime::bool_set(self.address.clone(), data)}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> bool
|
||||
{
|
||||
unsafe {bool_get(self.address.clone())}
|
||||
unsafe {runtime::bool_get(self.address.clone())}
|
||||
}
|
||||
}
|
||||
impl SzunType for Boolean {
|
||||
fn type_id() -> usize { unsafe {type_outer(0, types::TYPE_BOOLEAN)} }
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(0, types::TYPE_BOOLEAN)} }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
impl Clone for Boolean {
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl TryFrom<Any> for Boolean {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Any> for Boolean { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl Drop for Boolean {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn boolean(data:bool) -> Boolean
|
||||
{
|
||||
Boolean::from(data)
|
||||
}
|
||||
|
||||
impl Clone for Boolean {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())} }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Not for Boolean {
|
||||
type Output = Self;
|
||||
fn not(self) -> Self::Output {
|
||||
fn not(self) -> Self::Output
|
||||
{
|
||||
Self::from(!self.get())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Ref> for Boolean {
|
||||
type Error = SzunError;
|
||||
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error> {
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr })
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Ref> for Boolean { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl From<bool> for Boolean { fn from(value: bool) -> Self { Self::new().with(value) } }
|
||||
impl Into<bool> for Boolean { fn into(self) -> bool { self.get() } }
|
||||
|
||||
impl Drop for Boolean {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
23
src/interface/constant.rs
Normal file
23
src/interface/constant.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::{
|
||||
prelude::*,
|
||||
runtime::const_clone,
|
||||
};
|
||||
|
||||
pub struct Const<T: SzunType> {
|
||||
data:T,
|
||||
}
|
||||
impl<T: SzunType> Const<T> {
|
||||
pub fn from(data:&T) -> Self
|
||||
// Converts an object to a memory-continuous, fixed-size block.
|
||||
//
|
||||
{
|
||||
Self {
|
||||
data:T::__from_ref(unsafe {const_clone(data.__to_ref())}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &T
|
||||
{
|
||||
&self.data
|
||||
}
|
||||
}
|
@ -1,19 +1,16 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer,
|
||||
clone,
|
||||
integer_set, integer_get,
|
||||
},
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct Integer {
|
||||
address:Ref,
|
||||
}
|
||||
impl Integer {
|
||||
pub fn new() -> Self {
|
||||
Self { address:unsafe {acquire(Self::type_id())} }
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
|
||||
pub fn with<T: num::Num + num::NumCast>(mut self, data:T) -> Self
|
||||
@ -22,59 +19,60 @@ impl Integer {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set<T: num::Num + num::NumCast>(&mut self, data:T) {
|
||||
pub fn set<T: num::Num + num::NumCast>(&mut self, data:T)
|
||||
{
|
||||
match num::NumCast::from(data) {
|
||||
Some(data) => unsafe {integer_set(self.address.clone(), data)}
|
||||
Some(data) => unsafe {runtime::integer_set(self.address.clone(), data)}
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T: num::Num + num::NumCast>(&self) -> T {
|
||||
num::NumCast::from(unsafe {integer_get(self.address.clone())}).unwrap()
|
||||
pub fn get<T: num::Num + num::NumCast>(&self) -> T
|
||||
{
|
||||
num::NumCast::from(unsafe {runtime::integer_get(self.address.clone())}).unwrap()
|
||||
}
|
||||
}
|
||||
impl SzunType for Integer {
|
||||
fn type_id() -> usize { unsafe {type_outer(0, types::TYPE_INTEGER)} }
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(0, types::TYPE_INTEGER)} }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
|
||||
pub fn integer<T: num::Num + num::NumCast>(data:T) -> Integer
|
||||
{
|
||||
Integer::new().with(data)
|
||||
}
|
||||
|
||||
impl Clone for Integer {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())} }
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl TryFrom<Any> for Integer {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Any> for Integer { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl Drop for Integer {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Neg for Integer {
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self::Output {
|
||||
fn neg(self) -> Self::Output
|
||||
{
|
||||
Self::new().with(-self.get::<i64>())
|
||||
}
|
||||
}
|
||||
|
||||
crate::util::macros::impl_ops_numeric_all!(Integer, i64);
|
||||
|
||||
impl TryFrom<Ref> for Integer {
|
||||
type Error = SzunError;
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error> {
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr })
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Ref> for Integer { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl Drop for Integer {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
pub fn integer<T: num::Num + num::NumCast>(data:T) -> Integer
|
||||
{
|
||||
Integer::new().with(data)
|
||||
}
|
||||
|
@ -1,13 +1,8 @@
|
||||
use std::marker::PhantomData;
|
||||
use crate::{
|
||||
prelude::*, runtime::{
|
||||
acquire, release, clone,
|
||||
type_outer, type_key,
|
||||
list_reserve, list_clear,
|
||||
list_insert, list_push, list_pop,
|
||||
list_at, list_back, list_set,
|
||||
list_length, list_capacity,
|
||||
}, types
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct List<T: SzunType> {
|
||||
@ -15,33 +10,38 @@ pub struct List<T: SzunType> {
|
||||
_data:PhantomData<T>,
|
||||
}
|
||||
impl<T: SzunType> List<T> {
|
||||
pub fn new() -> Self {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
address:unsafe {acquire(Self::type_id())},
|
||||
address:unsafe {runtime::acquire(Self::type_id())},
|
||||
_data:PhantomData
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert<D: SzunType>(&mut self, index:usize, data:&D)
|
||||
{
|
||||
if index <= self.len() && self.compatible(data) {
|
||||
unsafe {list_insert(self.address.clone(), index, data.__to_ref())};
|
||||
if self.compatible(data) {
|
||||
unsafe {runtime::list_insert(self.address.clone(), index, data.__to_ref())};
|
||||
} else {
|
||||
panic!("szun mismatched type");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push<D: SzunType>(&mut self, data:&D)
|
||||
{
|
||||
if self.compatible(data) {
|
||||
unsafe {list_push(self.address.clone(), data.__to_ref())};
|
||||
unsafe {runtime::list_push(self.address.clone(), data.__to_ref())};
|
||||
} else {
|
||||
panic!("szun mismatched type");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<T>
|
||||
{
|
||||
let refr = unsafe {list_back(self.address.clone())};
|
||||
let refr = unsafe {runtime::list_back(self.address.clone())};
|
||||
if refr.is_some() {
|
||||
let result = Some(T::__from_ref(unsafe {clone(refr)}));
|
||||
unsafe {list_pop(self.address.clone())};
|
||||
let result = Some(T::__from_ref(unsafe {runtime::clone(refr)}));
|
||||
unsafe {runtime::list_pop(self.address.clone())};
|
||||
result
|
||||
} else { None }
|
||||
}
|
||||
@ -49,23 +49,25 @@ impl<T: SzunType> List<T> {
|
||||
pub fn set<D: SzunType>(&mut self, index:usize, data:&D)
|
||||
{
|
||||
if self.compatible(data) {
|
||||
unsafe {list_set(self.address.clone(), index, data.__to_ref())};
|
||||
unsafe {runtime::list_set(self.address.clone(), index, data.__to_ref())};
|
||||
} else {
|
||||
panic!("szun mismatched type");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
unsafe {list_clear(self.address.clone())};
|
||||
unsafe {runtime::list_clear(self.address.clone())};
|
||||
}
|
||||
|
||||
pub fn reserve(&mut self, length:usize)
|
||||
{
|
||||
unsafe {list_reserve(self.address.clone(), length)};
|
||||
unsafe {runtime::list_reserve(self.address.clone(), length)};
|
||||
}
|
||||
|
||||
pub fn get(&mut self, index:usize) -> T
|
||||
{
|
||||
let refr = unsafe {list_at(self.address.clone(), index)};
|
||||
let refr = unsafe {runtime::list_at(self.address.clone(), index)};
|
||||
if refr.is_some() {
|
||||
T::__from_ref(refr)
|
||||
} else { panic!("index out of bounds: {} / {}", index, self.len()) }
|
||||
@ -73,7 +75,7 @@ impl<T: SzunType> List<T> {
|
||||
|
||||
pub fn try_get(&mut self, index:usize) -> Option<T>
|
||||
{
|
||||
let refr = unsafe {list_at(self.address.clone(), index)};
|
||||
let refr = unsafe {runtime::list_at(self.address.clone(), index)};
|
||||
if refr.is_some() {
|
||||
Some(T::__from_ref(refr))
|
||||
} else { None }
|
||||
@ -81,48 +83,41 @@ impl<T: SzunType> List<T> {
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
unsafe {list_length(self.address.clone())}
|
||||
unsafe {runtime::list_length(self.address.clone())}
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize
|
||||
{
|
||||
unsafe {list_capacity(self.address.clone())}
|
||||
unsafe {runtime::list_capacity(self.address.clone())}
|
||||
}
|
||||
}
|
||||
impl<T: SzunType> SzunType for List<T> {
|
||||
fn type_id() -> usize {
|
||||
unsafe {type_outer(T::type_id(), types::TYPE_LIST)}
|
||||
fn type_id() -> usize
|
||||
{
|
||||
unsafe {runtime::type_outer(T::type_id(), types::TYPE_LIST)}
|
||||
}
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool {
|
||||
R::type_id() == T::type_id() || unsafe {type_key(T::type_id())} == types::TYPE_VARYING
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool
|
||||
{
|
||||
R::type_id() == T::type_id() || unsafe {runtime::type_key(T::type_id())} == types::TYPE_VAR
|
||||
}
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(address:Ref) -> Self { Self { address:address, _data:PhantomData } }
|
||||
}
|
||||
impl<T: SzunType> Clone for List<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self::new()
|
||||
}
|
||||
fn clone(&self) -> Self { Self::__from_ref(unsafe {runtime::clone(self.address.clone())}) }
|
||||
}
|
||||
|
||||
impl<T: SzunType> TryFrom<Ref> for List<T> {
|
||||
impl<T: SzunType> TryFrom<Any> for List<T> {
|
||||
type Error = SzunError;
|
||||
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error> {
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr, _data:PhantomData })
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<T: SzunType> Into<Ref> for List<T> {
|
||||
fn into(self) -> Ref { self.address.clone() }
|
||||
}
|
||||
|
||||
impl<T: SzunType> Into<Any> for List<T> { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl<T: SzunType> Drop for List<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
fn drop(&mut self) { unsafe {runtime::release(self.address.clone())}; }
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
mod any; pub use any::*;
|
||||
|
||||
mod null; pub use null::*;
|
||||
mod boolean; pub use boolean::*;
|
||||
|
||||
@ -10,3 +12,9 @@ mod sequence; pub use sequence::*;
|
||||
mod var; pub use var::*;
|
||||
mod array; pub use array::*;
|
||||
mod list; pub use list::*;
|
||||
mod sparse; pub use sparse::*;
|
||||
mod table; pub use table::*;
|
||||
|
||||
mod schema; pub use schema::*;
|
||||
|
||||
mod constant; pub use constant::*;
|
||||
|
@ -1,71 +1,67 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer,
|
||||
clone,
|
||||
natural_set, natural_get,
|
||||
},
|
||||
runtime,
|
||||
};
|
||||
|
||||
pub struct Natural {
|
||||
address:Ref,
|
||||
}
|
||||
impl Natural {
|
||||
pub fn new() -> Self {
|
||||
Self { address:unsafe {acquire(Self::type_id())} }
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
|
||||
pub fn with<T: num::Num + num::NumCast>(mut self, data:T) -> Self {
|
||||
pub fn with<T: num::Num + num::NumCast>(mut self, data:T) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set<T: num::Num + num::NumCast>(&mut self, data:T) {
|
||||
pub fn set<T: num::Num + num::NumCast>(&mut self, data:T)
|
||||
{
|
||||
match num::NumCast::from(data) {
|
||||
Some(data) => unsafe {natural_set(self.address.clone(), data)}
|
||||
Some(data) => unsafe {runtime::natural_set(self.address.clone(), data)}
|
||||
None => { }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T: num::Num + num::NumCast>(&self) -> T {
|
||||
num::NumCast::from(unsafe {natural_get(self.address.clone())}).unwrap()
|
||||
num::NumCast::from(unsafe {runtime::natural_get(self.address.clone())}).unwrap()
|
||||
}
|
||||
}
|
||||
impl SzunType for Natural {
|
||||
fn type_id() -> usize { unsafe {type_outer(0, types::TYPE_NATURAL)} }
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(0, types::TYPE_NATURAL)} }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
|
||||
pub fn natural<T: num::Num + num::NumCast>(data:T) -> Natural
|
||||
{
|
||||
Natural::new().with(data)
|
||||
}
|
||||
|
||||
impl Clone for Natural {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())} }
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl TryFrom<Any> for Natural {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Any> for Natural { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl Drop for Natural {
|
||||
fn drop(&mut self) {
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
crate::util::macros::impl_ops_numeric_all!(Natural, u64);
|
||||
|
||||
impl From<Ref> for Natural {
|
||||
fn from(refr: Ref) -> Self {
|
||||
if refr.class == Self::type_id() {
|
||||
Self { address:refr }
|
||||
} else { panic!("mismatched szun types"); }
|
||||
}
|
||||
}
|
||||
impl Into<Ref> for Natural { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl Drop for Natural {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
pub fn natural<T: num::Num + num::NumCast>(data:T) -> Natural
|
||||
{
|
||||
Natural::new().with(data)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
prelude::*,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct Null { }
|
||||
@ -10,7 +11,16 @@ pub fn null() -> Null { Null::new() }
|
||||
|
||||
impl SzunType for Null {
|
||||
fn type_id() -> usize { types::TYPE_NULL }
|
||||
fn to_ref(self) -> Ref { Ref { class:0, address:0 } }
|
||||
|
||||
fn encode(&self) -> Vec<u8>
|
||||
{
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn decode(&mut self, _:&Vec<u8>, _:&mut usize) -> Result<(), SzunError>
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
@ -20,3 +30,8 @@ impl SzunType for Null {
|
||||
impl Clone for Null {
|
||||
fn clone(&self) -> Self { Null::new() }
|
||||
}
|
||||
impl TryFrom<Any> for Null {
|
||||
type Error = SzunError;
|
||||
fn try_from(_: Any) -> Result<Self, Self::Error> { Ok(Self { }) }
|
||||
}
|
||||
impl Into<Any> for Null { fn into(self) -> Any { Any::__from_ref(Ref::null()) } }
|
||||
|
0
src/interface/pile.rs
Normal file
0
src/interface/pile.rs
Normal file
45
src/interface/schema.rs
Normal file
45
src/interface/schema.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use crate::{
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct Schema {
|
||||
address:Ref,
|
||||
}
|
||||
impl Schema {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
}
|
||||
impl SzunType for Schema {
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(0, types::TYPE_NATURAL)} }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
impl Clone for Schema {
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl TryFrom<Any> for Schema {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Any> for Schema { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl Drop for Schema {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
@ -1,13 +1,6 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer,
|
||||
clone,
|
||||
sequence_resize,
|
||||
sequence_set, sequence_get,
|
||||
sequence_length,
|
||||
},
|
||||
runtime,
|
||||
};
|
||||
|
||||
pub struct Sequence {
|
||||
@ -16,7 +9,7 @@ pub struct Sequence {
|
||||
impl Sequence {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {acquire(Self::type_id())} }
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
|
||||
pub fn with(mut self, data:Vec<u8>) -> Self
|
||||
@ -33,18 +26,18 @@ impl Sequence {
|
||||
|
||||
pub fn set(&mut self, data:Vec<u8>)
|
||||
{
|
||||
unsafe {sequence_resize(self.address.clone(), data.len())};
|
||||
unsafe {runtime::sequence_resize(self.address.clone(), data.len())};
|
||||
for i in 0..data.len() {
|
||||
unsafe {sequence_set(self.address.clone(), i, data[i])};
|
||||
unsafe {runtime::sequence_set(self.address.clone(), i, data[i])};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_str(&mut self, data:&str)
|
||||
{
|
||||
let data = data.as_bytes();
|
||||
unsafe {sequence_resize(self.address.clone(), data.len())};
|
||||
unsafe {runtime::sequence_resize(self.address.clone(), data.len())};
|
||||
for i in 0..data.len() {
|
||||
unsafe {sequence_set(self.address.clone(), i, data[i])};
|
||||
unsafe {runtime::sequence_set(self.address.clone(), i, data[i])};
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +45,7 @@ impl Sequence {
|
||||
{
|
||||
let mut data = Vec::new();
|
||||
for i in 0..data.len() {
|
||||
data.push(unsafe {sequence_get(self.address.clone(), i)});
|
||||
data.push(unsafe {runtime::sequence_get(self.address.clone(), i)});
|
||||
}
|
||||
data
|
||||
}
|
||||
@ -61,37 +54,53 @@ impl Sequence {
|
||||
{
|
||||
let mut data = Vec::new();
|
||||
for i in 0..self.len() {
|
||||
data.push(unsafe {sequence_get(self.address.clone(), i)});
|
||||
data.push(unsafe {runtime::sequence_get(self.address.clone(), i)});
|
||||
}
|
||||
String::from_utf8(data).unwrap()
|
||||
}
|
||||
|
||||
pub fn set_at(&mut self, index:usize, data:u8)
|
||||
{
|
||||
unsafe {sequence_set(self.address.clone(), index, data)}
|
||||
unsafe {runtime::sequence_set(self.address.clone(), index, data)}
|
||||
}
|
||||
|
||||
pub fn get_at(&self, index:usize) -> u8
|
||||
{
|
||||
unsafe {sequence_get(self.address.clone(), index)}
|
||||
unsafe {runtime::sequence_get(self.address.clone(), index)}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
unsafe {sequence_length(self.address.clone())}
|
||||
unsafe {runtime::sequence_length(self.address.clone())}
|
||||
}
|
||||
}
|
||||
impl SzunType for Sequence {
|
||||
fn type_id() -> usize {
|
||||
unsafe {type_outer(0, types::TYPE_SEQUENCE)}
|
||||
}
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(0, types::TYPE_SEQUENCE)} }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { false }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
impl Clone for Sequence {
|
||||
fn clone(&self) -> Self { Self::__from_ref(unsafe {runtime::clone(self.address.clone())}) }
|
||||
}
|
||||
impl TryFrom<Any> for Sequence {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Any> for Sequence { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl Drop for Sequence {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sequence(data:Vec<u8>) -> Sequence
|
||||
{
|
||||
@ -102,26 +111,3 @@ pub fn string(data:&str) -> Sequence
|
||||
{
|
||||
Sequence::new().with_str(data)
|
||||
}
|
||||
|
||||
impl Clone for Sequence {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())} }
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Ref> for Sequence {
|
||||
type Error = SzunError;
|
||||
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error> {
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr })
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Ref> for Sequence { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl Drop for Sequence {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
128
src/interface/sparse.rs
Normal file
128
src/interface/sparse.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use std::marker::PhantomData;
|
||||
use crate::{
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct Sparse<T: SzunType> {
|
||||
address:Ref,
|
||||
_data:PhantomData<T>,
|
||||
}
|
||||
impl<T: SzunType> Sparse<T> {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
address:unsafe {runtime::acquire(Self::type_id())},
|
||||
_data:PhantomData
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set<D: SzunType>(&mut self, index:usize, data:&D)
|
||||
{
|
||||
if self.compatible(data) {
|
||||
unsafe {runtime::sparse_set(self.address.clone(), index, data.__to_ref())};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset<D: SzunType>(&mut self, index:usize, data:&D)
|
||||
{
|
||||
if self.compatible(data) {
|
||||
unsafe {runtime::sparse_unset(self.address.clone(), index)};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
unsafe {runtime::sparse_clear(self.address.clone())};
|
||||
}
|
||||
|
||||
pub fn get(&mut self, index:usize) -> T
|
||||
{
|
||||
let refr = unsafe {runtime::sparse_get(self.address.clone(), index)};
|
||||
if refr.is_some() {
|
||||
T::__from_ref(refr)
|
||||
} else { panic!("index out of bounds: {} / {}", index, self.len()) }
|
||||
}
|
||||
|
||||
pub fn try_get(&mut self, index:usize) -> Option<T>
|
||||
{
|
||||
let refr = unsafe {runtime::sparse_get(self.address.clone(), index)};
|
||||
if refr.is_some() {
|
||||
Some(T::__from_ref(refr))
|
||||
} else { None }
|
||||
}
|
||||
|
||||
pub fn at(&mut self, index:usize) -> T
|
||||
{
|
||||
let refr = unsafe {runtime::sparse_at(self.address.clone(), index)};
|
||||
if refr.is_some() {
|
||||
T::__from_ref(refr)
|
||||
} else { panic!("index out of bounds: {} / {}", index, self.len()) }
|
||||
}
|
||||
|
||||
pub fn first(&self) -> usize
|
||||
{
|
||||
unsafe {runtime::sparse_first(self.address.clone())}
|
||||
}
|
||||
|
||||
pub fn last(&self) -> usize
|
||||
{
|
||||
unsafe {runtime::sparse_last(self.address.clone())}
|
||||
}
|
||||
|
||||
pub fn next(&self) -> usize
|
||||
{
|
||||
unsafe {runtime::sparse_next(self.address.clone())}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize
|
||||
{
|
||||
unsafe {runtime::sparse_length(self.address.clone())}
|
||||
}
|
||||
}
|
||||
impl<T: SzunType> SzunType for Sparse<T> {
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(T::type_id(), types::TYPE_SPARSE)} }
|
||||
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool
|
||||
{
|
||||
R::type_id() == T::type_id() || unsafe {runtime::type_key(T::type_id())} == types::TYPE_VAR
|
||||
}
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(address:Ref) -> Self { Self { address:address, _data:PhantomData } }
|
||||
}
|
||||
impl<T: SzunType> Clone for Sparse<T> {
|
||||
fn clone(&self) -> Self { Self::__from_ref(unsafe {runtime::clone(self.address.clone())}) }
|
||||
}
|
||||
impl<T: SzunType> TryFrom<Any> for Sparse<T> {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<T: SzunType> Into<Any> for Sparse<T> { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl<T: SzunType> Drop for Sparse<T> {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SzunType> TryFrom<Ref> for Sparse<T> {
|
||||
type Error = SzunError;
|
||||
|
||||
fn try_from(addr: Ref) -> Result<Self, Self::Error>
|
||||
{
|
||||
if addr.class == Self::type_id() {
|
||||
Ok(Self { address:addr, _data:PhantomData })
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<T: SzunType> Into<Ref> for Sparse<T> {
|
||||
fn into(self) -> Ref { self.address.clone() }
|
||||
}
|
||||
|
59
src/interface/table.rs
Normal file
59
src/interface/table.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use std::marker::PhantomData;
|
||||
use crate::{
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
};
|
||||
|
||||
pub struct Table<T: SzunType> {
|
||||
address:Ref,
|
||||
_data:PhantomData<T>,
|
||||
}
|
||||
impl<T: SzunType> Table<T> {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
address:unsafe {runtime::acquire(Self::type_id())},
|
||||
_data:PhantomData
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn with_size(mut self, length:usize) -> Self { }
|
||||
|
||||
//pub fn set<R: SzunType>(&mut self, index:usize, data:&R) { }
|
||||
//pub fn unset(&mut self, index:usize) { }
|
||||
//pub fn get(&self, index:usize) -> T { }
|
||||
//pub fn try_get(&self, index:usize) -> Result<T,()> { }
|
||||
//pub fn resize(&mut self, length:usize) { }
|
||||
//pub fn clear(&mut self) { }
|
||||
//pub fn len(&self) -> usize { 0 }
|
||||
//pub fn next(&self) -> usize { 0 }
|
||||
}
|
||||
impl<T: SzunType> SzunType for Table<T> {
|
||||
fn type_id() -> usize {
|
||||
unsafe {runtime::type_outer(T::type_id(), types::TYPE_TABLE)}
|
||||
}
|
||||
|
||||
fn compatible<R: SzunType>(&self, _:&R) -> bool {
|
||||
R::type_id() == T::type_id() || unsafe {runtime::type_key(T::type_id())} == types::TYPE_VAR
|
||||
}
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr, _data:PhantomData } }
|
||||
}
|
||||
impl<T: SzunType> Clone for Table<T> {
|
||||
fn clone(&self) -> Self { Self::__from_ref(unsafe {runtime::clone(self.address.clone())}) }
|
||||
}
|
||||
impl<T: SzunType> TryFrom<Any> for Table<T> {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self::__from_ref(obj.__to_ref()))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl<T: SzunType> Into<Any> for Table<T> { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl<T: SzunType> Drop for Table<T> {
|
||||
fn drop(&mut self) { unsafe {runtime::release(self.address.clone())}; }
|
||||
}
|
@ -1,86 +1,95 @@
|
||||
use crate::{
|
||||
prelude::*, types,
|
||||
runtime::{
|
||||
acquire, release,
|
||||
type_outer, type_sanitize,
|
||||
clone,
|
||||
var_set, var_get,
|
||||
},
|
||||
prelude::*,
|
||||
runtime,
|
||||
types,
|
||||
Any,
|
||||
};
|
||||
|
||||
pub struct Var {
|
||||
address:Ref,
|
||||
}
|
||||
impl Var {
|
||||
pub fn new() -> Self {
|
||||
Self { address:unsafe {acquire(Self::type_id())} }
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self { address:unsafe {runtime::acquire(Self::type_id())} }
|
||||
}
|
||||
|
||||
pub fn with<T: SzunType>(mut self, data:&T) -> Self {
|
||||
pub fn with<T: SzunType>(mut self, data:&T) -> Self
|
||||
{
|
||||
self.set(data);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set<T: SzunType>(&mut self, data:&T) {
|
||||
unsafe {var_set(self.address.clone(), data.__to_ref())}
|
||||
pub fn set<T: SzunType>(&mut self, data:&T)
|
||||
{
|
||||
unsafe {runtime::var_set(self.address.clone(), data.__to_ref())}
|
||||
}
|
||||
|
||||
pub fn get<T: SzunType>(&self) -> T {
|
||||
let refr = unsafe {var_get(self.address.clone())};
|
||||
if unsafe {type_sanitize(refr.class)} == T::type_id() {
|
||||
pub fn get<T: SzunType>(&self) -> T
|
||||
{
|
||||
let refr = unsafe {runtime::var_get(self.address.clone())};
|
||||
if unsafe {runtime::type_sanitize(refr.class)} == T::type_id() {
|
||||
T::__from_ref(refr)
|
||||
} else { panic!("mismatched szun types"); }
|
||||
}
|
||||
|
||||
pub fn try_get<T: SzunType>(&self) -> Result<T,SzunError> {
|
||||
let refr = unsafe {var_get(self.address.clone())};
|
||||
if unsafe {type_sanitize(refr.class)} == T::type_id() {
|
||||
pub fn get_any(&self) -> Any
|
||||
{
|
||||
let refr = unsafe {runtime::var_get(self.address.clone())};
|
||||
Any::__from_ref(refr)
|
||||
}
|
||||
|
||||
pub fn try_get<T: SzunType>(&self) -> Result<T,SzunError>
|
||||
{
|
||||
let refr = unsafe {runtime::var_get(self.address.clone())};
|
||||
if unsafe {runtime::type_sanitize(refr.class)} == T::type_id() {
|
||||
Ok(T::__from_ref(refr))
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
|
||||
pub fn has<T: SzunType>(&self) -> bool {
|
||||
let refr = unsafe {var_get(self.address.clone())};
|
||||
unsafe {type_sanitize(refr.class) == T::type_id()}
|
||||
pub fn has<T: SzunType>(&self) -> bool
|
||||
{
|
||||
let refr = unsafe {runtime::var_get(self.address.clone())};
|
||||
unsafe {runtime::type_sanitize(refr.class) == T::type_id()}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
unsafe {var_set(self.address.clone(), Ref::null())}
|
||||
unsafe {runtime::var_set(self.address.clone(), Ref::null())}
|
||||
}
|
||||
}
|
||||
impl SzunType for Var {
|
||||
fn type_id() -> usize { unsafe {type_outer(0, types::TYPE_VARYING)} }
|
||||
fn to_ref(self) -> Ref { self.address.clone() }
|
||||
|
||||
fn type_id() -> usize { unsafe {runtime::type_outer(0, types::TYPE_VAR)} }
|
||||
|
||||
fn compatible<T: SzunType>(&self, _:&T) -> bool { true }
|
||||
|
||||
fn __to_ref(&self) -> Ref { self.address.clone() }
|
||||
fn __from_ref(refr:Ref) -> Self { Self { address:refr } }
|
||||
}
|
||||
impl Clone for Var {
|
||||
fn clone(&self) -> Self
|
||||
{
|
||||
Self::__from_ref(unsafe {runtime::clone(self.address.clone())})
|
||||
}
|
||||
}
|
||||
impl TryFrom<Any> for Var {
|
||||
type Error = SzunError;
|
||||
fn try_from(obj: Any) -> Result<Self, Self::Error>
|
||||
{
|
||||
if obj.type_id() == Self::type_id() {
|
||||
Ok(Self { address:obj.__to_ref() })
|
||||
} else { Err(SzunError::MismatchedType) }
|
||||
}
|
||||
}
|
||||
impl Into<Any> for Var { fn into(self) -> Any { Any::__from_ref(self.address.clone()) } }
|
||||
impl Drop for Var {
|
||||
fn drop(&mut self)
|
||||
{
|
||||
unsafe {runtime::release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn var<T: SzunType>(data:&T) -> Var
|
||||
{
|
||||
Var::new().with(data)
|
||||
}
|
||||
|
||||
impl Clone for Var {
|
||||
fn clone(&self) -> Self {
|
||||
Self { address:unsafe {clone(self.address.clone())} }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Ref> for Var {
|
||||
fn from(refr: Ref) -> Self {
|
||||
if refr.class == Self::type_id() {
|
||||
Self { address:refr }
|
||||
} else { panic!("mismatched szun types"); }
|
||||
}
|
||||
}
|
||||
impl Into<Ref> for Var { fn into(self) -> Ref { self.address.clone() } }
|
||||
|
||||
impl Drop for Var {
|
||||
fn drop(&mut self) {
|
||||
unsafe {release(self.address.clone())};
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ mod types;
|
||||
mod util;
|
||||
mod runtime;
|
||||
mod interface; pub use interface::*;
|
||||
//mod encoding; pub use encoding::*;
|
||||
mod encode; pub use encode::*;
|
||||
|
||||
//#[cfg(test)] mod tests;
|
||||
|
@ -1,3 +1,6 @@
|
||||
pub enum SzunError {
|
||||
NotImplemented,
|
||||
MismatchedType,
|
||||
EndOfData,
|
||||
BadData,
|
||||
}
|
||||
|
@ -1,9 +1,31 @@
|
||||
mod reference; pub use reference::Ref;
|
||||
mod error; pub use error::SzunError;
|
||||
pub use crate::Any;
|
||||
|
||||
pub trait SzunType : Clone {
|
||||
pub trait SzunType : Clone + TryFrom<Any> + Into<Any> {
|
||||
fn type_id() -> usize;
|
||||
fn to_ref(self) -> Ref;
|
||||
fn to_any(self) -> Any { self.into() }
|
||||
|
||||
fn tag(&self) -> Vec<u8>
|
||||
{
|
||||
let mut data = Vec::<u8>::new();
|
||||
let mut current = Self::type_id();
|
||||
|
||||
while current != 0 {
|
||||
data.append(&mut Vec::<u8>::new());
|
||||
current = 0;
|
||||
}
|
||||
|
||||
data
|
||||
}
|
||||
|
||||
fn encode(&self) -> Vec<u8> { crate::encode::encode(self.__to_ref()) }
|
||||
fn encode_data(&self) -> Vec<u8> { crate::encode::encode_data(self.__to_ref()) }
|
||||
|
||||
fn decode(&mut self, _:&Vec<u8>, _:&mut usize) -> Result<(), SzunError>
|
||||
{
|
||||
Err(SzunError::NotImplemented)
|
||||
}
|
||||
|
||||
fn compatible<T: SzunType>(&self, refr:&T) -> bool;
|
||||
|
||||
|
@ -4,6 +4,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Ref {
|
||||
pub(crate) class:usize,
|
||||
pub(crate) address:usize,
|
||||
@ -14,6 +15,8 @@ impl Ref {
|
||||
pub fn is_some(&self) -> bool { self.address != 0 }
|
||||
pub fn is_none(&self) -> bool { self.address == 0 }
|
||||
|
||||
pub fn type_id(&self) -> usize { self.class }
|
||||
|
||||
pub fn is<T: SzunType>(&self) -> bool { unsafe {type_key(T::type_id()) == type_key(self.class)} }
|
||||
|
||||
pub(crate) fn clone(&self) -> Self
|
||||
|
@ -2,6 +2,8 @@ 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);
|
||||
extern "C" size_t block_get_bits(Reference addr, size_t index, size_t length);
|
||||
extern "C" void block_set_bits(Reference addr, size_t index, size_t length, size_t value);
|
||||
|
||||
//extern "C" uint64_t block_get_natural(Reference addr);
|
||||
//extern "C" int64_t block_get_integer(Reference addr);
|
||||
|
@ -4,7 +4,6 @@ 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);
|
||||
extern "C" size_t schema_indexof(Reference addr, size_t key);
|
||||
@ -12,3 +11,4 @@ extern "C" size_t schema_keyof(Reference addr, size_t index);
|
||||
extern "C" size_t schema_bind(Reference addr, size_t key);
|
||||
extern "C" size_t schema_binding(size_t key);
|
||||
extern "C" bool schema_has(size_t id);
|
||||
//extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to);
|
||||
|
@ -1,5 +1,5 @@
|
||||
extern "C" size_t sparse_header_length(Reference addr);
|
||||
extern "C" Type::SparseHeader sparse_header_data(Reference addr, size_t index);
|
||||
size_t sparse_header_length(Reference addr);
|
||||
Type::SparseHeader sparse_header_data(Reference addr, size_t index);
|
||||
extern "C" size_t sparse_length(Reference addr);
|
||||
extern "C" void sparse_clear(Reference addr);
|
||||
extern "C" size_t sparse_first(Reference addr);
|
||||
@ -9,4 +9,3 @@ extern "C" Reference sparse_at(Reference addr, size_t index);
|
||||
extern "C" Reference sparse_get(Reference addr, size_t index);
|
||||
extern "C" void sparse_set(Reference addr, size_t index, Reference source);
|
||||
extern "C" void sparse_unset(Reference addr, size_t index);
|
||||
extern "C" size_t sparse_indexof(Reference addr, size_t index);
|
||||
|
7
src/runtime/header/implement/table.h
Normal file
7
src/runtime/header/implement/table.h
Normal file
@ -0,0 +1,7 @@
|
||||
extern "C" size_t table_length(Reference addr);
|
||||
extern "C" void table_resize(Reference addr, size_t size);
|
||||
extern "C" void table_clear(Reference addr);
|
||||
extern "C" void table_set(Reference addr, size_t index, Reference data);
|
||||
extern "C" void table_unset(Reference addr, size_t index);
|
||||
extern "C" Reference table_get(Reference addr, size_t index);
|
||||
extern "C" size_t integer_next(Reference addr);
|
@ -1,6 +1,8 @@
|
||||
uint8_t* allocate(size_t type_id, size_t count);
|
||||
extern "C" Reference acquire(size_t type_id);
|
||||
void drop(Reference addr);
|
||||
extern "C" void release(Reference id);
|
||||
extern "C" Reference clone(Reference src);
|
||||
extern "C" bool copy(Reference dst, Reference src);
|
||||
extern "C" bool transfer(Reference dst, Reference src);
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
size_t array_length(Reference addr)
|
||||
{
|
||||
return type_innerkey(addr.type);
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
size_t block_length(Reference addr)
|
||||
// Returns the data length of the block.
|
||||
//
|
||||
@ -25,6 +27,23 @@ extern "C" void block_set(Reference addr, size_t index, uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" size_t block_get_bits(Reference addr, size_t index, size_t length)
|
||||
{
|
||||
size_t result = 0;
|
||||
size_t byte_index = index >> 3;
|
||||
if(byte_index < block_length(addr)) {
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" void block_set_bits(Reference addr, size_t index, size_t length, size_t data)
|
||||
{
|
||||
size_t byte_index = index >> 3;
|
||||
if(byte_index < block_length(addr)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*extern "C" uint64_t block_get_natural(Reference addr)
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" void bool_set(Reference addr, Type::Boolean value)
|
||||
{
|
||||
*(reinterpret_cast<Type::Boolean*>(addr.address)) = value;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" void decimal_set(Reference addr, Type::Decimal value)
|
||||
{
|
||||
*(reinterpret_cast<Type::Decimal*>(addr.address)) = value;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" void integer_set(Reference addr, Type::Integer value)
|
||||
{
|
||||
*(reinterpret_cast<Type::Integer*>(addr.address)) = value;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
Reference list_cell(Reference addr, size_t index)
|
||||
// Returns a reference to the list cell at the specified index.
|
||||
//
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" void natural_set(Reference addr, Type::Natural value)
|
||||
{
|
||||
*(reinterpret_cast<Type::Natural*>(addr.address)) = value;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" size_t record_length(Reference addr)
|
||||
{
|
||||
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" size_t schema_length(Reference addr)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" size_t sequence_length(Reference addr)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
|
@ -1,10 +1,12 @@
|
||||
extern "C" size_t sparse_header_length(Reference addr)
|
||||
#include "lib.h"
|
||||
|
||||
size_t sparse_header_length(Reference addr)
|
||||
{
|
||||
auto& list = *reinterpret_cast<Type::Sparse*>(addr.address);
|
||||
return list.header.length;
|
||||
}
|
||||
|
||||
extern "C" Type::SparseHeader sparse_header_data(Reference addr, size_t index)
|
||||
Type::SparseHeader sparse_header_data(Reference addr, size_t index)
|
||||
{
|
||||
auto& list = *reinterpret_cast<Type::Sparse*>(addr.address);
|
||||
Type::SparseHeader header {0};
|
||||
@ -79,6 +81,8 @@ extern "C" size_t sparse_last(Reference addr)
|
||||
}
|
||||
|
||||
extern "C" Reference sparse_at(Reference addr, size_t index)
|
||||
// Returns
|
||||
//
|
||||
{
|
||||
Reference result {0};
|
||||
auto& list = *reinterpret_cast<Type::Sparse*>(addr.address);
|
||||
@ -96,7 +100,7 @@ extern "C" Reference sparse_at(Reference addr, size_t index)
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return refr_make_temporary(result);
|
||||
}
|
||||
|
||||
extern "C" Reference sparse_get(Reference addr, size_t index)
|
||||
@ -137,7 +141,7 @@ extern "C" Reference sparse_get(Reference addr, size_t index)
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return refr_make_temporary(result);
|
||||
}
|
||||
|
||||
extern "C" void sparse_set(Reference addr, size_t index, Reference source)
|
||||
@ -270,7 +274,7 @@ extern "C" void sparse_unset(Reference addr, size_t index)
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" size_t sparse_indexof(Reference addr, size_t index)
|
||||
/*extern "C" size_t sparse_indexof(Reference addr, size_t index)
|
||||
{
|
||||
auto& list = *reinterpret_cast<Type::Sparse*>(addr.address);
|
||||
|
||||
@ -285,4 +289,4 @@ extern "C" size_t sparse_indexof(Reference addr, size_t index)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
|
56
src/runtime/implement/table.cc
Normal file
56
src/runtime/implement/table.cc
Normal file
@ -0,0 +1,56 @@
|
||||
#include "lib.h"
|
||||
|
||||
Reference table_cell(Reference addr, size_t index)
|
||||
// Returns a reference to the cell at the specified index.
|
||||
//
|
||||
{
|
||||
Reference result {0};
|
||||
Type::Table& table = *reinterpret_cast<Type::Table*>(addr.address);
|
||||
size_t inner = type_inner(addr.type);
|
||||
size_t offset = type_size(inner);
|
||||
|
||||
// validate for overflow
|
||||
if(table.data.data != nullptr && offset > 0 && index < list.data.capacity) {
|
||||
result.type = inner;
|
||||
result.address = rawlist_cell(list.data, offset, index);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
extern "C" size_t table_length(Reference addr)
|
||||
{
|
||||
Type::Table& table = *reinterpret_cast<Type::Table*>(addr.address);
|
||||
return rawlist_length(table.data);
|
||||
}
|
||||
|
||||
extern "C" void table_resize(Reference addr, size_t size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern "C" void table_clear(Reference addr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern "C" void table_set(Reference addr, size_t index, Reference data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern "C" void table_unset(Reference addr, size_t index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern "C" Reference table_get(Reference addr, size_t index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern "C" size_t table_next(Reference addr)
|
||||
{
|
||||
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
#include "lib.h"
|
||||
|
||||
extern "C" Reference var_get(Reference addr)
|
||||
// Returns the inner reference.
|
||||
//
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
@ -24,6 +24,7 @@ extern "C" {
|
||||
pub fn release(addr:Ref);
|
||||
|
||||
pub fn clone(src:Ref) -> Ref;
|
||||
pub fn const_clone(src:Ref) -> Ref;
|
||||
pub fn copy(dst:Ref, src:Ref) -> bool;
|
||||
pub fn transfer(dst:Ref, src:Ref) -> bool;
|
||||
|
||||
@ -58,6 +59,8 @@ extern "C" {
|
||||
|
||||
pub fn block_get(addr:Ref, index:usize) -> u8;
|
||||
pub fn block_set(addr:Ref, index:usize, data:u8);
|
||||
pub fn block_get_bits(addr:Ref, index:usize, length:usize) -> usize;
|
||||
pub fn block_set_bits(addr:Ref, index:usize, length:usize, data:usize);
|
||||
|
||||
pub fn sequence_length(addr:Ref) -> usize;
|
||||
pub fn sequence_get(addr:Ref, index:usize) -> u8;
|
||||
@ -85,18 +88,23 @@ extern "C" {
|
||||
pub fn list_remove(addr:Ref, index:usize);
|
||||
pub fn list_reserve(addr:Ref, capacity:usize);
|
||||
|
||||
//pub fn sparse_header_length(addr:Ref) -> usize;
|
||||
//pub fn sparse_header_data(addr:Ref, index:usize) -> SparseHeader;
|
||||
//pub fn sparse_length(addr:Ref) -> usize;
|
||||
//pub fn sparse_clear(addr:Ref);
|
||||
//pub fn sparse_first(addr:Ref) -> usize;
|
||||
//pub fn sparse_next(addr:Ref) -> usize;
|
||||
//pub fn sparse_last(addr:Ref) -> usize;
|
||||
//pub fn sparse_get(addr:Ref, index:usize) -> Ref;
|
||||
//pub fn sparse_at(addr:Ref, index:usize) -> Ref;
|
||||
//pub fn sparse_set(addr:Ref, index:usize, source:Ref);
|
||||
//pub fn sparse_unset(addr:Ref, index:usize);
|
||||
//pub fn sparse_indexof(addr:Ref, index:usize) -> usize;
|
||||
pub fn sparse_length(addr:Ref) -> usize;
|
||||
pub fn sparse_clear(addr:Ref);
|
||||
pub fn sparse_first(addr:Ref) -> usize;
|
||||
pub fn sparse_next(addr:Ref) -> usize;
|
||||
pub fn sparse_last(addr:Ref) -> usize;
|
||||
pub fn sparse_get(addr:Ref, index:usize) -> Ref;
|
||||
pub fn sparse_at(addr:Ref, index:usize) -> Ref;
|
||||
pub fn sparse_set(addr:Ref, index:usize, source:Ref);
|
||||
pub fn sparse_unset(addr:Ref, index:usize);
|
||||
|
||||
pub fn table_length(addr:Ref) -> usize;
|
||||
pub fn table_resize(addr:Ref, size:usize);
|
||||
pub fn table_clear(addr:Ref);
|
||||
pub fn table_set(addr:Ref, index:usize, data:Ref);
|
||||
pub fn table_unset(addr:Ref, index:usize);
|
||||
pub fn table_get(addr:Ref, index:usize) -> Ref;
|
||||
pub fn table_next(addr:Ref) -> usize;
|
||||
|
||||
//pub fn record_length(addr:Ref) -> usize;
|
||||
//pub fn record_type(addr:Ref, index:usize) -> usize;
|
||||
@ -105,17 +113,17 @@ extern "C" {
|
||||
//pub fn record_keyof(addr:Ref, index:usize) -> usize;
|
||||
//pub fn record_indexof(addr:Ref, key:usize) -> usize;
|
||||
|
||||
//pub fn schema_length(addr:Ref) -> usize;
|
||||
//pub fn schema_insert(addr:Ref, index:usize, type_id:usize) -> usize;
|
||||
//pub fn schema_update(addr:Ref, index:usize, type_id:usize);
|
||||
//pub fn schema_get(addr:Ref, index:usize) -> usize;
|
||||
//pub fn schema_remove(addr:Ref, index:usize);
|
||||
//pub fn schema_clear(addr:Ref);
|
||||
pub fn schema_length(addr:Ref) -> usize;
|
||||
pub fn schema_insert(addr:Ref, index:usize, type_id:usize) -> usize;
|
||||
pub fn schema_update(addr:Ref, index:usize, type_id:usize);
|
||||
pub fn schema_get(addr:Ref, index:usize) -> usize;
|
||||
pub fn schema_remove(addr:Ref, index:usize);
|
||||
pub fn schema_clear(addr:Ref);
|
||||
pub fn schema_map(addr:Ref, key:usize, index:usize);
|
||||
pub fn schema_unmap(addr:Ref, key:usize);
|
||||
pub fn schema_indexof(addr:Ref, key:usize) -> usize;
|
||||
pub fn schema_keyof(addr:Ref, index:usize) -> usize;
|
||||
pub fn schema_bind(addr:Ref, id:usize) -> usize;
|
||||
pub fn schema_has(id:usize) -> bool;
|
||||
//pub fn schema_reorder(addr:Ref, from:usize, to:usize);
|
||||
//pub fn schema_map(addr:Ref, key:usize, index:usize);
|
||||
//pub fn schema_unmap(addr:Ref, key:usize);
|
||||
//pub fn schema_indexof(addr:Ref, key:usize) -> usize;
|
||||
//pub fn schema_keyof(addr:Ref, index:usize) -> usize;
|
||||
//pub fn schema_bind(addr:Ref, id:usize) -> usize;
|
||||
//pub fn schema_has(id:usize) -> bool;
|
||||
}
|
||||
|
@ -55,6 +55,20 @@ struct List {
|
||||
RawList data;
|
||||
};
|
||||
|
||||
struct PaletteList {
|
||||
struct Record {
|
||||
size_t palette;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
RawList data;
|
||||
RawList contents;
|
||||
};
|
||||
|
||||
struct Table {
|
||||
RawList data;
|
||||
};
|
||||
|
||||
extern "C" struct SparseHeader {
|
||||
size_t start;
|
||||
size_t length;
|
||||
|
30
src/types.rs
30
src/types.rs
@ -1,30 +1,32 @@
|
||||
pub const TYPE_NULL :usize = 0x00;
|
||||
pub const TYPE_BOOLEAN :usize = 0x01;
|
||||
/* ... */
|
||||
pub const TYPE_BYTE :usize = 0x04;
|
||||
pub const TYPE_CHAR :usize = 0x05;
|
||||
//pub const TYPE_BYTE :usize = 0x04;
|
||||
//pub const TYPE_CHAR :usize = 0x05;
|
||||
/* ... */
|
||||
pub const TYPE_NATURAL :usize = 0x08;
|
||||
pub const TYPE_INTEGER :usize = 0x09;
|
||||
pub const TYPE_DECIMAL :usize = 0x0A;
|
||||
pub const TYPE_SIGNIFICANT :usize = 0x0B;
|
||||
pub const TYPE_COMPLEX :usize = 0x0C;
|
||||
//pub const TYPE_DECIMAL :usize = 0x0A;
|
||||
//pub const TYPE_SIGNIFICANT :usize = 0x0B;
|
||||
//pub const TYPE_COMPLEX :usize = 0x0C; ?
|
||||
/* ... */
|
||||
pub const TYPE_RANGE :usize = 0x0F;
|
||||
//pub const TYPE_RANGE :usize = 0x0F;
|
||||
pub const TYPE_BLOCK :usize = 0x10;
|
||||
pub const TYPE_SEQUENCE :usize = 0x11;
|
||||
/* ... */
|
||||
pub const TYPE_VARYING :usize = 0x20;
|
||||
pub const TYPE_OPTIONAL :usize = 0x21;
|
||||
pub const TYPE_VAR :usize = 0x20;
|
||||
//pub const TYPE_OPTIONAL :usize = 0x21;
|
||||
pub const TYPE_ARRAY :usize = 0x22;
|
||||
pub const TYPE_LIST :usize = 0x23;
|
||||
pub const TYPE_BAG :usize = 0x24;
|
||||
//pub const TYPE_BAG :usize = 0x24; ?
|
||||
pub const TYPE_SPARSE :usize = 0x25;
|
||||
pub const TYPE_TRIE :usize = 0x26;
|
||||
pub const TYPE_MAP :usize = 0x27;
|
||||
pub const TYPE_TREE :usize = 0x28;
|
||||
pub const TYPE_GRAPH :usize = 0x29;
|
||||
//pub const TYPE_TRIE :usize = 0x26;
|
||||
//pub const TYPE_MAP :usize = 0x27; ?
|
||||
//pub const TYPE_TREE :usize = 0x28; ?
|
||||
//pub const TYPE_GRAPH :usize = 0x29; ?
|
||||
/* ... */
|
||||
pub const TYPE_ENUM :usize = 0x7d;
|
||||
pub const TYPE_TABLE :usize = 0x30;
|
||||
/* ... */
|
||||
//pub const TYPE_ENUM :usize = 0x7d; ?
|
||||
pub const TYPE_RECORD :usize = 0x7e;
|
||||
pub const TYPE_SCHEMA :usize = 0x7f;
|
||||
|
@ -1,6 +1,8 @@
|
||||
//mod typetree; pub use typetree::TypeTree;
|
||||
//mod memory; pub use memory::Memory;
|
||||
|
||||
use crate::SzunError;
|
||||
|
||||
fn pack_count_leading_ones(data:u8) -> usize
|
||||
{
|
||||
(data == 0xff) as usize
|
||||
@ -72,13 +74,13 @@ pub fn pack_integer(data:i64) -> Vec<u8>
|
||||
pack_data(pack_encode_size(udata, true), udata, negative)
|
||||
}
|
||||
|
||||
fn unpack_data(data:&Vec<u8>, index:&mut usize, signed:bool) -> u64
|
||||
fn unpack_data(data:&Vec<u8>, index:&mut usize, signed:bool) -> Result<u64, SzunError>
|
||||
{
|
||||
let mut result :u64 = 0;
|
||||
let mut result :u64;
|
||||
let mut negative = false;
|
||||
|
||||
if *index < data.len() {
|
||||
let mut pack_size = pack_count_leading_ones(data[*index]);
|
||||
|
||||
if pack_size < 7 {
|
||||
result = (((data[*index] as u64) << pack_size) & 0xFF) >> pack_size;
|
||||
if signed {
|
||||
@ -91,7 +93,10 @@ fn unpack_data(data:&Vec<u8>, index:&mut usize, signed:bool) -> u64
|
||||
else {
|
||||
*index += 1;
|
||||
if pack_size == 8 {
|
||||
pack_size = unpack_natural(&data, index) as usize;
|
||||
pack_size = match unpack_natural(&data, index) {
|
||||
Ok(value) => value as usize,
|
||||
Err(_) => return Err(SzunError::BadData),
|
||||
};
|
||||
}
|
||||
pack_size -= 1;
|
||||
|
||||
@ -103,23 +108,34 @@ fn unpack_data(data:&Vec<u8>, index:&mut usize, signed:bool) -> u64
|
||||
*index += 1;
|
||||
}
|
||||
|
||||
for _ in 1..pack_size + 1 {
|
||||
result <<= 8;
|
||||
result += data[*index] as u64;
|
||||
*index += 1;
|
||||
}
|
||||
if *index + pack_size < data.len() {
|
||||
for _ in 1..pack_size + 1 {
|
||||
result <<= 8;
|
||||
result += data[*index] as u64;
|
||||
*index += 1;
|
||||
}
|
||||
|
||||
if negative { result = !result; }
|
||||
if negative { result = !result; }
|
||||
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(SzunError::EndOfData)
|
||||
}
|
||||
}
|
||||
else {
|
||||
Err(SzunError::EndOfData)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn unpack_natural(data:&Vec<u8>, index:&mut usize) -> u64
|
||||
pub fn unpack_natural(data:&Vec<u8>, index:&mut usize) -> Result<u64, SzunError>
|
||||
{
|
||||
unpack_data(data, index, false)
|
||||
}
|
||||
|
||||
pub fn unpack_integer(data:&Vec<u8>, index:&mut usize) -> i64
|
||||
pub fn unpack_integer(data:&Vec<u8>, index:&mut usize) -> Result<i64, SzunError>
|
||||
{
|
||||
unpack_data(data, index, true) as i64
|
||||
match unpack_data(data, index, true) {
|
||||
Ok(value) => Ok(value as i64),
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user