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