1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2022.
use crate::ErrorCode;
use core::ptr;
pub trait CopyOrErr {
/// Copies a nonoverlapping slice from src to self. Returns Err(ErrorCode) if source and self
/// are not the same length. This is a non-panicing version of slice::copy_from_slice.
fn copy_from_slice_or_err(&mut self, src: &Self) -> Result<(), ErrorCode>;
}
impl CopyOrErr for [u8] {
fn copy_from_slice_or_err(&mut self, src: &Self) -> Result<(), ErrorCode> {
if self.len() == src.len() {
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
// checked to have the same length. The slices cannot overlap because
// mutable references are exclusive.
unsafe {
ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
}
Ok(())
} else {
Err(ErrorCode::SIZE)
}
}
}
impl CopyOrErr for [u16] {
fn copy_from_slice_or_err(&mut self, src: &Self) -> Result<(), ErrorCode> {
if self.len() == src.len() {
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
// checked to have the same length. The slices cannot overlap because
// mutable references are exclusive.
unsafe {
ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
}
Ok(())
} else {
Err(ErrorCode::SIZE)
}
}
}
impl CopyOrErr for [u32] {
fn copy_from_slice_or_err(&mut self, src: &Self) -> Result<(), ErrorCode> {
if self.len() == src.len() {
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
// checked to have the same length. The slices cannot overlap because
// mutable references are exclusive.
unsafe {
ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
}
Ok(())
} else {
Err(ErrorCode::SIZE)
}
}
}
impl CopyOrErr for [u64] {
fn copy_from_slice_or_err(&mut self, src: &Self) -> Result<(), ErrorCode> {
if self.len() == src.len() {
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
// checked to have the same length. The slices cannot overlap because
// mutable references are exclusive.
unsafe {
ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
}
Ok(())
} else {
Err(ErrorCode::SIZE)
}
}
}
impl CopyOrErr for [usize] {
fn copy_from_slice_or_err(&mut self, src: &Self) -> Result<(), ErrorCode> {
if self.len() == src.len() {
// SAFETY: `self` is valid for `self.len()` elements by definition, and `src` was
// checked to have the same length. The slices cannot overlap because
// mutable references are exclusive.
unsafe {
ptr::copy_nonoverlapping(src.as_ptr(), self.as_mut_ptr(), self.len());
}
Ok(())
} else {
Err(ErrorCode::SIZE)
}
}
}