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