safe_transmute/
base.rs

1//! Primitives for object and array transmutation.
2//!
3//! The functions in this module are very unsafe and their use is not
4//! recommended unless you *really* know what you are doing.
5
6
7use self::super::guard::{SingleValueGuard, PermissiveGuard, SingleManyGuard, Guard};
8use self::super::error::Error;
9use core::mem::size_of;
10#[cfg(feature = "alloc")]
11use core::mem::forget;
12#[cfg(feature = "alloc")]
13use alloc::vec::Vec;
14use core::slice;
15
16
17/// Convert a byte slice into a single instance of a `Copy`able type.
18///
19/// The byte slice must have at least enough bytes to fill a single instance of
20/// a type, extraneous data is ignored.
21///
22/// # Safety
23///
24/// - This function does not perform memory alignment checks. The beginning of
25///   the slice data must be properly aligned for accessing the value of type `T`.
26/// - The byte data needs to correspond to a valid `T` value.
27///
28/// Failure to fulfill any of the requirements above may result in undefined
29/// behavior.
30///
31/// # Errors
32///
33/// An error is returned if the slice does not have enough bytes for a single
34/// value `T`.
35///
36/// # Examples
37///
38/// ```
39/// # use safe_transmute::base::from_bytes;
40/// # include!("../tests/test_util/le_to_native.rs");
41/// # fn main() {
42/// // Little-endian
43/// unsafe {
44/// # /*
45///     assert_eq!(from_bytes::<u32>(&[0x00, 0x00, 0x00, 0x01])?, 0x0100_0000);
46/// # */
47/// #   assert_eq!(from_bytes::<u32>(&Le2NAl4([0x00, 0x00, 0x00, 0x01]).0.le_to_native::<u32>()).unwrap(), 0x0100_0000);
48/// }
49/// # }
50/// ```
51pub unsafe fn from_bytes<T: Copy>(bytes: &[u8]) -> Result<T, Error<u8, T>> {
52    SingleManyGuard::check::<T>(bytes)?;
53    Ok(slice::from_raw_parts(bytes.as_ptr() as *const T, 1)[0])
54}
55
56/// Convert a byte slice into a single instance of a `Copy`able type.
57///
58/// The byte slice must have exactly the expected number of bytes to fill a
59/// single instance of a type, without trailing space.
60///
61/// # Safety
62///
63/// - This function does not perform memory alignment checks. The beginning of
64///   the slice data must be properly aligned for accessing the value of type `T`.
65/// - The byte data needs to correspond to a valid `T` value.
66///
67/// Failure to fulfill any of the requirements above may result in undefined
68/// behavior.
69///
70/// # Errors
71///
72/// An error is returned if the slice's length is not equal to the size of a
73/// single value `T`.
74///
75/// # Examples
76///
77/// ```
78/// # use safe_transmute::base::from_bytes_pedantic;
79/// # include!("../tests/test_util/le_to_native.rs");
80/// # fn main() {
81/// // Little-endian
82/// unsafe {
83/// # /*
84///     assert_eq!(from_bytes_pedantic::<u32>(&[0x00, 0x00, 0x00, 0x01])?, 0x0100_0000);
85/// # */
86/// #   assert_eq!(
87/// #       from_bytes_pedantic::<u32>(&Le2NAl4([0x00, 0x00, 0x00, 0x01]).0.le_to_native::<u32>()).unwrap(),
88/// #       0x0100_0000
89/// #   );
90/// }
91/// # }
92/// ```
93pub unsafe fn from_bytes_pedantic<T: Copy>(bytes: &[u8]) -> Result<T, Error<u8, T>> {
94    SingleValueGuard::check::<T>(bytes)?;
95    Ok(slice::from_raw_parts(bytes.as_ptr() as *const T, 1)[0])
96}
97
98/// View a byte slice as a slice of an arbitrary type.
99///
100/// The required byte length of the slice depends on the chosen boundary guard.
101/// Please see the [Guard API](../guard/index.html).
102///
103/// # Safety
104///
105/// - This function does not perform memory alignment checks. The beginning of
106///   the slice data must be properly aligned for accessing vlues of type `T`.
107/// - The byte data needs to correspond to a valid contiguous sequence of `T`
108///   values. Types `T` with a `Drop` implementation are unlikely to be safe
109///   in this regard.
110///
111/// Failure to fulfill any of the requirements above may result in undefined
112/// behavior.
113///
114/// # Errors
115///
116/// An error is returned if the data does not comply with the policies of the
117/// given guard `G`.
118///
119/// # Examples
120///
121/// ```
122/// # use safe_transmute::base::transmute_many;
123/// # use safe_transmute::SingleManyGuard;
124/// # include!("../tests/test_util/le_to_native.rs");
125/// # fn main() {
126/// // Little-endian
127/// unsafe {
128/// # /*
129///     assert_eq!(
130///         transmute_many::<u16, SingleManyGuard>(&[0x00, 0x01, 0x00, 0x02])?,
131/// # */
132/// #   assert_eq!(transmute_many::<u16, SingleManyGuard>(&Le2NAl4([0x00, 0x01, 0x00, 0x02]).0.le_to_native::<u16>()).unwrap(),
133///         &[0x0100, 0x0200]
134///     );
135/// }
136/// # }
137/// ```
138pub unsafe fn transmute_many<T, G: Guard>(bytes: &[u8]) -> Result<&[T], Error<u8, T>> {
139    G::check::<T>(bytes)?;
140    Ok(slice::from_raw_parts(bytes.as_ptr() as *const T, bytes.len() / size_of::<T>()))
141}
142
143/// View a mutable byte slice as a slice of an arbitrary type.
144///
145/// The required byte length of the slice depends on the chosen boundary guard.
146/// Please see the [Guard API](../guard/index.html).
147///
148/// # Safety
149///
150/// - This function does not perform memory alignment checks. The beginning of
151///   the slice data must be properly aligned for accessing vlues of type `T`.
152/// - The byte data needs to correspond to a valid contiguous sequence of `T`
153///   values. Types `T` with a `Drop` implementation are unlikely to be safe
154///   in this regard.
155///
156/// Failure to fulfill any of the requirements above may result in undefined
157/// behavior.
158///
159/// # Errors
160///
161/// An error is returned if the data does not comply with the policies of the
162/// given guard `G`.
163///
164/// # Examples
165///
166/// ```
167/// # use safe_transmute::base::transmute_many_mut;
168/// # use safe_transmute::SingleManyGuard;
169/// # include!("../tests/test_util/le_to_native.rs");
170/// # fn main() {
171/// // Little-endian
172/// unsafe {
173/// # /*
174///     assert_eq!(
175///         transmute_many_mut::<u16, SingleManyGuard>(&mut [0xFF, 0x01, 0x00, 0x02])?,
176/// # */
177/// #   assert_eq!(transmute_many_mut::<u16, SingleManyGuard>(&mut Le2NAl4([0xFF, 0x01, 0x00, 0x02]).0.le_to_native::<u16>()).unwrap(),
178///         &mut [0x01FF, 0x0200]
179///     );
180/// }
181/// # }
182/// ```
183pub unsafe fn transmute_many_mut<T, G: Guard>(bytes: &mut [u8]) -> Result<&mut [T], Error<u8, T>> {
184    G::check::<T>(bytes)?;
185    Ok(slice::from_raw_parts_mut(bytes.as_mut_ptr() as *mut T, bytes.len() / size_of::<T>()))
186}
187
188/// View a byte slice as a slice of an arbitrary type.
189///
190/// The resulting slice will have as many instances of a type as will fit,
191/// rounded down. The permissive guard is a no-op, which makes it possible for
192/// this function to return a slice directly. It is therefore equivalent to
193/// `transmute_many::<_, PermissiveGuard>(bytes).unwrap()`.
194///
195/// # Safety
196///
197/// - This function does not perform memory alignment checks. The beginning of
198///   the slice data must be properly aligned for accessing vlues of type `T`.
199/// - The byte data needs to correspond to a valid contiguous sequence of `T`
200///   values. Types `T` with a `Drop` implementation are unlikely to be safe
201///   in this regard.
202///
203/// Failure to fulfill any of the requirements above may result in undefined
204/// behavior.
205///
206/// # Examples
207///
208/// ```
209/// # use safe_transmute::base::transmute_many_permissive;
210/// # include!("../tests/test_util/le_to_native.rs");
211/// # fn main() {
212/// // Little-endian
213/// unsafe {
214/// # /*
215///     assert_eq!(
216///         transmute_many_permissive::<u16>(&[0x00, 0x01, 0x00, 0x02]),
217/// # */
218/// #   assert_eq!(transmute_many_permissive::<u16>(&Le2NAl4([0x00, 0x01, 0x00, 0x02]).0.le_to_native::<u16>()),
219///         &[0x0100, 0x0200]
220///     );
221/// }
222/// # }
223/// ```
224pub unsafe fn transmute_many_permissive<T>(bytes: &[u8]) -> &[T] {
225    transmute_many::<_, PermissiveGuard>(bytes).expect("permissive guard should never fail")
226}
227
228/// Transform a vector into a vector of another element type.
229///
230/// The vector's allocated byte buffer (if already allocated) will be reused.
231///
232/// # Safety
233///
234/// Vector transmutations are **exceptionally** dangerous because of
235/// the constraints imposed by
236/// [`Vec::from_raw_parts()`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.from_raw_parts).
237///
238/// Unless *all* of the following requirements are fulfilled, this operation
239/// may result in undefined behavior:
240///
241/// - The target type `T` must have the same size and minimum alignment as the
242///   type `S`.
243/// - The vector's data needs to correspond to a valid contiguous sequence of
244///   `T` values. Types `T` with a `Drop` implementation are unlikely to be
245///   safe in this regard.
246///
247/// # Examples
248///
249/// ```
250/// # use safe_transmute::base::transmute_vec;
251/// unsafe {
252///     assert_eq!(
253///         transmute_vec::<u8, i8>(vec![0x00, 0x01, 0x00, 0x02]),
254///         vec![0x00i8, 0x01i8, 0x00i8, 0x02i8]
255///     );
256/// }
257/// ```
258#[cfg(feature = "alloc")]
259pub unsafe fn transmute_vec<S, T>(mut vec: Vec<S>) -> Vec<T> {
260    let ptr = vec.as_mut_ptr();
261    let capacity = vec.capacity() * size_of::<S>() / size_of::<T>();
262    let len = vec.len() * size_of::<S>() / size_of::<T>();
263    forget(vec);
264    Vec::from_raw_parts(ptr as *mut T, len, capacity)
265}