1use inherit_methods_macro::inherit_methods;
6use ostd_pod::Pod;
7
8use super::{Infallible, PodOnce, VmIo, VmIoFill, VmIoOnce, VmReader, VmWriter};
9use crate::{
10 Error,
11 mm::{FallibleVmRead, FallibleVmWrite},
12 prelude::*,
13};
14
15pub trait HasVmReaderWriter {
21 type Types: VmReaderWriterTypes;
30
31 fn reader(&self) -> <Self::Types as VmReaderWriterTypes>::Reader<'_>;
33 fn writer(&self) -> <Self::Types as VmReaderWriterTypes>::Writer<'_>;
35}
36
37pub trait VmReaderWriterTypes {
39 type Reader<'a>;
41 type Writer<'a>;
43
44 fn to_reader_result(reader: Self::Reader<'_>) -> Result<VmReader<'_, Infallible>>;
46 fn to_writer_result(writer: Self::Writer<'_>) -> Result<VmWriter<'_, Infallible>>;
48}
49
50pub enum VmReaderWriterIdentity {}
52impl VmReaderWriterTypes for VmReaderWriterIdentity {
53 type Reader<'a> = VmReader<'a, Infallible>;
54 type Writer<'a> = VmWriter<'a, Infallible>;
55 fn to_reader_result(reader: Self::Reader<'_>) -> Result<VmReader<'_, Infallible>> {
56 Ok(reader)
57 }
58 fn to_writer_result(writer: Self::Writer<'_>) -> Result<VmWriter<'_, Infallible>> {
59 Ok(writer)
60 }
61}
62
63pub enum VmReaderWriterResult {}
65impl VmReaderWriterTypes for VmReaderWriterResult {
66 type Reader<'a> = Result<VmReader<'a, Infallible>>;
67 type Writer<'a> = Result<VmWriter<'a, Infallible>>;
68 fn to_reader_result(reader: Self::Reader<'_>) -> Result<VmReader<'_, Infallible>> {
69 reader
70 }
71 fn to_writer_result(writer: Self::Writer<'_>) -> Result<VmWriter<'_, Infallible>> {
72 writer
73 }
74}
75
76impl<S: HasVmReaderWriter + Send + Sync> VmIo for S {
77 fn read(&self, offset: usize, writer: &mut VmWriter) -> Result<()> {
78 let mut reader = <Self as HasVmReaderWriter>::Types::to_reader_result(self.reader())?;
79
80 let limit = offset.checked_add(writer.avail()).ok_or(Error::Overflow)?;
81 if limit > reader.remain() {
82 return Err(Error::InvalidArgs);
83 }
84
85 reader.skip(offset);
86 let _len = reader
87 .to_fallible()
88 .read_fallible(writer)
89 .map_err(|(err, _)| err)?;
90 debug_assert!(!writer.has_avail());
91 Ok(())
92 }
93
94 fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
95 let mut reader = <Self as HasVmReaderWriter>::Types::to_reader_result(self.reader())?;
96
97 let limit = offset.checked_add(buf.len()).ok_or(Error::Overflow)?;
98 if limit > reader.remain() {
99 return Err(Error::InvalidArgs);
100 }
101
102 let len = reader.skip(offset).read(&mut VmWriter::from(&mut *buf));
103 debug_assert_eq!(len, buf.len());
104 Ok(())
105 }
106
107 fn read_val<T: Pod>(&self, offset: usize) -> Result<T> {
111 let mut reader = <Self as HasVmReaderWriter>::Types::to_reader_result(self.reader())?;
112
113 if offset > reader.remain() {
114 return Err(Error::InvalidArgs);
115 }
116
117 reader.skip(offset).read_val()
118 }
119
120 fn write(&self, offset: usize, reader: &mut VmReader) -> Result<()> {
121 let mut writer = <Self as HasVmReaderWriter>::Types::to_writer_result(self.writer())?;
122
123 let limit = offset.checked_add(reader.remain()).ok_or(Error::Overflow)?;
124 if limit > writer.avail() {
125 return Err(Error::InvalidArgs);
126 }
127
128 writer.skip(offset);
129 let _len = writer
130 .to_fallible()
131 .write_fallible(reader)
132 .map_err(|(err, _)| err)?;
133 debug_assert!(!reader.has_remain());
134 Ok(())
135 }
136
137 fn write_bytes(&self, offset: usize, buf: &[u8]) -> Result<()> {
138 let mut writer = <Self as HasVmReaderWriter>::Types::to_writer_result(self.writer())?;
139
140 let limit = offset.checked_add(buf.len()).ok_or(Error::Overflow)?;
141 if limit > writer.avail() {
142 return Err(Error::InvalidArgs);
143 }
144
145 let len = writer.skip(offset).write(&mut VmReader::from(buf));
146 debug_assert_eq!(len, buf.len());
147 Ok(())
148 }
149
150 fn write_val<T: Pod>(&self, offset: usize, new_val: &T) -> Result<()> {
154 let mut writer = <Self as HasVmReaderWriter>::Types::to_writer_result(self.writer())?;
155
156 if offset > writer.avail() {
157 return Err(Error::InvalidArgs);
158 }
159
160 writer.skip(offset).write_val(new_val)
161 }
162}
163
164impl<S: HasVmReaderWriter> VmIoFill for S {
165 fn fill_zeros(&self, offset: usize, len: usize) -> core::result::Result<(), (Error, usize)> {
166 let mut writer = <Self as HasVmReaderWriter>::Types::to_writer_result(self.writer())
167 .map_err(|err| (err, 0))?;
168
169 if offset > writer.avail() {
170 return Err((Error::InvalidArgs, 0));
171 }
172
173 let filled_len = writer.skip(offset).fill_zeros(len);
174 if filled_len == len {
175 Ok(())
176 } else {
177 Err((Error::InvalidArgs, filled_len))
178 }
179 }
180}
181
182impl<S: HasVmReaderWriter> VmIoOnce for S {
183 fn read_once<T: PodOnce>(&self, offset: usize) -> Result<T> {
184 let mut reader = <Self as HasVmReaderWriter>::Types::to_reader_result(self.reader())?;
185 reader.skip(offset).read_once()
186 }
187
188 fn write_once<T: PodOnce>(&self, offset: usize, new_val: &T) -> Result<()> {
189 let mut writer = <Self as HasVmReaderWriter>::Types::to_writer_result(self.writer())?;
190 writer.skip(offset).write_once(new_val)
191 }
192}
193
194macro_rules! impl_vm_io_pointer {
201 ($typ:ty,$from:tt) => {
202 #[inherit_methods(from = $from)]
203 impl<T: HasVmReaderWriter> HasVmReaderWriter for $typ {
204 type Types = T::Types;
205 fn reader(&self) -> <Self::Types as VmReaderWriterTypes>::Reader<'_>;
206 fn writer(&self) -> <Self::Types as VmReaderWriterTypes>::Writer<'_>;
207 }
208 };
209}
210
211impl_vm_io_pointer!(&T, "(**self)");
212impl_vm_io_pointer!(&mut T, "(**self)");
213impl_vm_io_pointer!(Box<T>, "(**self)");
214impl_vm_io_pointer!(Arc<T>, "(**self)");