From f8575ec0418e7ef8a44b175e4164bdd3613bffcc Mon Sep 17 00:00:00 2001 From: Able Date: Thu, 30 Mar 2023 22:19:57 -0500 Subject: [PATCH] initial work on the EXI format --- Cargo.lock | 4 + Cargo.toml | 1 + drivers/audio/pc_beeper_driver/src/main.rs | 3 + libraries/exi/Cargo.toml | 8 ++ libraries/exi/src/lib.rs | 58 +++++++++++ libraries/exi/src/types.rs | 107 +++++++++++++++++++++ libraries/std/src/lib.rs | 1 - libraries/std/src/object/mod.rs | 84 ---------------- libraries/std/src/object/types.rs | 48 --------- 9 files changed, 181 insertions(+), 133 deletions(-) create mode 100644 libraries/exi/Cargo.toml create mode 100644 libraries/exi/src/lib.rs create mode 100644 libraries/exi/src/types.rs delete mode 100644 libraries/std/src/object/mod.rs delete mode 100644 libraries/std/src/object/types.rs diff --git a/Cargo.lock b/Cargo.lock index b88af32..7275495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,10 @@ dependencies = [ name = "derelict_microarchitecture" version = "0.1.0" +[[package]] +name = "exi" +version = "0.1.0" + [[package]] name = "fnv" version = "1.0.7" diff --git a/Cargo.toml b/Cargo.toml index 2aef1a2..a0bd7ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ "libraries/audio_interface", "libraries/clparse", "libraries/cryptography", + "libraries/exi", "libraries/locale-maxima", "libraries/messaging", "libraries/process", diff --git a/drivers/audio/pc_beeper_driver/src/main.rs b/drivers/audio/pc_beeper_driver/src/main.rs index cc04b80..5002c39 100644 --- a/drivers/audio/pc_beeper_driver/src/main.rs +++ b/drivers/audio/pc_beeper_driver/src/main.rs @@ -1,7 +1,10 @@ #![no_std] #![no_main] +extern crate alloc; + #[no_mangle] fn start() { // Simple driver + let mut audio_ring: [u8; 2048] = [0; 2048]; } diff --git a/libraries/exi/Cargo.toml b/libraries/exi/Cargo.toml new file mode 100644 index 0000000..f997c39 --- /dev/null +++ b/libraries/exi/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "exi" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/libraries/exi/src/lib.rs b/libraries/exi/src/lib.rs new file mode 100644 index 0000000..ba6b7dc --- /dev/null +++ b/libraries/exi/src/lib.rs @@ -0,0 +1,58 @@ +use types::NBitUnsignedInteger; + +pub mod types; + +pub const EXI_HEADER_START: &str = "$EXI"; + +pub struct ExiOptions { + // NOTE: Go back to the EXI spec and fix this + pub alignment: u8, + + pub compression: bool, + + pub strict: bool, + + pub fragment: bool, + + // https://www.w3.org/TR/exi/#key-preserveOption + pub preserve: bool, + + // https://www.w3.org/TR/exi/#key-selfContained + pub self_contained: bool, + + // https://www.w3.org/TR/exi/#key-schemaIdOption + pub schema_id: String, + + // https://www.w3.org/TR/exi/#key-datatypeRepresentationOption + // NOTE: What possible usecase could you have for changing the representation of data types. + // Touching this will be UB. Cry about it. + pub datatype_representation_map: bool, + + // https://www.w3.org/TR/exi/#key-blockSizeOption + pub block_size: NBitUnsignedInteger, + + // https://www.w3.org/TR/exi/#key-valueMaxLengthOption + pub value_max_length: NBitUnsignedInteger, + + // https://www.w3.org/TR/exi/#key-valuePartitionCapacityOption + pub value_partition_capacity: NBitUnsignedInteger, + + // https://www.w3.org/TR/exi/#key-userMetaData + pub user_defined_meta_data: String, +} + +pub enum ExiFormatVersion { + PreviewVersion1 = 1_0000, + // The ableOS standard + FinalVersion1 = 0_0000, + FinalVersion15 = 0_1110, + FinalVersion16 = 0_1111_0000, + FinalVersion17 = 0_1111_0001, +} + +pub struct ExiHeader { + exi_format: ExiFormatVersion, + exi_options: ExiOptions, +} + +pub struct ExiDocument {} diff --git a/libraries/exi/src/types.rs b/libraries/exi/src/types.rs new file mode 100644 index 0000000..d871755 --- /dev/null +++ b/libraries/exi/src/types.rs @@ -0,0 +1,107 @@ +pub struct List { + pub length: usize, + pub values: Vec, +} +// https://www.w3.org/TR/exi/#encodingUnsignedInteger +pub struct NBitUnsignedInteger { + pub length: Option, + pub bits: Vec, +} +impl NBitUnsignedInteger { + pub fn new(length: Integer) -> Self { + let c = if length.bits == vec![0] { + None + } else { + Some(length) + }; + Self { + length: c, + bits: Vec::new(), + } + } +} + +pub struct BinaryBlob { + pub length: Integer, + pub bytes: Vec, +} + +pub struct Decimal { + pub lhs: UnsignedInteger, + pub rhs: UnsignedInteger, +} + +pub enum EXITypes { + Binary(BinaryBlob), + Boolean(bool), + Decimal(Decimal), + Float(f64), + Integer(Integer), + UnsignedInteger(UnsignedInteger), + QName(String), + DateTime(DateTime), + NBitUnsignedInteger(NBitUnsignedInteger), + String(String), + List(List), +} + +pub struct DateTime { + pub year: Integer, + pub month_day: NBitUnsignedInteger, + pub time: NBitUnsignedInteger, + pub fractional_secs: NBitUnsignedInteger, + pub timezone: NBitUnsignedInteger, + pub presence: bool, +} + +impl DateTime { + pub fn new() -> Self { + Self { + year: Integer::new(), + month_day: NBitUnsignedInteger::new(9.into()), + time: NBitUnsignedInteger::new(17.into()), + fractional_secs: NBitUnsignedInteger::new(9.into()), + timezone: NBitUnsignedInteger::new(11.into()), + presence: false, + } + } +} + +pub struct Integer { + pub negative: bool, + pub bits: Vec, +} +impl Integer { + pub fn new() -> Self { + Self { + negative: false, + bits: vec![0], + } + } +} + +impl From for Integer { + fn from(value: i8) -> Self { + Self { + negative: value.is_negative(), + bits: value.abs().to_le_bytes().to_vec(), + } + } +} + +pub struct UnsignedInteger { + pub bits: Vec, +} +impl UnsignedInteger { + pub fn new() -> Self { + Self { bits: vec![0] } + } +} + +impl From for UnsignedInteger { + fn from(value: i8) -> Self { + Self { + bits: value.abs().to_le_bytes().to_vec(), + } + } +} diff --git a/libraries/std/src/lib.rs b/libraries/std/src/lib.rs index 1b09fe3..b781d37 100644 --- a/libraries/std/src/lib.rs +++ b/libraries/std/src/lib.rs @@ -8,7 +8,6 @@ mod entry; pub mod env; pub mod exit; pub mod io; -pub mod object; #[cfg(not(test))] pub mod panic; diff --git a/libraries/std/src/object/mod.rs b/libraries/std/src/object/mod.rs deleted file mode 100644 index 32b6aa4..0000000 --- a/libraries/std/src/object/mod.rs +++ /dev/null @@ -1,84 +0,0 @@ -pub mod types; -use types::*; - -use alloc::string::{String, ToString}; -use alloc::vec::Vec; - -use hashbrown::HashMap; -#[derive(Debug)] -pub enum ObjectErrors { - PropertyNotFound, - NoProperties, - FailureToInsert, -} - -pub struct Object { - properties: HashMap, - children: Option>, -} -impl Object { - pub fn new(name: Types) -> Self { - let mut obj = Self { - properties: HashMap::new(), - children: None, - }; - let _ = obj.set_value("name".into(), name); - obj - } - pub fn get_value(&mut self, key: Types) -> Result { - use ObjectErrors::*; - if self.properties.is_empty() { - return Err(NoProperties); - } - - let ret = self.properties.get(&key).unwrap(); - Ok(ret.clone()) - } - pub fn set_value(&mut self, key: Types, value: Types) -> Result<(), ObjectErrors> { - let ret = self.properties.insert(key, value); - match ret { - Some(_) => {} - None => return Err(ObjectErrors::FailureToInsert), - } - - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::{types::Types, Object}; - - #[test] - fn object_creation() { - let obj = Object::new(Types::new("hi")); - } - - #[test] - fn property_set() { - let key = Types::Byte(8); - let value = Types::Byte(9); - - let mut obj = Object::new("hi".into()); - obj.set_value(key, value); - } - - #[test] - fn property_read() { - let key = Types::new("name"); - - let mut obj = Object::new("hi".into()); - obj.set_value("name".into(), "hi".into()).unwrap(); - let ret = obj.get_value(key); - - match ret { - Ok(val) => assert_eq!(val, Types::new("hi")), - Err(_err) => todo!(), - } - } -} - -#[inline] -fn type_of(_: &T) -> &str { - core::any::type_name::() -} diff --git a/libraries/std/src/object/types.rs b/libraries/std/src/object/types.rs deleted file mode 100644 index 5c33d25..0000000 --- a/libraries/std/src/object/types.rs +++ /dev/null @@ -1,48 +0,0 @@ -use core::fmt::Debug; -use core::fmt::Display; - -use alloc::string::{String, ToString}; - -use super::type_of; - -#[derive(PartialEq, Eq, Hash, Debug, Clone)] -pub enum Types { - Null, - Byte(u8), - String(String), -} -impl Types { - pub fn new(value: T) -> Self { - let type_of = type_of(&value); - match type_of { - "&str" => return Self::String(value.to_string()), - "alloc::string::String" => return Self::String(value.to_string()), - type_name => { - panic!( - " - Invalid type: {} - {}", - value, type_name - ); - } - } - } -} - -impl From for Types { - fn from(value: u8) -> Self { - Self::Byte(value) - } -} - -impl From for Types { - fn from(value: String) -> Self { - Self::String(value) - } -} - -impl From<&str> for Types { - fn from(value: &str) -> Self { - Self::String(value.to_string()) - } -}