|
12 | 12 | //! |
13 | 13 |
|
14 | 14 | use internals::array_vec::ArrayVec; |
15 | | -use internals::compact_size; |
| 15 | +use internals::{compact_size, ToU64}; |
16 | 16 |
|
17 | 17 | use super::{Encodable, Encoder}; |
18 | 18 |
|
@@ -250,6 +250,27 @@ impl<A: Encoder, B: Encoder, C: Encoder, D: Encoder, E: Encoder, F: Encoder> Enc |
250 | 250 | fn advance(&mut self) -> bool { self.inner.advance() } |
251 | 251 | } |
252 | 252 |
|
| 253 | +/// Encoder for a compact size encoded integer. |
| 254 | +pub struct CompactSizeEncoder { |
| 255 | + buf: Option<ArrayVec<u8, SIZE>>, |
| 256 | +} |
| 257 | + |
| 258 | +impl CompactSizeEncoder { |
| 259 | + /// Constructs a new `CompactSizeEncoder`. |
| 260 | + pub fn new(value: impl ToU64) -> Self { Self { buf: Some(compact_size::encode(value)) } } |
| 261 | +} |
| 262 | + |
| 263 | +impl Encoder for CompactSizeEncoder { |
| 264 | + #[inline] |
| 265 | + fn current_chunk(&self) -> Option<&[u8]> { self.buf.as_ref().map(|b| &b[..]) } |
| 266 | + |
| 267 | + #[inline] |
| 268 | + fn advance(&mut self) -> bool { |
| 269 | + self.buf = None; |
| 270 | + false |
| 271 | + } |
| 272 | +} |
| 273 | + |
253 | 274 | #[cfg(test)] |
254 | 275 | mod tests { |
255 | 276 | use super::*; |
@@ -651,4 +672,42 @@ mod tests { |
651 | 672 | assert!(!encoder.advance()); |
652 | 673 | assert_eq!(encoder.current_chunk(), None); |
653 | 674 | } |
| 675 | + #[test] |
| 676 | + fn encode_compact_size() { |
| 677 | + // 1-byte |
| 678 | + let mut e = CompactSizeEncoder::new(0x10u64); |
| 679 | + assert_eq!(e.current_chunk(), Some(&[0x10][..])); |
| 680 | + assert!(!e.advance()); |
| 681 | + assert_eq!(e.current_chunk(), None); |
| 682 | + |
| 683 | + let mut e = CompactSizeEncoder::new(0xFCu64); |
| 684 | + assert_eq!(e.current_chunk(), Some(&[0xFC][..])); |
| 685 | + assert!(!e.advance()); |
| 686 | + |
| 687 | + // 0xFD + u16 |
| 688 | + let mut e = CompactSizeEncoder::new(0x00FDu64); |
| 689 | + assert_eq!(e.current_chunk(), Some(&[0xFD, 0xFD, 0x00][..])); |
| 690 | + assert!(!e.advance()); |
| 691 | + |
| 692 | + let mut e = CompactSizeEncoder::new(0x0FFFu64); |
| 693 | + assert_eq!(e.current_chunk(), Some(&[0xFD, 0xFF, 0x0F][..])); |
| 694 | + assert!(!e.advance()); |
| 695 | + |
| 696 | + // 0xFE + u32 |
| 697 | + let mut e = CompactSizeEncoder::new(0x0001_0000u64); |
| 698 | + assert_eq!(e.current_chunk(), Some(&[0xFE, 0x00, 0x00, 0x01, 0x00][..])); |
| 699 | + assert!(!e.advance()); |
| 700 | + |
| 701 | + let mut e = CompactSizeEncoder::new(0x0F0F_0F0Fu64); |
| 702 | + assert_eq!(e.current_chunk(), Some(&[0xFE, 0x0F, 0x0F, 0x0F, 0x0F][..])); |
| 703 | + assert!(!e.advance()); |
| 704 | + |
| 705 | + // 0xFF + u64 |
| 706 | + let mut e = CompactSizeEncoder::new(0x0000_F0F0_F0F0_F0E0u64); |
| 707 | + assert_eq!( |
| 708 | + e.current_chunk(), |
| 709 | + Some(&[0xFF, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00][..]) |
| 710 | + ); |
| 711 | + assert!(!e.advance()); |
| 712 | + } |
654 | 713 | } |
0 commit comments