Skip to content

Commit

Permalink
Add rust_dbg_hex
Browse files Browse the repository at this point in the history
  • Loading branch information
NickeZ committed Dec 2, 2024
1 parent 96da936 commit 4d78e11
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 20 deletions.
35 changes: 35 additions & 0 deletions src/rust/bitbox02-rust-c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,38 @@ pub extern "C" fn rust_log(ptr: *const ::util::c_types::c_char) {
::util::log::rtt_target::rprintln!("{}", s);
}
}

/// This function is for debug purposes only!
///
/// Don't use this in production, the returned pointer is only valid until this function is called
/// again. This function is not thread safe.
///
/// Returns a null terminated string, suitable for printing with printf in C.
///
/// Max `len` is 64. This function panics if `len` is to large.
///
/// Usage:
/// uint8_t arr[2] = {1,2};
/// util_log("%s", rust_dbg_hex(arr, sizeof(arr)));
///
#[no_mangle]
#[cfg(feature = "rtt")]
pub extern "C" fn rust_dbg_hex(
buf: *mut ::util::c_types::c_uchar,
len: usize,
) -> *const ::util::c_types::c_char {
#![allow(static_mut_refs)]

const MAX_BYTES_LEN: usize = 64;
if len > MAX_BYTES_LEN {
panic!("Cannot convert more than {} bytes", MAX_BYTES_LEN);
}

let bytes = util::Bytes::new(buf, len);

static mut BUF: [u8; MAX_BYTES_LEN * 2 + 1] = [0; MAX_BYTES_LEN * 2 + 1];
let buf = unsafe { &mut BUF };
bytes.to_slice_hex(buf);
buf[len] = 0; // Null terminator.
buf as _
}
46 changes: 26 additions & 20 deletions src/rust/bitbox02-rust-c/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,9 @@ pub extern "C" fn rust_util_zero(mut dst: BytesMut) {
util::zero(dst.as_mut())
}

/// Convert bytes to hex representation
///
/// * `buf` - bytes to convert to hex.
/// * `out` - hex will be written here. out len must be at least 2*buf.len+1.
#[no_mangle]
pub extern "C" fn rust_util_uint8_to_hex(buf: Bytes, mut out: BytesMut) {
let bytes = buf.as_ref();
let hexlen = bytes.len() * 2;
// Avoid .unwrap() here until the following compiler regression is fixed:
// https://github.com/rust-lang/rust/issues/83925
match hex::encode_to_slice(bytes, &mut out.as_mut()[..hexlen]) {
Ok(()) => {}
Err(err) => panic!("{:?}", err),
}
// Null terminator.
out.as_mut()[hexlen] = 0;
pub extern "C" fn rust_util_uint8_to_hex(src: Bytes, mut dst: BytesMut) {
src.to_slice_hex(dst.as_mut());
}

#[repr(C)]
Expand Down Expand Up @@ -97,13 +84,32 @@ impl AsMut<[u8]> for BytesMut {
}
}

impl Bytes {
pub fn new(buf: *const c_uchar, len: usize) -> Bytes {
Bytes { buf, len }
}

/// Convert bytes to hex representation
///
/// * `out` - hex will be written here. out len must be at least 2*len.
pub fn to_slice_hex(&self, out: &mut [u8]) {
let bytes = self.as_ref();
let hexlen = bytes.len() * 2;
// Avoid .unwrap() here until the following compiler regression is fixed:
// https://github.com/rust-lang/rust/issues/83925
if let Err(err) = hex::encode_to_slice(bytes, &mut out.as_mut()[..hexlen]) {
panic!("{:?}", err);
}
}
}

/// Convert buffer to slice
///
/// * `buf` - Must be a valid pointer to an array of bytes
/// * `len` - Length of buffer, `buf[len-1]` must be a valid dereference
#[no_mangle]
pub extern "C" fn rust_util_bytes(buf: *const c_uchar, len: usize) -> Bytes {
Bytes { buf, len }
Bytes::new(buf, len)
}

/// Convert buffer to mutable slice
Expand Down Expand Up @@ -175,15 +181,15 @@ mod tests {
fn test_uint8_to_hex() {
let buf = [1u8, 2, 3, 14, 15, 255];
let mut string = String::from("xxxxxxxxxxxxx");
rust_util_uint8_to_hex(rust_util_bytes(buf.as_ptr(), buf.len()), unsafe {
rust_util_bytes_mut(string.as_mut_ptr(), string.len())
rust_util_bytes(buf.as_ptr(), buf.len()).to_slice_hex(unsafe {
rust_util_bytes_mut(string.as_mut_ptr(), string.len()).as_mut()
});
assert_eq!(string, "0102030e0fff\0");

// Bigger buffer also works.
let mut string = String::from("\0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
rust_util_uint8_to_hex(rust_util_bytes(buf.as_ptr(), buf.len()), unsafe {
rust_util_bytes_mut(string.as_mut_ptr(), string.len())
rust_util_bytes(buf.as_ptr(), buf.len()).to_slice_hex(unsafe {
rust_util_bytes_mut(string.as_mut_ptr(), string.len()).as_mut()
});
assert_eq!(string, "0102030e0fff\0xxxxxxxxxxxxxxxxxxxxxxx");
}
Expand Down

0 comments on commit 4d78e11

Please sign in to comment.