1use std::mem;
29use std::ptr;
30
31pub const MAX_VAR_INT: u64 = 4_611_686_018_427_387_903;
33
34pub type Result<T> = std::result::Result<T, BufferTooShortError>;
39
40#[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
58pub trait OctetsWriter {
63 type Error;
65
66 fn put_bytes(&mut self, v: &[u8]) -> std::result::Result<(), Self::Error>;
68
69 #[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
88macro_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#[derive(Debug, PartialEq, Eq)]
165pub struct Octets<'a> {
166 buf: &'a [u8],
167 off: usize,
168}
169
170impl<'a> Octets<'a> {
171 pub fn with_slice(buf: &'a [u8]) -> Self {
176 Octets { buf, off: 0 }
177 }
178
179 pub fn get_u8(&mut self) -> Result<u8> {
182 get_u!(self, u8, 1)
183 }
184
185 pub fn peek_u8(&mut self) -> Result<u8> {
188 peek_u!(self, u8, 1)
189 }
190
191 pub fn get_u16(&mut self) -> Result<u16> {
194 get_u!(self, u16, 2)
195 }
196
197 pub fn get_u24(&mut self) -> Result<u32> {
200 get_u!(self, u32, 3)
201 }
202
203 pub fn get_u32(&mut self) -> Result<u32> {
206 get_u!(self, u32, 4)
207 }
208
209 pub fn get_u64(&mut self) -> Result<u64> {
212 get_u!(self, u64, 8)
213 }
214
215 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 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 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 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 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 #[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 #[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 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 return Err(BufferTooShortError);
317 } else if flags & FLAG_SYM == FLAG_SYM {
318 if out.len() + 1 > max_len {
320 return Err(BufferTooShortError);
321 }
322 out.push(sym);
323 }
324
325 state = next;
326
327 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 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 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 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 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 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 pub fn cap(&self) -> usize {
398 self.buf.len() - self.off
399 }
400
401 pub fn len(&self) -> usize {
403 self.buf.len()
404 }
405
406 pub fn is_empty(&self) -> bool {
408 self.buf.len() == 0
409 }
410
411 pub fn off(&self) -> usize {
413 self.off
414 }
415
416 pub fn buf(&self) -> &'a [u8] {
418 self.buf
419 }
420
421 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#[derive(Debug, PartialEq, Eq)]
437pub struct OctetsMut<'a> {
438 buf: &'a mut [u8],
439 off: usize,
440}
441
442impl<'a> OctetsMut<'a> {
443 pub fn with_slice(buf: &'a mut [u8]) -> Self {
448 OctetsMut { buf, off: 0 }
449 }
450
451 pub fn get_u8(&mut self) -> Result<u8> {
454 get_u!(self, u8, 1)
455 }
456
457 pub fn peek_u8(&mut self) -> Result<u8> {
460 peek_u!(self, u8, 1)
461 }
462
463 pub fn put_u8(&mut self, v: u8) -> Result<&mut [u8]> {
466 put_u!(self, u8, v, 1)
467 }
468
469 pub fn get_u16(&mut self) -> Result<u16> {
472 get_u!(self, u16, 2)
473 }
474
475 pub fn put_u16(&mut self, v: u16) -> Result<&mut [u8]> {
478 put_u!(self, u16, v, 2)
479 }
480
481 pub fn get_u24(&mut self) -> Result<u32> {
484 get_u!(self, u32, 3)
485 }
486
487 pub fn put_u24(&mut self, v: u32) -> Result<&mut [u8]> {
490 put_u!(self, u32, v, 3)
491 }
492
493 pub fn get_u32(&mut self) -> Result<u32> {
496 get_u!(self, u32, 4)
497 }
498
499 pub fn put_u32(&mut self, v: u32) -> Result<&mut [u8]> {
502 put_u!(self, u32, v, 4)
503 }
504
505 pub fn get_u64(&mut self) -> Result<u64> {
508 get_u!(self, u64, 8)
509 }
510
511 pub fn put_u64(&mut self, v: u64) -> Result<&mut [u8]> {
514 put_u!(self, u64, v, 8)
515 }
516
517 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 pub fn put_varint(&mut self, v: u64) -> Result<&mut [u8]> {
546 self.put_varint_with_len(v, varint_len(v))
547 }
548
549 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 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 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 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 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 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 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 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 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 #[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 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 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 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 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 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 pub fn cap(&self) -> usize {
761 self.buf.len() - self.off
762 }
763
764 pub fn len(&self) -> usize {
766 self.buf.len()
767 }
768
769 pub fn is_empty(&self) -> bool {
771 self.buf.len() == 0
772 }
773
774 pub fn off(&self) -> usize {
776 self.off
777 }
778
779 pub fn buf(&self) -> &[u8] {
781 self.buf
782 }
783
784 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
810pub 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
826pub 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#[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 bits |= code << (64 - pending);
895 continue;
896 }
897
898 pending -= 64;
899 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 pending = (pending + 7) & !7; 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#[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;