diff --git a/examples/example.rs b/examples/example.rs index 9f29414a..f39afd1e 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -2,7 +2,11 @@ use std::convert::{TryFrom, TryInto}; -use deku::prelude::*; +use deku::{ + container::Container, + ctx::{BitSize, ByteSize, Endian}, + prelude::*, +}; #[derive(Debug, PartialEq, DekuRead, DekuWrite)] struct FieldF { @@ -49,8 +53,18 @@ fn main() { ] .as_ref(); - let test_deku = DekuTest::try_from(test_data).unwrap(); + let mut container = Container::new(std::io::Cursor::new(test_data.clone())); + let a = u8::from_reader(&mut container, (Endian::Little, ByteSize(1))); + let b = u8::from_reader(&mut container, (Endian::Little, BitSize(7))); + let c = u8::from_reader(&mut container, (Endian::Little, BitSize(1))); + let d = u16::from_reader(&mut container, (Endian::Big, BitSize(16))); + println!("{a:02x?}"); + println!("{b:02x?}"); + println!("{c:02x?}"); + println!("{d:02x?}"); + let test_deku = DekuTest::try_from(test_data).unwrap(); + println!("{test_deku:02x?}"); assert_eq!( DekuTest { field_a: 0xab, diff --git a/src/impls/primitive.rs b/src/impls/primitive.rs index 7168b8ee..48cb21a6 100644 --- a/src/impls/primitive.rs +++ b/src/impls/primitive.rs @@ -3,6 +3,7 @@ use alloc::format; use core::convert::TryInto; use bitvec::prelude::*; +use std::io::Read; use crate::ctx::*; use crate::prelude::NeedSize; @@ -23,6 +24,15 @@ impl DekuRead<'_, (Endian, ByteSize)> for u8 { let value = input[..MAX_TYPE_BITS].load::(); Ok((MAX_TYPE_BITS, value)) } + + fn from_reader( + container: &mut crate::container::Container, + (endian, size): (Endian, ByteSize), + ) -> Result { + let mut bits = container.read_bits(8).unwrap(); + let a = ::read(&mut bits, (endian, size))?; + Ok(a.1) + } } macro_rules! ImplDekuReadBits { @@ -111,6 +121,15 @@ macro_rules! ImplDekuReadBits { }; Ok((bit_size, value)) } + + fn from_reader( + container: &mut crate::container::Container, + (endian, size): (Endian, BitSize), + ) -> Result<$typ, DekuError> { + let mut bits = container.read_bits(size.0).unwrap(); + let a = <$typ>::read(&mut bits, (endian, size))?; + Ok(a.1) + } } }; } @@ -182,6 +201,15 @@ macro_rules! ImplDekuReadBytes { Ok((bit_size, value)) } + + fn from_reader( + container: &mut crate::container::Container, + (endian, size): (Endian, ByteSize), + ) -> Result<$typ, DekuError> { + let mut bits = container.read_bits(size.0 * 8).unwrap(); + let a = <$typ>::read(&mut bits, (endian, size))?; + Ok(a.1) + } } }; } @@ -202,7 +230,17 @@ macro_rules! ImplDekuReadSignExtend { let value = (value as $typ) << shift >> shift; Ok((amt_read, value)) } + + fn from_reader( + container: &mut crate::container::Container, + (endian, size): (Endian, ByteSize), + ) -> Result<$typ, DekuError> { + let mut bits = container.read_bits(size.0 * 8).unwrap(); + let a = <$typ>::read(&mut bits, (endian, size))?; + Ok(a.1) + } } + impl DekuRead<'_, (Endian, BitSize)> for $typ { fn read( input: &BitSlice, @@ -217,6 +255,14 @@ macro_rules! ImplDekuReadSignExtend { let value = (value as $typ) << shift >> shift; Ok((amt_read, value)) } + fn from_reader( + container: &mut crate::container::Container, + (endian, size): (Endian, BitSize), + ) -> Result<$typ, DekuError> { + let mut bits = container.read_bits(size.0).unwrap(); + let a = <$typ>::read(&mut bits, (endian, size))?; + Ok(a.1) + } } }; } @@ -238,6 +284,17 @@ macro_rules! ForwardDekuRead { <$typ>::read(input, (endian, bit_size)) } } + + fn from_reader( + container: &mut crate::container::Container, + endian: Endian, + ) -> Result<$typ, DekuError> { + let bit_size = BitSize::of::<$typ>(); + + let mut bits = container.read_bits(bit_size.0).unwrap(); + let a = <$typ>::read(&mut bits, endian)?; + Ok(a.1) + } } // Only have `bit_size`, set `endian` to `Endian::default`. @@ -250,6 +307,17 @@ macro_rules! ForwardDekuRead { <$typ>::read(input, (endian, byte_size)) } + + fn from_reader( + container: &mut crate::container::Container, + byte_size: ByteSize, + ) -> Result<$typ, DekuError> { + let endian = Endian::default(); + + let mut bits = container.read_bits(byte_size.0 * 8).unwrap(); + let a = <$typ>::read(&mut bits, (endian, byte_size))?; + Ok(a.1) + } } // Only have `bit_size`, set `endian` to `Endian::default`. @@ -267,12 +335,30 @@ macro_rules! ForwardDekuRead { <$typ>::read(input, (endian, bit_size)) } } + + fn from_reader( + container: &mut crate::container::Container, + bit_size: BitSize, + ) -> Result<$typ, DekuError> { + let endian = Endian::default(); + + let mut bits = container.read_bits(bit_size.0).unwrap(); + let a = <$typ>::read(&mut bits, bit_size)?; + Ok(a.1) + } } impl DekuRead<'_> for $typ { fn read(input: &BitSlice, _: ()) -> Result<(usize, Self), DekuError> { <$typ>::read(input, Endian::default()) } + + fn from_reader( + container: &mut crate::container::Container, + _: (), + ) -> Result<$typ, DekuError> { + <$typ>::from_reader(container, Endian::default()) + } } }; } diff --git a/src/lib.rs b/src/lib.rs index 97819920..dc2018e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -269,6 +269,8 @@ pub struct EncodedString { #[cfg(feature = "alloc")] extern crate alloc; +use std::io::Read; + #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -281,6 +283,7 @@ pub mod bitvec { pub use deku_derive::*; pub mod attributes; +pub mod container; pub mod ctx; pub mod error; mod impls; @@ -302,6 +305,16 @@ pub trait DekuRead<'a, Ctx = ()> { ) -> Result<(usize, Self), DekuError> where Self: Sized; + + fn from_reader( + container: &mut crate::container::Container, + ctx: Ctx, + ) -> Result + where + Self: Sized, + { + todo!(); + } } /// "Reader" trait: implemented on DekuRead struct and enum containers. A `container` is a type which