mod3d_base/
byte_buffer.rs

1//a ByteBuffer
2//tp ByteBuffer
3/// A trait for all types that are to be used as sources of data for
4/// buffers of, e.g. vertex data, indices, etc
5///
6/// The data is viewed by OpenGL as a pointer and byte length; these
7/// methods provide access to the data in that way.
8///
9/// These methods are all safe - any use of the information they
10/// provide may be unsafe.
11pub trait ByteBuffer {
12    /// Get the length of the data buffer in bytes
13    fn byte_length(&self) -> usize;
14    /// Borrow the data as an array of bytes
15    fn borrow_bytes(&self) -> &[u8];
16    /// Return a pointer to the first byte of the data contents
17    fn as_u8_ptr(&self) -> *const u8;
18}
19
20//ti ByteBuffer for [T; N]
21/// Implement ByteBuffer for slice of T
22impl<T, const N: usize> ByteBuffer for [T; N] {
23    //fp byte_length
24    fn byte_length(&self) -> usize {
25        std::mem::size_of::<T>() * N
26    }
27
28    //fp borrow_bytes
29    ///
30    fn borrow_bytes(&self) -> &[u8] {
31        let len = std::mem::size_of::<T>() * self.len();
32        let data = self.as_u8_ptr();
33
34        // # Safety
35        //
36        // The resultant slice is derived from a valid pointer and
37        // length; the data can be interpreted as u8 if required; so
38        // this is safe.
39        unsafe { std::slice::from_raw_parts(data, len) }
40    }
41
42    //fp as_u8_ptr
43    fn as_u8_ptr(&self) -> *const u8 {
44        let data: *const T = &self[0];
45
46        // # Safety
47        //
48        // The resultant pointer is a valid pointer to u8 (assuming T
49        // is initialized?). Use of the resultant pointer is always
50        // unsafe, as it is a pointer; but that is down to the user of
51        // a pointer.
52        unsafe { std::mem::transmute::<_, *const u8>(data) }
53    }
54
55    //zz All done
56}
57
58//ti ByteBuffer for Vec
59/// Implement ByteBuffer for Vec
60impl<T> ByteBuffer for Vec<T> {
61    //fp byte_length
62    fn byte_length(&self) -> usize {
63        std::mem::size_of::<T>() * self.len()
64    }
65
66    //fp borrow_bytes
67    fn borrow_bytes(&self) -> &[u8] {
68        let len = std::mem::size_of::<T>() * self.len();
69        let data = self.as_u8_ptr();
70        // # Safety
71        //
72        // The resultant slice is derived from a valid pointer and
73        // length; the data can be interpreted as u8 if required; so
74        // this is safe.
75        unsafe { std::slice::from_raw_parts(data, len) }
76    }
77
78    //fp as_u8_ptr
79    fn as_u8_ptr(&self) -> *const u8 {
80        let data: *const T = &self[0];
81        // # Safety
82        //
83        // The resultant pointer is a valid pointer to u8 (assuming T
84        // is initialized?). Use of the resultant pointer is always
85        // unsafe, as it is a pointer; but that is down to the user of
86        // a pointer.
87        unsafe { std::mem::transmute::<_, *const u8>(data) }
88    }
89
90    //zz All done
91}
92
93//ti ByteBuffer for &[T]
94/// Implement ByteBuffer for &[T]
95impl<T> ByteBuffer for &[T] {
96    //fp byte_length
97    fn byte_length(&self) -> usize {
98        std::mem::size_of_val(*self)
99    }
100
101    //fp borrow_bytes
102    fn borrow_bytes(&self) -> &[u8] {
103        let len = std::mem::size_of_val(*self);
104        let data = self.as_u8_ptr();
105        // # Safety
106        //
107        // The resultant slice is derived from a valid pointer and
108        // length; the data can be interpreted as u8 if required; so
109        // this is safe.
110        unsafe { std::slice::from_raw_parts(data, len) }
111    }
112
113    //fp as_u8_ptr
114    fn as_u8_ptr(&self) -> *const u8 {
115        let data: *const T = self.as_ptr();
116        // # Safety
117        //
118        // The resultant pointer is a valid pointer to u8 (assuming T
119        // is initialized?). Use of the resultant pointer is always
120        // unsafe, as it is a pointer; but that is down to the user of
121        // a pointer.
122        unsafe { std::mem::transmute::<_, *const u8>(data) }
123    }
124
125    //zz All done
126}