rust/zerocopy/src/lib.rs

Source file repositories/reference/linux-study-clean/rust/zerocopy/src/lib.rs

File Facts

System
Linux kernel
Corpus path
rust/zerocopy/src/lib.rs
Extension
.rs
Size
276792 bytes
Lines
7613
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

struct WithPadding {
            x: u8,
            y: u16,
        }
        struct ReadsInRead;
        impl std::io::Read for ReadsInRead {
            fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
                // This body branches on every byte of `buf`, ensuring that it
                // exhibits UB if any byte of `buf` is uninitialized.
                if buf.iter().all(|&x| x == 0) {
                    Ok(buf.len())
                } else {
                    buf.iter_mut().for_each(|x| *x = 0);
                    Ok(buf.len())
                }
            }
        }
        assert!(matches!(WithPadding::read_from_io(ReadsInRead), Ok(WithPadding { x: 0, y: 0 })));
    }

    #[test]
    #[cfg(feature = "std")]
    fn test_read_write_io() {
        let mut long_buffer = [0, 0, 0, 0];
        assert!(matches!(u16::MAX.write_to_io(&mut long_buffer[..]), Ok(())));
        assert_eq!(long_buffer, [255, 255, 0, 0]);
        assert!(matches!(u16::read_from_io(&long_buffer[..]), Ok(u16::MAX)));

        let mut short_buffer = [0, 0];
        assert!(u32::MAX.write_to_io(&mut short_buffer[..]).is_err());
        assert_eq!(short_buffer, [255, 255]);
        assert!(u32::read_from_io(&short_buffer[..]).is_err());
    }

    #[test]
    fn test_try_from_bytes_try_read_from() {
        assert_eq!(<bool as TryFromBytes>::try_read_from_bytes(&[0]), Ok(false));
        assert_eq!(<bool as TryFromBytes>::try_read_from_bytes(&[1]), Ok(true));

        assert_eq!(<bool as TryFromBytes>::try_read_from_prefix(&[0, 2]), Ok((false, &[2][..])));
        assert_eq!(<bool as TryFromBytes>::try_read_from_prefix(&[1, 2]), Ok((true, &[2][..])));

        assert_eq!(<bool as TryFromBytes>::try_read_from_suffix(&[2, 0]), Ok((&[2][..], false)));
        assert_eq!(<bool as TryFromBytes>::try_read_from_suffix(&[2, 1]), Ok((&[2][..], true)));

        // If we don't pass enough bytes, it fails.
        assert!(matches!(
            <u8 as TryFromBytes>::try_read_from_bytes(&[]),
            Err(TryReadError::Size(_))
        ));
        assert!(matches!(
            <u8 as TryFromBytes>::try_read_from_prefix(&[]),
            Err(TryReadError::Size(_))
        ));
        assert!(matches!(
            <u8 as TryFromBytes>::try_read_from_suffix(&[]),
            Err(TryReadError::Size(_))
        ));

        // If we pass too many bytes, it fails.
        assert!(matches!(
            <u8 as TryFromBytes>::try_read_from_bytes(&[0, 0]),
            Err(TryReadError::Size(_))
        ));

        // If we pass an invalid value, it fails.
        assert!(matches!(
            <bool as TryFromBytes>::try_read_from_bytes(&[2]),
            Err(TryReadError::Validity(_))
        ));
        assert!(matches!(
            <bool as TryFromBytes>::try_read_from_prefix(&[2, 0]),
            Err(TryReadError::Validity(_))
        ));
        assert!(matches!(
            <bool as TryFromBytes>::try_read_from_suffix(&[0, 2]),
            Err(TryReadError::Validity(_))
        ));

        // Reading from a misaligned buffer should still succeed. Since `AU64`'s
        // alignment is 8, and since we read from two adjacent addresses one
        // byte apart, it is guaranteed that at least one of them (though
        // possibly both) will be misaligned.
        let bytes: [u8; 9] = [0, 0, 0, 0, 0, 0, 0, 0, 0];
        assert_eq!(<AU64 as TryFromBytes>::try_read_from_bytes(&bytes[..8]), Ok(AU64(0)));
        assert_eq!(<AU64 as TryFromBytes>::try_read_from_bytes(&bytes[1..9]), Ok(AU64(0)));

        assert_eq!(
            <AU64 as TryFromBytes>::try_read_from_prefix(&bytes[..8]),
            Ok((AU64(0), &[][..]))

Annotation

Implementation Notes