Implement encode/decode, fix bugs, update README with new functions.
This commit is contained in:
parent
c5d551bde2
commit
7addefd634
30
README.md
30
README.md
@ -78,25 +78,35 @@ Destruct and deallocate a type.
|
|||||||
```
|
```
|
||||||
release(refer);
|
release(refer);
|
||||||
```
|
```
|
||||||
> Warning: To avoid access violations, `release()` should not be used with interface objects, such as Boolean.
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
`transfer(dst:Reference, src:Reference) -> Result<(),()>`
|
||||||
|
Move an object from one location to another, clearing the original.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`copy(dst:Reference, src:Reference) -> Result<(),()>`
|
||||||
|
Copy the contents of an objcet to another location, keeping the original.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
`encode(refer:Reference) -> Vec<u8>`
|
`encode(refer:Reference) -> Vec<u8>`
|
||||||
`encode_raw(refer:Reference) -> Vec<u8>`
|
`encode_raw(refer:Reference) -> Vec<u8>`
|
||||||
|
`encode_tag(refer:Reference) -> Vec<u8>`
|
||||||
|
|
||||||
Serializes an object into binary encoding.
|
Serializes an object into binary encoding.
|
||||||
The raw variant does not produce a tag prefix for the root object.
|
The raw variant does not produce a tag prefix for the root object.
|
||||||
|
|
||||||
> Not implemented
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`decode(data:Vec<u8>) -> Result<Reference,()>`
|
`decode(data:&Vec<u8>, index:&mut usize) -> Result<Type,()>`
|
||||||
`decode_raw(data:Vec<u8>, type_id:usize) -> Result<Reference,()>`
|
`decode_raw(data:&Vec<u8>, type_id:usize, index:&mut usize) -> Result<Type,()>`
|
||||||
|
`decode_tag(data:&Vec<u8>, index:&mut usize) -> Result<usize,()>`
|
||||||
|
|
||||||
Parses a valid binary encoding and produces the represented object.
|
Parses a valid binary encoding and produces the represented object.
|
||||||
The raw variant does not decode a tag prefix on the root object.
|
The raw variant does not decode a tag prefix on the root object.
|
||||||
|
|
||||||
> Not implemented
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Language Compiler
|
## Language Compiler
|
||||||
@ -241,7 +251,15 @@ value.set(-273);
|
|||||||
|
|
||||||
|
|
||||||
## Significant
|
## Significant
|
||||||
Stores a fixed-precision, variable-magnitude
|
Stores a fixed-precision, variable-magnitude number.
|
||||||
|
|
||||||
|
`get() -> f64`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`set(value:f64)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
## Block
|
## Block
|
||||||
|
192
src/encoding/mod.rs
Normal file
192
src/encoding/mod.rs
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
use crate::{
|
||||||
|
runtime::{
|
||||||
|
Reference,
|
||||||
|
kind_hasinner, type_hasinner, type_inner, type_outer,
|
||||||
|
type_key, type_innerkey,
|
||||||
|
},
|
||||||
|
tag,
|
||||||
|
Type,
|
||||||
|
util::*,
|
||||||
|
};
|
||||||
|
use crate::kind;
|
||||||
|
use crate::{
|
||||||
|
Boolean,
|
||||||
|
Natural, Integer,
|
||||||
|
Block, Sequence,
|
||||||
|
Array, List,
|
||||||
|
Record,
|
||||||
|
};
|
||||||
|
use crate::util;
|
||||||
|
|
||||||
|
pub fn encode_tag(addr:Reference) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut type_id = addr.class;
|
||||||
|
let mut result = Vec::<u8>::new();
|
||||||
|
let mut remaining :usize = 1;
|
||||||
|
while remaining > 0 {
|
||||||
|
result.append(&mut util::pack_natural(unsafe {type_key(type_id)} as u64));
|
||||||
|
|
||||||
|
remaining -= 1;
|
||||||
|
if remaining == 0 {
|
||||||
|
remaining += unsafe {type_hasinner(type_id)};
|
||||||
|
}
|
||||||
|
type_id = unsafe {type_inner(type_id)};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode_data(addr:Reference) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut result = Vec::<u8>::new();
|
||||||
|
match unsafe {type_key(addr.class)} {
|
||||||
|
tag::BOOLEAN => {
|
||||||
|
result.append(&mut util::pack_natural(Boolean::from(addr).unwrap().get() as u64));
|
||||||
|
}
|
||||||
|
tag::NATURAL => {
|
||||||
|
result.append(&mut util::pack_natural(Natural::from(addr).unwrap().get() as u64));
|
||||||
|
}
|
||||||
|
tag::INTEGER => {
|
||||||
|
result.append(&mut &mut util::pack_integer(Integer::from(addr).unwrap().get() as i64));
|
||||||
|
}
|
||||||
|
tag::BLOCK => {
|
||||||
|
result.append(&mut Block::from(addr).unwrap().get());
|
||||||
|
}
|
||||||
|
tag::SEQUENCE => {
|
||||||
|
let data = Sequence::from(addr).unwrap();
|
||||||
|
result.append(&mut util::pack_natural(data.size() as u64));
|
||||||
|
result.append(&mut data.get_raw());
|
||||||
|
}
|
||||||
|
tag::ARRAY => {
|
||||||
|
let data = Array::from(addr).unwrap();
|
||||||
|
for i in 0..data.length() {
|
||||||
|
if unsafe {type_innerkey(addr.class)} == tag::VARYING {
|
||||||
|
result.append(&mut encode(data.at(i)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.append(&mut encode_data(data.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tag::LIST => {
|
||||||
|
let data = List::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)} == tag::VARYING {
|
||||||
|
result.append(&mut encode(data.at(i)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.append(&mut encode_data(data.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tag::RECORD => {
|
||||||
|
let data = Record::from(addr).unwrap();
|
||||||
|
for i in 0..data.length() {
|
||||||
|
if kind(data.kindof(i)) == tag::VARYING {
|
||||||
|
result.append(&mut encode(data.at(i)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.append(&mut encode_data(data.at(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode(addr:Reference) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut result = encode_tag(addr);
|
||||||
|
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<Type,()>
|
||||||
|
{
|
||||||
|
match unsafe {type_key(type_id)} {
|
||||||
|
tag::VARYING => {
|
||||||
|
return decode(data, index);
|
||||||
|
}
|
||||||
|
tag::BOOLEAN => {
|
||||||
|
return Ok(Type::Boolean(Boolean::with(unpack_natural(data, index) == 1)));
|
||||||
|
}
|
||||||
|
tag::NATURAL => {
|
||||||
|
return Ok(Type::Natural(Natural::with(unpack_natural(data, index))));
|
||||||
|
}
|
||||||
|
tag::INTEGER => {
|
||||||
|
return Ok(Type::Integer(Integer::with(unpack_integer(data, index))));
|
||||||
|
}
|
||||||
|
tag::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(Type::Block(Block::with(size, bytes)));
|
||||||
|
}
|
||||||
|
tag::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(Type::Sequence(Sequence::with_raw(bytes)));
|
||||||
|
}
|
||||||
|
tag::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(Type::Record(value))
|
||||||
|
}
|
||||||
|
Err(_) => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode(data:&Vec<u8>, index:&mut usize) -> Result<Type,()>
|
||||||
|
{
|
||||||
|
return match decode_tag(data, index) {
|
||||||
|
Ok(type_id) => decode_data(data, type_id, index),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
@ -53,6 +53,17 @@ impl Array {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize
|
pub fn length(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {array_length(self.addr)}
|
unsafe {array_length(self.addr)}
|
||||||
|
@ -31,7 +31,25 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize
|
pub fn with(size:usize, data:Vec<u8>) -> Self
|
||||||
|
{
|
||||||
|
let mut obj = Self::new(size);
|
||||||
|
obj.set(data);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {block_length(self.addr)}
|
unsafe {block_length(self.addr)}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,17 @@ impl Boolean {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, value:bool)
|
pub fn set(&mut self, value:bool)
|
||||||
{
|
{
|
||||||
unsafe { bool_set(self.addr, value) };
|
unsafe { bool_set(self.addr, value) };
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use crate::tag;
|
use crate::tag;
|
||||||
use crate::runtime;
|
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 varying() -> usize { 0 }
|
pub fn varying() -> usize { 0 }
|
||||||
pub fn null() -> usize { unsafe { runtime::type_outer(0, tag::NULL) } }
|
pub fn null() -> usize { unsafe { runtime::type_outer(0, tag::NULL) } }
|
||||||
pub fn boolean() -> usize { unsafe { runtime::type_outer(0, tag::BOOLEAN) } }
|
pub fn boolean() -> usize { unsafe { runtime::type_outer(0, tag::BOOLEAN) } }
|
||||||
|
@ -37,6 +37,17 @@ impl Integer {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, value:i64)
|
pub fn set(&mut self, value:i64)
|
||||||
{
|
{
|
||||||
unsafe { integer_set(self.addr, value) };
|
unsafe { integer_set(self.addr, value) };
|
||||||
|
@ -44,6 +44,17 @@ impl List {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn capacity(&self) -> usize
|
pub fn capacity(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {list_capacity(self.addr)}
|
unsafe {list_capacity(self.addr)}
|
||||||
|
@ -16,27 +16,49 @@ mod schema; pub use schema::Schema;
|
|||||||
mod record; pub use record::Record;
|
mod record; pub use record::Record;
|
||||||
|
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Varying(Varying),
|
|
||||||
Null,
|
Null,
|
||||||
|
Varying(Varying),
|
||||||
Boolean(Boolean),
|
Boolean(Boolean),
|
||||||
Natural(Natural),
|
Natural(Natural),
|
||||||
Integer(Integer),
|
Integer(Integer),
|
||||||
Block(Block),
|
Block(Block),
|
||||||
|
Sequence(Sequence),
|
||||||
Array(Array),
|
Array(Array),
|
||||||
List(List),
|
List(List),
|
||||||
|
Record(Record),
|
||||||
|
Schema(Schema),
|
||||||
}
|
}
|
||||||
impl Type {
|
impl Type {
|
||||||
pub fn from(addr:Reference) -> Self
|
pub fn from(addr:Reference) -> Self
|
||||||
{
|
{
|
||||||
match unsafe {type_key(addr.class)} {
|
match unsafe {type_key(addr.class)} {
|
||||||
tag::VARYING => Type::Varying(Varying::from(addr).unwrap()),
|
|
||||||
tag::NULL => Type::Null,
|
tag::NULL => Type::Null,
|
||||||
|
tag::VARYING => Type::Varying(Varying::from(addr).unwrap()),
|
||||||
tag::BOOLEAN => Type::Boolean(Boolean::from(addr).unwrap()),
|
tag::BOOLEAN => Type::Boolean(Boolean::from(addr).unwrap()),
|
||||||
tag::NATURAL => Type::Natural(Natural::from(addr).unwrap()),
|
tag::NATURAL => Type::Natural(Natural::from(addr).unwrap()),
|
||||||
tag::INTEGER => Type::Integer(Integer::from(addr).unwrap()),
|
tag::INTEGER => Type::Integer(Integer::from(addr).unwrap()),
|
||||||
|
tag::BLOCK => Type::Block(Block::from(addr).unwrap()),
|
||||||
|
tag::SEQUENCE => Type::Sequence(Sequence::from(addr).unwrap()),
|
||||||
tag::ARRAY => Type::Array(Array::from(addr).unwrap()),
|
tag::ARRAY => Type::Array(Array::from(addr).unwrap()),
|
||||||
tag::LIST => Type::List(List::from(addr).unwrap()),
|
tag::LIST => Type::List(List::from(addr).unwrap()),
|
||||||
|
tag::RECORD => Type::Record(Record::from(addr).unwrap()),
|
||||||
_ => Type::Null,
|
_ => Type::Null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> Reference
|
||||||
|
{
|
||||||
|
match &self {
|
||||||
|
Type::Varying(obj) => **obj,
|
||||||
|
Type::Boolean(obj) => **obj,
|
||||||
|
Type::Natural(obj) => **obj,
|
||||||
|
Type::Integer(obj) => **obj,
|
||||||
|
Type::Block(obj) => **obj,
|
||||||
|
Type::Sequence(obj) => **obj,
|
||||||
|
Type::Array(obj) => **obj,
|
||||||
|
Type::List(obj) => **obj,
|
||||||
|
Type::Record(obj) => **obj,
|
||||||
|
_ => Reference::null(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,17 @@ impl Natural {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(&mut self, value:u64)
|
pub fn set(&mut self, value:u64)
|
||||||
{
|
{
|
||||||
unsafe { natural_set(self.addr, value) };
|
unsafe { natural_set(self.addr, value) };
|
||||||
|
@ -7,6 +7,7 @@ use crate::runtime::{
|
|||||||
record_length,
|
record_length,
|
||||||
record_at, record_update,
|
record_at, record_update,
|
||||||
record_indexof, record_keyof,
|
record_indexof, record_keyof,
|
||||||
|
record_type,
|
||||||
};
|
};
|
||||||
use crate::tag;
|
use crate::tag;
|
||||||
use super::record;
|
use super::record;
|
||||||
@ -63,6 +64,17 @@ impl Record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize
|
pub fn length(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {record_length(self.addr)}
|
unsafe {record_length(self.addr)}
|
||||||
@ -98,17 +110,6 @@ impl Record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 indexof(&self, key:&str) -> Option<usize>
|
pub fn indexof(&self, key:&str) -> Option<usize>
|
||||||
{
|
{
|
||||||
let key_index = name_indexof(key);
|
let key_index = name_indexof(key);
|
||||||
@ -120,6 +121,22 @@ impl Record {
|
|||||||
None
|
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 std::ops::Deref for Record {
|
impl std::ops::Deref for Record {
|
||||||
type Target = Reference;
|
type Target = Reference;
|
||||||
|
@ -45,6 +45,17 @@ impl Schema {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize
|
pub fn length(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {schema_length(self.addr)}
|
unsafe {schema_length(self.addr)}
|
||||||
|
@ -33,14 +33,33 @@ impl 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
|
pub fn with(data:&str) -> Self
|
||||||
{
|
{
|
||||||
let mut obj = Self::new();
|
let mut obj = Self::new();
|
||||||
|
println!("a");
|
||||||
obj.set(data);
|
obj.set(data);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn length(&self) -> usize
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {sequence_length(self.addr)}
|
unsafe {sequence_length(self.addr)}
|
||||||
}
|
}
|
||||||
@ -48,6 +67,7 @@ impl Sequence {
|
|||||||
pub fn set_raw(&mut self, data:Vec<u8>)
|
pub fn set_raw(&mut self, data:Vec<u8>)
|
||||||
{
|
{
|
||||||
unsafe { sequence_clear(self.addr); }
|
unsafe { sequence_clear(self.addr); }
|
||||||
|
println!("c {}", data.len());
|
||||||
if data.len() > 0 {
|
if data.len() > 0 {
|
||||||
unsafe { sequence_reserve(self.addr, data.len()); }
|
unsafe { sequence_reserve(self.addr, data.len()); }
|
||||||
for i in 0..data.len() {
|
for i in 0..data.len() {
|
||||||
@ -65,6 +85,7 @@ impl Sequence {
|
|||||||
{
|
{
|
||||||
let length = unsafe {sequence_length(self.addr)};
|
let length = unsafe {sequence_length(self.addr)};
|
||||||
let mut result = Vec::<u8>::new();
|
let mut result = Vec::<u8>::new();
|
||||||
|
println!("d {}", length);
|
||||||
|
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
result.reserve_exact(length);
|
result.reserve_exact(length);
|
||||||
|
@ -9,3 +9,13 @@ pub fn release(addr:runtime::Reference)
|
|||||||
{
|
{
|
||||||
unsafe {runtime::release(addr)}
|
unsafe {runtime::release(addr)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copy(_dst:runtime::Reference, _src:runtime::Reference) -> Result<(),()>
|
||||||
|
{
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transfer(_dst:runtime::Reference, _src:runtime::Reference) -> Result<(),()>
|
||||||
|
{
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
@ -30,6 +30,17 @@ impl Varying {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(&mut self)
|
||||||
|
{
|
||||||
|
self.managed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(mut self)
|
||||||
|
{
|
||||||
|
self.detach();
|
||||||
|
unsafe { release(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_null(&self) -> bool
|
pub fn is_null(&self) -> bool
|
||||||
{
|
{
|
||||||
(unsafe {varying_get(self.addr)}).address == 0
|
(unsafe {varying_get(self.addr)}).address == 0
|
||||||
|
76
src/lib.rs
76
src/lib.rs
@ -3,58 +3,44 @@
|
|||||||
mod tag;
|
mod tag;
|
||||||
mod util;
|
mod util;
|
||||||
mod runtime;
|
mod runtime;
|
||||||
mod interface; pub use interface::*;
|
mod interface;
|
||||||
|
pub use interface::*;
|
||||||
const SCH_MAGAZINE :usize = 0x110;
|
mod encoding; pub use encoding::*;
|
||||||
const SCH_MAGAZINE_ROW :usize = 0x111;
|
|
||||||
|
|
||||||
pub fn test() {
|
pub fn test() {
|
||||||
Schema::with(vec![
|
Schema::with(vec![
|
||||||
("type", natural()),
|
("nat", natural()),
|
||||||
("quantity", natural()),
|
("pass", block(6)),
|
||||||
]).bind(SCH_MAGAZINE_ROW);
|
]).bind(9);
|
||||||
Schema::with(vec![
|
Schema::with(vec![
|
||||||
("size", natural()),
|
("str", sequence()),
|
||||||
("content", list(record(SCH_MAGAZINE_ROW))),
|
("int", integer()),
|
||||||
]).bind(SCH_MAGAZINE);
|
("bool", boolean()),
|
||||||
|
("rec", record(9)),
|
||||||
|
]).bind(10);
|
||||||
|
|
||||||
let mag = Record::with(SCH_MAGAZINE, vec![
|
let out = encode(*Record::with(10, vec![
|
||||||
("size", *Natural::with(30)),
|
("str", *Sequence::with("hello!")),
|
||||||
]).unwrap();
|
("int", *Integer::with(-70)),
|
||||||
let mut contents = List::from(mag.get("content")).unwrap();
|
("bool", *Boolean::with(true)),
|
||||||
contents.append(*Record::with_values(SCH_MAGAZINE_ROW, vec![
|
("rec", *Record::with(9, vec![
|
||||||
*Natural::with(2),
|
("nat", *Natural::with(8)),
|
||||||
*Natural::with(5),
|
("pass", *Block::with(6, vec![1, 2, 3, 4, 5, 6])),
|
||||||
|
]).unwrap()),
|
||||||
]).unwrap());
|
]).unwrap());
|
||||||
contents.append(*Record::with_values(SCH_MAGAZINE_ROW, vec![
|
match decode(&out, &mut 0) {
|
||||||
*Natural::with(1),
|
Ok(ty) => match ty {
|
||||||
*Natural::with(25),
|
Type::Record(rec) => {
|
||||||
]).unwrap());
|
println!("{}", Sequence::from(rec.get("str")).unwrap().get());
|
||||||
|
println!("{}", Integer::from(rec.get("int")).unwrap().get());
|
||||||
{
|
println!("{}", Boolean::from(rec.get("bool")).unwrap().get());
|
||||||
// get and remove bullet
|
let sub = Record::from(rec.get("rec")).unwrap();
|
||||||
let mut list = List::from(mag.at(1)).unwrap();
|
println!("{}", Natural::from(sub.get("nat")).unwrap().get());
|
||||||
if list.length() > 0 {
|
println!("{:?}", Block::from(sub.get("pass")).unwrap().get());
|
||||||
let row = Record::from(list.at(list.length() - 1)).unwrap();
|
|
||||||
let mut cell = Natural::from(row.at(1)).unwrap();
|
|
||||||
let value = cell.get();
|
|
||||||
if value > 1 {
|
|
||||||
cell.set(value - 1);
|
|
||||||
} else {
|
|
||||||
list.remove(list.length() - 1);
|
|
||||||
}
|
}
|
||||||
}
|
_ => { println!("Other"); }
|
||||||
}
|
},
|
||||||
|
Err(_) => { println!("Failure"); }
|
||||||
println!("Magazine ({})",
|
|
||||||
Natural::from(mag.at(0)).unwrap().get(),
|
|
||||||
);
|
|
||||||
for i in 0..contents.length() {
|
|
||||||
let row = Record::from(contents.at(i)).unwrap();
|
|
||||||
println!(" - {} [{}]",
|
|
||||||
Natural::from(row.at(0)).unwrap().get(),
|
|
||||||
Natural::from(row.at(1)).unwrap().get(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,20 +39,40 @@ extern "C" size_t type_size(size_t type_id)
|
|||||||
case Type::Tag::Boolean: return sizeof(Type::Boolean);
|
case Type::Tag::Boolean: return sizeof(Type::Boolean);
|
||||||
case Type::Tag::Natural: return sizeof(Type::Natural);
|
case Type::Tag::Natural: return sizeof(Type::Natural);
|
||||||
case Type::Tag::Integer: return sizeof(Type::Integer);
|
case Type::Tag::Integer: return sizeof(Type::Integer);
|
||||||
case Type::Tag::Block: return DB_TYPE.key(DB_TYPE.inner(type_id));
|
case Type::Tag::Block: return type_innerkey(type_id);
|
||||||
case Type::Tag::Sequence: return sizeof(Type::Sequence);
|
case Type::Tag::Sequence: return sizeof(Type::Sequence);
|
||||||
|
|
||||||
case Type::Tag::Array: {
|
case Type::Tag::Array: {
|
||||||
size_t length = DB_TYPE.inner(type_id);
|
size_t length = DB_TYPE.inner(type_id);
|
||||||
size_t inner = DB_TYPE.inner(length);
|
size_t inner = DB_TYPE.inner(length);
|
||||||
return static_cast<size_t>(DB_TYPE.key(length)) * type_size(inner);
|
if(inner == Type::Tag::Null) {
|
||||||
};
|
return sizeof(Reference);
|
||||||
case Type::Tag::List: return sizeof(Type::List);
|
}
|
||||||
case Type::Tag::Record: {
|
else {
|
||||||
auto binding = DB_SCHEMA.get(type_innerkey(type_id));
|
return static_cast<size_t>(DB_TYPE.key(length)) * type_size(inner);
|
||||||
if(binding != nullptr) {
|
|
||||||
return binding->size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Type::Tag::List:
|
||||||
|
case Type::Tag::Record:
|
||||||
|
{
|
||||||
|
size_t innerkey = type_innerkey(type_id);
|
||||||
|
if(innerkey == Type::Tag::Null) {
|
||||||
|
return sizeof(Reference);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch(type) {
|
||||||
|
case Type::Tag::List: return sizeof(Type::List);
|
||||||
|
case Type::Tag::Record: {
|
||||||
|
auto binding = DB_SCHEMA.get(type_innerkey(type_id));
|
||||||
|
if(binding != nullptr) {
|
||||||
|
return binding->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case Type::Tag::Schema: return sizeof(Type::Schema);
|
case Type::Tag::Schema: return sizeof(Type::Schema);
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
@ -88,6 +108,24 @@ size_t type_alignment(size_t type_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" size_t kind_hasinner(size_t kind)
|
||||||
|
{
|
||||||
|
switch(kind) {
|
||||||
|
case Type::Tag::Array:
|
||||||
|
return 2;
|
||||||
|
case Type::Tag::Block:
|
||||||
|
case Type::Tag::List:
|
||||||
|
case Type::Tag::Record:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" size_t type_hasinner(size_t type_id)
|
||||||
|
{
|
||||||
|
return kind_hasinner(type_key(type_id));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
|
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
|
||||||
{
|
{
|
||||||
std::string str(reinterpret_cast<const char*>(bytes), length);
|
std::string str(reinterpret_cast<const char*>(bytes), length);
|
||||||
@ -239,18 +277,32 @@ bool copy(Reference src, Reference dst)
|
|||||||
case Type::Tag::Boolean:
|
case Type::Tag::Boolean:
|
||||||
case Type::Tag::Natural:
|
case Type::Tag::Natural:
|
||||||
case Type::Tag::Integer:
|
case Type::Tag::Integer:
|
||||||
case Type::Tag::Block:
|
case Type::Tag::Block: {
|
||||||
{
|
|
||||||
memcpy(destination.address, source.address, type_size(source.type));
|
memcpy(destination.address, source.address, type_size(source.type));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case Type::Tag::Sequence: {
|
||||||
|
auto& src_seq = *reinterpret_cast<Type::Sequence*>(source.address);
|
||||||
|
auto& dst_seq = *reinterpret_cast<Type::Sequence*>(destination.address);
|
||||||
|
|
||||||
|
rawlist_clear(dst_seq.data);
|
||||||
|
rawlist_reserve(dst_seq.data, sizeof(uint8_t), src_seq.data.length);
|
||||||
|
memcpy(dst_seq.data.data, src_seq.data.data, sizeof(uint8_t) * src_seq.data.length);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Type::Tag::Array: {
|
||||||
|
for(size_t i = 0; i < array_length(source); ++i) {
|
||||||
|
copy(array_cell(source, i), array_cell(destination, i));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case Type::Tag::List: {
|
case Type::Tag::List: {
|
||||||
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
|
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
|
||||||
auto& dst_list = *reinterpret_cast<Type::List*>(destination.address);
|
auto& dst_list = *reinterpret_cast<Type::List*>(destination.address);
|
||||||
|
|
||||||
|
drop(destination);
|
||||||
rawlist_reserve(dst_list.data, type_size(type_inner(source.type)), src_list.data.capacity);
|
rawlist_reserve(dst_list.data, type_size(type_inner(source.type)), src_list.data.capacity);
|
||||||
dst_list.data.length = src_list.data.length;
|
dst_list.data.length = src_list.data.length;
|
||||||
//dst_list.data = allocate(type_inner(source.type), src_list.capacity);
|
|
||||||
|
|
||||||
for(size_t i = 0; i < src_list.data.length; ++i) {
|
for(size_t i = 0; i < src_list.data.length; ++i) {
|
||||||
copy(list_at(source, i), list_at(destination, i));
|
copy(list_at(source, i), list_at(destination, i));
|
||||||
@ -273,6 +325,8 @@ bool copy(Reference src, Reference dst)
|
|||||||
auto& src_schema = *reinterpret_cast<Type::Schema*>(source.address);
|
auto& src_schema = *reinterpret_cast<Type::Schema*>(source.address);
|
||||||
auto& dst_schema = *reinterpret_cast<Type::Schema*>(destination.address);
|
auto& dst_schema = *reinterpret_cast<Type::Schema*>(destination.address);
|
||||||
|
|
||||||
|
rawlist_clear(dst_schema.data);
|
||||||
|
rawlist_clear(dst_schema.map);
|
||||||
rawlist_reserve(dst_schema.data, sizeof(size_t), src_schema.data.length);
|
rawlist_reserve(dst_schema.data, sizeof(size_t), src_schema.data.length);
|
||||||
rawlist_reserve(dst_schema.map, sizeof(size_t), src_schema.map.length);
|
rawlist_reserve(dst_schema.map, sizeof(size_t), src_schema.map.length);
|
||||||
|
|
||||||
@ -300,6 +354,20 @@ bool copy(Reference src, Reference dst)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference resolve_addr(Reference addr)
|
||||||
|
{
|
||||||
|
Reference result = addr;
|
||||||
|
if(result.type == Type::Tag::Null) {
|
||||||
|
if(result.address != nullptr) {
|
||||||
|
result = *reinterpret_cast<Reference*>(result.address);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result = Reference {0};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Varying //
|
// Varying //
|
||||||
|
|
||||||
@ -677,6 +745,15 @@ extern "C" size_t record_length(Reference addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" size_t record_type(Reference addr, size_t index)
|
||||||
|
{
|
||||||
|
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
|
||||||
|
if(binding != nullptr && index < binding->data.size()) {
|
||||||
|
return binding->data[index].type;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference record_cell(Reference addr, size_t index)
|
Reference record_cell(Reference addr, size_t index)
|
||||||
{
|
{
|
||||||
Reference result {0};
|
Reference result {0};
|
||||||
@ -890,6 +967,7 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
|
|||||||
binding.data.push_back(row);
|
binding.data.push_back(row);
|
||||||
}
|
}
|
||||||
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
||||||
|
binding.references = 0;
|
||||||
|
|
||||||
for(size_t i = 0; i < object.map.length; ++i) {
|
for(size_t i = 0; i < object.map.length; ++i) {
|
||||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
|
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
|
||||||
|
@ -24,9 +24,11 @@ extern "C" void test();
|
|||||||
extern "C" size_t type_outer(size_t id, size_t key);
|
extern "C" size_t type_outer(size_t id, size_t key);
|
||||||
extern "C" size_t type_inner(size_t id);
|
extern "C" size_t type_inner(size_t id);
|
||||||
extern "C" size_t type_key(size_t id);
|
extern "C" size_t type_key(size_t id);
|
||||||
|
extern "C" size_t type_innerkey(size_t id);
|
||||||
extern "C" size_t type_size(size_t type_id);
|
extern "C" size_t type_size(size_t type_id);
|
||||||
|
size_t type_alignment(size_t type_id);
|
||||||
|
extern "C" size_t type_hasinner(size_t type_id);
|
||||||
|
|
||||||
//extern "C" size_t schema_bind(Reference addr, size_t id);
|
|
||||||
|
|
||||||
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length);
|
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length);
|
||||||
std::string name_keyof_internal(size_t index);
|
std::string name_keyof_internal(size_t index);
|
||||||
@ -37,6 +39,8 @@ extern "C" Reference acquire(size_t type_id);
|
|||||||
extern "C" void release(Reference id);
|
extern "C" void release(Reference id);
|
||||||
extern "C" bool copy(Reference src, Reference dst);
|
extern "C" bool copy(Reference src, Reference dst);
|
||||||
|
|
||||||
|
Reference resolve_addr(Reference addr);
|
||||||
|
|
||||||
// Varying //
|
// Varying //
|
||||||
extern "C" Reference varying_get(Reference addr);
|
extern "C" Reference varying_get(Reference addr);
|
||||||
extern "C" void varying_set(Reference addr, Reference source);
|
extern "C" void varying_set(Reference addr, Reference source);
|
||||||
@ -93,6 +97,7 @@ extern "C" void list_reserve(Reference addr, size_t capacity);
|
|||||||
|
|
||||||
// Record //
|
// Record //
|
||||||
extern "C" size_t record_length(Reference addr);
|
extern "C" size_t record_length(Reference addr);
|
||||||
|
extern "C" size_t record_type(Reference addr, size_t index);
|
||||||
Reference record_cell(Reference addr, size_t index);
|
Reference record_cell(Reference addr, size_t index);
|
||||||
extern "C" Reference record_at(Reference addr, size_t index);
|
extern "C" Reference record_at(Reference addr, size_t index);
|
||||||
extern "C" void record_update(Reference addr, size_t index, Reference source);
|
extern "C" void record_update(Reference addr, size_t index, Reference source);
|
||||||
|
@ -37,6 +37,9 @@ extern "C" {
|
|||||||
pub fn type_outer(type_id:usize, key:usize) -> usize;
|
pub fn type_outer(type_id:usize, key:usize) -> usize;
|
||||||
pub fn type_inner(type_id:usize) -> usize;
|
pub fn type_inner(type_id:usize) -> usize;
|
||||||
pub fn type_key(type_id:usize) -> usize;
|
pub fn type_key(type_id:usize) -> usize;
|
||||||
|
pub fn type_innerkey(type_id:usize) -> usize;
|
||||||
|
pub fn kind_hasinner(kind:usize) -> usize;
|
||||||
|
pub fn type_hasinner(type_id:usize) -> usize;
|
||||||
|
|
||||||
pub fn type_size(type_id:usize) -> usize;
|
pub fn type_size(type_id:usize) -> usize;
|
||||||
|
|
||||||
@ -92,6 +95,7 @@ extern "C" {
|
|||||||
//pub fn list_count(addr:Reference, target:Reference, start:usize) -> usize;
|
//pub fn list_count(addr:Reference, target:Reference, start:usize) -> usize;
|
||||||
|
|
||||||
pub fn record_length(addr:Reference) -> usize;
|
pub fn record_length(addr:Reference) -> usize;
|
||||||
|
pub fn record_type(addr:Reference, index:usize) -> usize;
|
||||||
pub fn record_at(addr:Reference, index:usize) -> Reference;
|
pub fn record_at(addr:Reference, index:usize) -> Reference;
|
||||||
pub fn record_update(addr:Reference, index:usize, source:Reference);
|
pub fn record_update(addr:Reference, index:usize, source:Reference);
|
||||||
pub fn record_keyof(addr:Reference, index:usize) -> usize;
|
pub fn record_keyof(addr:Reference, index:usize) -> usize;
|
||||||
|
@ -111,7 +111,7 @@ public:
|
|||||||
return find_header(index) != m_headers.size();
|
return find_header(index) != m_headers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const T* get(size_t index) const
|
T* get(size_t index)
|
||||||
{
|
{
|
||||||
size_t header_index = find_header(index);
|
size_t header_index = find_header(index);
|
||||||
if(header_index < m_headers.size()) {
|
if(header_index < m_headers.size()) {
|
||||||
|
@ -77,6 +77,7 @@ struct SchemaBinding {
|
|||||||
size_t binding;
|
size_t binding;
|
||||||
size_t alignment;
|
size_t alignment;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
size_t references;
|
||||||
|
|
||||||
SparseList<size_t> map;
|
SparseList<size_t> map;
|
||||||
std::vector<Row> data;
|
std::vector<Row> data;
|
||||||
|
97
src/tests.rs
97
src/tests.rs
@ -62,7 +62,7 @@ fn integer_set_get()
|
|||||||
fn block_initialize()
|
fn block_initialize()
|
||||||
{
|
{
|
||||||
let value = Block::new(8);
|
let value = Block::new(8);
|
||||||
assert_eq!(8, value.length(), "Block::new(8) has length of 8.");
|
assert_eq!(8, value.size(), "Block::new(8) has length of 8.");
|
||||||
assert_eq!(vec![0;8], value.get(), "Block::new(8) has value of 0.");
|
assert_eq!(vec![0;8], value.get(), "Block::new(8) has value of 0.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ fn block_set_get()
|
|||||||
fn sequence_initialize()
|
fn sequence_initialize()
|
||||||
{
|
{
|
||||||
let value = Sequence::new();
|
let value = Sequence::new();
|
||||||
assert_eq!(0, value.length(), "Sequence::new() has length 0.");
|
assert_eq!(0, value.size(), "Sequence::new() has length 0.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -86,7 +86,7 @@ fn sequence_set_get_raw()
|
|||||||
{
|
{
|
||||||
let mut value = Sequence::new();
|
let mut value = Sequence::new();
|
||||||
value.set_raw(vec![0, 1, 2, 3, 2, 1]);
|
value.set_raw(vec![0, 1, 2, 3, 2, 1]);
|
||||||
assert_eq!(6, value.length(), "Sequence.set_raw([0,1,2,3,2,1]) has length 6.");
|
assert_eq!(6, value.size(), "Sequence.set_raw([0,1,2,3,2,1]) has length 6.");
|
||||||
assert_eq!(vec![0,1,2,3,2,1], value.get_raw(), "Sequence.set_raw([0,1,2,3,2,1]) produces value [0,1,2,3,2,1].");
|
assert_eq!(vec![0,1,2,3,2,1], value.get_raw(), "Sequence.set_raw([0,1,2,3,2,1]) produces value [0,1,2,3,2,1].");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,10 +95,46 @@ fn sequence_set_get_str()
|
|||||||
{
|
{
|
||||||
let mut value = Sequence::new();
|
let mut value = Sequence::new();
|
||||||
value.set("hello");
|
value.set("hello");
|
||||||
assert_eq!(5, value.length(), "Sequence.set(hello) has length 5.");
|
assert_eq!(5, value.size(), "Sequence.set(hello) has length 5.");
|
||||||
assert_eq!(String::from("hello"), value.get(), "Sequence.set(hello) produces value hello.");
|
assert_eq!(String::from("hello"), value.get(), "Sequence.set(hello) produces value hello.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_from()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_with()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_length()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_at()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_set()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_initialize()
|
fn list_initialize()
|
||||||
{
|
{
|
||||||
@ -147,7 +183,16 @@ fn list_clear()
|
|||||||
#[test]
|
#[test]
|
||||||
fn list_insert()
|
fn list_insert()
|
||||||
{
|
{
|
||||||
|
let mut list = List::with(natural(), vec![
|
||||||
|
*Natural::with(21),
|
||||||
|
*Natural::with(23),
|
||||||
|
*Natural::with(24),
|
||||||
|
]);
|
||||||
|
assert_eq!(3, list.length(), "List initialized with 3 elements has length of 3.");
|
||||||
|
list.insert(1, *Natural::with(22));
|
||||||
|
assert_eq!(21, list.length(), "First element has value of 21.");
|
||||||
|
assert_eq!(22, list.length(), "Second element has value of 22.");
|
||||||
|
assert_eq!(23, list.length(), "Third element has value of 23.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -222,3 +267,45 @@ fn list_reserve()
|
|||||||
list.reserve(capacity);
|
list.reserve(capacity);
|
||||||
assert_eq!(capacity, list.capacity(), "List has updated capacity.");
|
assert_eq!(capacity, list.capacity(), "List has updated capacity.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_from()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_with()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_with_values()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_at()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_set()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn schema_initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user