mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 20:48:55 +00:00
data_model: allow reading structs from io::Read
Add a from_reader() function that allows reading a DataInit type from a std::io::Read stream. BUG=None TEST=./build_test Change-Id: Iaacae489db2c265d6b1a9af6e18c11c9e6efe354 Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1737723 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
parent
3d690c6f53
commit
301583c01a
1 changed files with 21 additions and 1 deletions
|
@ -2,7 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::mem::size_of;
|
||||
use std::io;
|
||||
use std::mem::{align_of, size_of};
|
||||
use std::slice::{from_raw_parts, from_raw_parts_mut};
|
||||
|
||||
/// Types for which it is safe to initialize from raw data.
|
||||
|
@ -64,6 +65,25 @@ pub unsafe trait DataInit: Copy + Send + Sync {
|
|||
}
|
||||
}
|
||||
|
||||
/// Creates an instance of `Self` by copying raw data from an io::Read stream.
|
||||
fn from_reader<R: io::Read>(mut read: R) -> io::Result<Self> {
|
||||
// Allocate a Vec<u8> with enough extra space for the worst-case alignment offset.
|
||||
let mut data = vec![0u8; size_of::<Self>() + align_of::<Self>()];
|
||||
|
||||
// Get a u8 slice within data with sufficient alignment for Self.
|
||||
let align_offset = data.as_ptr().align_offset(align_of::<Self>());
|
||||
let mut aligned_data = &mut data[align_offset..align_offset + size_of::<Self>()];
|
||||
|
||||
read.read_exact(&mut aligned_data)?;
|
||||
match Self::from_slice(&aligned_data) {
|
||||
Some(obj) => Ok(*obj),
|
||||
None => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
"from_slice failed",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a reference to `self` into a slice of bytes.
|
||||
///
|
||||
/// The value of `self` is not copied. Instead, the slice is made from a reference to `self`.
|
||||
|
|
Loading…
Reference in a new issue