ironrdp_core/
cursor.rs

1use core::fmt;
2
3/// Error indicating that there are not enough bytes in the buffer to perform an operation.
4#[derive(Copy, Eq, PartialEq, Clone, Debug)]
5pub struct NotEnoughBytesError {
6    received: usize,
7    expected: usize,
8}
9
10impl NotEnoughBytesError {
11    /// The number of bytes received.
12    #[must_use]
13    #[inline]
14    pub const fn received(&self) -> usize {
15        self.received
16    }
17
18    /// The number of bytes expected.
19    #[must_use]
20    #[inline]
21    pub const fn expected(&self) -> usize {
22        self.expected
23    }
24}
25
26impl fmt::Display for NotEnoughBytesError {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        write!(
29            f,
30            "not enough bytes for operation: received {} bytes, expected {} bytes",
31            self.received, self.expected
32        )
33    }
34}
35
36#[cfg(feature = "std")]
37impl std::error::Error for NotEnoughBytesError {}
38
39macro_rules! ensure_enough_bytes {
40    (in: $buf:ident, size: $expected:expr) => {{
41        let received = $buf.len();
42        let expected = $expected;
43        if !(received >= expected) {
44            return Err(NotEnoughBytesError { received, expected });
45        }
46    }};
47}
48
49/// A cursor for reading bytes from a buffer.
50#[derive(Clone, Debug)]
51pub struct ReadCursor<'a> {
52    inner: &'a [u8],
53    pos: usize,
54}
55
56impl<'a> ReadCursor<'a> {
57    /// Create a new `ReadCursor` from a byte slice.
58    #[inline]
59    pub const fn new(bytes: &'a [u8]) -> Self {
60        Self { inner: bytes, pos: 0 }
61    }
62
63    /// Returns the number of bytes remaining.
64    #[inline]
65    #[track_caller]
66    pub const fn len(&self) -> usize {
67        self.inner.len() - self.pos
68    }
69
70    /// Returns `true` if there are no bytes remaining.
71    #[inline]
72    pub const fn is_empty(&self) -> bool {
73        self.len() == 0
74    }
75
76    /// Returns `true` if there are no bytes remaining.
77    #[inline]
78    pub const fn eof(&self) -> bool {
79        self.is_empty()
80    }
81
82    /// Returns a slice of the remaining bytes.
83    #[inline]
84    #[track_caller]
85    pub fn remaining(&self) -> &'a [u8] {
86        let idx = core::cmp::min(self.pos, self.inner.len());
87        &self.inner[idx..]
88    }
89
90    /// Returns two cursors, one with the first `mid` bytes and the other with the remaining bytes.
91    #[inline]
92    #[track_caller]
93    #[must_use]
94    pub const fn split_at_peek(&self, mid: usize) -> (ReadCursor<'a>, ReadCursor<'a>) {
95        let (left, right) = self.inner.split_at(self.pos + mid);
96        let left = ReadCursor {
97            inner: left,
98            pos: self.pos,
99        };
100        let right = ReadCursor { inner: right, pos: 0 };
101        (left, right)
102    }
103
104    /// Returns two cursors, one with the first `mid` bytes and the other with the remaining bytes.
105    ///
106    /// The current cursor will be moved to the end.
107    #[inline]
108    #[track_caller]
109    #[must_use]
110    pub fn split_at(&mut self, mid: usize) -> (ReadCursor<'a>, ReadCursor<'a>) {
111        let res = self.split_at_peek(mid);
112        self.pos = self.inner.len();
113        res
114    }
115
116    /// Return the inner byte slice.
117    #[inline]
118    pub const fn inner(&self) -> &[u8] {
119        self.inner
120    }
121
122    /// Returns the current position.
123    #[inline]
124    pub const fn pos(&self) -> usize {
125        self.pos
126    }
127
128    /// Read an array of `N` bytes.
129    #[inline]
130    #[track_caller]
131    pub fn read_array<const N: usize>(&mut self) -> [u8; N] {
132        let bytes = &self.inner[self.pos..self.pos + N];
133        self.pos += N;
134        bytes.try_into().expect("N-elements array")
135    }
136
137    /// Read a slice of `n` bytes.
138    #[inline]
139    #[track_caller]
140    pub fn read_slice(&mut self, n: usize) -> &'a [u8] {
141        let bytes = &self.inner[self.pos..self.pos + n];
142        self.pos += n;
143        bytes
144    }
145
146    /// Read the remaining bytes.
147    pub fn read_remaining(&mut self) -> &[u8] {
148        self.read_slice(self.len())
149    }
150
151    /// Read a `u8`.
152    #[inline]
153    #[track_caller]
154    pub fn read_u8(&mut self) -> u8 {
155        self.read_array::<1>()[0]
156    }
157
158    /// Try to read a `u8`.
159    #[inline]
160    pub fn try_read_u8(&mut self) -> Result<u8, NotEnoughBytesError> {
161        ensure_enough_bytes!(in: self, size: 1);
162        Ok(self.read_array::<1>()[0])
163    }
164
165    /// Read a `i16`.
166    #[inline]
167    #[track_caller]
168    pub fn read_i16(&mut self) -> i16 {
169        i16::from_le_bytes(self.read_array::<2>())
170    }
171
172    /// Read a `i16` in big-endian.
173    #[inline]
174    #[track_caller]
175    pub fn read_i16_be(&mut self) -> i16 {
176        i16::from_be_bytes(self.read_array::<2>())
177    }
178
179    /// Try to read a `i16`.
180    #[inline]
181    pub fn try_read_i16(&mut self) -> Result<i16, NotEnoughBytesError> {
182        ensure_enough_bytes!(in: self, size: 2);
183        Ok(i16::from_le_bytes(self.read_array::<2>()))
184    }
185
186    /// Try to read a `i16` in big-endian.
187    #[inline]
188    pub fn try_read_i16_be(&mut self) -> Result<i16, NotEnoughBytesError> {
189        ensure_enough_bytes!(in: self, size: 2);
190        Ok(i16::from_be_bytes(self.read_array::<2>()))
191    }
192
193    /// Read a `u16`.
194    #[inline]
195    #[track_caller]
196    pub fn read_u16(&mut self) -> u16 {
197        u16::from_le_bytes(self.read_array::<2>())
198    }
199
200    /// Read a `u16` in big-endian.
201    #[inline]
202    #[track_caller]
203    pub fn read_u16_be(&mut self) -> u16 {
204        u16::from_be_bytes(self.read_array::<2>())
205    }
206
207    /// Try to read a `u16`.
208    #[inline]
209    pub fn try_read_u16(&mut self) -> Result<u16, NotEnoughBytesError> {
210        ensure_enough_bytes!(in: self, size: 2);
211        Ok(u16::from_le_bytes(self.read_array::<2>()))
212    }
213
214    /// Try to read a `u16` in big-endian.
215    #[inline]
216    pub fn try_read_u16_be(&mut self) -> Result<u16, NotEnoughBytesError> {
217        ensure_enough_bytes!(in: self, size: 2);
218        Ok(u16::from_be_bytes(self.read_array::<2>()))
219    }
220
221    /// Read a `u32`.
222    #[inline]
223    #[track_caller]
224    pub fn read_u32(&mut self) -> u32 {
225        u32::from_le_bytes(self.read_array::<4>())
226    }
227
228    /// Read a `u32` in big-endian.
229    #[inline]
230    #[track_caller]
231    pub fn read_u32_be(&mut self) -> u32 {
232        u32::from_be_bytes(self.read_array::<4>())
233    }
234
235    /// Try to read a `u32`.
236    #[inline]
237    pub fn try_read_u32(&mut self) -> Result<u32, NotEnoughBytesError> {
238        ensure_enough_bytes!(in: self, size: 4);
239        Ok(u32::from_le_bytes(self.read_array::<4>()))
240    }
241
242    /// Try to read a `u32` in big-endian.
243    #[inline]
244    pub fn try_read_u32_be(&mut self) -> Result<u32, NotEnoughBytesError> {
245        ensure_enough_bytes!(in: self, size: 4);
246        Ok(u32::from_be_bytes(self.read_array::<4>()))
247    }
248
249    /// Read a `u64`.
250    #[inline]
251    #[track_caller]
252    pub fn read_u64(&mut self) -> u64 {
253        u64::from_le_bytes(self.read_array::<8>())
254    }
255
256    /// Read a `u64` in big-endian.
257    #[inline]
258    #[track_caller]
259    pub fn read_u64_be(&mut self) -> u64 {
260        u64::from_be_bytes(self.read_array::<8>())
261    }
262
263    /// Try to read a `u64`.
264    #[inline]
265    pub fn try_read_u64(&mut self) -> Result<u64, NotEnoughBytesError> {
266        ensure_enough_bytes!(in: self, size: 8);
267        Ok(u64::from_le_bytes(self.read_array::<8>()))
268    }
269
270    /// Try to read a `u64` in big-endian.
271    #[inline]
272    pub fn try_read_u64_be(&mut self) -> Result<u64, NotEnoughBytesError> {
273        ensure_enough_bytes!(in: self, size: 8);
274        Ok(u64::from_be_bytes(self.read_array::<8>()))
275    }
276
277    /// Read a `i32`.
278    #[inline]
279    pub fn read_i32(&mut self) -> i32 {
280        i32::from_le_bytes(self.read_array::<4>())
281    }
282
283    /// Read a `i32` in big-endian.
284    #[inline]
285    pub fn read_i32_be(&mut self) -> i32 {
286        i32::from_be_bytes(self.read_array::<4>())
287    }
288
289    /// Try to read a `i32`.
290    #[inline]
291    pub fn try_read_i32(&mut self) -> Result<i32, NotEnoughBytesError> {
292        ensure_enough_bytes!(in: self, size: 4);
293        Ok(i32::from_le_bytes(self.read_array::<4>()))
294    }
295
296    /// Try to read a `i32` in big-endian.
297    #[inline]
298    pub fn try_read_i32_be(&mut self) -> Result<i32, NotEnoughBytesError> {
299        ensure_enough_bytes!(in: self, size: 4);
300        Ok(i32::from_be_bytes(self.read_array::<4>()))
301    }
302
303    /// Read a `i64`.
304    #[inline]
305    pub fn read_i64(&mut self) -> i64 {
306        i64::from_le_bytes(self.read_array::<8>())
307    }
308
309    /// Read a `i64` in big-endian.
310    #[inline]
311    pub fn read_i64_be(&mut self) -> i64 {
312        i64::from_be_bytes(self.read_array::<8>())
313    }
314
315    /// Try to read a `i64`.
316    #[inline]
317    pub fn try_read_i64(&mut self) -> Result<i64, NotEnoughBytesError> {
318        ensure_enough_bytes!(in: self, size: 8);
319        Ok(i64::from_le_bytes(self.read_array::<8>()))
320    }
321
322    /// Try to read a `i64` in big-endian.
323    #[inline]
324    pub fn try_read_i64_be(&mut self) -> Result<i64, NotEnoughBytesError> {
325        ensure_enough_bytes!(in: self, size: 8);
326        Ok(i64::from_be_bytes(self.read_array::<8>()))
327    }
328
329    /// Read a `u128`.
330    #[inline]
331    pub fn read_u128(&mut self) -> u128 {
332        u128::from_le_bytes(self.read_array::<16>())
333    }
334
335    /// Read a `u128` in big-endian.
336    #[inline]
337    pub fn read_u128_be(&mut self) -> u128 {
338        u128::from_be_bytes(self.read_array::<16>())
339    }
340
341    /// Try to read a `u128`.
342    #[inline]
343    pub fn try_read_u128(&mut self) -> Result<u128, NotEnoughBytesError> {
344        ensure_enough_bytes!(in: self, size: 16);
345        Ok(u128::from_le_bytes(self.read_array::<16>()))
346    }
347
348    /// Try to read a `u128` in big-endian.
349    #[inline]
350    pub fn try_read_u128_be(&mut self) -> Result<u128, NotEnoughBytesError> {
351        ensure_enough_bytes!(in: self, size: 16);
352        Ok(u128::from_be_bytes(self.read_array::<16>()))
353    }
354
355    /// Peek at the next `N` bytes without consuming them.
356    #[inline]
357    #[track_caller]
358    pub fn peek<const N: usize>(&mut self) -> [u8; N] {
359        self.inner[self.pos..self.pos + N].try_into().expect("N-elements array")
360    }
361
362    /// Peek at the next `N` bytes without consuming them.
363    #[inline]
364    #[track_caller]
365    pub fn peek_slice(&mut self, n: usize) -> &'a [u8] {
366        &self.inner[self.pos..self.pos + n]
367    }
368
369    /// Peek a `u8` without consuming it.
370    #[inline]
371    #[track_caller]
372    pub fn peek_u8(&mut self) -> u8 {
373        self.peek::<1>()[0]
374    }
375
376    /// Try to peek a `u8` without consuming it.
377    #[inline]
378    pub fn try_peek_u8(&mut self) -> Result<u8, NotEnoughBytesError> {
379        ensure_enough_bytes!(in: self, size: 1);
380        Ok(self.peek::<1>()[0])
381    }
382
383    /// Peek a `u16` without consuming it.
384    #[inline]
385    #[track_caller]
386    pub fn peek_u16(&mut self) -> u16 {
387        u16::from_le_bytes(self.peek::<2>())
388    }
389
390    /// Peek a big-endian `u16` without consuming it.
391    #[inline]
392    #[track_caller]
393    pub fn peek_u16_be(&mut self) -> u16 {
394        u16::from_be_bytes(self.peek::<2>())
395    }
396
397    /// Try to peek a `u16` without consuming it.
398    #[inline]
399    pub fn try_peek_u16(&mut self) -> Result<u16, NotEnoughBytesError> {
400        ensure_enough_bytes!(in: self, size: 2);
401        Ok(u16::from_le_bytes(self.peek::<2>()))
402    }
403
404    /// Try to peek a big-endian `u16` without consuming it.
405    #[inline]
406    pub fn try_peek_u16_be(&mut self) -> Result<u16, NotEnoughBytesError> {
407        ensure_enough_bytes!(in: self, size: 2);
408        Ok(u16::from_be_bytes(self.peek::<2>()))
409    }
410
411    /// Peek a `u32` without consuming it.
412    #[inline]
413    #[track_caller]
414    pub fn peek_u32(&mut self) -> u32 {
415        u32::from_le_bytes(self.peek::<4>())
416    }
417
418    /// Peek a big-endian `u32` without consuming it.
419    #[inline]
420    #[track_caller]
421    pub fn peek_u32_be(&mut self) -> u32 {
422        u32::from_be_bytes(self.peek::<4>())
423    }
424
425    /// Try to peek a `u32` without consuming it.
426    #[inline]
427    pub fn try_peek_u32(&mut self) -> Result<u32, NotEnoughBytesError> {
428        ensure_enough_bytes!(in: self, size: 4);
429        Ok(u32::from_le_bytes(self.peek::<4>()))
430    }
431
432    /// Try to peek a big-endian `u32` without consuming it.
433    #[inline]
434    pub fn try_peek_u32_be(&mut self) -> Result<u32, NotEnoughBytesError> {
435        ensure_enough_bytes!(in: self, size: 4);
436        Ok(u32::from_be_bytes(self.peek::<4>()))
437    }
438
439    /// Peek a `u64` without consuming it.
440    #[inline]
441    #[track_caller]
442    pub fn peek_u64(&mut self) -> u64 {
443        u64::from_le_bytes(self.peek::<8>())
444    }
445
446    /// Peek a big-endian `u64` without consuming it.
447    #[inline]
448    #[track_caller]
449    pub fn peek_u64_be(&mut self) -> u64 {
450        u64::from_be_bytes(self.peek::<8>())
451    }
452
453    /// Try to peek a `u64` without consuming it.
454    #[inline]
455    pub fn try_peek_u64(&mut self) -> Result<u64, NotEnoughBytesError> {
456        ensure_enough_bytes!(in: self, size: 8);
457        Ok(u64::from_le_bytes(self.peek::<8>()))
458    }
459
460    /// Try to peek a big-endian `u64` without consuming it.
461    #[inline]
462    pub fn try_peek_u64_be(&mut self) -> Result<u64, NotEnoughBytesError> {
463        ensure_enough_bytes!(in: self, size: 8);
464        Ok(u64::from_be_bytes(self.peek::<8>()))
465    }
466
467    /// Advance the cursor by `len` bytes.
468    #[inline]
469    #[track_caller]
470    pub fn advance(&mut self, len: usize) {
471        self.pos += len;
472    }
473
474    /// Return a new cursor advanced by `len` bytes.
475    #[inline]
476    #[track_caller]
477    #[must_use]
478    pub const fn advanced(&'a self, len: usize) -> ReadCursor<'a> {
479        ReadCursor {
480            inner: self.inner,
481            pos: self.pos + len,
482        }
483    }
484
485    /// Rewind the cursor by `len` bytes.
486    #[inline]
487    #[track_caller]
488    pub fn rewind(&mut self, len: usize) {
489        self.pos -= len;
490    }
491
492    /// Return a new cursor rewinded by `len` bytes.
493    #[inline]
494    #[track_caller]
495    #[must_use]
496    pub const fn rewinded(&'a self, len: usize) -> ReadCursor<'a> {
497        ReadCursor {
498            inner: self.inner,
499            pos: self.pos - len,
500        }
501    }
502}
503
504#[cfg(feature = "std")]
505impl std::io::Read for ReadCursor<'_> {
506    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
507        let n_to_copy = core::cmp::min(buf.len(), self.len());
508        let to_copy = self.read_slice(n_to_copy);
509        buf.copy_from_slice(to_copy);
510        Ok(n_to_copy)
511    }
512}
513
514/// A cursor for writing bytes to a buffer.
515#[derive(Debug)]
516pub struct WriteCursor<'a> {
517    inner: &'a mut [u8],
518    pos: usize,
519}
520
521impl<'a> WriteCursor<'a> {
522    /// Create a new `WriteCursor` from a mutable slice of bytes.
523    #[inline]
524    pub fn new(bytes: &'a mut [u8]) -> Self {
525        Self { inner: bytes, pos: 0 }
526    }
527
528    /// Returns the number of bytes remaining.
529    #[inline]
530    #[track_caller]
531    pub const fn len(&self) -> usize {
532        self.inner.len() - self.pos
533    }
534
535    /// Returns `true` if there are no bytes remaining.
536    #[inline]
537    pub const fn is_empty(&self) -> bool {
538        self.len() == 0
539    }
540
541    /// Returns `true` if there are no bytes remaining.
542    #[inline]
543    pub const fn eof(&self) -> bool {
544        self.is_empty()
545    }
546
547    /// Returns a slice of the remaining bytes.
548    #[inline]
549    #[track_caller]
550    pub fn remaining(&self) -> &[u8] {
551        let idx = core::cmp::min(self.pos, self.inner.len());
552        &self.inner[idx..]
553    }
554
555    /// Returns a mutable slice of the remaining bytes.
556    #[inline]
557    #[track_caller]
558    pub fn remaining_mut(&mut self) -> &mut [u8] {
559        let idx = core::cmp::min(self.pos, self.inner.len());
560        &mut self.inner[idx..]
561    }
562
563    /// Returns the inner byte slice.
564    #[inline]
565    pub const fn inner(&self) -> &[u8] {
566        self.inner
567    }
568
569    /// Returns the inner mutable byte slice.
570    #[inline]
571    pub fn inner_mut(&mut self) -> &mut [u8] {
572        self.inner
573    }
574
575    /// Returns the current position of the cursor.
576    #[inline]
577    pub const fn pos(&self) -> usize {
578        self.pos
579    }
580
581    /// Write an array of bytes to the buffer.
582    #[inline]
583    #[track_caller]
584    pub fn write_array<const N: usize>(&mut self, array: [u8; N]) {
585        self.inner[self.pos..self.pos + N].copy_from_slice(&array);
586        self.pos += N;
587    }
588
589    /// Write a slice of bytes to the buffer.
590    #[inline]
591    #[track_caller]
592    pub fn write_slice(&mut self, slice: &[u8]) {
593        let n = slice.len();
594        self.inner[self.pos..self.pos + n].copy_from_slice(slice);
595        self.pos += n;
596    }
597
598    /// Write a byte to the buffer.
599    #[inline]
600    #[track_caller]
601    pub fn write_u8(&mut self, value: u8) {
602        self.write_array(value.to_le_bytes())
603    }
604
605    /// Write a signed byte to the buffer.
606    #[inline]
607    #[track_caller]
608    pub fn write_i8(&mut self, value: i8) {
609        self.write_array(value.to_le_bytes())
610    }
611
612    /// Write a little-endian `u16` to the buffer.
613    #[inline]
614    #[track_caller]
615    pub fn write_u16(&mut self, value: u16) {
616        self.write_array(value.to_le_bytes())
617    }
618
619    /// Write a big-endian `u16` to the buffer.
620    #[inline]
621    #[track_caller]
622    pub fn write_u16_be(&mut self, value: u16) {
623        self.write_array(value.to_be_bytes())
624    }
625
626    /// Write a signed little-endian `i16` to the buffer.
627    #[inline]
628    #[track_caller]
629    pub fn write_i16(&mut self, value: i16) {
630        self.write_array(value.to_le_bytes())
631    }
632
633    /// Write a signed big-endian `i16` to the buffer.
634    #[inline]
635    #[track_caller]
636    pub fn write_i16_be(&mut self, value: i16) {
637        self.write_array(value.to_be_bytes())
638    }
639
640    /// Write a little-endian `u32` to the buffer.
641    #[inline]
642    #[track_caller]
643    pub fn write_u32(&mut self, value: u32) {
644        self.write_array(value.to_le_bytes())
645    }
646
647    /// Write a big-endian `u32` to the buffer.
648    #[inline]
649    #[track_caller]
650    pub fn write_u32_be(&mut self, value: u32) {
651        self.write_array(value.to_be_bytes())
652    }
653
654    /// Write a signed little-endian `i32` to the buffer.
655    #[inline]
656    #[track_caller]
657    pub fn write_i32(&mut self, value: i32) {
658        self.write_array(value.to_le_bytes())
659    }
660
661    /// Write a little-endian `u64` to the buffer.
662    #[inline]
663    #[track_caller]
664    pub fn write_u64(&mut self, value: u64) {
665        self.write_array(value.to_le_bytes())
666    }
667
668    /// Write a big-endian `u64` to the buffer.
669    #[inline]
670    #[track_caller]
671    pub fn write_u64_be(&mut self, value: u64) {
672        self.write_array(value.to_be_bytes())
673    }
674
675    /// Write a signed little-endian `i64` to the buffer.
676    #[inline]
677    #[track_caller]
678    pub fn write_i64(&mut self, value: i64) {
679        self.write_array(value.to_le_bytes())
680    }
681
682    /// Write a signed big-endian `i64` to the buffer.
683    #[inline]
684    #[track_caller]
685    pub fn write_i64_be(&mut self, value: i64) {
686        self.write_array(value.to_be_bytes())
687    }
688
689    /// Write a little-endian `u128` to the buffer.
690    #[inline]
691    #[track_caller]
692    pub fn write_u128(&mut self, value: u128) {
693        self.write_array(value.to_le_bytes())
694    }
695
696    /// Write a big-endian `u128` to the buffer.
697    #[inline]
698    #[track_caller]
699    pub fn write_u128_be(&mut self, value: u128) {
700        self.write_array(value.to_be_bytes())
701    }
702
703    /// Advance the cursor by `len` bytes.
704    #[inline]
705    #[track_caller]
706    pub fn advance(&mut self, len: usize) {
707        self.pos += len;
708    }
709
710    /// Returns a new cursor advanced by `len` bytes.
711    #[inline]
712    #[track_caller]
713    #[must_use]
714    pub fn advanced(&'a mut self, len: usize) -> WriteCursor<'a> {
715        WriteCursor {
716            inner: self.inner,
717            pos: self.pos + len,
718        }
719    }
720
721    /// Rewind the cursor by `len` bytes.
722    #[inline]
723    #[track_caller]
724    pub fn rewind(&mut self, len: usize) {
725        self.pos -= len;
726    }
727
728    /// Returns a new cursor rewinded by `len` bytes.
729    #[inline]
730    #[track_caller]
731    #[must_use]
732    pub fn rewinded(&'a mut self, len: usize) -> WriteCursor<'a> {
733        WriteCursor {
734            inner: self.inner,
735            pos: self.pos - len,
736        }
737    }
738}
739
740#[cfg(feature = "std")]
741impl std::io::Write for WriteCursor<'_> {
742    #[inline]
743    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
744        self.write_slice(buf);
745        Ok(buf.len())
746    }
747
748    #[inline]
749    fn flush(&mut self) -> std::io::Result<()> {
750        Ok(())
751    }
752}