aboutsummaryrefslogtreecommitdiff
path: root/src/datatypes.rs
diff options
context:
space:
mode:
authorIgor Tolmachov <me@igorek.dev>2023-09-08 17:33:59 +0900
committerIgor Tolmachev <me@igorek.dev>2024-06-23 15:34:33 +0900
commit9003b81813ff171edfc6101868c226c5c7d1957c (patch)
tree63db162b56b282bc2ec71f86f26dee8dbc2550c8 /src/datatypes.rs
parentb8c83ab5c133dc1330aa425a012d45f3c62e7ef1 (diff)
downloadarchivator-9003b81813ff171edfc6101868c226c5c7d1957c.tar.gz
archivator-9003b81813ff171edfc6101868c226c5c7d1957c.zip
Add basic zip reader
Diffstat (limited to 'src/datatypes.rs')
-rw-r--r--src/datatypes.rs116
1 files changed, 10 insertions, 106 deletions
diff --git a/src/datatypes.rs b/src/datatypes.rs
index 7712064..59c7552 100644
--- a/src/datatypes.rs
+++ b/src/datatypes.rs
@@ -1,116 +1,20 @@
1use crate::result::ArchiveResult; 1use crate::result::ArchiveResult;
2use crate::utils::ReadHelper;
2use std::io::{Read, Write}; 3use std::io::{Read, Write};
3 4
4pub trait ArchiveDatatype 5pub trait ArchiveDatatype<const SIZE: usize>: Sized {
5where 6 const SIZE: usize = SIZE;
6 Self: Sized,
7{
8 const SIZE: usize;
9 7
10 fn read(reader: impl Read) -> ArchiveResult<Self>; 8 fn parse(buf: [u8; SIZE]) -> Self;
11 9
12 fn write(&self, writer: impl Write) -> ArchiveResult<()>; 10 fn dump(&self) -> [u8; SIZE];
13}
14
15pub mod utils {
16 pub fn read_string(buf: &[u8]) -> String {
17 String::from_utf8(buf.into()).unwrap()
18 }
19 11
20 pub fn write_string(string: &str) -> &[u8] { 12 fn read(mut reader: impl Read) -> ArchiveResult<Self> {
21 string.as_bytes() 13 Ok(Self::parse(reader.read2buf::<SIZE>()?))
22 } 14 }
23 15
24 pub fn vec(vec: &[u8]) -> &[u8] { 16 fn write(&self, mut writer: impl Write) -> ArchiveResult<()> {
25 vec 17 writer.write(&self.dump())?;
18 Ok(())
26 } 19 }
27
28 #[macro_export]
29 macro_rules! create_archive_datatype {
30 {
31 $vis:vis struct $struct_name:ident {
32 $($field:ident: $field_type:ty,)*
33 }
34
35 $(
36 let $custom_field:ident: $custom_field_type:ty {
37 size: $custom_field_size: expr,
38 read: $custom_field_read: path,
39 write: $custom_field_write: path,
40 }
41 )*
42
43 $(
44 const {
45 $($const_name:ident: $const_type:ty = $const_value:expr;)+
46 }
47 )?
48
49 $(
50 read $read_code:block
51 )?
52
53 $(
54 write $write_code:block
55 )?
56 }
57 => {
58 #[derive(Debug)]
59 $vis struct $struct_name {
60 $($vis $field: $field_type),*,
61 $($vis $custom_field: $custom_field_type),*
62 }
63
64 $(
65 impl $struct_name {
66 $(const $const_name: $const_type = $const_value;)*
67 }
68 )?
69
70 impl ArchiveDatatype for $struct_name {
71 const SIZE: usize = ($((<$field_type>::BITS / 8)+)*0) as usize;
72
73 fn read(mut reader: impl Read) -> ArchiveResult<Self> {
74 let mut buf = [0; Self::SIZE];
75 reader.read(&mut buf)?;
76
77 $(
78 let (bytes, buf) = buf.split_at((<$field_type>::BITS / 8) as usize);
79 let $field = <$field_type>::from_le_bytes(bytes.try_into().unwrap());
80 )*
81
82 $(
83 let $custom_field = {
84 let mut buf = vec![0; $custom_field_size as usize];
85 reader.read(&mut buf)?;
86 $custom_field_read(&buf).into()
87 };
88 )*
89
90 #[allow(dropping_references)]
91 drop(buf);
92
93 $($read_code;)?
94
95 Ok(
96 Self {
97 $($field),*,
98 $($custom_field),*
99 }
100 )
101 }
102
103 fn write(&self, mut writer: impl Write) -> ArchiveResult<()> {
104 $($write_code;)?
105 writer.write(&[
106 $(&self.$field.to_le_bytes()[..]),*,
107 $(&$custom_field_write(&self.$custom_field)),*
108 ].concat())?;
109 Ok(())
110 }
111 }
112 };
113 }
114
115 pub use create_archive_datatype;
116} 20}