Initialize project.
This commit is contained in:
commit
9b3f7698b5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "szun"
|
||||||
|
version = "0.1.0"
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "szun"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
12
project.code-workspace
Normal file
12
project.code-workspace
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"rust-analyzer.linkedProjects": [
|
||||||
|
".\\Cargo.toml"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
7
src/bin/main.rs
Normal file
7
src/bin/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fn main()
|
||||||
|
{
|
||||||
|
let d = szun::Integer::from(-1);
|
||||||
|
let enc = d.encode();
|
||||||
|
|
||||||
|
for b in enc { print!("{:02x}", b); } print!("\n");
|
||||||
|
}
|
19
src/data/boolean.rs
Normal file
19
src/data/boolean.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::{Szun, Type};
|
||||||
|
|
||||||
|
pub struct Boolean {
|
||||||
|
data:bool,
|
||||||
|
}
|
||||||
|
impl Boolean {
|
||||||
|
pub fn new() -> Szun
|
||||||
|
{
|
||||||
|
Szun::Boolean(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from(data:bool) -> Szun
|
||||||
|
{
|
||||||
|
Szun::Boolean(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Type for Boolean {
|
||||||
|
fn tag() -> u32 { 0x02 }
|
||||||
|
}
|
19
src/data/integer.rs
Normal file
19
src/data/integer.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::{Szun, Type};
|
||||||
|
|
||||||
|
pub struct Integer {
|
||||||
|
data:i64,
|
||||||
|
}
|
||||||
|
impl Integer {
|
||||||
|
pub fn new() -> Szun
|
||||||
|
{
|
||||||
|
Szun::Integer(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from(data:i64) -> Szun
|
||||||
|
{
|
||||||
|
Szun::Integer(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Type for Integer {
|
||||||
|
fn tag() -> u32 { 0x11 }
|
||||||
|
}
|
4
src/data/mod.rs
Normal file
4
src/data/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
mod null; pub use null::Null;
|
||||||
|
mod boolean; pub use boolean::Boolean;
|
||||||
|
mod natural; pub use natural::Natural;
|
||||||
|
mod integer; pub use integer::Integer;
|
19
src/data/natural.rs
Normal file
19
src/data/natural.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use crate::{Szun, Type};
|
||||||
|
|
||||||
|
pub struct Natural {
|
||||||
|
data:u64,
|
||||||
|
}
|
||||||
|
impl Natural {
|
||||||
|
pub fn new() -> Szun
|
||||||
|
{
|
||||||
|
Szun::Natural(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from(data:u64) -> Szun
|
||||||
|
{
|
||||||
|
Szun::Natural(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Type for Natural {
|
||||||
|
fn tag() -> u32 { 0x10 }
|
||||||
|
}
|
11
src/data/null.rs
Normal file
11
src/data/null.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use crate::{Szun, Type};
|
||||||
|
|
||||||
|
pub struct Null { }
|
||||||
|
impl Null {
|
||||||
|
pub fn new() -> Szun {
|
||||||
|
Szun::Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Type for Null {
|
||||||
|
fn tag() -> u32 { 0x00 }
|
||||||
|
}
|
129
src/lib.rs
Normal file
129
src/lib.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
mod util;
|
||||||
|
mod template; use template::Type;
|
||||||
|
mod data; pub use data::*;
|
||||||
|
|
||||||
|
pub enum Szun {
|
||||||
|
Null,
|
||||||
|
Boolean(bool),
|
||||||
|
Natural(u64),
|
||||||
|
Integer(i64),
|
||||||
|
Decimal(f64),
|
||||||
|
Block(Vec<u8>),
|
||||||
|
String(String),
|
||||||
|
Set(Vec<Szun>),
|
||||||
|
Array(Vec<Szun>),
|
||||||
|
List(Vec<Szun>),
|
||||||
|
Sparse(Vec<Szun>),
|
||||||
|
Map(Vec<Szun>),
|
||||||
|
//Tree(Vec<Szun>),
|
||||||
|
//Graph(Vec<Szun>),
|
||||||
|
Enum(Vec<Szun>),
|
||||||
|
Selection(Vec<Szun>),
|
||||||
|
Record(Vec<Szun>),
|
||||||
|
Schema(Vec<Szun>),
|
||||||
|
}
|
||||||
|
impl Szun {
|
||||||
|
fn encode_parts(&self) -> (Vec<u32>, Vec<u8>)
|
||||||
|
{
|
||||||
|
let mut tags = Vec::<u32>::with_capacity(1);
|
||||||
|
let mut encoded = Vec::<u8>::with_capacity(64);
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Self::Null => {
|
||||||
|
tags.push(Null::tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Boolean(_data) => {
|
||||||
|
tags.push(Boolean::tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Natural(data) => {
|
||||||
|
tags.push(Natural::tag());
|
||||||
|
encoded.append(&mut util::pack_natural(*data));
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Integer(data) => {
|
||||||
|
tags.push(Integer::tag());
|
||||||
|
encoded.append(&mut &mut util::pack_integer(*data));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
tags.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Self::Decimal(_data) => {
|
||||||
|
tag = Decimal::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Block(_data) => {
|
||||||
|
tag = Block::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::String(_data) => {
|
||||||
|
tag = String::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Set(_data) => {
|
||||||
|
tag = Set::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Array(_data) => {
|
||||||
|
tag = Array::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::List(_data) => {
|
||||||
|
tag = List::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Sparse(_data) => {
|
||||||
|
tag = Sparse::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Map(_data) => {
|
||||||
|
tag = Map::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Enum(_data) => {
|
||||||
|
tag = Enum::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Selection(_data) => {
|
||||||
|
tag = Selection::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Record(_data) => {
|
||||||
|
tag = Record::tag();
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::Schema(_data) => {
|
||||||
|
tag = Schema::tag();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return (tags, encoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode_data(&self) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let (_, encoded) = self.encode_parts();
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode(&self) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let (tags, data) = self.encode_parts();
|
||||||
|
let mut prefix = Vec::<u8>::with_capacity(16);
|
||||||
|
|
||||||
|
for tag in tags {
|
||||||
|
prefix.append(&mut util::pack_natural(tag as u64));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut encoded = Vec::<u8>::with_capacity(prefix.len() + data.len());
|
||||||
|
for b in prefix { encoded.push(b); }
|
||||||
|
for b in data { encoded.push(b); }
|
||||||
|
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
}
|
3
src/template/mod.rs
Normal file
3
src/template/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub trait Type {
|
||||||
|
fn tag() -> u32;
|
||||||
|
}
|
123
src/util/mod.rs
Normal file
123
src/util/mod.rs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
fn pack_count_leading_ones(data:u8) -> usize
|
||||||
|
{
|
||||||
|
(data == 0xff) as usize
|
||||||
|
+ (data >= 0xfe) as usize
|
||||||
|
+ (data >= 0xfc) as usize
|
||||||
|
+ (data >= 0xf8) as usize
|
||||||
|
+ (data >= 0xf0) as usize
|
||||||
|
+ (data >= 0xe0) as usize
|
||||||
|
+ (data >= 0xc0) as usize
|
||||||
|
+ (data >= 0x80) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pack_encode_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
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pack_data(size:usize, data:u64, sign:bool) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut data = data;
|
||||||
|
let mut buffer :Vec<u8> = vec![0];
|
||||||
|
let mut header_size = size - 1;
|
||||||
|
let mut buffer_size = size;
|
||||||
|
|
||||||
|
if header_size >= 8 {
|
||||||
|
buffer.append(&mut pack_natural(header_size as u64));
|
||||||
|
buffer_size += buffer.len() - 1;
|
||||||
|
header_size = 8;
|
||||||
|
}
|
||||||
|
buffer.resize(buffer_size, 0);
|
||||||
|
buffer[0] = ((0xFF00 >> header_size) & 0xFF) as u8;
|
||||||
|
|
||||||
|
for i in 1..buffer_size + 1 {
|
||||||
|
buffer[buffer_size - i] |= (data & 0xFF) as u8;
|
||||||
|
data >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if sign {
|
||||||
|
match header_size {
|
||||||
|
8 => { buffer[buffer_size - (size - 1)] |= 0x80; }
|
||||||
|
7 => { buffer[1] |= 0x80; }
|
||||||
|
_ => { buffer[0] |= 1 << 6 - header_size; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pack_natural(data:u64) -> Vec<u8>
|
||||||
|
{
|
||||||
|
pack_data(pack_encode_size(data, false), data, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pack_integer(data:i64) -> Vec<u8>
|
||||||
|
{
|
||||||
|
let mut udata :u64 = data as u64;
|
||||||
|
let negative :bool = data < 0;
|
||||||
|
if negative { udata = !udata; }
|
||||||
|
|
||||||
|
pack_data(pack_encode_size(udata, true), udata, negative)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack_data(data:&Vec<u8>, index:&mut usize, signed:bool) -> u64
|
||||||
|
{
|
||||||
|
let mut result :u64 = 0;
|
||||||
|
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 {
|
||||||
|
let sign_mask = 1 << (6 - pack_size);
|
||||||
|
println!("data: {}, mask: {}", result, sign_mask);
|
||||||
|
negative = (result & sign_mask) != 0;
|
||||||
|
result &= !sign_mask;
|
||||||
|
}
|
||||||
|
*index += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*index += 1;
|
||||||
|
if pack_size == 8 {
|
||||||
|
pack_size = unpack_natural(&data, index) as usize;
|
||||||
|
}
|
||||||
|
pack_size -= 1;
|
||||||
|
|
||||||
|
result = data[*index] as u64;
|
||||||
|
if signed {
|
||||||
|
negative = (result & 0x80) != 0;
|
||||||
|
result &= 0x7F;
|
||||||
|
}
|
||||||
|
*index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 1..pack_size + 1 {
|
||||||
|
result <<= 8;
|
||||||
|
result += data[*index] as u64;
|
||||||
|
*index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if negative { result = !result; }
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack_natural(data:&Vec<u8>, index:&mut usize) -> u64
|
||||||
|
{
|
||||||
|
unpack_data(data, index, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpack_integer(data:&Vec<u8>, index:&mut usize) -> i64
|
||||||
|
{
|
||||||
|
unpack_data(data, index, true) as i64
|
||||||
|
}
|
Reference in New Issue
Block a user