1use super::error::KcpSegmentParseError;
4use super::types::{
5 KcpCommand, KcpConversationId, KcpFragment, KcpSequenceNumber, KcpTimestamp, KcpUnacknowledged,
6};
7
8pub const KCP_SEGMENT_HEADER_LEN: usize = 24;
10
11#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub struct KcpSegment<'a> {
14 bytes: &'a [u8],
15}
16
17impl<'a> KcpSegment<'a> {
18 pub fn parse(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), KcpSegmentParseError> {
23 if bytes.len() < KCP_SEGMENT_HEADER_LEN {
24 return Err(KcpSegmentParseError::HeaderTruncated {
25 required: KCP_SEGMENT_HEADER_LEN,
26 available: bytes.len(),
27 });
28 }
29
30 let payload_length = u32::from_le_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]);
31 let payload_length = usize::try_from(payload_length).map_err(|_| {
32 KcpSegmentParseError::PayloadLengthNotRepresentable {
33 value: payload_length,
34 }
35 })?;
36 let length = KCP_SEGMENT_HEADER_LEN.checked_add(payload_length).ok_or(
37 KcpSegmentParseError::LengthOverflow {
38 header_length: KCP_SEGMENT_HEADER_LEN,
39 payload_length,
40 },
41 )?;
42 if bytes.len() < length {
43 return Err(KcpSegmentParseError::PayloadTruncated {
44 required: length,
45 available: bytes.len(),
46 });
47 }
48
49 Ok((
50 Self {
51 bytes: &bytes[..length],
52 },
53 &bytes[length..],
54 ))
55 }
56
57 pub const fn conversation_id(self) -> KcpConversationId {
59 KcpConversationId::new(u32::from_le_bytes([
60 self.bytes[0],
61 self.bytes[1],
62 self.bytes[2],
63 self.bytes[3],
64 ]))
65 }
66
67 pub const fn command(self) -> KcpCommand {
69 KcpCommand::new(self.bytes[4])
70 }
71
72 pub const fn fragment(self) -> KcpFragment {
74 KcpFragment::new(self.bytes[5])
75 }
76
77 pub const fn window_size(self) -> u16 {
79 u16::from_le_bytes([self.bytes[6], self.bytes[7]])
80 }
81
82 pub const fn timestamp(self) -> KcpTimestamp {
84 KcpTimestamp::new(u32::from_le_bytes([
85 self.bytes[8],
86 self.bytes[9],
87 self.bytes[10],
88 self.bytes[11],
89 ]))
90 }
91
92 pub const fn sequence_number(self) -> KcpSequenceNumber {
94 KcpSequenceNumber::new(u32::from_le_bytes([
95 self.bytes[12],
96 self.bytes[13],
97 self.bytes[14],
98 self.bytes[15],
99 ]))
100 }
101
102 pub const fn unacknowledged(self) -> KcpUnacknowledged {
104 KcpUnacknowledged::new(u32::from_le_bytes([
105 self.bytes[16],
106 self.bytes[17],
107 self.bytes[18],
108 self.bytes[19],
109 ]))
110 }
111
112 pub const fn payload_length(self) -> u32 {
114 u32::from_le_bytes([
115 self.bytes[20],
116 self.bytes[21],
117 self.bytes[22],
118 self.bytes[23],
119 ])
120 }
121
122 pub fn payload(self) -> &'a [u8] {
124 &self.bytes[KCP_SEGMENT_HEADER_LEN..]
125 }
126
127 pub const fn as_bytes(self) -> &'a [u8] {
129 self.bytes
130 }
131}
132
133#[derive(Debug, Eq, PartialEq)]
135pub struct KcpSegmentMut<'a> {
136 bytes: &'a mut [u8],
137}
138
139impl<'a> KcpSegmentMut<'a> {
140 pub fn parse(bytes: &'a mut [u8]) -> Result<(Self, &'a mut [u8]), KcpSegmentParseError> {
145 let (segment, _) = KcpSegment::parse(bytes)?;
146 let (segment_bytes, suffix) = bytes.split_at_mut(segment.as_bytes().len());
147 Ok((Self::from_validated(segment_bytes), suffix))
148 }
149
150 pub(crate) fn from_validated(bytes: &'a mut [u8]) -> Self {
151 Self { bytes }
152 }
153
154 pub fn conversation_id(&self) -> KcpConversationId {
156 KcpConversationId::new(u32::from_le_bytes([
157 self.bytes[0],
158 self.bytes[1],
159 self.bytes[2],
160 self.bytes[3],
161 ]))
162 }
163
164 pub fn command(&self) -> KcpCommand {
166 KcpCommand::new(self.bytes[4])
167 }
168
169 pub fn fragment(&self) -> KcpFragment {
171 KcpFragment::new(self.bytes[5])
172 }
173
174 pub fn window_size(&self) -> u16 {
176 u16::from_le_bytes([self.bytes[6], self.bytes[7]])
177 }
178
179 pub fn timestamp(&self) -> KcpTimestamp {
181 KcpTimestamp::new(u32::from_le_bytes([
182 self.bytes[8],
183 self.bytes[9],
184 self.bytes[10],
185 self.bytes[11],
186 ]))
187 }
188
189 pub fn sequence_number(&self) -> KcpSequenceNumber {
191 KcpSequenceNumber::new(u32::from_le_bytes([
192 self.bytes[12],
193 self.bytes[13],
194 self.bytes[14],
195 self.bytes[15],
196 ]))
197 }
198
199 pub fn unacknowledged(&self) -> KcpUnacknowledged {
201 KcpUnacknowledged::new(u32::from_le_bytes([
202 self.bytes[16],
203 self.bytes[17],
204 self.bytes[18],
205 self.bytes[19],
206 ]))
207 }
208
209 pub fn payload_length(&self) -> u32 {
211 u32::from_le_bytes([
212 self.bytes[20],
213 self.bytes[21],
214 self.bytes[22],
215 self.bytes[23],
216 ])
217 }
218
219 pub fn payload(&self) -> &[u8] {
221 &self.bytes[KCP_SEGMENT_HEADER_LEN..]
222 }
223
224 pub fn payload_mut(&mut self) -> &mut [u8] {
226 &mut self.bytes[KCP_SEGMENT_HEADER_LEN..]
227 }
228
229 pub fn as_bytes(&self) -> &[u8] {
231 self.bytes
232 }
233
234 pub fn set_conversation_id(&mut self, value: KcpConversationId) {
236 self.bytes[0..4].copy_from_slice(&value.raw().to_le_bytes());
237 }
238
239 pub fn set_command(&mut self, value: KcpCommand) {
241 self.bytes[4] = value.raw();
242 }
243
244 pub fn set_fragment(&mut self, value: KcpFragment) {
246 self.bytes[5] = value.raw();
247 }
248
249 pub fn set_window_size(&mut self, value: u16) {
251 self.bytes[6..8].copy_from_slice(&value.to_le_bytes());
252 }
253
254 pub fn set_timestamp(&mut self, value: KcpTimestamp) {
256 self.bytes[8..12].copy_from_slice(&value.raw().to_le_bytes());
257 }
258
259 pub fn set_sequence_number(&mut self, value: KcpSequenceNumber) {
261 self.bytes[12..16].copy_from_slice(&value.raw().to_le_bytes());
262 }
263
264 pub fn set_unacknowledged(&mut self, value: KcpUnacknowledged) {
266 self.bytes[16..20].copy_from_slice(&value.raw().to_le_bytes());
267 }
268}