cat_dev/fsemul/pcfs/sata/proto/
write_file.rs1use crate::{errors::NetworkParseError, fsemul::pcfs::sata::proto::MoveToFileLocation};
7use bytes::{Buf, BufMut, Bytes, BytesMut};
8use valuable::{Fields, NamedField, NamedValues, StructDef, Structable, Valuable, Value, Visit};
9
10#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct SataWriteFilePacketBody {
13 block_count: u32,
14 block_size: u32,
15 handle: i32,
16 move_to_pointer: MoveToFileLocation,
17 should_move: bool,
18}
19
20impl SataWriteFilePacketBody {
21 #[must_use]
23 pub const fn new(
24 block_count: u32,
25 block_size: u32,
26 file_descriptor: i32,
27 move_to: Option<MoveToFileLocation>,
28 ) -> Self {
29 Self {
30 block_count,
31 block_size,
32 handle: file_descriptor,
33 move_to_pointer: if let Some(mt) = move_to {
34 mt
35 } else {
36 MoveToFileLocation::Begin
37 },
38 should_move: move_to.is_some(),
39 }
40 }
41
42 #[must_use]
43 pub const fn block_count(&self) -> u32 {
44 self.block_count
45 }
46
47 pub const fn set_block_count(&mut self, new_count: u32) {
48 self.block_count = new_count;
49 }
50
51 #[must_use]
52 pub const fn block_size(&self) -> u32 {
53 self.block_size
54 }
55
56 pub const fn set_block_size(&mut self, new_size: u32) {
57 self.block_size = new_size;
58 }
59
60 #[must_use]
61 pub const fn file_descriptor(&self) -> i32 {
62 self.handle
63 }
64
65 pub const fn set_file_descriptor(&mut self, new_fd: i32) {
66 self.handle = new_fd;
67 }
68
69 #[must_use]
70 pub const fn move_to_pointer(&self) -> MoveToFileLocation {
71 self.move_to_pointer
72 }
73
74 pub const fn set_move_to(&mut self, new_move: Option<MoveToFileLocation>) {
75 if let Some(nm) = new_move {
76 self.move_to_pointer = nm;
77 self.should_move = true;
78 } else {
79 self.move_to_pointer = MoveToFileLocation::Begin;
80 self.should_move = false;
81 }
82 }
83
84 #[must_use]
85 pub const fn should_move(&self) -> bool {
86 self.should_move
87 }
88}
89
90impl From<&SataWriteFilePacketBody> for Bytes {
91 fn from(value: &SataWriteFilePacketBody) -> Self {
92 let mut buff = BytesMut::with_capacity(20);
93
94 buff.put_u32(value.block_count);
95 buff.put_u32(value.block_size);
96 buff.put_i32(value.handle);
97 buff.put_u32(u32::from(value.move_to_pointer));
98 buff.put_u32(u32::from(value.should_move));
100
101 buff.freeze()
102 }
103}
104
105impl From<SataWriteFilePacketBody> for Bytes {
106 fn from(value: SataWriteFilePacketBody) -> Self {
107 Self::from(&value)
108 }
109}
110
111impl TryFrom<Bytes> for SataWriteFilePacketBody {
112 type Error = NetworkParseError;
113
114 fn try_from(mut value: Bytes) -> Result<Self, Self::Error> {
115 if value.len() < 20 {
116 return Err(NetworkParseError::FieldNotLongEnough(
117 "SataWriteFile",
118 "Body",
119 20,
120 value.len(),
121 value,
122 ));
123 }
124 if value.len() > 20 {
125 return Err(NetworkParseError::UnexpectedTrailer(
126 "SataWriteFile",
127 value.slice(20..),
128 ));
129 }
130
131 let block_count = value.get_u32();
132 let block_length = value.get_u32();
133 let handle = value.get_i32();
134 let move_to_ptr = value.get_u32();
135 let should_move = value.get_u32();
136
137 Ok(Self {
138 block_count,
139 block_size: block_length,
140 handle,
141 move_to_pointer: MoveToFileLocation::try_from(move_to_ptr)?,
142 should_move: (should_move & 1) != 0,
143 })
144 }
145}
146
147const SATA_WRITE_FILE_PACKET_BODY_FIELDS: &[NamedField<'static>] = &[
148 NamedField::new("block_count"),
149 NamedField::new("block_size"),
150 NamedField::new("handle"),
151 NamedField::new("move_to_pointer"),
152 NamedField::new("should_move"),
153];
154
155impl Structable for SataWriteFilePacketBody {
156 fn definition(&self) -> StructDef<'_> {
157 StructDef::new_static(
158 "SataWriteFilePacketBody",
159 Fields::Named(SATA_WRITE_FILE_PACKET_BODY_FIELDS),
160 )
161 }
162}
163
164impl Valuable for SataWriteFilePacketBody {
165 fn as_value(&self) -> Value<'_> {
166 Value::Structable(self)
167 }
168
169 fn visit(&self, visitor: &mut dyn Visit) {
170 visitor.visit_named_fields(&NamedValues::new(
171 SATA_WRITE_FILE_PACKET_BODY_FIELDS,
172 &[
173 Valuable::as_value(&self.block_count),
174 Valuable::as_value(&self.block_size),
175 Valuable::as_value(&self.handle),
176 Valuable::as_value(&self.move_to_pointer),
177 Valuable::as_value(&self.should_move),
178 ],
179 ));
180 }
181}