Skip to content

Commit

Permalink
Merge pull request #57 from elfenpiff/iox2-56-add-from-bytes-truncated
Browse files Browse the repository at this point in the history
[#56] Introduce `from_bytes_truncated`
  • Loading branch information
elfenpiff authored Dec 29, 2023
2 parents b11a41d + f7a9966 commit b9f6f66
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 17 deletions.
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 @@ -23,7 +23,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

0 comments on commit b9f6f66

Please sign in to comment.