-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide Try{Into|From}Ctx impls for fixed byte array #93
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -181,13 +181,16 @@ | |
//! ``` | ||
|
||
use core::mem::size_of; | ||
use core::mem::transmute; | ||
use core::ptr::copy_nonoverlapping; | ||
use core::{result, str}; | ||
#[cfg(feature = "std")] | ||
use std::ffi::{CStr, CString}; | ||
|
||
use crate::endian::Endian; | ||
use crate::error; | ||
use crate::Pread; | ||
use crate::Pwrite; | ||
|
||
/// A trait for measuring how large something is; for a byte sequence, it will be its length. | ||
pub trait MeasureWith<Ctx> { | ||
|
@@ -400,14 +403,13 @@ macro_rules! signed_to_unsigned { | |
|
||
macro_rules! write_into { | ||
($typ:ty, $size:expr, $n:expr, $dst:expr, $endian:expr) => {{ | ||
assert!($dst.len() >= $size); | ||
let bytes = if $endian.is_little() { | ||
$n.to_le() | ||
} else { | ||
$n.to_be() | ||
} | ||
.to_ne_bytes(); | ||
unsafe { | ||
assert!($dst.len() >= $size); | ||
let bytes = transmute::<$typ, [u8; $size]>(if $endian.is_little() { | ||
$n.to_le() | ||
} else { | ||
$n.to_be() | ||
}); | ||
copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size); | ||
} | ||
}}; | ||
|
@@ -568,12 +570,12 @@ macro_rules! from_ctx_float_impl { | |
&mut data as *mut signed_to_unsigned!($typ) as *mut u8, | ||
$size, | ||
); | ||
transmute(if le.is_little() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a need for another transmute here? |
||
data.to_le() | ||
} else { | ||
data.to_be() | ||
}) | ||
} | ||
$typ::from_bits(if le.is_little() { | ||
data.to_le() | ||
} else { | ||
data.to_be() | ||
}) | ||
} | ||
} | ||
impl<'a> TryFromCtx<'a, Endian> for $typ | ||
|
@@ -841,6 +843,25 @@ impl TryIntoCtx for CString { | |
self.as_c_str().try_into_ctx(dst, ()) | ||
} | ||
} | ||
impl<'a, const N: usize> TryFromCtx<'a> for [u8; N] { | ||
type Error = error::Error; | ||
fn try_from_ctx(from: &'a [u8], _ctx: ()) -> Result<(Self, usize), Self::Error> { | ||
// Unwrap is OK, since pread_with already asserts the length. | ||
Ok((from.pread_with::<&'a [u8]>(0, N)?.try_into().unwrap(), N)) | ||
} | ||
} | ||
impl<const N: usize> TryIntoCtx for [u8; N] { | ||
type Error = error::Error; | ||
fn try_into_ctx(self, from: &mut [u8], _ctx: ()) -> Result<usize, Self::Error> { | ||
from.pwrite(self.as_slice(), 0) | ||
} | ||
} | ||
impl<'a, const N: usize> TryIntoCtx for &'a [u8; N] { | ||
type Error = error::Error; | ||
fn try_into_ctx(self, from: &mut [u8], ctx: ()) -> Result<usize, Self::Error> { | ||
(*self).try_into_ctx(from, ctx) | ||
} | ||
} | ||
|
||
// example of marshalling to bytes, let's wait until const is an option | ||
// impl FromCtx for [u8; 10] { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#![allow(clippy::disallowed_names)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm not sure this is needed. |
||
// this exists primarily to test various API usages of scroll; e.g., must compile | ||
|
||
use std::ops::{Deref, DerefMut}; | ||
|
@@ -136,6 +137,11 @@ impl<'a> Segments<'a> { | |
Ok(sections) | ||
} | ||
} | ||
impl<'a> Default for Segments<'a> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not a big fan of having identical default & new -- if anything, maybe better to have the |
||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} | ||
|
||
fn lifetime_passthrough_<'a>(segments: &Segments<'a>, section_name: &str) -> Option<&'a [u8]> { | ||
let segment_name = "__TEXT"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a need for this transmute here?