diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/neqo-transport/src/stream_id.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/neqo-transport/src/stream_id.rs')
-rw-r--r-- | third_party/rust/neqo-transport/src/stream_id.rs | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/third_party/rust/neqo-transport/src/stream_id.rs b/third_party/rust/neqo-transport/src/stream_id.rs new file mode 100644 index 0000000000..c82b09d8c4 --- /dev/null +++ b/third_party/rust/neqo-transport/src/stream_id.rs @@ -0,0 +1,170 @@ +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Stream ID and stream index handling. + +use neqo_common::Role; + +#[derive(PartialEq, Debug, Copy, Clone, PartialOrd, Eq, Ord, Hash)] + +/// The type of stream, either Bi-Directional or Uni-Directional. +pub enum StreamType { + BiDi, + UniDi, +} + +#[derive(Debug, Eq, PartialEq, Clone, Copy, Ord, PartialOrd, Hash)] +pub struct StreamId(u64); + +impl StreamId { + pub const fn new(id: u64) -> Self { + Self(id) + } + + pub fn init(stream_type: StreamType, role: Role) -> Self { + let type_val = match stream_type { + StreamType::BiDi => 0, + StreamType::UniDi => 2, + }; + Self(type_val + Self::role_bit(role)) + } + + pub fn as_u64(self) -> u64 { + self.0 + } + + pub fn is_bidi(self) -> bool { + self.as_u64() & 0x02 == 0 + } + + pub fn is_uni(self) -> bool { + !self.is_bidi() + } + + pub fn stream_type(self) -> StreamType { + if self.is_bidi() { + StreamType::BiDi + } else { + StreamType::UniDi + } + } + + pub fn is_client_initiated(self) -> bool { + self.as_u64() & 0x01 == 0 + } + + pub fn is_server_initiated(self) -> bool { + !self.is_client_initiated() + } + + pub fn role(self) -> Role { + if self.is_client_initiated() { + Role::Client + } else { + Role::Server + } + } + + pub fn is_self_initiated(self, my_role: Role) -> bool { + match my_role { + Role::Client if self.is_client_initiated() => true, + Role::Server if self.is_server_initiated() => true, + _ => false, + } + } + + pub fn is_remote_initiated(self, my_role: Role) -> bool { + !self.is_self_initiated(my_role) + } + + pub fn is_send_only(self, my_role: Role) -> bool { + self.is_uni() && self.is_self_initiated(my_role) + } + + pub fn is_recv_only(self, my_role: Role) -> bool { + self.is_uni() && self.is_remote_initiated(my_role) + } + + pub fn next(&mut self) { + self.0 += 4; + } + + /// This returns a bit that is shared by all streams created by this role. + pub fn role_bit(role: Role) -> u64 { + match role { + Role::Server => 1, + Role::Client => 0, + } + } +} + +impl From<u64> for StreamId { + fn from(val: u64) -> Self { + Self::new(val) + } +} + +impl PartialEq<u64> for StreamId { + fn eq(&self, other: &u64) -> bool { + self.as_u64() == *other + } +} + +impl AsRef<u64> for StreamId { + fn as_ref(&self) -> &u64 { + &self.0 + } +} + +impl ::std::fmt::Display for StreamId { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.as_u64()) + } +} + +#[cfg(test)] +mod test { + use super::StreamId; + use neqo_common::Role; + + #[test] + fn bidi_stream_properties() { + let id1 = StreamId::from(16); + assert!(id1.is_bidi()); + assert!(!id1.is_uni()); + assert!(id1.is_client_initiated()); + assert!(!id1.is_server_initiated()); + assert_eq!(id1.role(), Role::Client); + assert!(id1.is_self_initiated(Role::Client)); + assert!(!id1.is_self_initiated(Role::Server)); + assert!(!id1.is_remote_initiated(Role::Client)); + assert!(id1.is_remote_initiated(Role::Server)); + assert!(!id1.is_send_only(Role::Server)); + assert!(!id1.is_send_only(Role::Client)); + assert!(!id1.is_recv_only(Role::Server)); + assert!(!id1.is_recv_only(Role::Client)); + assert_eq!(id1.as_u64(), 16); + } + + #[test] + fn uni_stream_properties() { + let id2 = StreamId::from(35); + assert!(!id2.is_bidi()); + assert!(id2.is_uni()); + assert!(!id2.is_client_initiated()); + assert!(id2.is_server_initiated()); + assert_eq!(id2.role(), Role::Server); + assert!(!id2.is_self_initiated(Role::Client)); + assert!(id2.is_self_initiated(Role::Server)); + assert!(id2.is_remote_initiated(Role::Client)); + assert!(!id2.is_remote_initiated(Role::Server)); + assert!(id2.is_send_only(Role::Server)); + assert!(!id2.is_send_only(Role::Client)); + assert!(!id2.is_recv_only(Role::Server)); + assert!(id2.is_recv_only(Role::Client)); + assert_eq!(id2.as_u64(), 35); + } +} |