1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use crate::OpCode;
/// A received frame.
#[derive(Debug, PartialEq, Eq)]
pub struct Frame<'a> {
/// Indicates if this is the final frame in a message.
fin: bool,
/// The opcode of the frame.
opcode: OpCode,
/// The payload of the frame.
payload: &'a [u8],
}
impl<'a> Frame<'a> {
/// Creates a new [`Frame`].
pub const fn new(fin: bool, opcode: OpCode, payload: &'a [u8]) -> Self {
Self {
fin,
opcode,
payload,
}
}
/// Returns whether this is the final frame in a message.
pub const fn is_final(&self) -> bool {
self.fin
}
/// Returns the opcode of the frame.
pub const fn opcode(&self) -> OpCode {
self.opcode
}
/// Returns the payload of the frame.
pub const fn payload(&self) -> &'a [u8] {
self.payload
}
pub fn write_payload(&self, dst: &mut [u8]) -> Option<usize> {
if dst.len() < self.payload.len() {
return None;
}
dst[..self.payload.len()].copy_from_slice(self.payload);
Some(self.payload.len())
}
}
/// A mutable received frame.
#[derive(Debug)]
pub struct FrameMut<'a> {
/// Indicates if this is the final frame in a message.
fin: bool,
/// The opcode of the frame.
opcode: OpCode,
/// The masking key of the frame, if any.
mask: Option<[u8; 4]>,
/// The payload of the frame.
payload: &'a mut [u8],
}
impl<'a> FrameMut<'a> {
/// Creates a new [`FrameMut`].
pub const fn new(
fin: bool,
opcode: OpCode,
mask: Option<[u8; 4]>,
payload: &'a mut [u8],
) -> Self {
Self {
fin,
opcode,
mask,
payload,
}
}
pub const fn into_frame(self) -> Frame<'a> {
Frame {
fin: self.fin,
opcode: self.opcode,
payload: self.payload,
}
}
pub fn unmask(&mut self) {
if let Some(mask) = self.mask {
crate::mask::unmask(self.payload, mask);
}
}
}
#[derive(Debug)]
pub struct Header {
/// Indicates if this is the final frame in a message.
fin: bool,
/// The opcode of the frame.
opcode: OpCode,
/// The length of the payload.
payload_len: usize,
}
impl Header {
pub const fn new(fin: bool, opcode: OpCode, payload_len: usize) -> Self {
Self {
fin,
opcode,
payload_len,
}
}
/// Writes the header into the dst buffer.
pub fn write(&self, dst: &mut [u8]) -> Option<usize> {
if dst.len() < 2 {
return None;
}
dst[0] = (self.fin as u8) << 7 | (self.opcode as u8);
let len = self.payload_len;
let size = if len < 126 {
dst[1] = len as u8;
2
} else if len < 65536 {
if dst.len() < 4 {
return None;
}
dst[1] = 126;
dst[2..4].copy_from_slice(&(len as u16).to_be_bytes());
4
} else {
if dst.len() < 10 {
return None;
}
dst[1] = 127;
dst[2..10].copy_from_slice(&(len as u64).to_be_bytes());
10
};
Some(size)
}
}