inspect_format/
utils.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::constants;
6
7/// Returns the smallest order such that (MIN_ORDER_SHIFT << order) >= size.
8/// Size must be non zero.
9pub fn fit_order(size: usize) -> usize {
10    // Safety: `leading_zeros` returns a u32, so this is safe promotion
11    (std::mem::size_of::<usize>() * 8 - (size - 1).leading_zeros() as usize)
12        .saturating_sub(constants::MIN_ORDER_SHIFT)
13}
14
15/// Get size in bytes of a given |order|.
16pub fn order_to_size(order: u8) -> usize {
17    constants::MIN_ORDER_SIZE << order
18}
19
20/// Get the necessary |block size| to fit the given |payload_size| in range
21/// MIN_ORDER_SIZE <= block size <= MAX_ORDER_SIZE
22pub fn block_size_for_payload(payload_size: usize) -> usize {
23    (payload_size + constants::HEADER_SIZE_BYTES)
24        .clamp(constants::MIN_ORDER_SIZE, constants::MAX_ORDER_SIZE)
25}
26
27/// Get the size in bytes for the payload section of a block of the given |order|.
28pub fn payload_size_for_order(order: u8) -> usize {
29    order_to_size(order) - constants::HEADER_SIZE_BYTES
30}
31
32#[cfg(test)]
33mod test {
34    use super::*;
35
36    #[test]
37    fn fit_order_test() {
38        assert_eq!(0, fit_order(1));
39        assert_eq!(0, fit_order(16));
40        assert_eq!(1, fit_order(17));
41        assert_eq!(2, fit_order(33));
42        assert_eq!(7, fit_order(2048));
43    }
44
45    #[test]
46    fn order_to_size_test() {
47        assert_eq!(16, order_to_size(0));
48        assert_eq!(32, order_to_size(1));
49        assert_eq!(64, order_to_size(2));
50        assert_eq!(128, order_to_size(3));
51        assert_eq!(256, order_to_size(4));
52        assert_eq!(512, order_to_size(5));
53        assert_eq!(1024, order_to_size(6));
54        assert_eq!(2048, order_to_size(7));
55    }
56
57    #[test]
58    fn fit_payload_test() {
59        for payload_size in 0..500 {
60            let block_size = block_size_for_payload(payload_size);
61            let order = fit_order(block_size) as u8;
62            let payload_max = payload_size_for_order(order);
63            assert!(
64                payload_size <= payload_max,
65                "Needed {} bytes for a payload, but only got {}; block size {}, order {}",
66                payload_size,
67                payload_max,
68                block_size,
69                order
70            );
71        }
72    }
73}