1cac7dca0Sopenharmony_ci// Copyright (c) 2023 Huawei Device Co., Ltd.
2cac7dca0Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
3cac7dca0Sopenharmony_ci// you may not use this file except in compliance with the License.
4cac7dca0Sopenharmony_ci// You may obtain a copy of the License at
5cac7dca0Sopenharmony_ci//
6cac7dca0Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
7cac7dca0Sopenharmony_ci//
8cac7dca0Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
9cac7dca0Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
10cac7dca0Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11cac7dca0Sopenharmony_ci// See the License for the specific language governing permissions and
12cac7dca0Sopenharmony_ci// limitations under the License.
13cac7dca0Sopenharmony_ci
14cac7dca0Sopenharmony_ciuse std::fmt;
15cac7dca0Sopenharmony_ci
16cac7dca0Sopenharmony_ciuse crate::sys::windows::afd::{
17cac7dca0Sopenharmony_ci    POLL_ABORT, POLL_ACCEPT, POLL_CONNECT_FAIL, POLL_DISCONNECT, POLL_RECEIVE, POLL_SEND,
18cac7dca0Sopenharmony_ci};
19cac7dca0Sopenharmony_ciuse crate::sys::windows::iocp::CompletionStatus;
20cac7dca0Sopenharmony_ciuse crate::{EventTrait, Token};
21cac7dca0Sopenharmony_ci
22cac7dca0Sopenharmony_ci/// An io event
23cac7dca0Sopenharmony_ci#[derive(Debug)]
24cac7dca0Sopenharmony_cipub struct Event {
25cac7dca0Sopenharmony_ci    pub(crate) flags: u32,
26cac7dca0Sopenharmony_ci    pub(crate) data: u64,
27cac7dca0Sopenharmony_ci}
28cac7dca0Sopenharmony_ci
29cac7dca0Sopenharmony_ciimpl Event {
30cac7dca0Sopenharmony_ci    /// Creates a new `Event` with `Token`.
31cac7dca0Sopenharmony_ci    pub(crate) fn new(token: Token) -> Event {
32cac7dca0Sopenharmony_ci        Event {
33cac7dca0Sopenharmony_ci            flags: 0,
34cac7dca0Sopenharmony_ci            data: usize::from(token) as u64,
35cac7dca0Sopenharmony_ci        }
36cac7dca0Sopenharmony_ci    }
37cac7dca0Sopenharmony_ci
38cac7dca0Sopenharmony_ci    /// Sets `Event` as readable.
39cac7dca0Sopenharmony_ci    pub(super) fn set_readable(&mut self) {
40cac7dca0Sopenharmony_ci        self.flags |= POLL_RECEIVE
41cac7dca0Sopenharmony_ci    }
42cac7dca0Sopenharmony_ci
43cac7dca0Sopenharmony_ci    /// Converts `Event` to `CompletionStatus`.
44cac7dca0Sopenharmony_ci    pub(super) fn as_completion_status(&self) -> CompletionStatus {
45cac7dca0Sopenharmony_ci        CompletionStatus::new(self.flags, self.data as usize, std::ptr::null_mut())
46cac7dca0Sopenharmony_ci    }
47cac7dca0Sopenharmony_ci
48cac7dca0Sopenharmony_ci    /// Converts `CompletionStatus` to `Event`.
49cac7dca0Sopenharmony_ci    pub(super) fn from_completion_status(status: &CompletionStatus) -> Event {
50cac7dca0Sopenharmony_ci        Event {
51cac7dca0Sopenharmony_ci            flags: status.bytes_transferred(),
52cac7dca0Sopenharmony_ci            data: status.token() as u64,
53cac7dca0Sopenharmony_ci        }
54cac7dca0Sopenharmony_ci    }
55cac7dca0Sopenharmony_ci}
56cac7dca0Sopenharmony_ci
57cac7dca0Sopenharmony_ci/// Storage completed events
58cac7dca0Sopenharmony_cipub struct Events {
59cac7dca0Sopenharmony_ci    pub(crate) status: Box<[CompletionStatus]>,
60cac7dca0Sopenharmony_ci    pub(crate) events: Vec<Event>,
61cac7dca0Sopenharmony_ci}
62cac7dca0Sopenharmony_ci
63cac7dca0Sopenharmony_ciimpl Events {
64cac7dca0Sopenharmony_ci    /// Creates a new `Events`.
65cac7dca0Sopenharmony_ci    pub fn with_capacity(cap: usize) -> Events {
66cac7dca0Sopenharmony_ci        Events {
67cac7dca0Sopenharmony_ci            status: vec![CompletionStatus::zero(); cap].into_boxed_slice(),
68cac7dca0Sopenharmony_ci            events: Vec::with_capacity(cap),
69cac7dca0Sopenharmony_ci        }
70cac7dca0Sopenharmony_ci    }
71cac7dca0Sopenharmony_ci
72cac7dca0Sopenharmony_ci    /// Clear the Events
73cac7dca0Sopenharmony_ci    pub fn clear(&mut self) {
74cac7dca0Sopenharmony_ci        self.events.clear();
75cac7dca0Sopenharmony_ci        for status in self.status.iter_mut() {
76cac7dca0Sopenharmony_ci            *status = CompletionStatus::zero();
77cac7dca0Sopenharmony_ci        }
78cac7dca0Sopenharmony_ci    }
79cac7dca0Sopenharmony_ci
80cac7dca0Sopenharmony_ci    /// Returns an iterator over the slice.
81cac7dca0Sopenharmony_ci    /// The iterator yields all items from start to end.
82cac7dca0Sopenharmony_ci    pub fn iter(&self) -> IterEvent {
83cac7dca0Sopenharmony_ci        IterEvent {
84cac7dca0Sopenharmony_ci            iter: &self.events,
85cac7dca0Sopenharmony_ci            index: 0,
86cac7dca0Sopenharmony_ci        }
87cac7dca0Sopenharmony_ci    }
88cac7dca0Sopenharmony_ci
89cac7dca0Sopenharmony_ci    /// Returns true if the vector contains no elements.
90cac7dca0Sopenharmony_ci    pub fn is_empty(&self) -> bool {
91cac7dca0Sopenharmony_ci        self.events.is_empty()
92cac7dca0Sopenharmony_ci    }
93cac7dca0Sopenharmony_ci
94cac7dca0Sopenharmony_ci    /// Returns len of Events.
95cac7dca0Sopenharmony_ci    pub fn len(&self) -> usize {
96cac7dca0Sopenharmony_ci        self.events.len()
97cac7dca0Sopenharmony_ci    }
98cac7dca0Sopenharmony_ci}
99cac7dca0Sopenharmony_ci
100cac7dca0Sopenharmony_ciimpl fmt::Debug for Events {
101cac7dca0Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102cac7dca0Sopenharmony_ci        f.debug_list().entries(self).finish()
103cac7dca0Sopenharmony_ci    }
104cac7dca0Sopenharmony_ci}
105cac7dca0Sopenharmony_ci
106cac7dca0Sopenharmony_ciimpl<'a> IntoIterator for &'a Events {
107cac7dca0Sopenharmony_ci    type Item = &'a Event;
108cac7dca0Sopenharmony_ci    type IntoIter = IterEvent<'a>;
109cac7dca0Sopenharmony_ci
110cac7dca0Sopenharmony_ci    fn into_iter(self) -> Self::IntoIter {
111cac7dca0Sopenharmony_ci        self.iter()
112cac7dca0Sopenharmony_ci    }
113cac7dca0Sopenharmony_ci}
114cac7dca0Sopenharmony_ci
115cac7dca0Sopenharmony_cipub struct IterEvent<'a> {
116cac7dca0Sopenharmony_ci    iter: &'a Vec<Event>,
117cac7dca0Sopenharmony_ci    index: usize,
118cac7dca0Sopenharmony_ci}
119cac7dca0Sopenharmony_ci
120cac7dca0Sopenharmony_ciimpl<'a> Iterator for IterEvent<'a> {
121cac7dca0Sopenharmony_ci    type Item = &'a Event;
122cac7dca0Sopenharmony_ci    fn next(&mut self) -> Option<Self::Item> {
123cac7dca0Sopenharmony_ci        if self.index < self.iter.len() {
124cac7dca0Sopenharmony_ci            self.index += 1;
125cac7dca0Sopenharmony_ci            Some(&self.iter[self.index - 1])
126cac7dca0Sopenharmony_ci        } else {
127cac7dca0Sopenharmony_ci            None
128cac7dca0Sopenharmony_ci        }
129cac7dca0Sopenharmony_ci    }
130cac7dca0Sopenharmony_ci
131cac7dca0Sopenharmony_ci    fn count(self) -> usize {
132cac7dca0Sopenharmony_ci        self.iter.len()
133cac7dca0Sopenharmony_ci    }
134cac7dca0Sopenharmony_ci}
135cac7dca0Sopenharmony_ci
136cac7dca0Sopenharmony_cipub(crate) const READABLE_FLAGS: u32 =
137cac7dca0Sopenharmony_ci    POLL_RECEIVE | POLL_DISCONNECT | POLL_ABORT | POLL_ACCEPT | POLL_CONNECT_FAIL;
138cac7dca0Sopenharmony_cipub(crate) const WRITABLE_FLAGS: u32 = POLL_SEND | POLL_ABORT | POLL_CONNECT_FAIL;
139cac7dca0Sopenharmony_cipub(crate) const READ_CLOSED_FLAGS: u32 = POLL_DISCONNECT | POLL_ABORT | POLL_CONNECT_FAIL;
140cac7dca0Sopenharmony_cipub(crate) const WRITE_CLOSED_FLAGS: u32 = POLL_ABORT | POLL_CONNECT_FAIL;
141cac7dca0Sopenharmony_cipub(crate) const ERROR_FLAGS: u32 = POLL_CONNECT_FAIL;
142cac7dca0Sopenharmony_ci
143cac7dca0Sopenharmony_ciimpl EventTrait for Event {
144cac7dca0Sopenharmony_ci    fn token(&self) -> Token {
145cac7dca0Sopenharmony_ci        Token(self.data as usize)
146cac7dca0Sopenharmony_ci    }
147cac7dca0Sopenharmony_ci
148cac7dca0Sopenharmony_ci    fn is_readable(&self) -> bool {
149cac7dca0Sopenharmony_ci        self.flags & READABLE_FLAGS != 0
150cac7dca0Sopenharmony_ci    }
151cac7dca0Sopenharmony_ci
152cac7dca0Sopenharmony_ci    fn is_writable(&self) -> bool {
153cac7dca0Sopenharmony_ci        (self.flags & WRITABLE_FLAGS) != 0
154cac7dca0Sopenharmony_ci    }
155cac7dca0Sopenharmony_ci
156cac7dca0Sopenharmony_ci    fn is_read_closed(&self) -> bool {
157cac7dca0Sopenharmony_ci        self.flags & READ_CLOSED_FLAGS != 0
158cac7dca0Sopenharmony_ci    }
159cac7dca0Sopenharmony_ci
160cac7dca0Sopenharmony_ci    fn is_write_closed(&self) -> bool {
161cac7dca0Sopenharmony_ci        self.flags & WRITE_CLOSED_FLAGS != 0
162cac7dca0Sopenharmony_ci    }
163cac7dca0Sopenharmony_ci
164cac7dca0Sopenharmony_ci    fn is_error(&self) -> bool {
165cac7dca0Sopenharmony_ci        self.flags & ERROR_FLAGS != 0
166cac7dca0Sopenharmony_ci    }
167cac7dca0Sopenharmony_ci}
168