unsigned_varint/encode.rs
1// Copyright 2018 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of
4// this software and associated documentation files (the "Software"), to deal in
5// the Software without restriction, including without limitation the rights to
6// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7// the Software, and to permit persons to whom the Software is furnished to do so,
8// subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
16// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20//! Basic unsigned-varint encoding.
21
22macro_rules! encode {
23 ($number:expr, $buf:expr) => {{
24 let mut n = $number;
25 let mut i = 0;
26 for b in $buf.iter_mut() {
27 *b = n as u8 | 0x80;
28 n >>= 7;
29 if n == 0 {
30 *b &= 0x7f;
31 break
32 }
33 i += 1
34 }
35 debug_assert_eq!(n, 0);
36 &$buf[0..=i]
37 }}
38}
39
40
41/// Encode the given `u8` into the given byte array.
42///
43/// Returns the slice of encoded bytes.
44#[inline]
45pub fn u8(number: u8, buf: &mut [u8; U8_LEN]) -> &[u8] {
46 encode!(number, buf)
47}
48
49/// Encode the given `u16` into the given byte array.
50///
51/// Returns the slice of encoded bytes.
52#[inline]
53pub fn u16(number: u16, buf: &mut [u8; U16_LEN]) -> &[u8] {
54 encode!(number, buf)
55}
56
57/// Encode the given `u32` into the given byte array.
58///
59/// Returns the slice of encoded bytes.
60#[inline]
61pub fn u32(number: u32, buf: &mut [u8; U32_LEN]) -> &[u8] {
62 encode!(number, buf)
63}
64
65/// Encode the given `u64` into the given byte array.
66///
67/// Returns the slice of encoded bytes.
68#[inline]
69pub fn u64(number: u64, buf: &mut [u8; U64_LEN]) -> &[u8] {
70 encode!(number, buf)
71}
72
73/// Encode the given `u128` into the given byte array.
74///
75/// Returns the slice of encoded bytes.
76#[inline]
77pub fn u128(number: u128, buf: &mut [u8; U128_LEN]) -> &[u8] {
78 encode!(number, buf)
79}
80
81/// Encode the given `usize` into the given byte array.
82///
83/// Returns the slice of encoded bytes.
84#[inline]
85#[cfg(target_pointer_width = "64")]
86pub fn usize(number: usize, buf: &mut [u8; USIZE_LEN]) -> &[u8] {
87 u64(number as u64, buf)
88}
89
90/// Encode the given `usize` into the given byte array.
91///
92/// Returns the slice of encoded bytes.
93#[inline]
94#[cfg(target_pointer_width = "32")]
95pub fn usize(number: usize, buf: &mut [u8; USIZE_LEN]) -> &[u8] {
96 u32(number as u32, buf)
97}
98
99/// Create new array buffer for encoding of `u8` values.
100#[inline]
101pub fn u8_buffer() -> [u8; U8_LEN] {
102 [0; U8_LEN]
103}
104
105/// Create new array buffer for encoding of `u16` values.
106#[inline]
107pub fn u16_buffer() -> [u8; U16_LEN] {
108 [0; U16_LEN]
109}
110
111/// Create new array buffer for encoding of `u32` values.
112#[inline]
113pub fn u32_buffer() -> [u8; U32_LEN] {
114 [0; U32_LEN]
115}
116
117/// Create new array buffer for encoding of `u64` values.
118#[inline]
119pub fn u64_buffer() -> [u8; U64_LEN] {
120 [0; U64_LEN]
121}
122
123/// Create new array buffer for encoding of `u128` values.
124#[inline]
125pub fn u128_buffer() -> [u8; U128_LEN] {
126 [0; U128_LEN]
127}
128
129/// Create new array buffer for encoding of `usize` values.
130#[inline]
131pub fn usize_buffer() -> [u8; USIZE_LEN] {
132 [0; USIZE_LEN]
133}
134
135
136// Required lengths of encoding buffers:
137
138const U8_LEN: usize = 2;
139const U16_LEN: usize = 3;
140const U32_LEN: usize = 5;
141const U64_LEN: usize = 10;
142const U128_LEN: usize = 19;
143
144#[cfg(target_pointer_width = "64")]
145const USIZE_LEN: usize = U64_LEN;
146
147#[cfg(target_pointer_width = "32")]
148const USIZE_LEN: usize = U32_LEN;
149