Skip to content
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

[#56] Introduce from_bytes_truncated #57

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@
* [ ] `#![no_std]` on `stable` on all tier 1 platforms
* [ ] completely dynamic setup with dynamic shared memory

## Shared Memory Container & Types

* [ ] Make `iceoryx2_bb_container` public with announcement
* [ ] Create and document dynamic size container concept for shared memory and apply it
to all existing containers: `ByteString`, `Vec`, `Queue`
* Open Question: How can these containers be cloned, copied?
* [ ] Introduce additional containers: `HashMap`, `Tree`, `Set`, `List`
* [ ] Introduce elementary types, look into: `simple-si-units` crate
* Add types like: memory size, percentage, strict percentage (0..100), data throughput, resolution
(further types found in informatics)
* [ ] Add `derive` proc macro to ensure that only shm compatible types can be
transferred via zero-copy

## Language Bindings

* [ ] C
Expand Down
2 changes: 1 addition & 1 deletion doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

### New API features

* Example [#1](https://github.com/eclipse-iceoryx/iceoryx2/issues/1)
* Add `FixedSizeByteString::from_bytes_truncated` [#56](https://github.com/eclipse-iceoryx/iceoryx2/issues/56)

### API Breaking Changes

Expand Down
16 changes: 16 additions & 0 deletions iceoryx2-bb/container/src/byte_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,22 @@ impl<const CAPACITY: usize> FixedSizeByteString<CAPACITY> {
Ok(new_self)
}

/// Creates a new [`FixedSizeByteString`] from a byte slice. If the byte slice does not fit
/// into the [`FixedSizeByteString`] it will be truncated.
pub fn from_bytes_truncated(bytes: &[u8]) -> Self {
let mut new_self = Self::new();
new_self.len = std::cmp::min(bytes.len(), CAPACITY);
for (i, byte) in bytes.iter().enumerate().take(new_self.len) {
new_self.data[i].write(*byte);
}

if new_self.len < CAPACITY {
new_self.data[new_self.len].write(0);
}

new_self
}

/// Creates a new byte string from a given null-terminated string
///
/// # Safety
Expand Down
37 changes: 29 additions & 8 deletions iceoryx2-bb/container/tests/byte_string_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,40 @@ fn fixed_size_byte_string_from_bytes_works() {
assert_that!(sut.pop(), eq Some(b'd'));
}

#[test]
fn fixed_size_byte_string_from_bytes_truncated_works() {
let sut = Sut::from_bytes(b"bonjour world");
assert_that!(sut, is_ok);
let mut sut = sut.unwrap();

assert_that!(sut, is_not_empty);
assert_that!(sut.is_full(), eq false);
assert_that!(sut, len 13);
assert_that!(sut, eq b"bonjour world");
assert_that!(sut, ne b"bonjour world! woo");
assert_that!(sut.as_bytes(), eq b"bonjour world");
assert_that!(sut.as_mut_bytes(), eq b"bonjour world");
assert_that!(sut.as_bytes_with_nul(), eq b"bonjour world\0");
assert_that!(sut.pop(), eq Some(b'd'));
}

#[test]
fn fixed_size_byte_string_from_byte_slice_works() {
let mut sut = Sut::from(b"hello world!");
let sut = FixedSizeByteString::<5>::from_bytes_truncated(b"hell");

assert_that!(sut, is_not_empty);
assert_that!(sut.is_full(), eq false);
assert_that!(sut, len 12);
assert_that!(sut, eq b"hello world!");
assert_that!(sut, ne b"hello world! woo");
assert_that!(sut.as_bytes(), eq b"hello world!");
assert_that!(sut.as_mut_bytes(), eq b"hello world!");
assert_that!(sut.as_bytes_with_nul(), eq b"hello world!\0");
assert_that!(sut.pop(), eq Some(b'!'));
assert_that!(sut, len 4);
assert_that!(sut, eq b"hell");
assert_that!(sut.as_bytes_with_nul(), eq b"hell\0");

let sut = FixedSizeByteString::<5>::from_bytes_truncated(b"hello world");

assert_that!(sut, is_not_empty);
assert_that!(sut.is_full(), eq true);
assert_that!(sut, len 5);
assert_that!(sut, eq b"hello");
assert_that!(sut.as_bytes_with_nul(), eq b"hello\0");
}

#[test]
Expand Down
7 changes: 6 additions & 1 deletion iceoryx2-bb/posix/src/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,12 @@ pub enum MutexThreadTerminationBehavior {
/// mutex owning
/// thread/process dies the mutex is put into an inconsistent state which can be recovered with
/// [`Mutex::make_consistent()`]. The inconsistent state is detected by the next instance which
/// calls [`Mutex::lock()`], [`Mutex::try_lock()`] or [`Mutex::timed_lock()`].
/// calls [`Mutex::try_lock()`] or [`Mutex::timed_lock()`].
///
/// **Important:** If the owner dies after another thread has already locked the [`Mutex`] it
/// may become impossible to recover the [`Mutex`]. Therefore, this feature should be used
/// only in combination with either [`Mutex::try_lock`] or [`Mutex::timed_lock()`] and
/// never with [`Mutex::lock()`].
///
/// This is also known as robust mutex.
ReleaseWhenLocked = posix::PTHREAD_MUTEX_ROBUST,
Expand Down
16 changes: 9 additions & 7 deletions iceoryx2-bb/posix/tests/mutex_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,14 +405,16 @@ fn mutex_can_be_recovered_when_thread_died() {
});
});

let guard = sut.lock();
assert_that!(guard, is_err);
match guard.as_ref().err().as_ref().unwrap() {
MutexLockError::LockAcquiredButOwnerDied(_) => (),
_ => assert_that!(true, eq false),
loop {
let guard = sut.try_lock();

if guard.is_ok() {
assert_that!(guard.as_ref().unwrap(), is_none);
} else if let Err(MutexLockError::LockAcquiredButOwnerDied(_)) = guard {
sut.make_consistent();
break;
}
}
sut.make_consistent();
drop(guard);

let guard = sut.try_lock();
assert_that!(guard, is_ok);
Expand Down