fdomain_client/fidl_next/
codec.rs1use super::wire_handle::WireHandle;
6use crate::responder::Responder;
7use crate::{AsHandleRef, Channel, ChannelMessageStream, ChannelWriter, Error, Handle};
8use fidl_fuchsia_fdomain as proto;
9use fidl_next_codec::decoder::InternalHandleDecoder;
10use fidl_next_codec::encoder::InternalHandleEncoder;
11use fidl_next_codec::{CHUNK_SIZE, Chunk, DecodeError, Decoder, EncodeError, Encoder};
12use fidl_next_protocol::Transport;
13use futures::channel::oneshot;
14use futures::{FutureExt, StreamExt};
15
16use std::pin::Pin;
17use std::ptr::NonNull;
18use std::task::{Context, Poll, ready};
19
20pub trait HandleDecoder {
22 fn take_raw_handle(&mut self) -> Result<u32, DecodeError>;
26
27 fn handles_remaining(&mut self) -> usize;
29}
30
31pub trait HandleEncoder {
33 fn push_handle(&mut self, handle: Handle) -> Result<(), EncodeError>;
35
36 fn handles_pushed(&self) -> usize;
38}
39
40#[derive(Default)]
42pub struct SendBuffer {
43 handles: Vec<Handle>,
44 chunks: Vec<Chunk>,
45}
46
47impl SendBuffer {
48 pub fn new() -> Self {
50 Self::default()
51 }
52
53 pub fn handles(&self) -> &[Handle] {
55 &self.handles
56 }
57}
58
59impl InternalHandleEncoder for SendBuffer {
60 #[inline]
61 fn __internal_handle_count(&self) -> usize {
62 self.handles.len()
63 }
64}
65
66impl Encoder for SendBuffer {
67 #[inline]
68 fn bytes_written(&self) -> usize {
69 Encoder::bytes_written(&self.chunks)
70 }
71
72 #[inline]
73 fn write_zeroes(&mut self, len: usize) {
74 Encoder::write_zeroes(&mut self.chunks, len)
75 }
76
77 #[inline]
78 fn write(&mut self, bytes: &[u8]) {
79 Encoder::write(&mut self.chunks, bytes)
80 }
81
82 #[inline]
83 fn rewrite(&mut self, pos: usize, bytes: &[u8]) {
84 Encoder::rewrite(&mut self.chunks, pos, bytes)
85 }
86}
87
88impl HandleEncoder for SendBuffer {
89 fn push_handle(&mut self, handle: Handle) -> Result<(), EncodeError> {
90 self.handles.push(handle.into());
91 Ok(())
92 }
93
94 fn handles_pushed(&self) -> usize {
95 self.handles.len()
96 }
97}
98
99pub struct RecvBuffer {
101 handles: Vec<WireHandle>,
102 chunks: Vec<Chunk>,
103 chunks_taken: usize,
104 handles_taken: usize,
105}
106
107unsafe impl Decoder for RecvBuffer {
108 fn take_chunks_raw(&mut self, count: usize) -> Result<NonNull<Chunk>, DecodeError> {
109 if count > self.chunks.len() - self.chunks_taken {
110 return Err(DecodeError::InsufficientData);
111 }
112
113 let chunks = unsafe { self.chunks.as_mut_ptr().add(self.chunks_taken) };
114 self.chunks_taken += count;
115
116 unsafe { Ok(NonNull::new_unchecked(chunks)) }
117 }
118
119 fn commit(&mut self) {
120 for handle in &mut self.handles[0..self.handles_taken] {
121 handle.invalidate();
122 }
123 }
124
125 fn finish(&self) -> Result<(), DecodeError> {
126 if self.chunks_taken != self.chunks.len() {
127 return Err(DecodeError::ExtraBytes {
128 num_extra: (self.chunks.len() - self.chunks_taken) * CHUNK_SIZE,
129 });
130 }
131
132 if self.handles_taken != self.handles.len() {
133 return Err(DecodeError::ExtraHandles {
134 num_extra: self.handles.len() - self.handles_taken,
135 });
136 }
137
138 Ok(())
139 }
140}
141
142impl InternalHandleDecoder for RecvBuffer {
143 fn __internal_take_handles(&mut self, count: usize) -> Result<(), DecodeError> {
144 if count > self.handles.len() - self.handles_taken {
145 return Err(DecodeError::InsufficientHandles);
146 }
147
148 for i in self.handles_taken..self.handles_taken + count {
149 drop(self.handles[i].take_handle());
150 }
151 self.handles_taken += count;
152
153 Ok(())
154 }
155
156 fn __internal_handles_remaining(&self) -> usize {
157 self.handles.len() - self.handles_taken
158 }
159}
160
161impl HandleDecoder for RecvBuffer {
162 fn take_raw_handle(&mut self) -> Result<u32, DecodeError> {
163 if self.handles_taken >= self.handles.len() {
164 return Err(DecodeError::InsufficientHandles);
165 }
166
167 let handle = self.handles[self.handles_taken].as_raw_handle();
168 self.handles_taken += 1;
169
170 Ok(handle)
171 }
172
173 fn handles_remaining(&mut self) -> usize {
174 self.handles.len() - self.handles_taken
175 }
176}
177
178#[derive(Clone)]
180pub struct Shared {
181 writer: ChannelWriter,
182}
183
184pub enum SendFutureState {
186 BadGeometry,
188 Wait(oneshot::Receiver<Result<(), Error>>),
189}
190
191pub struct Exclusive {
193 stream: ChannelMessageStream,
194}
195
196impl Transport for Channel {
197 type Error = Error;
198
199 fn split(self) -> (Self::Shared, Self::Exclusive) {
200 let (stream, writer) = self.stream().expect("could not split channel");
201 (Shared { writer }, Exclusive { stream })
202 }
203
204 type Shared = Shared;
205 type SendBuffer = SendBuffer;
206 type SendFutureState = SendFutureState;
207
208 fn acquire(_: &Self::Shared) -> Self::SendBuffer {
209 SendBuffer::new()
210 }
211
212 fn begin_send(sender: &Self::Shared, buffer: Self::SendBuffer) -> Self::SendFutureState {
213 let client = sender.writer.as_channel().as_handle_ref().client();
214 let handle = sender.writer.as_channel().as_handle_ref().proto();
215 let data = buffer.chunks;
216 let handles = buffer.handles;
217
218 let data = unsafe {
220 std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * CHUNK_SIZE).to_vec()
221 };
222
223 if data.len() > zx_types::ZX_CHANNEL_MAX_MSG_BYTES as usize
224 || handles.len() > zx_types::ZX_CHANNEL_MAX_MSG_HANDLES as usize
225 {
226 SendFutureState::BadGeometry
227 } else {
228 let handles =
229 proto::Handles::Handles(handles.into_iter().map(|x| x.take_proto()).collect());
230 let (sender, receiver) = oneshot::channel();
231 let mut client = client.0.lock().unwrap();
232 client.request(
233 crate::ordinals::WRITE_CHANNEL,
234 proto::ChannelWriteChannelRequest { handle, data, handles },
235 Responder::WriteChannel(sender),
236 );
237
238 SendFutureState::Wait(receiver)
239 }
240 }
241
242 fn poll_send(
243 mut future_state: Pin<&mut Self::SendFutureState>,
244 ctx: &mut Context<'_>,
245 _: &Self::Shared,
246 ) -> Poll<Result<(), Option<Self::Error>>> {
247 match &mut *future_state {
248 SendFutureState::BadGeometry => Poll::Ready(Err(Some(Error::FDomain(
249 proto::Error::TargetError(fidl::Status::OUT_OF_RANGE.into_raw()),
250 )))),
251 SendFutureState::Wait(receiver) => receiver.poll_unpin(ctx).map(|x| {
252 match x.expect("Receiver disappeared with no reply") {
253 Ok(x) => Ok(x),
254 Err(Error::FDomain(proto::Error::TargetError(e)))
255 if e == fidl::Status::PEER_CLOSED.into_raw() =>
256 {
257 Err(None)
258 }
259 Err(e) => Err(Some(e)),
260 }
261 }),
262 }
263 }
264
265 type Exclusive = Exclusive;
266 type RecvFutureState = ();
267 type RecvBuffer = RecvBuffer;
268
269 fn begin_recv(_: &Self::Shared, _: &mut Self::Exclusive) -> Self::RecvFutureState {}
270
271 fn poll_recv(
272 _: Pin<&mut Self::RecvFutureState>,
273 ctx: &mut Context<'_>,
274 _: &Self::Shared,
275 exclusive: &mut Self::Exclusive,
276 ) -> Poll<Result<Self::RecvBuffer, Option<Self::Error>>> {
277 let poll_stream = exclusive.stream.poll_next_unpin(ctx);
278
279 let Some(msg) = ready!(poll_stream).transpose().map_err(Some)? else {
280 return Poll::Ready(Err(None));
281 };
282
283 let chunks = unsafe {
285 std::slice::from_raw_parts(
286 msg.bytes.as_ptr() as *const Chunk,
287 msg.bytes.len() / CHUNK_SIZE,
288 )
289 .to_vec()
290 };
291 let handles = msg.handles.into_iter().map(|x| Handle::from(x.handle).into()).collect();
292
293 Poll::Ready(Ok(RecvBuffer { handles, chunks, chunks_taken: 0, handles_taken: 0 }))
294 }
295}