Initialize project.

This commit is contained in:
yukirij 2023-04-26 22:13:32 -07:00
commit 9b3f7698b5
13 changed files with 362 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View 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
View 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
View File

@ -0,0 +1,12 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"rust-analyzer.linkedProjects": [
".\\Cargo.toml"
]
}
}

7
src/bin/main.rs Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,3 @@
pub trait Type {
fn tag() -> u32;
}

123
src/util/mod.rs Normal file
View 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
}