1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//! Extension traits that allow for the reading and writing of [unsigned LEB128] //! integer values. //! //! # Read //! //! To read [unsigned LEB128] integers, do so through the [`ReadULeb128Ext`] //! extension trait. Importing this trait into a file allows for reading //! unsigned integers encoded in [unsigned LEB128] from any type that implements //! [`Read`]. //! //! ``` //! use std::io::Cursor; //! use uleb128::ReadULeb128Ext; //! //! let mut rdr = Cursor::new(vec![0b1000_0000, 0b0000_0001]); //! assert_eq!(128, rdr.read_uleb128_u32().unwrap()); //! ``` //! //! # Write //! //! To write unsigned integers as [unsigned LEB128], do so through the //! [`WriteULeb128Ext`] extension trait. Importing this trait into a file allows //! for writing unsigned integers as [unsigned LEB128] from any type that //! implements [`Write`]. //! //! ``` //! use uleb128::WriteULeb128Ext; //! //! let mut wtr = vec![]; //! wtr.write_uleb128_u32(128).unwrap(); //! //! assert_eq!(wtr, vec![0b1000_0000, 0b0000_0001]); //! ``` //! //! [unsigned LEB128]: https://en.wikipedia.org/wiki/LEB128#Unsigned_LEB128 //! [`ReadULeb128Ext`]: crate::ReadULeb128Ext //! [`Read`]: std::io::Read //! [`Write`]: std::io::Write #![warn(missing_docs)] #[macro_use] extern crate quick_error; mod error; mod io; pub use error::{Error, Result}; pub use io::{ReadULeb128Ext, WriteULeb128Ext}; pub(crate) const ULEB128_U32_MAX_LENGTH: usize = 5; pub(crate) const ULEB128_U64_MAX_LENGTH: usize = 10; const fn max_value(len: usize) -> usize { 128usize.pow(len as u32) - 1 } macro_rules! len_body { ($n:ident, $ty:ty, $len:expr) => {{ for len in 1..$len { if $n <= max_value(len) as $ty { return len; } } $len }}; } /// Get the length of the unsigned 32-bit integer's [unsigned LEB128] /// representation in bytes. /// /// # Examples /// /// ``` /// use uleb128::uleb128_u32_len; /// /// assert_eq!(1, uleb128_u32_len(127)); /// assert_eq!(2, uleb128_u32_len(128)); /// ``` /// /// [unsigned LEB128]: https://en.wikipedia.org/wiki/LEB128#Unsigned_LEB128 pub fn uleb128_u32_len(n: u32) -> usize { len_body!(n, u32, ULEB128_U32_MAX_LENGTH) } /// Get the length of the unsigned 64-bit integer's [unsigned LEB128] /// representation in bytes. /// /// # Examples /// /// ``` /// use uleb128::uleb128_u64_len; /// /// assert_eq!(5, uleb128_u64_len(34_359_738_367)); /// assert_eq!(6, uleb128_u64_len(34_359_738_368)); /// ``` /// /// [unsigned LEB128]: https://en.wikipedia.org/wiki/LEB128#Unsigned_LEB128 pub fn uleb128_u64_len(n: u64) -> usize { len_body!(n, u64, ULEB128_U64_MAX_LENGTH) }