From e502eefecd7cd1950177fd50361e2202b3fae587 Mon Sep 17 00:00:00 2001 From: Aleksey Yakovlev Date: Fri, 28 Jun 2024 14:45:02 +0700 Subject: [PATCH] refactored byte buffer --- .gitignore | 2 +- .idea/hexo.iml | 1 + Cargo.lock | 5 ++ Cargo.toml | 4 + hexo-io/Cargo.toml | 6 ++ .../util => hexo-io/src}/byte_buffer.rs | 79 +++++++++++-------- hexo-io/src/lib.rs | 1 + src/compiler/compiler.rs | 2 +- src/compiler/native_fn/implementations.rs | 14 ++-- src/compiler/native_fn/signature.rs | 2 +- src/compiler/rst/compilation_context.rs | 3 +- src/compiler/rst/compiler.rs | 3 +- src/compiler/rst/node.rs | 2 +- src/compiler/util/mod.rs | 2 - src/main.rs | 2 + 15 files changed, 81 insertions(+), 47 deletions(-) create mode 100644 hexo-io/Cargo.toml rename {src/compiler/util => hexo-io/src}/byte_buffer.rs (59%) create mode 100644 hexo-io/src/lib.rs diff --git a/.gitignore b/.gitignore index aeb54e4..95a45ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea -/target +**/target out.bin \ No newline at end of file diff --git a/.idea/hexo.iml b/.idea/hexo.iml index e70e9ce..f4f9d0b 100644 --- a/.idea/hexo.iml +++ b/.idea/hexo.iml @@ -2,6 +2,7 @@ + diff --git a/Cargo.lock b/Cargo.lock index c2f86e6..b383aa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -229,11 +229,16 @@ version = "0.7.5" dependencies = [ "clap", "console", + "hexo-io", "notify", "pest", "pest_derive", ] +[[package]] +name = "hexo-io" +version = "0.1.0" + [[package]] name = "inotify" version = "0.9.6" diff --git a/Cargo.toml b/Cargo.toml index 862c648..eb2f237 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,9 +15,13 @@ exclude = [ "testcases" ] +[workspace] +members = ["hexo-io"] + [dependencies] clap = { version = "4.5.4", features = ["derive"] } pest = "2.7.9" pest_derive = "2.7.9" notify = "6.1.1" console = "0.15.8" +hexo-io = { path = "hexo-io" } diff --git a/hexo-io/Cargo.toml b/hexo-io/Cargo.toml new file mode 100644 index 0000000..ae4d240 --- /dev/null +++ b/hexo-io/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hexo-io" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/src/compiler/util/byte_buffer.rs b/hexo-io/src/byte_buffer.rs similarity index 59% rename from src/compiler/util/byte_buffer.rs rename to hexo-io/src/byte_buffer.rs index 20ac3dc..a9b90ee 100644 --- a/src/compiler/util/byte_buffer.rs +++ b/hexo-io/src/byte_buffer.rs @@ -1,38 +1,40 @@ -use crate::compiler::util::encoding::to_shrunk_bytes; use std::fmt::{Debug, Formatter}; use std::string::FromUtf8Error; #[derive(Clone)] -pub(crate) struct ByteBuffer { +pub struct ByteBuffer { inner: Vec, } -impl ByteBuffer { - pub(crate) fn new() -> Self { - ByteBuffer { inner: Vec::new() } +impl Debug for ByteBuffer { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("{:?}", self.inner)) } +} - pub(crate) fn from(vec: Vec) -> Self { - ByteBuffer { inner: vec } +impl ByteBuffer { + pub fn new() -> Self { + ByteBuffer { inner: Vec::new() } } - pub(crate) fn push_byte(&mut self, byte: u8) { + pub fn push_byte(&mut self, byte: u8) { self.inner.push(byte); } - pub(crate) fn push_string(&mut self, string: String) { + pub fn push_string(&mut self, string: String) { self.inner.extend_from_slice(string.as_bytes()); } - pub(crate) fn push_u32_shrunk(&mut self, num: u32) { - self.inner.extend(to_shrunk_bytes(num)); + pub fn push_u32_shrunk(&mut self, num: u32) { + self.inner.extend(Self::_to_shrunk_bytes(num)); } - pub(crate) fn push_byte_buffer(&mut self, other: &ByteBuffer) { - self.inner.extend(other.as_vec()); + pub fn push_byte_buffer(&mut self, other: &ByteBuffer) { + self.inner.extend(other.to_vec()); } - pub(crate) fn pad_left(&mut self, size: usize) { + /// Moves the byte buffer to the left by the specified [size] + pub fn pad_left(&mut self, size: usize) { let padding = size.checked_sub(self.inner.len()); if let Some(padding) = padding { if padding > 0 { @@ -43,7 +45,8 @@ impl ByteBuffer { } } - pub(crate) fn pad_right(&mut self, size: usize) { + /// Moves the byte buffer to the right by the specified [size] + pub fn pad_right(&mut self, size: usize) { let padding = size.checked_sub(self.inner.len()); if let Some(padding) = padding { @@ -54,15 +57,12 @@ impl ByteBuffer { } } - pub(crate) fn len(&self) -> usize { + /// Returns the length of the byte buffer + pub fn len(&self) -> usize { self.inner.len() } - pub(crate) fn as_vec(&self) -> Vec { - self.inner.clone() - } - - pub(crate) fn as_usize(&self) -> usize { + pub fn as_usize_unsafe(&self) -> usize { let mut padded = self.clone(); padded.pad_left(4); ((padded.inner[0] as usize) << 24) + @@ -71,13 +71,35 @@ impl ByteBuffer { (padded.inner[3] as usize) } - pub(crate) fn as_string(&self) -> Result { + /// Clones inner representation of the byte buffer and returns Vec of it + pub fn to_vec(&self) -> Vec { + self.inner.clone() + } + + pub fn to_string(&self) -> Result { String::from_utf8(self.inner.clone()) } + + fn _to_shrunk_bytes(value: u32) -> Vec { + let mut bytes = Vec::new(); + let mut value = value; + while value > 0 { + bytes.push((value & 0xFF) as u8); + value >>= 8; + } + bytes + } + +} + +impl From> for ByteBuffer { + fn from(value: Vec) -> Self { + ByteBuffer { inner: value } + } } mod test { - use crate::compiler::util::ByteBuffer; + use crate::byte_buffer::ByteBuffer; #[test] fn byte_push() { @@ -87,7 +109,7 @@ mod test { assert_eq!(buffer.len(), 2); - assert_eq!(buffer.as_vec(), vec![0x01, 0x02]); + assert_eq!(buffer.to_vec(), vec![0x01, 0x02]); } #[test] @@ -98,7 +120,7 @@ mod test { assert_eq!(buffer.len(), 11); assert_eq!( - buffer.as_vec(), + buffer.to_vec(), vec![104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] ); } @@ -110,12 +132,7 @@ mod test { assert_eq!(buffer.len(), 1); - assert_eq!(buffer.as_vec(), vec![13]); + assert_eq!(buffer.to_vec(), vec![13]); } } -impl Debug for ByteBuffer { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str(&format!("{:?}", self.inner)) - } -} diff --git a/hexo-io/src/lib.rs b/hexo-io/src/lib.rs new file mode 100644 index 0000000..6f5abef --- /dev/null +++ b/hexo-io/src/lib.rs @@ -0,0 +1 @@ +pub mod byte_buffer; diff --git a/src/compiler/compiler.rs b/src/compiler/compiler.rs index 9072ded..0c07d14 100644 --- a/src/compiler/compiler.rs +++ b/src/compiler/compiler.rs @@ -55,6 +55,6 @@ impl HexoCompiler { ) -> Result { let rst = self.compile_rst(source)?; - Ok(Compilation::from(rst.emits.as_vec())) + Ok(Compilation::from(rst.emits.to_vec())) } } diff --git a/src/compiler/native_fn/implementations.rs b/src/compiler/native_fn/implementations.rs index 463041f..d3d607f 100644 --- a/src/compiler/native_fn/implementations.rs +++ b/src/compiler/native_fn/implementations.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; use std::fs::File; use std::io::Read; +use hexo_io::byte_buffer::ByteBuffer; use crate::compiler::native_fn::error::Error; use crate::compiler::native_fn::signature::{NativeFunction, NativeFunctionSignature}; -use crate::compiler::util::ByteBuffer; pub(crate) fn create_len_native_function() -> NativeFunction { NativeFunction { @@ -32,7 +32,7 @@ pub(crate) fn create_pad_left_native_function() -> NativeFunction { let mut arg0 = get_argument_at(&arguments, 0, "pad_left")?.clone(); let arg1 = get_argument_at(&arguments, 1, "pad_left")?; - arg0.pad_left(arg1.as_usize()); + arg0.pad_left(arg1.as_usize_unsafe()); Ok(arg0.clone()) }, @@ -48,7 +48,7 @@ pub(crate) fn create_pad_right_native_function() -> NativeFunction { let mut arg0: ByteBuffer = get_argument_at(&arguments, 0, "pad_right")?.clone(); let arg1 = get_argument_at(&arguments, 1, "pad_right")?; - arg0.pad_right(arg1.as_usize()); + arg0.pad_right(arg1.as_usize_unsafe()); Ok(arg0.clone()) }, @@ -62,7 +62,7 @@ pub(crate) fn create_cmd_native_function() -> NativeFunction { }, executor: |arguments: HashMap| { let command = get_argument_at(&arguments, 0, "cmd")? - .as_string() + .to_string() .map_err(|e| Error::Unknown(e.to_string()))?; let output = std::process::Command::new(command) @@ -88,7 +88,7 @@ pub(crate) fn create_read_file_native_function() -> NativeFunction { executor: |arguments: HashMap| { let arg0 = get_argument_at(&arguments, 0, "read_file")?; - let file_path = arg0.as_string() + let file_path = arg0.to_string() .map_err(|e| Error::Unknown(e.to_string()))?; let mut file = File::open(file_path) @@ -122,9 +122,9 @@ pub(crate) fn create_pad_native_function() -> NativeFunction { let mut buffer = get_argument_at(&arguments, 0, "pad")?.clone(); let left_padding = get_named_argument(&arguments, "left") - .map(|b| b.as_usize()); + .map(|b| b.as_usize_unsafe()); let right_padding = get_named_argument(&arguments, "right") - .map(|b| b.as_usize()); + .map(|b| b.as_usize_unsafe()); if let Some(size) = left_padding { buffer.pad_left(size); diff --git a/src/compiler/native_fn/signature.rs b/src/compiler/native_fn/signature.rs index 68e26a2..5d79542 100644 --- a/src/compiler/native_fn/signature.rs +++ b/src/compiler/native_fn/signature.rs @@ -1,5 +1,5 @@ -use crate::compiler::util::ByteBuffer; use std::collections::HashMap; +use hexo_io::byte_buffer::ByteBuffer; use crate::compiler::native_fn::error::Error; #[derive(Clone, Debug)] diff --git a/src/compiler/rst/compilation_context.rs b/src/compiler/rst/compilation_context.rs index 802754c..2fb3073 100644 --- a/src/compiler/rst/compilation_context.rs +++ b/src/compiler/rst/compilation_context.rs @@ -2,8 +2,7 @@ use crate::compiler::cst::{CstEmitStatement}; use crate::compiler::native_fn::{NativeFunction, NativeFunctionIndex}; use std::collections::HashMap; use std::path::{Path, PathBuf}; - -use crate::compiler::util::ByteBuffer; +use hexo_io::byte_buffer::ByteBuffer; #[derive(Clone, Debug)] pub(crate) struct ConstantBinding { diff --git a/src/compiler/rst/compiler.rs b/src/compiler/rst/compiler.rs index 6981776..4e06805 100644 --- a/src/compiler/rst/compiler.rs +++ b/src/compiler/rst/compiler.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::path::Path; +use hexo_io::byte_buffer::ByteBuffer; use crate::compiler::cst::{ CstActualParameter, CstAtom, CstAtomVec, CstEmitStatement, CstFile, CstFunctionStatement, @@ -8,7 +9,7 @@ use crate::compiler::rst::compilation_context::{ CompilationContext, ConstantBinding, FunctionBinding, }; use crate::compiler::rst::node::HexoFile; -use crate::compiler::util::{ByteBuffer, next_identifier}; +use crate::compiler::util::{next_identifier}; use crate::compiler::HexoCompiler; use crate::compiler::rst::error::Error; diff --git a/src/compiler/rst/node.rs b/src/compiler/rst/node.rs index 1f1ae13..0538554 100644 --- a/src/compiler/rst/node.rs +++ b/src/compiler/rst/node.rs @@ -1,6 +1,6 @@ use crate::compiler::rst::compilation_context::CompilationContext; -use crate::compiler::util::ByteBuffer; use std::path::PathBuf; +use hexo_io::byte_buffer::ByteBuffer; #[derive(Debug)] pub(crate) struct HexoFile { diff --git a/src/compiler/util/mod.rs b/src/compiler/util/mod.rs index 792d474..76e6453 100644 --- a/src/compiler/util/mod.rs +++ b/src/compiler/util/mod.rs @@ -1,6 +1,4 @@ -mod byte_buffer; pub(crate) mod encoding; mod id_generator; -pub(crate) use byte_buffer::ByteBuffer; pub(crate) use id_generator::next_identifier; diff --git a/src/main.rs b/src/main.rs index 1dd0625..25e2318 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,8 @@ fn run_sample() -> Result<(), Error> { #[test] fn run_test_cases() { fn read_file(filename: &PathBuf) -> Vec { + let a = hexo_io::byte_buffer::ByteBuffer::new(); + let mut f = File::open(filename).expect("no file found"); let metadata = std::fs::metadata(filename).expect("unable to read metadata"); let mut buffer = vec![0; metadata.len() as usize];