1 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4 // option. This file may not be copied, modified, or distributed
5 // except according to those terms.
6 
7 // Stream ID and stream index handling.
8 
9 use std::ops::AddAssign;
10 
11 use crate::connection::{Role, LOCAL_STREAM_LIMIT_BIDI, LOCAL_STREAM_LIMIT_UNI};
12 use crate::frame::StreamType;
13 
14 pub struct StreamIndexes {
15     pub local_max_stream_uni: StreamIndex,
16     pub local_max_stream_bidi: StreamIndex,
17     pub local_next_stream_uni: StreamIndex,
18     pub local_next_stream_bidi: StreamIndex,
19     pub remote_max_stream_uni: StreamIndex,
20     pub remote_max_stream_bidi: StreamIndex,
21     pub remote_next_stream_uni: StreamIndex,
22     pub remote_next_stream_bidi: StreamIndex,
23 }
24 
25 impl StreamIndexes {
new() -> Self26     pub fn new() -> Self {
27         Self {
28             local_max_stream_bidi: StreamIndex::new(LOCAL_STREAM_LIMIT_BIDI),
29             local_max_stream_uni: StreamIndex::new(LOCAL_STREAM_LIMIT_UNI),
30             local_next_stream_uni: StreamIndex::new(0),
31             local_next_stream_bidi: StreamIndex::new(0),
32             remote_max_stream_bidi: StreamIndex::new(0),
33             remote_max_stream_uni: StreamIndex::new(0),
34             remote_next_stream_uni: StreamIndex::new(0),
35             remote_next_stream_bidi: StreamIndex::new(0),
36         }
37     }
38 }
39 
40 #[derive(Debug, Eq, PartialEq, Clone, Copy, Ord, PartialOrd, Hash)]
41 pub struct StreamId(u64);
42 
43 impl StreamId {
is_bidi(self) -> bool44     pub fn is_bidi(self) -> bool {
45         self.0 & 0x02 == 0
46     }
47 
is_uni(self) -> bool48     pub fn is_uni(self) -> bool {
49         !self.is_bidi()
50     }
51 
stream_type(self) -> StreamType52     pub fn stream_type(self) -> StreamType {
53         if self.is_bidi() {
54             StreamType::BiDi
55         } else {
56             StreamType::UniDi
57         }
58     }
59 
is_client_initiated(self) -> bool60     pub fn is_client_initiated(self) -> bool {
61         self.0 & 0x01 == 0
62     }
63 
is_server_initiated(self) -> bool64     pub fn is_server_initiated(self) -> bool {
65         !self.is_client_initiated()
66     }
67 
role(self) -> Role68     pub fn role(self) -> Role {
69         if self.is_client_initiated() {
70             Role::Client
71         } else {
72             Role::Server
73         }
74     }
75 
is_self_initiated(self, my_role: Role) -> bool76     pub fn is_self_initiated(self, my_role: Role) -> bool {
77         match my_role {
78             Role::Client if self.is_client_initiated() => true,
79             Role::Server if self.is_server_initiated() => true,
80             _ => false,
81         }
82     }
83 
is_remote_initiated(self, my_role: Role) -> bool84     pub fn is_remote_initiated(self, my_role: Role) -> bool {
85         !self.is_self_initiated(my_role)
86     }
87 
is_send_only(self, my_role: Role) -> bool88     pub fn is_send_only(self, my_role: Role) -> bool {
89         self.is_uni() && self.is_self_initiated(my_role)
90     }
91 
is_recv_only(self, my_role: Role) -> bool92     pub fn is_recv_only(self, my_role: Role) -> bool {
93         self.is_uni() && self.is_remote_initiated(my_role)
94     }
95 
as_u64(self) -> u6496     pub fn as_u64(self) -> u64 {
97         self.0
98     }
99 }
100 
101 impl From<u64> for StreamId {
from(val: u64) -> Self102     fn from(val: u64) -> Self {
103         Self(val)
104     }
105 }
106 
107 #[derive(Debug, Eq, PartialEq, Clone, Copy, Ord, PartialOrd, Hash)]
108 pub struct StreamIndex(u64);
109 
110 impl StreamIndex {
new(val: u64) -> Self111     pub fn new(val: u64) -> Self {
112         Self(val)
113     }
114 
to_stream_id(self, stream_type: StreamType, role: Role) -> StreamId115     pub fn to_stream_id(self, stream_type: StreamType, role: Role) -> StreamId {
116         let type_val = match stream_type {
117             StreamType::BiDi => 0,
118             StreamType::UniDi => 2,
119         };
120         let role_val = match role {
121             Role::Server => 1,
122             Role::Client => 0,
123         };
124 
125         StreamId::from((self.0 << 2) + type_val + role_val)
126     }
127 
as_u64(self) -> u64128     pub fn as_u64(self) -> u64 {
129         self.0
130     }
131 }
132 
133 impl From<StreamId> for StreamIndex {
from(val: StreamId) -> Self134     fn from(val: StreamId) -> Self {
135         Self(val.as_u64() >> 2)
136     }
137 }
138 
139 impl AddAssign<u64> for StreamIndex {
add_assign(&mut self, other: u64)140     fn add_assign(&mut self, other: u64) {
141         *self = Self::new(self.as_u64() + other)
142     }
143 }
144