ktls_core/
utils.rs

1//! Utilities
2
3use std::fmt;
4use std::mem::MaybeUninit;
5use std::num::NonZeroUsize;
6
7#[derive(Clone, Default)]
8/// A simple buffer with a read offset.
9pub struct Buffer {
10    /// The inner buffer data.
11    inner: Vec<u8>,
12
13    /// The number of initialized but unfilled bytes in the inner buffer.
14    unfilled_initialized: usize,
15
16    /// Read offset of the buffer.
17    offset: usize,
18}
19
20impl fmt::Debug for Buffer {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        f.debug_struct("Buffer")
23            .field("len", &self.inner.len())
24            .field("capacity", &self.inner.capacity())
25            .field("unfilled_initialized", &self.unfilled_initialized)
26            .field("offset", &self.offset)
27            .finish()
28    }
29}
30
31impl From<Vec<u8>> for Buffer {
32    #[inline]
33    fn from(buffer: Vec<u8>) -> Self {
34        Self::new(buffer)
35    }
36}
37
38impl Buffer {
39    #[inline]
40    #[must_use]
41    /// Creates a new [`Buffer`] from the given bytes slice.
42    pub fn new(buffer: Vec<u8>) -> Self {
43        Self {
44            inner: buffer,
45            unfilled_initialized: 0,
46            offset: 0,
47        }
48    }
49
50    #[must_use]
51    /// Creates an empty [`Buffer`].
52    pub const fn empty() -> Self {
53        Self {
54            inner: Vec::new(),
55            unfilled_initialized: 0,
56            offset: 0,
57        }
58    }
59
60    #[track_caller]
61    /// Reads the unread part of the buffer with the provided F, and advances
62    /// the read offset by the number of bytes read.
63    ///
64    /// Returns the number of bytes read by `f`.
65    ///
66    /// # Panics
67    ///
68    /// Panics if the closure returns an invalid read count.
69    pub fn read<F>(&mut self, f: F) -> Option<NonZeroUsize>
70    where
71        F: FnOnce(&[u8]) -> usize,
72    {
73        if self.inner.is_empty() {
74            // Empty buffer, nothing to read.
75
76            return None;
77        }
78
79        let Some((_, unread)) = self.inner.split_at_checked(self.offset) else {
80            unreachable!(
81                "The offset is always within the buffer length, but it is not: offset = {}, len = \
82                 {}",
83                self.offset,
84                self.inner.len()
85            );
86        };
87
88        if unread.is_empty() {
89            // All data has been read, reset the buffer.
90            self.reset();
91
92            return None;
93        }
94
95        let has_read = NonZeroUsize::new(f(unread));
96
97        match has_read {
98            Some(n) if n.get() <= unread.len() => {
99                // Advance the read offset, ensuring it does not exceed the buffer
100                // length.
101                self.offset = self.offset.saturating_add(n.get());
102            }
103            Some(n) => panic!(
104                "The closure read more bytes than available: read = {}, available = {}",
105                n,
106                unread.len()
107            ),
108            None => {}
109        }
110
111        has_read
112    }
113
114    #[inline]
115    #[must_use]
116    /// Returns the unread part of the buffer as a byte slice.
117    pub fn unread(&self) -> &[u8] {
118        &self.inner[self.offset..]
119    }
120
121    #[inline]
122    /// Drains the inner buffer data, clearing the buffer but does not change
123    /// its capacity, and returns the drained data.
124    pub fn drain(&mut self) -> Option<Vec<u8>> {
125        if self.unread().is_empty() {
126            None
127        } else {
128            let drained = self.unread().to_vec();
129
130            // Reset the buffer after draining.
131            self.reset();
132
133            Some(drained)
134        }
135    }
136
137    #[inline]
138    /// Reserves capacity for at least `additional` more bytes.
139    pub(crate) fn reserve(&mut self, additional: usize) {
140        self.inner.reserve(additional);
141    }
142
143    #[inline]
144    /// Returns a mutable reference to the unfilled part of the buffer without
145    /// ensuring that it has been fully initialized.
146    pub(crate) fn unfilled_mut(&mut self) -> &mut [MaybeUninit<u8>] {
147        self.unfilled_initialized = 0;
148
149        self.inner.spare_capacity_mut()
150    }
151
152    #[inline]
153    /// Returns a reference to the unfilled but initialized part of the buffer.
154    pub(crate) fn unfilled_initialized(&self) -> &[u8] {
155        #[allow(unsafe_code)]
156        // SAFETY: We have ensured that the unfilled part is initialized.
157        unsafe {
158            std::slice::from_raw_parts(
159                self.inner
160                    .as_ptr()
161                    .add(self.inner.len()),
162                self.unfilled_initialized,
163            )
164        }
165    }
166
167    #[allow(unsafe_code)]
168    #[inline]
169    /// Marks additional `cnt` bytes of uninitialized part of the inner buffer
170    /// as initialized.
171    ///
172    /// # Safety
173    ///
174    /// The caller must ensure that the first `cnt` bytes of the spare capacity
175    /// have been initialized, and that `self.initialized + cnt` does not exceed
176    /// the capacity of the inner buffer.
177    ///
178    /// It is recommended to update the initialized bytes after acquiring (via
179    /// [`Spare::unfilled_mut`]) and writing to the unfilled part of the
180    /// buffer.
181    pub(crate) unsafe fn assume_init_additional(&mut self, cnt: usize) {
182        let unfilled_initialized = self.unfilled_initialized + cnt;
183
184        debug_assert!(self.inner.len() + unfilled_initialized <= self.inner.capacity());
185
186        self.unfilled_initialized = unfilled_initialized;
187    }
188
189    #[inline]
190    /// Marks all initialized spare capacity as filled.
191    pub(crate) fn set_filled_all(&mut self) {
192        let initialized = self.inner.len() + self.unfilled_initialized;
193
194        debug_assert!(initialized <= self.inner.capacity());
195
196        #[allow(unsafe_code)]
197        // SAFETY: We have ensured that the unfilled part is initialized, and the length is valid.
198        unsafe {
199            self.inner.set_len(initialized);
200        };
201
202        self.unfilled_initialized = 0;
203    }
204
205    #[inline]
206    /// Resets the buffer, clearing the inner data and resetting the read
207    /// offset.
208    fn reset(&mut self) {
209        self.inner.truncate(0);
210        self.inner.shrink_to(65536);
211        self.offset = 0;
212    }
213}
214
215#[cfg(test)]
216#[allow(unsafe_code)]
217#[allow(clippy::redundant_closure_for_method_calls)]
218mod tests {
219    use super::*;
220
221    #[test]
222    fn test_buffer_new() {
223        let data = vec![1, 2, 3, 4, 5];
224        let buffer = Buffer::new(data.clone());
225
226        assert_eq!(buffer.unread(), &data);
227        assert_eq!(buffer.offset, 0);
228        assert_eq!(buffer.unfilled_initialized, 0);
229    }
230
231    #[test]
232    fn test_buffer_empty() {
233        let buffer = Buffer::empty();
234
235        assert!(buffer.unread().is_empty());
236        assert_eq!(buffer.offset, 0);
237        assert_eq!(buffer.unfilled_initialized, 0);
238        assert_eq!(buffer.inner.capacity(), 0);
239    }
240
241    #[test]
242    fn test_buffer_from_vec() {
243        let data = vec![10, 20, 30];
244        let buffer: Buffer = data.clone().into();
245
246        assert_eq!(buffer.unread(), &data);
247        assert_eq!(buffer.offset, 0);
248    }
249
250    #[test]
251    fn test_buffer_read_empty() {
252        let mut buffer = Buffer::empty();
253
254        let result = buffer.read(|data| {
255            assert!(data.is_empty());
256            0
257        });
258
259        assert!(result.is_none());
260    }
261
262    #[test]
263    fn test_buffer_read_partial() {
264        let mut buffer = Buffer::new(vec![1, 2, 3, 4, 5]);
265
266        // Read first 3 bytes
267        let result = buffer.read(|data| {
268            assert_eq!(data, &[1, 2, 3, 4, 5]);
269            3
270        });
271
272        assert_eq!(result.unwrap().get(), 3);
273        assert_eq!(buffer.unread(), &[4, 5]);
274        assert_eq!(buffer.offset, 3);
275    }
276
277    #[test]
278    fn test_buffer_read_full() {
279        let mut buffer = Buffer::new(vec![1, 2, 3]);
280
281        // Read all bytes
282        let result = buffer.read(|data| {
283            assert_eq!(data, &[1, 2, 3]);
284            3
285        });
286
287        assert_eq!(result.unwrap().get(), 3);
288        assert!(buffer.unread().is_empty());
289        assert_eq!(buffer.offset, 3);
290    }
291
292    #[test]
293    fn test_buffer_read_zero_bytes() {
294        let mut buffer = Buffer::new(vec![1, 2, 3]);
295
296        let result = buffer.read(|_data| 0);
297
298        assert!(result.is_none());
299        assert_eq!(buffer.unread(), &[1, 2, 3]);
300        assert_eq!(buffer.offset, 0);
301    }
302
303    #[test]
304    fn test_buffer_read_multiple_calls() {
305        let mut buffer = Buffer::new(vec![1, 2, 3, 4, 5, 6]);
306
307        // First read
308        let result1 = buffer.read(|data| {
309            assert_eq!(data, &[1, 2, 3, 4, 5, 6]);
310            2
311        });
312        assert_eq!(result1.unwrap().get(), 2);
313        assert_eq!(buffer.unread(), &[3, 4, 5, 6]);
314
315        // Second read
316        let result2 = buffer.read(|data| {
317            assert_eq!(data, &[3, 4, 5, 6]);
318            3
319        });
320        assert_eq!(result2.unwrap().get(), 3);
321        assert_eq!(buffer.unread(), &[6]);
322
323        // Third read (remaining)
324        let result3 = buffer.read(|data| {
325            assert_eq!(data, &[6]);
326            1
327        });
328        assert_eq!(result3.unwrap().get(), 1);
329        assert!(buffer.unread().is_empty());
330    }
331
332    #[test]
333    fn test_buffer_read_until_empty_resets() {
334        let mut buffer = Buffer::new(vec![1, 2, 3]);
335
336        // Read all data
337        let _ = buffer.read(|data| data.len());
338
339        // Buffer should still have offset set
340        assert_eq!(buffer.offset, 3);
341        assert!(buffer.unread().is_empty());
342
343        // Next read should reset and return None
344        let result = buffer.read(|_| 0);
345
346        assert!(result.is_none());
347        assert_eq!(buffer.offset, 0);
348        assert_eq!(buffer.inner.len(), 0); // Buffer is reset
349    }
350
351    #[test]
352    #[should_panic(expected = "The closure read more bytes than available")]
353    fn test_buffer_read_panic_read_too_much() {
354        let mut buffer = Buffer::new(vec![1, 2, 3]);
355
356        // Try to read more bytes than available
357        buffer.read(|data| {
358            assert_eq!(data.len(), 3);
359            4 // This should panic
360        });
361    }
362
363    #[test]
364    fn test_buffer_unread() {
365        let buffer = Buffer::new(vec![1, 2, 3, 4, 5]);
366        assert_eq!(buffer.unread(), &[1, 2, 3, 4, 5]);
367    }
368
369    #[test]
370    fn test_buffer_unread_after_partial_read() {
371        let mut buffer = Buffer::new(vec![1, 2, 3, 4, 5]);
372
373        // Read 2 bytes
374        let _ = buffer.read(|_| 2);
375
376        assert_eq!(buffer.unread(), &[3, 4, 5]);
377    }
378
379    #[test]
380    fn test_buffer_drain_empty() {
381        let mut buffer = Buffer::empty();
382
383        let drained = buffer.drain();
384        assert!(drained.is_none());
385    }
386
387    #[test]
388    fn test_buffer_drain_with_data() {
389        let mut buffer = Buffer::new(vec![1, 2, 3, 4, 5]);
390
391        let drained = buffer.drain();
392        assert_eq!(drained.unwrap(), vec![1, 2, 3, 4, 5]);
393
394        // Buffer should be reset after drain
395        assert!(buffer.unread().is_empty());
396        assert_eq!(buffer.offset, 0);
397        assert_eq!(buffer.inner.len(), 0);
398    }
399
400    #[test]
401    fn test_buffer_drain_after_partial_read() {
402        let mut buffer = Buffer::new(vec![1, 2, 3, 4, 5]);
403
404        // Read first 2 bytes
405        let _ = buffer.read(|_| 2);
406
407        let drained = buffer.drain();
408        assert_eq!(drained.unwrap(), vec![3, 4, 5]); // Only unread data
409
410        // Buffer should be reset
411        assert!(buffer.unread().is_empty());
412        assert_eq!(buffer.offset, 0);
413    }
414
415    #[test]
416    fn test_buffer_drain_fully_read() {
417        let mut buffer = Buffer::new(vec![1, 2, 3]);
418
419        // Read all data
420        let _ = buffer.read(|data| data.len());
421
422        let drained = buffer.drain();
423        assert!(drained.is_none()); // Nothing to drain
424    }
425
426    #[test]
427    fn test_buffer_reserve() {
428        let mut buffer = Buffer::empty();
429        let initial_capacity = buffer.inner.capacity();
430
431        buffer.reserve(100);
432        assert!(buffer.inner.capacity() >= initial_capacity + 100);
433    }
434
435    #[test]
436    fn test_buffer_unfilled_mut() {
437        let mut buffer = Buffer::empty();
438        buffer.reserve(10);
439
440        let unfilled = buffer.unfilled_mut();
441        assert_eq!(unfilled.len(), 10);
442        assert_eq!(buffer.unfilled_initialized, 0);
443
444        unsafe { buffer.assume_init_additional(5) };
445        assert_eq!(buffer.unfilled_initialized, 5);
446
447        let unfilled = buffer.unfilled_mut();
448        assert!(!unfilled.is_empty());
449        assert_eq!(buffer.unfilled_initialized, 0); // Should be reset to 0
450    }
451
452    #[test]
453    fn test_buffer_unfilled_initialized_empty() {
454        let buffer = Buffer::empty();
455        let unfilled_init = buffer.unfilled_initialized();
456        assert!(unfilled_init.is_empty());
457    }
458
459    #[test]
460    fn test_buffer_assume_init_additional() {
461        let mut buffer = Buffer::empty();
462        buffer.reserve(10);
463
464        // Simulate writing to unfilled part
465        unsafe {
466            buffer.assume_init_additional(5);
467        }
468
469        assert_eq!(buffer.unfilled_initialized, 5);
470
471        let unfilled_init = buffer.unfilled_initialized();
472        assert_eq!(unfilled_init.len(), 5);
473    }
474
475    #[test]
476    fn test_buffer_set_filled_all() {
477        let mut buffer = Buffer::empty();
478
479        buffer.reserve(10);
480
481        unsafe {
482            buffer.assume_init_additional(3);
483        }
484
485        assert_eq!(buffer.inner.len(), 0);
486
487        buffer.set_filled_all();
488
489        assert_eq!(buffer.inner.len(), 3);
490        assert_eq!(buffer.unfilled_initialized, 0);
491    }
492
493    #[test]
494    fn test_buffer_complex_workflow() {
495        // Test a complex workflow that uses multiple methods
496        let mut buffer = Buffer::new(vec![1, 2, 3, 4, 5]);
497
498        // Read some data
499        let _ = buffer.read(|_| 2);
500        assert_eq!(buffer.unread(), &[3, 4, 5]);
501
502        // Reserve more space
503        buffer.reserve(10);
504
505        // Get unfilled space and mark some as initialized
506        let _unfilled = buffer.unfilled_mut();
507        unsafe {
508            buffer.assume_init_additional(2);
509        }
510
511        // Set the initialized data as filled
512        buffer.set_filled_all();
513
514        // The buffer should now contain original unread data plus the new filled data
515        assert!(buffer.unread().len() >= 3); // At least the original unread data
516
517        // Drain everything
518        let drained = buffer.drain();
519        assert!(drained.is_some());
520        assert!(buffer.unread().is_empty());
521    }
522}