1// Copyright 2019 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.
45//! When generating a watcher event, one needs "a list of names" that are then converted into
6//! buffers sent to the watchers. In a sense, an iterator over a list of strings would work, but
7//! in order to avoid copying the data around, this namespace provides a more specialized version
8//! of this abstraction.
910use fidl_fuchsia_io as fio;
11use static_assertions::assert_eq_size;
1213/// Watcher event producer, that generates buffers filled with watcher events. Watchers use this
14/// API to obtain buffers that are then sent to the actual watchers. Every producer may generate
15/// multiple events, but they all need to be of the same type, as returned by [`Self::event()`] and
16/// [`Self::mask()`] methods.
17pub trait EventProducer {
18/// Returns a mask that represents the type of events this producer can generate, as one of the
19 /// `fidl_fuchsia_io::WatchMask::*` constants. There might be only one bit set and it should
20 /// correspond to the event returned by the [`Self::event()`] method. It is a duplication, but it
21 /// helps the callers that need both masks and event IDs.
22fn mask(&self) -> fio::WatchMask;
2324/// Returns an event ID this event producer will use to populate the buffers, as one of the
25 /// `fidl_fuchsia_io::WatchEvent::*` constants. Must match what [`Self::mask()`], returns, see
26 /// there for details.
27fn event(&self) -> fio::WatchEvent;
2829/// Checks if this producer can create another buffer, returning `true` if it can. This method
30 /// does not actually need to construct the buffer just yet, as an optimization if it will not
31 /// be needed.
32fn prepare_for_next_buffer(&mut self) -> bool;
3334/// Returns a copy of the current buffer prepared by this producer. This method will be the
35 /// one constructing a buffer, if necessary, after a preceding call to
36 /// [`Self::prepare_for_next_buffer()`].
37 ///
38 /// Note that this method will keep returning copies of the same buffer, until
39 /// [`Self::prepare_for_next_buffer()`] is not called explicitly.
40fn buffer(&mut self) -> Vec<u8>;
41}
4243/// Common mechanism used by both [`StaticVecEventProducer`] and, later, [`SinkEventProducer`].
44struct CachingEventProducer {
45 mask: fio::WatchMask,
46 event: fio::WatchEvent,
47 current_buffer: Option<Vec<u8>>,
48}
4950impl CachingEventProducer {
51fn new(mask: fio::WatchMask, event: fio::WatchEvent) -> Self {
52 CachingEventProducer { mask, event, current_buffer: None }
53 }
5455fn mask(&self) -> fio::WatchMask {
56self.mask
57 }
5859fn event(&self) -> fio::WatchEvent {
60self.event
61 }
6263fn prepare_for_next_buffer(&mut self) {
64self.current_buffer = None;
65 }
6667/// Users of [`CachingEventProducer`] should use this method to implement
68 /// [`EventProducer::buffer`]. `fill_buffer` is a callback used to populate the buffer when
69 /// necessary. It's 'u8' argument is the event ID used by this producer.
70fn buffer<FillBuffer>(&mut self, fill_buffer: FillBuffer) -> Vec<u8>
71where
72FillBuffer: FnOnce(fio::WatchEvent) -> Vec<u8>,
73 {
74match &self.current_buffer {
75Some(buf) => buf.clone(),
76None => {
77let buf = fill_buffer(self.event);
78self.current_buffer = Some(buf.clone());
79 buf
80 }
81 }
82 }
83}
8485/// An [`EventProducer`] that uses a `Vec<String>` with names of the entires to be put into the
86/// watcher event.
87pub struct StaticVecEventProducer {
88 cache: CachingEventProducer,
89 names: Vec<String>,
90 next: usize,
91}
9293impl StaticVecEventProducer {
94/// Constructs a new [`EventProducer`] that is producing names form the specified list,
95 /// building events of type `WatchEvent::Added`. `names` is not allowed to be empty.
96pub fn added(names: Vec<String>) -> Self {
97Self::new(fio::WatchMask::ADDED, fio::WatchEvent::Added, names)
98 }
99100/// Constructs a new [`EventProducer`] that is producing names form the specified list,
101 /// building events of type `WatchEvent::Removed`. `names` is not allowed to be empty.
102pub fn removed(names: Vec<String>) -> Self {
103Self::new(fio::WatchMask::REMOVED, fio::WatchEvent::Removed, names)
104 }
105106/// Constructs a new [`EventProducer`] that is producing names form the specified list,
107 /// building events of type `WatchEvent::Existing`. `names` is not allowed to be empty.
108pub fn existing(names: Vec<String>) -> Self {
109Self::new(fio::WatchMask::EXISTING, fio::WatchEvent::Existing, names)
110 }
111112fn new(mask: fio::WatchMask, event: fio::WatchEvent, names: Vec<String>) -> Self {
113debug_assert!(!names.is_empty());
114Self { cache: CachingEventProducer::new(mask, event), names, next: 0 }
115 }
116117// Can not use `&mut self` here as it would "lock" the whole object disallowing the
118 // `self.cache.buffer()` call where we want to pass this method in a closure.
119fn fill_buffer(event: fio::WatchEvent, next: &mut usize, names: &mut Vec<String>) -> Vec<u8> {
120let mut buffer = vec![];
121122while *next < names.len() {
123if !encode_name(&mut buffer, event, &names[*next]) {
124break;
125 }
126*next += 1;
127 }
128129 buffer
130 }
131}
132133impl EventProducer for StaticVecEventProducer {
134fn mask(&self) -> fio::WatchMask {
135self.cache.mask()
136 }
137138fn event(&self) -> fio::WatchEvent {
139self.cache.event()
140 }
141142fn prepare_for_next_buffer(&mut self) -> bool {
143self.cache.prepare_for_next_buffer();
144self.next < self.names.len()
145 }
146147fn buffer(&mut self) -> Vec<u8> {
148let cache = &mut self.cache;
149let next = &mut self.next;
150let names = &mut self.names;
151 cache.buffer(|event| Self::fill_buffer(event, next, names))
152 }
153}
154155/// An event producer for an event containing only one name. It is slightly optimized, but
156/// otherwise functionally equivalent to the [`StaticVecEventProducer`] with an array of one
157/// element.
158pub struct SingleNameEventProducer {
159 producer: SingleBufferEventProducer,
160}
161162impl SingleNameEventProducer {
163/// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
164 /// type `WatchEvent::Deleted`. Deleted refers to the directory the watcher itself is on, and
165 /// therefore statically refers to itself as ".".
166pub fn deleted() -> Self {
167Self::new(fio::WatchMask::DELETED, fio::WatchEvent::Deleted, ".")
168 }
169170/// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
171 /// type `WatchEvent::Added`.
172pub fn added(name: &str) -> Self {
173Self::new(fio::WatchMask::ADDED, fio::WatchEvent::Added, name)
174 }
175176/// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
177 /// type `WatchEvent::Removed`.
178pub fn removed(name: &str) -> Self {
179Self::new(fio::WatchMask::REMOVED, fio::WatchEvent::Removed, name)
180 }
181182/// Constructs a new [`SingleNameEventProducer`] that will produce an event for one name of
183 /// type `WatchEvent::Existing`.
184pub fn existing(name: &str) -> Self {
185Self::new(fio::WatchMask::EXISTING, fio::WatchEvent::Existing, name)
186 }
187188/// Constructs a new [`SingleNameEventProducer`] that will produce an `WatchEvent::Idle` event.
189pub fn idle() -> Self {
190Self::new(fio::WatchMask::IDLE, fio::WatchEvent::Idle, "")
191 }
192193fn new(mask: fio::WatchMask, event: fio::WatchEvent, name: &str) -> Self {
194let mut buffer = vec![];
195 encode_name(&mut buffer, event, name);
196197Self { producer: SingleBufferEventProducer::new(mask, event, buffer) }
198 }
199}
200201impl EventProducer for SingleNameEventProducer {
202fn mask(&self) -> fio::WatchMask {
203self.producer.mask()
204 }
205206fn event(&self) -> fio::WatchEvent {
207self.producer.event()
208 }
209210fn prepare_for_next_buffer(&mut self) -> bool {
211self.producer.prepare_for_next_buffer()
212 }
213214fn buffer(&mut self) -> Vec<u8> {
215self.producer.buffer()
216 }
217}
218219pub(crate) fn encode_name(buffer: &mut Vec<u8>, event: fio::WatchEvent, name: &str) -> bool {
220if buffer.len() + (2 + name.len()) > fio::MAX_BUF as usize {
221return false;
222 }
223224// We are going to encode the file name length as u8.
225debug_assert!(u8::max_value() as u64 >= fio::MAX_NAME_LENGTH);
226227 buffer.push(event.into_primitive());
228 buffer.push(name.len() as u8);
229 buffer.extend_from_slice(name.as_bytes());
230true
231}
232233enum SingleBufferEventProducerState {
234 Start,
235 FirstEvent,
236 Done,
237}
238239/// An event producer for an event that has one buffer of data.
240pub struct SingleBufferEventProducer {
241 mask: fio::WatchMask,
242 event: fio::WatchEvent,
243 buffer: Vec<u8>,
244 state: SingleBufferEventProducerState,
245}
246247impl SingleBufferEventProducer {
248/// Constructs a new [`SingleBufferEventProducer`] that will produce an event for one name of
249 /// type `WatchEvent::Existing`.
250pub fn existing(buffer: Vec<u8>) -> Self {
251assert_eq_size!(usize, u64);
252debug_assert!(buffer.len() as u64 <= fio::MAX_BUF);
253Self::new(fio::WatchMask::EXISTING, fio::WatchEvent::Existing, buffer)
254 }
255256fn new(mask: fio::WatchMask, event: fio::WatchEvent, buffer: Vec<u8>) -> Self {
257assert_eq_size!(usize, u64);
258debug_assert!(buffer.len() as u64 <= fio::MAX_BUF);
259Self { mask, event, buffer, state: SingleBufferEventProducerState::Start }
260 }
261}
262263impl EventProducer for SingleBufferEventProducer {
264fn mask(&self) -> fio::WatchMask {
265self.mask
266 }
267268fn event(&self) -> fio::WatchEvent {
269self.event
270 }
271272fn prepare_for_next_buffer(&mut self) -> bool {
273match self.state {
274 SingleBufferEventProducerState::Start => {
275self.state = SingleBufferEventProducerState::FirstEvent;
276true
277}
278 SingleBufferEventProducerState::FirstEvent => {
279self.state = SingleBufferEventProducerState::Done;
280false
281}
282 SingleBufferEventProducerState::Done => false,
283 }
284 }
285286fn buffer(&mut self) -> Vec<u8> {
287self.buffer.clone()
288 }
289}