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}