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
// Copyright 2023 Colin Finck <colin@reactos.org>
// SPDX-License-Identifier: MIT OR Apache-2.0
// #[macro_export] always exports all macros at the root, even when they better fit to individual modules.
// This is a current limitation of the Rust macro system.
//
// As a consequence, I'm also grouping all public macros here instead of giving people a wrong idea
// by associating them to modules.
/// Creates an [`NtUnicodeStr`] with `'static` lifetime for a string literal.
///
/// The internal buffer of the [`NtUnicodeStr`] will consist entirely of valid UTF-16 characters.
///
/// The internal buffer will also be NUL-terminated.
/// See the [unicode_string module-level documentation](crate::unicode_string) for the implications of that.
///
/// [`NtUnicodeStr`]: crate::unicode_string::NtUnicodeStr
#[macro_export]
macro_rules! nt_unicode_str {
($text:expr) => {{
const U16CSTR: &'static $crate::widestring::U16CStr = $crate::widestring::u16cstr!($text);
let buffer = U16CSTR.as_slice_with_nul();
// Include the terminating NUL character in `maximum_length` ...
let maximum_length_in_elements = buffer.len();
let maximum_length_in_bytes = maximum_length_in_elements * ::core::mem::size_of::<u16>();
assert!(
maximum_length_in_bytes <= ::core::primitive::u16::MAX as usize,
"String is too long (resulting byte length exceeds a u16)"
);
let maximum_length = maximum_length_in_bytes as u16;
// ... but not in `length`
assert!(maximum_length >= ::core::mem::size_of::<u16>() as u16);
let length = maximum_length - ::core::mem::size_of::<u16>() as u16;
unsafe {
$crate::unicode_string::NtUnicodeStr::from_raw_parts(
buffer.as_ptr(),
length,
maximum_length,
)
}
}};
}
#[cfg(test)]
mod tests {
use crate::unicode_string::NtUnicodeStr;
const TEST_STR: NtUnicodeStr<'static> = nt_unicode_str!("Moin");
#[test]
fn test_nt_unicode_str() {
assert_eq!(TEST_STR, "Moin");
assert_eq!(TEST_STR.len(), 8);
assert_eq!(TEST_STR.capacity(), 10);
}
}