Skip to main content

dope_sys/io/socket/record/
packet.rs

1use std::mem;
2
3use crate::{
4    Errno,
5    io::socket::record::{Fault, Record, Size, Transport},
6};
7
8/// Native sequenced packets retain each record's boundary in the kernel.
9pub struct Packet;
10
11impl Transport for Packet {
12    fn send(
13        value: u32,
14        mut send: impl for<'a> FnMut(&'a [u8]) -> Result<&'a [u8], Errno>,
15    ) -> Result<(), Fault> {
16        let bytes = value.to_ne_bytes();
17        loop {
18            match send(&bytes) {
19                Ok(sent) if sent.len() == bytes.len() => return Ok(()),
20                Ok(sent) => {
21                    return Err(Fault::Record(Size {
22                        expected: bytes.len(),
23                        actual: sent.len(),
24                    }));
25                }
26                Err(error) if error.is_intr() => {}
27                Err(error) => return Err(Fault::Syscall(error)),
28            }
29        }
30    }
31
32    fn recv(mut recv: impl for<'a> FnMut(&'a mut [u8]) -> Result<&'a mut [u8], Errno>) -> Record {
33        const EXTENT: usize = mem::size_of::<u32>() + 1;
34        let mut bytes = [0; EXTENT];
35        loop {
36            match recv(&mut bytes) {
37                Ok([]) => return Record::Closed,
38                Ok([a, b, c, d]) => return Record::Value(u32::from_ne_bytes([*a, *b, *c, *d])),
39                Ok(received) => {
40                    return Record::Failed(Fault::Record(Size {
41                        expected: mem::size_of::<u32>(),
42                        actual: received.len(),
43                    }));
44                }
45                Err(error) if error.is_intr() => {}
46                Err(error) => return Record::Failed(Fault::Syscall(error)),
47            }
48        }
49    }
50}