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