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