Skip to main content

fdomain_client/
vmo.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::handle::handle_type;
6use crate::responder::Responder;
7use crate::{Error, Handle, ordinals};
8use fidl_fuchsia_fdomain as proto;
9use futures::FutureExt;
10use std::future::Future;
11
12/// A virtual memory object (VMO) in a remote FDomain.
13#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
14pub struct Vmo(pub(crate) Handle);
15
16handle_type!(Vmo VMO);
17
18impl Vmo {
19    /// Read `size` bytes from the VMO at `offset`.
20    pub fn read(
21        &self,
22        offset: u64,
23        size: u64,
24    ) -> impl Future<Output = Result<Vec<u8>, Error>> + use<> {
25        let client = self.0.client();
26        let handle = self.0.proto();
27
28        client
29            .transaction(
30                ordinals::READ_VMO,
31                proto::VmoReadVmoRequest { handle, offset, size },
32                Responder::ReadVmo,
33            )
34            .map(|res| res.map(|r| r.data))
35    }
36
37    /// Read from the VMO into a buffer. Returns Ok(()) on success.
38    pub async fn read_slice(&self, buf: &mut [u8], offset: u64) -> Result<(), Error> {
39        let data = self.read(offset, buf.len() as u64).await?;
40        if data.len() != buf.len() {
41            return Err(Error::FDomain(proto::Error::TargetError(
42                zx_status::Status::OUT_OF_RANGE.into_raw(),
43            )));
44        }
45        buf.copy_from_slice(&data);
46        Ok(())
47    }
48
49    /// Write all data to the VMO at `offset`.
50    pub fn write(
51        &self,
52        data: &[u8],
53        offset: u64,
54    ) -> impl Future<Output = Result<(), Error>> + use<> {
55        let client = self.0.client();
56        let handle = self.0.proto();
57        let data = data.to_vec();
58
59        client.transaction(
60            ordinals::WRITE_VMO,
61            proto::VmoWriteVmoRequest { handle, offset, data },
62            Responder::WriteVmo,
63        )
64    }
65
66    /// Get the size of the VMO.
67    pub fn get_size(&self) -> impl Future<Output = Result<u64, Error>> + use<> {
68        let client = self.0.client();
69        let handle = self.0.proto();
70
71        client
72            .transaction(
73                ordinals::GET_VMO_SIZE,
74                proto::VmoGetVmoSizeRequest { handle },
75                Responder::GetVmoSize,
76            )
77            .map(|res| res.map(|r| r.size))
78    }
79
80    /// Set the size of the VMO.
81    pub fn set_size(&self, size: u64) -> impl Future<Output = Result<(), Error>> + use<> {
82        let client = self.0.client();
83        let handle = self.0.proto();
84
85        client.transaction(
86            ordinals::SET_VMO_SIZE,
87            proto::VmoSetVmoSizeRequest { handle, size },
88            Responder::SetVmoSize,
89        )
90    }
91
92    /// Get the stream size of the VMO.
93    pub fn get_stream_size(&self) -> impl Future<Output = Result<u64, Error>> + use<> {
94        let client = self.0.client();
95        let handle = self.0.proto();
96
97        client
98            .transaction(
99                ordinals::GET_VMO_STREAM_SIZE,
100                proto::VmoGetVmoStreamSizeRequest { handle },
101                Responder::GetVmoStreamSize,
102            )
103            .map(|res| res.map(|r| r.size))
104    }
105
106    /// Set the stream size of the VMO.
107    pub fn set_stream_size(&self, size: u64) -> impl Future<Output = Result<(), Error>> + use<> {
108        let client = self.0.client();
109        let handle = self.0.proto();
110
111        client.transaction(
112            ordinals::SET_VMO_STREAM_SIZE,
113            proto::VmoSetVmoStreamSizeRequest { handle, size },
114            Responder::SetVmoStreamSize,
115        )
116    }
117}