capsules_extra/net/
frag_utils.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5const BITMAP_SIZE: usize = 20;
6
7pub struct Bitmap {
8    map: [u8; BITMAP_SIZE],
9}
10
11impl Bitmap {
12    pub fn new() -> Bitmap {
13        Bitmap {
14            map: [0; BITMAP_SIZE],
15        }
16    }
17
18    pub fn clear(&mut self) {
19        for i in 0..self.map.len() {
20            self.map[i] = 0;
21        }
22    }
23
24    pub fn clear_bit(&mut self, idx: usize) {
25        let map_idx = idx / 8;
26        self.map[map_idx] &= !(1 << (idx % 8));
27    }
28
29    pub fn set_bit(&mut self, idx: usize) {
30        let map_idx = idx / 8;
31        self.map[map_idx] |= 1 << (idx % 8);
32    }
33
34    // Sets bits from start_idx (inclusive) to end_idx (exclusive).
35    // Returns false if any bits set overlap with already set bits,
36    // true otherwise.
37
38    // Returns true if successfully set bits, returns false if the bits
39    // overlapped with already set bits
40    // Note that each bit represents a multiple of 8 bytes (as everything
41    // must be in 8-byte groups), and thus we can store 8*8 = 64 "bytes" per
42    // byte in the bitmap.
43    pub fn set_bits(&mut self, start_idx: usize, end_idx: usize) -> bool {
44        if start_idx > end_idx {
45            return false;
46        }
47        let start_byte_idx = start_idx / 8;
48        let end_byte_idx = end_idx / 8;
49        let first = 0xff << (start_idx % 8);
50        let second = if end_idx % 8 == 0 {
51            0x00
52        } else {
53            0xff >> (8 - (end_idx % 8))
54        };
55        if start_byte_idx == end_byte_idx {
56            let result = (self.map[start_byte_idx] & (first & second)) == 0;
57            self.map[start_byte_idx] |= first & second;
58            result
59        } else {
60            let mut result = (self.map[start_byte_idx] & first) == 0;
61            result = result && ((self.map[end_byte_idx] & second) == 0);
62            self.map[start_byte_idx] |= first;
63            self.map[end_byte_idx] |= second;
64            // Set all bytes between start and end bytes.
65            for i in start_byte_idx + 1..end_byte_idx {
66                result = result && (self.map[i] == 0);
67                self.map[i] = 0xff;
68            }
69            result
70        }
71    }
72
73    pub fn is_complete(&self, total_length: usize) -> bool {
74        let mut result = true;
75        for i in 0..total_length / 8 {
76            result = result && (self.map[i] == 0xff);
77        }
78        // Check last byte.
79        let mask = 0xff >> (8 - (total_length % 8));
80        result = result && (self.map[total_length / 8] == mask);
81        result
82    }
83}