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