1#[cfg(feature = "alloc")]
25use crate::capability::FromClientHook;
26#[cfg(feature = "alloc")]
27use crate::private::capability::{ClientHook, PipelineHook, PipelineOp};
28use crate::private::layout::{PointerBuilder, PointerReader};
29use crate::traits::{FromPointerBuilder, FromPointerReader, SetterInput};
30use crate::Result;
31
32#[derive(Copy, Clone)]
33pub struct Owned(());
34
35impl crate::traits::Owned for Owned {
36 type Reader<'a> = Reader<'a>;
37 type Builder<'a> = Builder<'a>;
38}
39
40impl crate::introspect::Introspect for Owned {
41 fn introspect() -> crate::introspect::Type {
42 crate::introspect::TypeVariant::AnyPointer.into()
43 }
44}
45
46impl crate::traits::Pipelined for Owned {
47 type Pipeline = Pipeline;
48}
49
50#[derive(Copy, Clone)]
51pub struct Reader<'a> {
52 pub(crate) reader: PointerReader<'a>,
53}
54
55impl<'a> Reader<'a> {
56 pub fn new(reader: PointerReader<'_>) -> Reader<'_> {
57 Reader { reader }
58 }
59
60 #[inline]
61 pub fn is_null(&self) -> bool {
62 self.reader.is_null()
63 }
64
65 pub fn target_size(&self) -> Result<crate::MessageSize> {
67 self.reader.total_size()
68 }
69
70 #[inline]
71 pub fn get_as<T: FromPointerReader<'a>>(&self) -> Result<T> {
72 FromPointerReader::get_from_pointer(&self.reader, None)
73 }
74
75 #[cfg(feature = "alloc")]
76 pub fn get_as_capability<T: FromClientHook>(&self) -> Result<T> {
77 Ok(FromClientHook::new(self.reader.get_capability()?))
78 }
79
80 #[cfg(feature = "alloc")]
83 pub fn get_pipelined_cap(
84 &self,
85 ops: &[PipelineOp],
86 ) -> Result<alloc::boxed::Box<dyn ClientHook>> {
87 let mut pointer = self.reader;
88
89 for op in ops {
90 match *op {
91 PipelineOp::Noop => {}
92 PipelineOp::GetPointerField(idx) => {
93 pointer = pointer.get_struct(None)?.get_pointer_field(idx as usize);
94 }
95 }
96 }
97
98 pointer.get_capability()
99 }
100}
101
102impl<'a> FromPointerReader<'a> for Reader<'a> {
103 fn get_from_pointer(
104 reader: &PointerReader<'a>,
105 default: Option<&'a [crate::Word]>,
106 ) -> Result<Reader<'a>> {
107 if default.is_some() {
108 panic!("Unsupported: any_pointer with a default value.");
109 }
110 Ok(Reader { reader: *reader })
111 }
112}
113
114impl<'a> crate::traits::SetterInput<Owned> for Reader<'a> {
115 #[inline]
116 fn set_pointer_builder<'b>(
117 mut pointer: crate::private::layout::PointerBuilder<'b>,
118 value: Reader<'a>,
119 canonicalize: bool,
120 ) -> Result<()> {
121 pointer.copy_from(value.reader, canonicalize)
122 }
123}
124
125#[cfg(feature = "alloc")]
126impl<'a> crate::traits::Imbue<'a> for Reader<'a> {
127 fn imbue(&mut self, cap_table: &'a crate::private::layout::CapTable) {
128 self.reader
129 .imbue(crate::private::layout::CapTableReader::Plain(cap_table));
130 }
131}
132
133pub struct Builder<'a> {
134 builder: PointerBuilder<'a>,
135}
136
137impl<'a> Builder<'a> {
138 pub fn new(builder: PointerBuilder<'a>) -> Builder<'a> {
139 Builder { builder }
140 }
141
142 pub fn reborrow(&mut self) -> Builder<'_> {
143 Builder {
144 builder: self.builder.reborrow(),
145 }
146 }
147
148 pub fn is_null(&self) -> bool {
149 self.builder.is_null()
150 }
151
152 pub fn target_size(&self) -> Result<crate::MessageSize> {
154 self.builder.as_reader().total_size()
155 }
156
157 pub fn get_as<T: FromPointerBuilder<'a>>(self) -> Result<T> {
158 FromPointerBuilder::get_from_pointer(self.builder, None)
159 }
160
161 pub fn init_as<T: FromPointerBuilder<'a>>(self) -> T {
162 FromPointerBuilder::init_pointer(self.builder, 0)
163 }
164
165 pub fn initn_as<T: FromPointerBuilder<'a>>(self, size: u32) -> T {
166 FromPointerBuilder::init_pointer(self.builder, size)
167 }
168
169 pub fn set_as<T: crate::traits::Owned>(&mut self, value: impl SetterInput<T>) -> Result<()> {
170 SetterInput::set_pointer_builder(self.builder.reborrow(), value, false)
171 }
172
173 #[cfg(feature = "alloc")]
175 pub fn set_as_capability(&mut self, value: alloc::boxed::Box<dyn ClientHook>) {
176 self.builder.set_capability(value);
177 }
178
179 #[inline]
180 pub fn clear(&mut self) {
181 self.builder.clear()
182 }
183
184 pub fn into_reader(self) -> Reader<'a> {
185 Reader {
186 reader: self.builder.into_reader(),
187 }
188 }
189}
190
191impl<'a> FromPointerBuilder<'a> for Builder<'a> {
192 fn init_pointer(mut builder: PointerBuilder<'a>, _len: u32) -> Builder<'a> {
193 if !builder.is_null() {
194 builder.clear();
195 }
196 Builder { builder }
197 }
198 fn get_from_pointer(
199 builder: PointerBuilder<'a>,
200 default: Option<&'a [crate::Word]>,
201 ) -> Result<Builder<'a>> {
202 if default.is_some() {
203 panic!("AnyPointer defaults are unsupported")
204 }
205 Ok(Builder { builder })
206 }
207}
208
209#[cfg(feature = "alloc")]
210impl<'a> crate::traits::ImbueMut<'a> for Builder<'a> {
211 fn imbue_mut(&mut self, cap_table: &'a mut crate::private::layout::CapTable) {
212 self.builder
213 .imbue(crate::private::layout::CapTableBuilder::Plain(cap_table));
214 }
215}
216
217pub struct Pipeline {
218 #[cfg(feature = "alloc")]
220 pub hook: alloc::boxed::Box<dyn PipelineHook>,
221
222 #[cfg(feature = "alloc")]
223 ops: alloc::vec::Vec<PipelineOp>,
224}
225
226impl Pipeline {
227 #[cfg(feature = "alloc")]
228 pub fn new(hook: alloc::boxed::Box<dyn PipelineHook>) -> Self {
229 Self {
230 hook,
231 ops: alloc::vec::Vec::new(),
232 }
233 }
234
235 #[cfg(feature = "alloc")]
236 pub fn noop(&self) -> Self {
237 Self {
238 hook: self.hook.add_ref(),
239 ops: self.ops.clone(),
240 }
241 }
242
243 #[cfg(not(feature = "alloc"))]
244 pub fn noop(&self) -> Self {
245 Self {}
246 }
247
248 #[cfg(feature = "alloc")]
249 pub fn get_pointer_field(&self, pointer_index: u16) -> Self {
250 let mut new_ops = alloc::vec::Vec::with_capacity(self.ops.len() + 1);
251 for op in &self.ops {
252 new_ops.push(*op)
253 }
254 new_ops.push(PipelineOp::GetPointerField(pointer_index));
255 Self {
256 hook: self.hook.add_ref(),
257 ops: new_ops,
258 }
259 }
260
261 #[cfg(not(feature = "alloc"))]
262 pub fn get_pointer_field(&self, _pointer_index: u16) -> Self {
263 Self {}
264 }
265
266 #[cfg(feature = "alloc")]
267 pub fn as_cap(&self) -> alloc::boxed::Box<dyn ClientHook> {
268 self.hook.get_pipelined_cap(&self.ops)
269 }
270}
271
272impl crate::capability::FromTypelessPipeline for Pipeline {
273 fn new(typeless: Pipeline) -> Self {
274 typeless
275 }
276}
277
278impl<'a> From<Reader<'a>> for crate::dynamic_value::Reader<'a> {
279 fn from(a: Reader<'a>) -> crate::dynamic_value::Reader<'a> {
280 crate::dynamic_value::Reader::AnyPointer(a)
281 }
282}
283
284impl<'a> From<Builder<'a>> for crate::dynamic_value::Builder<'a> {
285 fn from(a: Builder<'a>) -> crate::dynamic_value::Builder<'a> {
286 crate::dynamic_value::Builder::AnyPointer(a)
287 }
288}
289
290#[cfg(feature = "alloc")]
291#[test]
292fn init_clears_value() {
293 let mut message = crate::message::Builder::new_default();
294 {
295 let root: crate::any_pointer::Builder = message.init_root();
296 let mut list: crate::primitive_list::Builder<u16> = root.initn_as(10);
297 for idx in 0..10 {
298 list.set(idx, idx as u16);
299 }
300 }
301
302 {
303 let root: crate::any_pointer::Builder = message.init_root();
304 assert!(root.is_null());
305 }
306
307 let mut output: alloc::vec::Vec<u8> = alloc::vec::Vec::new();
308 crate::serialize::write_message(&mut output, &message).unwrap();
309 assert_eq!(output.len(), 40);
310 for byte in &output[8..] {
311 assert_eq!(*byte, 0u8);
313 }
314}