Skip to main content

octets/
lib.rs

1// Copyright (C) 2018-2019, Cloudflare, Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright notice,
9//       this list of conditions and the following disclaimer.
10//
11//     * Redistributions in binary form must reproduce the above copyright
12//       notice, this list of conditions and the following disclaimer in the
13//       documentation and/or other materials provided with the distribution.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
19// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27/// Zero-copy abstraction for parsing and constructing network packets.
28use std::mem;
29use std::ptr;
30
31/// Maximum value that can be encoded via varint.
32pub const MAX_VAR_INT: u64 = 4_611_686_018_427_387_903;
33
34/// A specialized [`Result`] type for [`OctetsMut`] operations.
35///
36/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
37/// [`OctetsMut`]: struct.OctetsMut.html
38pub type Result<T> = std::result::Result<T, BufferTooShortError>;
39
40/// An error indicating that the provided [`OctetsMut`] is not big enough.
41///
42/// [`OctetsMut`]: struct.OctetsMut.html
43#[derive(Clone, Copy, Debug, PartialEq, Eq)]
44pub struct BufferTooShortError;
45
46impl std::fmt::Display for BufferTooShortError {
47    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
48        write!(f, "BufferTooShortError")
49    }
50}
51
52impl std::error::Error for BufferTooShortError {
53    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
54        None
55    }
56}
57
58/// A byte sink for encoders in this crate.
59///
60/// This lets callers use octets encoders with output targets other than a
61/// single contiguous [`OctetsMut`] buffer.
62pub trait OctetsWriter {
63    /// The error returned by the output sink.
64    type Error;
65
66    /// Writes `v` to the output sink.
67    fn put_bytes(&mut self, v: &[u8]) -> std::result::Result<(), Self::Error>;
68
69    /// Writes `v` to the output sink after HPACK Huffman-encoding it.
70    ///
71    /// The Huffman code implemented is the one defined for HPACK (RFC7541).
72    ///
73    /// Encoding is not atomic. An error can be returned after writing part of
74    /// the output, so callers cannot safely retry unless the sink discards the
75    /// partial output. Sinks that perform irreversible writes, such as sending
76    /// data over the network, must buffer the output or guarantee success.
77    #[cfg(feature = "huffman_hpack")]
78    fn put_huffman_encoded<const LOWER_CASE: bool>(
79        &mut self, v: &[u8],
80    ) -> std::result::Result<(), Self::Error>
81    where
82        Self: Sized,
83    {
84        huffman_encode_with::<LOWER_CASE, _, _>(v, |chunk| self.put_bytes(chunk))
85    }
86}
87
88/// Helper macro that asserts at compile time. It requires that
89/// `cond` is a const expression.
90macro_rules! static_assert {
91    ($cond:expr) => {{
92        const _: () = assert!($cond);
93    }};
94}
95
96macro_rules! peek_u {
97    ($b:expr, $ty:ty, $len:expr) => {{
98        let len = $len;
99        let src = &$b.buf[$b.off..];
100
101        if src.len() < len {
102            return Err(BufferTooShortError);
103        }
104
105        static_assert!($len <= mem::size_of::<$ty>());
106        let mut out: $ty = 0;
107        unsafe {
108            let dst = &mut out as *mut $ty as *mut u8;
109            let off = (mem::size_of::<$ty>() - len) as isize;
110
111            ptr::copy_nonoverlapping(src.as_ptr(), dst.offset(off), len);
112        };
113
114        Ok(<$ty>::from_be(out))
115    }};
116}
117
118macro_rules! get_u {
119    ($b:expr, $ty:ty, $len:expr) => {{
120        let out = peek_u!($b, $ty, $len);
121
122        $b.off += $len;
123
124        out
125    }};
126}
127
128macro_rules! put_u {
129    ($b:expr, $ty:ty, $v:expr, $len:expr) => {{
130        let len = $len;
131
132        if $b.buf.len() < $b.off + len {
133            return Err(BufferTooShortError);
134        }
135
136        let v = $v;
137
138        let dst = &mut $b.buf[$b.off..($b.off + len)];
139
140        static_assert!($len <= mem::size_of::<$ty>());
141        unsafe {
142            let src = &<$ty>::to_be(v) as *const $ty as *const u8;
143            let off = (mem::size_of::<$ty>() - len) as isize;
144
145            ptr::copy_nonoverlapping(src.offset(off), dst.as_mut_ptr(), len);
146        }
147
148        $b.off += $len;
149
150        Ok(dst)
151    }};
152}
153
154/// A zero-copy immutable byte buffer.
155///
156/// `Octets` wraps an in-memory buffer of bytes and provides utility functions
157/// for manipulating it. The underlying buffer is provided by the user and is
158/// not copied when creating an `Octets`. Operations are panic-free and will
159/// avoid indexing the buffer past its end.
160///
161/// Additionally, an offset (initially set to the start of the buffer) is
162/// incremented as bytes are read from / written to the buffer, to allow for
163/// sequential operations.
164#[derive(Debug, PartialEq, Eq)]
165pub struct Octets<'a> {
166    buf: &'a [u8],
167    off: usize,
168}
169
170impl<'a> Octets<'a> {
171    /// Creates an `Octets` from the given slice, without copying.
172    ///
173    /// Since the `Octets` is immutable, the input slice needs to be
174    /// immutable.
175    pub fn with_slice(buf: &'a [u8]) -> Self {
176        Octets { buf, off: 0 }
177    }
178
179    /// Reads an unsigned 8-bit integer from the current offset and advances
180    /// the buffer.
181    pub fn get_u8(&mut self) -> Result<u8> {
182        get_u!(self, u8, 1)
183    }
184
185    /// Reads an unsigned 8-bit integer from the current offset without
186    /// advancing the buffer.
187    pub fn peek_u8(&mut self) -> Result<u8> {
188        peek_u!(self, u8, 1)
189    }
190
191    /// Reads an unsigned 16-bit integer in network byte-order from the current
192    /// offset and advances the buffer.
193    pub fn get_u16(&mut self) -> Result<u16> {
194        get_u!(self, u16, 2)
195    }
196
197    /// Reads an unsigned 24-bit integer in network byte-order from the current
198    /// offset and advances the buffer.
199    pub fn get_u24(&mut self) -> Result<u32> {
200        get_u!(self, u32, 3)
201    }
202
203    /// Reads an unsigned 32-bit integer in network byte-order from the current
204    /// offset and advances the buffer.
205    pub fn get_u32(&mut self) -> Result<u32> {
206        get_u!(self, u32, 4)
207    }
208
209    /// Reads an unsigned 64-bit integer in network byte-order from the current
210    /// offset and advances the buffer.
211    pub fn get_u64(&mut self) -> Result<u64> {
212        get_u!(self, u64, 8)
213    }
214
215    /// Reads an unsigned variable-length integer in network byte-order from
216    /// the current offset and advances the buffer.
217    pub fn get_varint(&mut self) -> Result<u64> {
218        let first = self.peek_u8()?;
219
220        let len = varint_parse_len(first);
221
222        if len > self.cap() {
223            return Err(BufferTooShortError);
224        }
225
226        let out = match len {
227            1 => u64::from(self.get_u8()?),
228
229            2 => u64::from(self.get_u16()? & 0x3fff),
230
231            4 => u64::from(self.get_u32()? & 0x3fffffff),
232
233            8 => self.get_u64()? & 0x3fffffffffffffff,
234
235            _ => unreachable!(),
236        };
237
238        Ok(out)
239    }
240
241    /// Reads `len` bytes from the current offset without copying and advances
242    /// the buffer.
243    pub fn get_bytes(&mut self, len: usize) -> Result<Octets<'a>> {
244        if self.cap() < len {
245            return Err(BufferTooShortError);
246        }
247
248        let out = Octets {
249            buf: &self.buf[self.off..self.off + len],
250            off: 0,
251        };
252
253        self.off += len;
254
255        Ok(out)
256    }
257
258    /// Reads `len` bytes from the current offset without copying and advances
259    /// the buffer, where `len` is an unsigned 8-bit integer prefix.
260    pub fn get_bytes_with_u8_length(&mut self) -> Result<Octets<'a>> {
261        let len = self.get_u8()?;
262        self.get_bytes(len as usize)
263    }
264
265    /// Reads `len` bytes from the current offset without copying and advances
266    /// the buffer, where `len` is an unsigned 16-bit integer prefix in network
267    /// byte-order.
268    pub fn get_bytes_with_u16_length(&mut self) -> Result<Octets<'a>> {
269        let len = self.get_u16()?;
270        self.get_bytes(len as usize)
271    }
272
273    /// Reads `len` bytes from the current offset without copying and advances
274    /// the buffer, where `len` is an unsigned variable-length integer prefix
275    /// in network byte-order.
276    pub fn get_bytes_with_varint_length(&mut self) -> Result<Octets<'a>> {
277        let len = self.get_varint()?;
278        self.get_bytes(len as usize)
279    }
280
281    /// Decodes a Huffman-encoded value from the current offset.
282    ///
283    /// The Huffman code implemented is the one defined for HPACK (RFC7541).
284    #[cfg(feature = "huffman_hpack")]
285    pub fn get_huffman_decoded(&mut self) -> Result<Vec<u8>> {
286        self.get_huffman_decoded_with_max_length(usize::MAX)
287    }
288
289    /// Decodes a Huffman-encoded value from the current offset. The `max_len`
290    /// parameter controls the maximum length of the decoded value.
291    ///
292    /// The Huffman code implemented is the one defined for HPACK (RFC7541).
293    #[cfg(feature = "huffman_hpack")]
294    pub fn get_huffman_decoded_with_max_length(
295        &mut self, max_len: usize,
296    ) -> Result<Vec<u8>> {
297        use self::huffman_table::DECODE_TABLE;
298
299        const FLAG_END: u8 = 1;
300        const FLAG_SYM: u8 = 2;
301        const FLAG_ERR: u8 = 4;
302
303        // Max compression ratio is >= 0.5.
304        let initial_cap = std::cmp::min(self.cap() * 2, max_len);
305        let mut out = Vec::with_capacity(initial_cap);
306
307        let mut state = 0;
308        let mut eos = false;
309
310        while let Ok(byte) = self.get_u8() {
311            for data in [byte >> 4, byte & 0xf] {
312                let (next, sym, flags) = DECODE_TABLE[state][(data) as usize];
313
314                if flags & FLAG_ERR == FLAG_ERR {
315                    // Data followed the "end" marker.
316                    return Err(BufferTooShortError);
317                } else if flags & FLAG_SYM == FLAG_SYM {
318                    // Error if pushing sym (1 byte) would overflow.
319                    if out.len() + 1 > max_len {
320                        return Err(BufferTooShortError);
321                    }
322                    out.push(sym);
323                }
324
325                state = next;
326
327                // `eos` only correct when handling the byte & 0xf case; ignored
328                // and overwritten in the byte >> 4 case.
329                eos = flags & FLAG_END == FLAG_END;
330            }
331        }
332
333        if state != 0 && !eos {
334            return Err(BufferTooShortError);
335        }
336
337        Ok(out)
338    }
339
340    /// Reads `len` bytes from the current offset without copying and without
341    /// advancing the buffer.
342    pub fn peek_bytes(&self, len: usize) -> Result<Octets<'a>> {
343        if self.cap() < len {
344            return Err(BufferTooShortError);
345        }
346
347        let out = Octets {
348            buf: &self.buf[self.off..self.off + len],
349            off: 0,
350        };
351
352        Ok(out)
353    }
354
355    /// Rewinds the buffer offset by `len` elements.
356    pub fn rewind(&mut self, len: usize) -> Result<()> {
357        if self.off() < len {
358            return Err(BufferTooShortError);
359        }
360
361        self.off -= len;
362
363        Ok(())
364    }
365
366    /// Returns a slice of `len` elements from the current offset.
367    pub fn slice(&self, len: usize) -> Result<&'a [u8]> {
368        if len > self.cap() {
369            return Err(BufferTooShortError);
370        }
371
372        Ok(&self.buf[self.off..self.off + len])
373    }
374
375    /// Returns a slice of `len` elements from the end of the buffer.
376    pub fn slice_last(&self, len: usize) -> Result<&'a [u8]> {
377        if len > self.cap() {
378            return Err(BufferTooShortError);
379        }
380
381        let end = self.buf.len();
382        Ok(&self.buf[end - len..end])
383    }
384
385    /// Advances the buffer's offset.
386    pub fn skip(&mut self, skip: usize) -> Result<()> {
387        if skip > self.cap() {
388            return Err(BufferTooShortError);
389        }
390
391        self.off += skip;
392
393        Ok(())
394    }
395
396    /// Returns the remaining capacity in the buffer.
397    pub fn cap(&self) -> usize {
398        self.buf.len() - self.off
399    }
400
401    /// Returns the total length of the buffer.
402    pub fn len(&self) -> usize {
403        self.buf.len()
404    }
405
406    /// Returns `true` if the buffer is empty.
407    pub fn is_empty(&self) -> bool {
408        self.buf.len() == 0
409    }
410
411    /// Returns the current offset of the buffer.
412    pub fn off(&self) -> usize {
413        self.off
414    }
415
416    /// Returns a reference to the internal buffer.
417    pub fn buf(&self) -> &'a [u8] {
418        self.buf
419    }
420
421    /// Copies the buffer from the current offset into a new `Vec<u8>`.
422    pub fn to_vec(&self) -> Vec<u8> {
423        self.as_ref().to_vec()
424    }
425}
426
427impl AsRef<[u8]> for Octets<'_> {
428    fn as_ref(&self) -> &[u8] {
429        &self.buf[self.off..]
430    }
431}
432
433/// A zero-copy mutable byte buffer.
434///
435/// Like `Octets` but mutable.
436#[derive(Debug, PartialEq, Eq)]
437pub struct OctetsMut<'a> {
438    buf: &'a mut [u8],
439    off: usize,
440}
441
442impl<'a> OctetsMut<'a> {
443    /// Creates an `OctetsMut` from the given slice, without copying.
444    ///
445    /// Since there's no copy, the input slice needs to be mutable to allow
446    /// modifications.
447    pub fn with_slice(buf: &'a mut [u8]) -> Self {
448        OctetsMut { buf, off: 0 }
449    }
450
451    /// Reads an unsigned 8-bit integer from the current offset and advances
452    /// the buffer.
453    pub fn get_u8(&mut self) -> Result<u8> {
454        get_u!(self, u8, 1)
455    }
456
457    /// Reads an unsigned 8-bit integer from the current offset without
458    /// advancing the buffer.
459    pub fn peek_u8(&mut self) -> Result<u8> {
460        peek_u!(self, u8, 1)
461    }
462
463    /// Writes an unsigned 8-bit integer at the current offset and advances
464    /// the buffer.
465    pub fn put_u8(&mut self, v: u8) -> Result<&mut [u8]> {
466        put_u!(self, u8, v, 1)
467    }
468
469    /// Reads an unsigned 16-bit integer in network byte-order from the current
470    /// offset and advances the buffer.
471    pub fn get_u16(&mut self) -> Result<u16> {
472        get_u!(self, u16, 2)
473    }
474
475    /// Writes an unsigned 16-bit integer in network byte-order at the current
476    /// offset and advances the buffer.
477    pub fn put_u16(&mut self, v: u16) -> Result<&mut [u8]> {
478        put_u!(self, u16, v, 2)
479    }
480
481    /// Reads an unsigned 24-bit integer in network byte-order from the current
482    /// offset and advances the buffer.
483    pub fn get_u24(&mut self) -> Result<u32> {
484        get_u!(self, u32, 3)
485    }
486
487    /// Writes an unsigned 24-bit integer in network byte-order at the current
488    /// offset and advances the buffer.
489    pub fn put_u24(&mut self, v: u32) -> Result<&mut [u8]> {
490        put_u!(self, u32, v, 3)
491    }
492
493    /// Reads an unsigned 32-bit integer in network byte-order from the current
494    /// offset and advances the buffer.
495    pub fn get_u32(&mut self) -> Result<u32> {
496        get_u!(self, u32, 4)
497    }
498
499    /// Writes an unsigned 32-bit integer in network byte-order at the current
500    /// offset and advances the buffer.
501    pub fn put_u32(&mut self, v: u32) -> Result<&mut [u8]> {
502        put_u!(self, u32, v, 4)
503    }
504
505    /// Reads an unsigned 64-bit integer in network byte-order from the current
506    /// offset and advances the buffer.
507    pub fn get_u64(&mut self) -> Result<u64> {
508        get_u!(self, u64, 8)
509    }
510
511    /// Writes an unsigned 64-bit integer in network byte-order at the current
512    /// offset and advances the buffer.
513    pub fn put_u64(&mut self, v: u64) -> Result<&mut [u8]> {
514        put_u!(self, u64, v, 8)
515    }
516
517    /// Reads an unsigned variable-length integer in network byte-order from
518    /// the current offset and advances the buffer.
519    pub fn get_varint(&mut self) -> Result<u64> {
520        let first = self.peek_u8()?;
521
522        let len = varint_parse_len(first);
523
524        if len > self.cap() {
525            return Err(BufferTooShortError);
526        }
527
528        let out = match len {
529            1 => u64::from(self.get_u8()?),
530
531            2 => u64::from(self.get_u16()? & 0x3fff),
532
533            4 => u64::from(self.get_u32()? & 0x3fffffff),
534
535            8 => self.get_u64()? & 0x3fffffffffffffff,
536
537            _ => unreachable!(),
538        };
539
540        Ok(out)
541    }
542
543    /// Writes an unsigned variable-length integer in network byte-order at the
544    /// current offset and advances the buffer.
545    pub fn put_varint(&mut self, v: u64) -> Result<&mut [u8]> {
546        self.put_varint_with_len(v, varint_len(v))
547    }
548
549    /// Writes an unsigned variable-length integer of the specified length, in
550    /// network byte-order at the current offset and advances the buffer.
551    pub fn put_varint_with_len(
552        &mut self, v: u64, len: usize,
553    ) -> Result<&mut [u8]> {
554        if self.cap() < len {
555            return Err(BufferTooShortError);
556        }
557
558        let buf = match len {
559            1 => self.put_u8(v as u8)?,
560
561            2 => {
562                let buf = self.put_u16(v as u16)?;
563                buf[0] |= 0x40;
564                buf
565            },
566
567            4 => {
568                let buf = self.put_u32(v as u32)?;
569                buf[0] |= 0x80;
570                buf
571            },
572
573            8 => {
574                let buf = self.put_u64(v)?;
575                buf[0] |= 0xc0;
576                buf
577            },
578
579            _ => panic!("value is too large for varint"),
580        };
581
582        Ok(buf)
583    }
584
585    /// Reads `len` bytes from the current offset without copying and advances
586    /// the buffer.
587    pub fn get_bytes(&mut self, len: usize) -> Result<Octets<'_>> {
588        if self.cap() < len {
589            return Err(BufferTooShortError);
590        }
591
592        let out = Octets {
593            buf: &self.buf[self.off..self.off + len],
594            off: 0,
595        };
596
597        self.off += len;
598
599        Ok(out)
600    }
601
602    /// Reads `len` bytes from the current offset without copying and advances
603    /// the buffer.
604    pub fn get_bytes_mut(&mut self, len: usize) -> Result<OctetsMut<'_>> {
605        if self.cap() < len {
606            return Err(BufferTooShortError);
607        }
608
609        let out = OctetsMut {
610            buf: &mut self.buf[self.off..self.off + len],
611            off: 0,
612        };
613
614        self.off += len;
615
616        Ok(out)
617    }
618
619    /// Reads `len` bytes from the current offset without copying and advances
620    /// the buffer, where `len` is an unsigned 8-bit integer prefix.
621    pub fn get_bytes_with_u8_length(&mut self) -> Result<Octets<'_>> {
622        let len = self.get_u8()?;
623        self.get_bytes(len as usize)
624    }
625
626    /// Reads `len` bytes from the current offset without copying and advances
627    /// the buffer, where `len` is an unsigned 16-bit integer prefix in network
628    /// byte-order.
629    pub fn get_bytes_with_u16_length(&mut self) -> Result<Octets<'_>> {
630        let len = self.get_u16()?;
631        self.get_bytes(len as usize)
632    }
633
634    /// Reads `len` bytes from the current offset without copying and advances
635    /// the buffer, where `len` is an unsigned variable-length integer prefix
636    /// in network byte-order.
637    pub fn get_bytes_with_varint_length(&mut self) -> Result<Octets<'_>> {
638        let len = self.get_varint()?;
639        self.get_bytes(len as usize)
640    }
641
642    /// Reads `len` bytes from the current offset without copying and without
643    /// advancing the buffer.
644    pub fn peek_bytes(&mut self, len: usize) -> Result<Octets<'_>> {
645        if self.cap() < len {
646            return Err(BufferTooShortError);
647        }
648
649        let out = Octets {
650            buf: &self.buf[self.off..self.off + len],
651            off: 0,
652        };
653
654        Ok(out)
655    }
656
657    /// Reads `len` bytes from the current offset without copying and without
658    /// advancing the buffer.
659    pub fn peek_bytes_mut(&mut self, len: usize) -> Result<OctetsMut<'_>> {
660        if self.cap() < len {
661            return Err(BufferTooShortError);
662        }
663
664        let out = OctetsMut {
665            buf: &mut self.buf[self.off..self.off + len],
666            off: 0,
667        };
668
669        Ok(out)
670    }
671
672    /// Writes `v` to the current offset.
673    pub fn put_bytes(&mut self, v: &[u8]) -> Result<()> {
674        let len = v.len();
675
676        if self.cap() < len {
677            return Err(BufferTooShortError);
678        }
679
680        if len == 0 {
681            return Ok(());
682        }
683
684        self.as_mut()[..len].copy_from_slice(v);
685
686        self.off += len;
687
688        Ok(())
689    }
690
691    /// Writes `v` to the current offset after Huffman-encoding it.
692    ///
693    /// The Huffman code implemented is the one defined for HPACK (RFC7541).
694    #[cfg(feature = "huffman_hpack")]
695    pub fn put_huffman_encoded<const LOWER_CASE: bool>(
696        &mut self, v: &[u8],
697    ) -> Result<()> {
698        <Self as OctetsWriter>::put_huffman_encoded::<LOWER_CASE>(self, v)
699    }
700
701    /// Rewinds the buffer offset by `len` elements.
702    pub fn rewind(&mut self, len: usize) -> Result<()> {
703        if self.off() < len {
704            return Err(BufferTooShortError);
705        }
706
707        self.off -= len;
708
709        Ok(())
710    }
711
712    /// Splits the buffer in two at the given absolute offset.
713    pub fn split_at(
714        &mut self, off: usize,
715    ) -> Result<(OctetsMut<'_>, OctetsMut<'_>)> {
716        if self.len() < off {
717            return Err(BufferTooShortError);
718        }
719
720        let (left, right) = self.buf.split_at_mut(off);
721
722        let first = OctetsMut { buf: left, off: 0 };
723
724        let last = OctetsMut { buf: right, off: 0 };
725
726        Ok((first, last))
727    }
728
729    /// Returns a slice of `len` elements from the current offset.
730    pub fn slice(&'a mut self, len: usize) -> Result<&'a mut [u8]> {
731        if len > self.cap() {
732            return Err(BufferTooShortError);
733        }
734
735        Ok(&mut self.buf[self.off..self.off + len])
736    }
737
738    /// Returns a slice of `len` elements from the end of the buffer.
739    pub fn slice_last(&'a mut self, len: usize) -> Result<&'a mut [u8]> {
740        if len > self.cap() {
741            return Err(BufferTooShortError);
742        }
743
744        let end = self.buf.len();
745        Ok(&mut self.buf[end - len..end])
746    }
747
748    /// Advances the buffer's offset.
749    pub fn skip(&mut self, skip: usize) -> Result<()> {
750        if skip > self.cap() {
751            return Err(BufferTooShortError);
752        }
753
754        self.off += skip;
755
756        Ok(())
757    }
758
759    /// Returns the remaining capacity in the buffer.
760    pub fn cap(&self) -> usize {
761        self.buf.len() - self.off
762    }
763
764    /// Returns the total length of the buffer.
765    pub fn len(&self) -> usize {
766        self.buf.len()
767    }
768
769    /// Returns `true` if the buffer is empty.
770    pub fn is_empty(&self) -> bool {
771        self.buf.len() == 0
772    }
773
774    /// Returns the current offset of the buffer.
775    pub fn off(&self) -> usize {
776        self.off
777    }
778
779    /// Returns a reference to the internal buffer.
780    pub fn buf(&self) -> &[u8] {
781        self.buf
782    }
783
784    /// Copies the buffer from the current offset into a new `Vec<u8>`.
785    pub fn to_vec(&self) -> Vec<u8> {
786        self.as_ref().to_vec()
787    }
788}
789
790impl AsRef<[u8]> for OctetsMut<'_> {
791    fn as_ref(&self) -> &[u8] {
792        &self.buf[self.off..]
793    }
794}
795
796impl AsMut<[u8]> for OctetsMut<'_> {
797    fn as_mut(&mut self) -> &mut [u8] {
798        &mut self.buf[self.off..]
799    }
800}
801
802impl OctetsWriter for OctetsMut<'_> {
803    type Error = BufferTooShortError;
804
805    fn put_bytes(&mut self, v: &[u8]) -> Result<()> {
806        OctetsMut::put_bytes(self, v)
807    }
808}
809
810/// Returns how many bytes it would take to encode `v` as a variable-length
811/// integer.
812pub const fn varint_len(v: u64) -> usize {
813    if v <= 63 {
814        1
815    } else if v <= 16383 {
816        2
817    } else if v <= 1_073_741_823 {
818        4
819    } else if v <= MAX_VAR_INT {
820        8
821    } else {
822        unreachable!()
823    }
824}
825
826/// Returns how long the variable-length integer is, given its first byte.
827pub const fn varint_parse_len(first: u8) -> usize {
828    match first >> 6 {
829        0 => 1,
830        1 => 2,
831        2 => 4,
832        3 => 8,
833        _ => unreachable!(),
834    }
835}
836
837/// Returns how long the Huffman encoding of the given buffer will be.
838///
839/// The Huffman code implemented is the one defined for HPACK (RFC7541).
840#[cfg(feature = "huffman_hpack")]
841pub fn huffman_encoding_len<const LOWER_CASE: bool>(src: &[u8]) -> Result<usize> {
842    use self::huffman_table::ENCODE_TABLE;
843
844    let mut bits: usize = 0;
845
846    for &b in src {
847        let b = if LOWER_CASE {
848            b.to_ascii_lowercase()
849        } else {
850            b
851        };
852
853        let (nbits, _) = ENCODE_TABLE[b as usize];
854        bits += nbits;
855    }
856
857    let mut len = bits / 8;
858
859    if bits & 7 != 0 {
860        len += 1;
861    }
862
863    if len > src.len() {
864        return Err(BufferTooShortError);
865    }
866
867    Ok(len)
868}
869
870#[cfg(feature = "huffman_hpack")]
871fn huffman_encode_with<const LOWER_CASE: bool, F, E>(
872    src: &[u8], mut write: F,
873) -> std::result::Result<(), E>
874where
875    F: FnMut(&[u8]) -> std::result::Result<(), E>,
876{
877    use self::huffman_table::ENCODE_TABLE;
878
879    let mut bits: u64 = 0;
880    let mut pending = 0;
881
882    for &b in src {
883        let b = if LOWER_CASE {
884            b.to_ascii_lowercase()
885        } else {
886            b
887        };
888        let (nbits, code) = ENCODE_TABLE[b as usize];
889
890        pending += nbits;
891
892        if pending < 64 {
893            // Have room for the new token.
894            bits |= code << (64 - pending);
895            continue;
896        }
897
898        pending -= 64;
899        // Take only the bits that fit.
900        bits |= code >> pending;
901        write(&bits.to_be_bytes())?;
902
903        bits = if pending == 0 {
904            0
905        } else {
906            code << (64 - pending)
907        };
908    }
909
910    if pending == 0 {
911        return Ok(());
912    }
913
914    bits |= u64::MAX >> pending;
915    // TODO: replace with `next_multiple_of(8)` when stable.
916    pending = (pending + 7) & !7; // Round up to a byte.
917    bits >>= 64 - pending;
918
919    if pending >= 32 {
920        pending -= 32;
921        write(&((bits >> pending) as u32).to_be_bytes())?;
922    }
923
924    while pending > 0 {
925        pending -= 8;
926        write(&[(bits >> pending) as u8])?;
927    }
928
929    Ok(())
930}
931
932/// The functions in this mod test the compile time assertions in the
933/// `put_u` and `peek_u` macros. If you compile this crate with
934/// `--cfg test_invalid_len_compilation_fail`, e.g., by using
935/// `cargo rustc  -- --cfg test_invalid_len_compilation_fail`
936/// You will get two compiler errors
937#[cfg(test_invalid_len_compilation_fail)]
938pub mod fails_to_compile {
939    use super::*;
940    pub fn peek_invalid_fails_to_compile(b: &mut Octets) -> Result<u8> {
941        peek_u!(b, u8, 2)
942    }
943
944    pub fn put_invalid_fails_to_compile<'a>(
945        b: &'a mut OctetsMut, v: u8,
946    ) -> Result<&'a mut [u8]> {
947        put_u!(b, u8, v, 2)
948    }
949}
950
951#[cfg(feature = "huffman_hpack")]
952mod huffman_table;