1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//
// Copyright 2023, Colias Group, LLC
//
// SPDX-License-Identifier: BSD-2-Clause
//

use core::ops::Range;

use zerocopy::{AsBytes, FromBytes, FromZeroes};

#[repr(C)]
#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, AsBytes, FromBytes, FromZeroes)]
pub struct Descriptor {
    encoded_addr: usize,
    len: u32,
    _padding: [u8; 4],
    cookie: usize,
}

impl Descriptor {
    pub fn new(encoded_addr: usize, len: u32, cookie: usize) -> Self {
        Self {
            encoded_addr,
            len,
            _padding: [0; 4],
            cookie,
        }
    }

    pub fn from_encoded_addr_range(encoded_addr_range: Range<usize>, cookie: usize) -> Self {
        let encoded_addr = encoded_addr_range.start;
        let len = encoded_addr_range.len().try_into().unwrap();
        Self::new(encoded_addr, len, cookie)
    }

    pub fn encoded_addr(&self) -> usize {
        self.encoded_addr
    }

    pub fn set_encoded_addr(&mut self, encoded_addr: usize) {
        self.encoded_addr = encoded_addr;
    }

    #[allow(clippy::len_without_is_empty)]
    pub fn len(&self) -> u32 {
        self.len
    }

    pub fn set_len(&mut self, len: u32) {
        self.len = len;
    }

    pub fn cookie(&self) -> usize {
        self.cookie
    }

    pub fn set_cookie(&mut self, cookie: usize) {
        self.cookie = cookie;
    }

    pub fn encoded_addr_range(&self) -> Range<usize> {
        let start = self.encoded_addr();
        let len = self.len().try_into().unwrap();
        start..start.checked_add(len).unwrap()
    }
}