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