Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bd03ea7

Browse files
d-sonuganicholasbishop
authored andcommitted
Added tests for the unicode collation protocol
1 parent af715af commit bd03ea7

File tree

6 files changed

+171
-89
lines changed

6 files changed

+171
-89
lines changed

‎src/proto/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,4 @@ pub mod pi;
7474
pub mod rng;
7575
pub mod security;
7676
pub mod shim;
77-
pub mod string;
77+
pub mod string;

‎src/proto/string/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//! String protocols
1+
//! String protocols.
22
//!
33
//! The protocols provide some string operations like
44
//! lexical comparison.
55
6-
pub mod unicode_collation;
6+
pub mod unicode_collation;

‎src/proto/string/unicode_collation.rs

Lines changed: 58 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,43 @@
1-
//! The Unicode Collation Protocol
1+
//! The Unicode Collation Protocol.
22
//!
3-
//! Used in the boot services environment to perform
4-
//! lexical comparison functions on Unicode strings for given languages
3+
//! This protocol is used in the boot services environment to perform
4+
//! lexical comparison functions on Unicode strings for given languages.
55
66
use core::cmp::Ordering;
7+
use uefi::data_types::{CStr16, CStr8, Char16, Char8};
78
use uefi_macros::{unsafe_guid, Protocol};
8-
use uefi::data_types::{Char16, CStr16, Char8, CStr8};
99

10-
/// The Unicode Collation Protocol
10+
/// The Unicode Collation Protocol.
1111
///
12-
/// Used to perform case-insensitive comaprisons of strings
12+
/// Used to perform case-insensitive comaprisons of strings.
1313
#[repr(C)]
1414
#[unsafe_guid("a4c751fc-23ae-4c3e-92e9-4964cf63f349")]
1515
#[derive(Protocol)]
1616
pub struct UnicodeCollation {
17-
stri_coll: extern "efiapi" fn(
18-
this: &Self,
19-
s1: *const Char16,
20-
s2: *const Char16
21-
) -> isize,
22-
metai_match: extern "efiapi" fn(
23-
this: &Self,
24-
string: *const Char16,
25-
pattern: *const Char16
26-
) -> bool,
27-
str_lwr: extern "efiapi" fn(
28-
this: &Self,
29-
s: *mut Char16
30-
),
31-
str_upr: extern "efiapi" fn(
32-
this: &Self,
33-
s: *mut Char16
34-
),
35-
fat_to_str: extern "efiapi" fn(
36-
this: &Self,
37-
fat_size: usize,
38-
fat: *const Char8,
39-
s: *mut Char16
40-
),
41-
str_to_fat: extern "efiapi" fn(
42-
this: &Self,
43-
s: *const Char16,
44-
fat_size: usize,
45-
fat: *mut Char8
46-
) -> bool
17+
stri_coll: extern "efiapi" fn(this: &Self, s1: *const Char16, s2: *const Char16) -> isize,
18+
metai_match:
19+
extern "efiapi" fn(this: &Self, string: *const Char16, pattern: *const Char16) -> bool,
20+
str_lwr: extern "efiapi" fn(this: &Self, s: *mut Char16),
21+
str_upr: extern "efiapi" fn(this: &Self, s: *mut Char16),
22+
fat_to_str: extern "efiapi" fn(this: &Self, fat_size: usize, fat: *const Char8, s: *mut Char16),
23+
str_to_fat:
24+
extern "efiapi" fn(this: &Self, s: *const Char16, fat_size: usize, fat: *mut Char8) -> bool,
4725
}
4826

4927
impl UnicodeCollation {
5028
/// Performs a case insensitive comparison of two
51-
/// null-terminated strings
29+
/// null-terminated strings.
5230
pub fn stri_coll(&self, s1: &CStr16, s2: &CStr16) -> Ordering {
53-
let order = (self.stri_coll)(
54-
self,
55-
s1.as_ptr(),
56-
s2.as_ptr()
57-
);
58-
if order == 0 {
59-
Ordering::Equal
60-
} else if order < 0 {
61-
Ordering::Less
62-
} else {
63-
Ordering::Greater
64-
}
31+
let order = (self.stri_coll)(self, s1.as_ptr(), s2.as_ptr());
32+
order.cmp(&0)
6533
}
6634

6735
/// Performs a case insensitive comparison between a null terminated
68-
/// pattern string and a null terminated string
36+
/// pattern string and a null terminated string.
6937
///
7038
/// This function checks if character pattern described in `pattern`
7139
/// is found in `string`. If the pattern match succeeds, true is returned.
72-
/// Otherwise, false is returned
40+
/// Otherwise, false is returned.
7341
///
7442
/// The following syntax can be used to build the string `pattern`:
7543
///
@@ -85,77 +53,81 @@ impl UnicodeCollation {
8553
/// in ".FW", ".fw", ".Fw" or ".fW". The pattern "[a-z]" will match any
8654
/// letter in the alphabet. The pattern "z" will match the letter "z".
8755
/// The pattern "d?.*" will match the character "D" or "d" followed by
88-
/// any single character followed by a "." followed by any string
56+
/// any single character followed by a "." followed by any string.
8957
pub fn metai_match(&self, s: &CStr16, pattern: &CStr16) -> bool {
90-
(self.metai_match)(
91-
self,
92-
s.as_ptr(),
93-
pattern.as_ptr()
94-
)
58+
(self.metai_match)(self, s.as_ptr(), pattern.as_ptr())
9559
}
9660

97-
/// Converts the characters in `s` to lower case characters
98-
pub fn str_lwr<'a>(&self, s: &CStr16, buf: &'a mut [u16]) -> Result<&'a CStr16, StrConversionError> {
61+
/// Converts the characters in `s` to lower case characters.
62+
pub fn str_lwr<'a>(
63+
&self,
64+
s: &CStr16,
65+
buf: &'a mut [u16],
66+
) -> Result<&'a CStr16, StrConversionError> {
9967
let mut last_index = 0;
10068
for (i, c) in s.iter().enumerate() {
101-
*buf.get_mut(i)
102-
.ok_or(StrConversionError::BufferTooSmall)? = (*c).into();
69+
*buf.get_mut(i).ok_or(StrConversionError::BufferTooSmall)? = (*c).into();
10370
last_index = i;
10471
}
10572
*buf.get_mut(last_index + 1)
10673
.ok_or(StrConversionError::BufferTooSmall)? = 0;
107-
108-
(self.str_lwr)(
109-
self,
110-
buf.as_ptr() as *mut _
111-
);
74+
75+
(self.str_lwr)(self, buf.as_ptr() as *mut _);
11276

11377
Ok(unsafe { CStr16::from_u16_with_nul_unchecked(buf) })
11478
}
11579

116-
/// Coverts the characters in `s` to upper case characters
117-
pub fn str_upr<'a>(&self, s: &CStr16, buf: &'a mut [u16]) -> Result<&'a CStr16, StrConversionError> {
80+
/// Converts the characters in `s` to upper case characters.
81+
pub fn str_upr<'a>(
82+
&self,
83+
s: &CStr16,
84+
buf: &'a mut [u16],
85+
) -> Result<&'a CStr16, StrConversionError> {
11886
let mut last_index = 0;
11987
for (i, c) in s.iter().enumerate() {
120-
*buf.get_mut(i)
121-
.ok_or(StrConversionError::BufferTooSmall)? = (*c).into();
88+
*buf.get_mut(i).ok_or(StrConversionError::BufferTooSmall)? = (*c).into();
12289
last_index = i;
12390
}
12491
*buf.get_mut(last_index + 1)
12592
.ok_or(StrConversionError::BufferTooSmall)? = 0;
126-
127-
(self.str_upr)(
128-
self,
129-
buf.as_ptr() as *mut _
130-
);
93+
94+
(self.str_upr)(self, buf.as_ptr() as *mut _);
13195

13296
Ok(unsafe { CStr16::from_u16_with_nul_unchecked(buf) })
13397
}
13498

135-
/// Converts the 8.3 FAT file name `fat` to a null terminated string
136-
pub fn fat_to_str<'a>(&self, fat: &CStr8, buf: &'a mut [u16]) -> Result<&'a CStr16, StrConversionError> {
99+
/// Converts the 8.3 FAT file name `fat` to a null terminated string.
100+
pub fn fat_to_str<'a>(
101+
&self,
102+
fat: &CStr8,
103+
buf: &'a mut [u16],
104+
) -> Result<&'a CStr16, StrConversionError> {
137105
if buf.len() < fat.to_bytes_with_nul().len() {
138106
return Err(StrConversionError::BufferTooSmall);
139107
}
140108
(self.fat_to_str)(
141109
self,
142110
fat.to_bytes_with_nul().len(),
143111
fat.as_ptr(),
144-
buf.as_ptr() as *mut _
112+
buf.as_ptr() as *mut _,
145113
);
146114
Ok(unsafe { CStr16::from_u16_with_nul_unchecked(buf) })
147115
}
148116

149-
/// Converts the null terminated string `s` to legal characters in a FAT file name
150-
pub fn str_to_fat<'a>(&self, s: &CStr16, buf: &'a mut [u8]) -> Result<&'a CStr8, StrConversionError> {
117+
/// Converts the null terminated string `s` to legal characters in a FAT file name.
118+
pub fn str_to_fat<'a>(
119+
&self,
120+
s: &CStr16,
121+
buf: &'a mut [u8],
122+
) -> Result<&'a CStr8, StrConversionError> {
151123
if s.as_slice_with_nul().len() > buf.len() {
152124
return Err(StrConversionError::BufferTooSmall);
153125
}
154126
let failed = (self.str_to_fat)(
155127
self,
156128
s.as_ptr(),
157129
s.as_slice_with_nul().len(),
158-
buf.as_ptr() as *mut _
130+
buf.as_ptr() as *mut _,
159131
);
160132
if failed {
161133
Err(StrConversionError::ConversionFailed)
@@ -178,11 +150,11 @@ impl UnicodeCollation {
178150
}
179151
}
180152

181-
/// Errors returned by [`UnicodeCollation::str_lwr`] and [`UnicodeCollation::str_upr`]
153+
/// Errors returned by [`UnicodeCollation::str_lwr`] and [`UnicodeCollation::str_upr`].
182154
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
183155
pub enum StrConversionError {
184-
/// The conversion failed
156+
/// The conversion failed.
185157
ConversionFailed,
186-
/// The buffer given is too small to hold the string
187-
BufferTooSmall
188-
}
158+
/// The buffer given is too small to hold the string.
159+
BufferTooSmall,
160+
}

‎uefi-test-runner/src/proto/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn test(image: Handle, st: &mut SystemTable<Boot>) {
1919
network::test(bt);
2020
pi::test(bt);
2121
rng::test(bt);
22+
string::test(bt);
2223

2324
#[cfg(any(
2425
target_arch = "i386",
@@ -71,3 +72,4 @@ mod rng;
7172
target_arch = "aarch64"
7273
))]
7374
mod shim;
75+
mod string;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use uefi::prelude::*;
2+
3+
pub fn test(bt: &BootServices) {
4+
info!("Testing String protocols");
5+
6+
unicode_collation::test(bt);
7+
}
8+
9+
mod unicode_collation;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use core::cmp::Ordering;
2+
use uefi::prelude::*;
3+
use uefi::proto::string::unicode_collation::{StrConversionError, UnicodeCollation};
4+
use uefi::{CStr16, CStr8};
5+
6+
pub fn test(bt: &BootServices) {
7+
info!("Testing the Unicode Collation protocol");
8+
9+
if let Ok(handles) = bt.find_handles::<UnicodeCollation>() {
10+
for handle in handles {
11+
let uc = bt
12+
.open_protocol_exclusive::<UnicodeCollation>(handle)
13+
.unwrap();
14+
15+
let mut buf1 = [0; 30];
16+
let mut buf2 = [0; 30];
17+
18+
macro_rules! strings {
19+
($s1:expr, $s2:expr) => {{
20+
let s1 = CStr16::from_str_with_buf($s1, &mut buf1).unwrap();
21+
let s2 = CStr16::from_str_with_buf($s2, &mut buf2).unwrap();
22+
(s1, s2)
23+
}};
24+
}
25+
26+
let (s1, s2) = strings!("aab", "aaa");
27+
// "aab" is lexically greater than "aaa"
28+
assert_eq!(uc.stri_coll(s1, s2), Ordering::Greater);
29+
30+
let (s1, s2) = strings!("{}", "{}");
31+
assert_eq!(uc.stri_coll(s1, s2), Ordering::Equal);
32+
33+
let (s1, s2) = strings!("\t", "-");
34+
// Tab comes before dash in the unicode table
35+
assert_eq!(uc.stri_coll(s1, s2), Ordering::Less);
36+
37+
let (s, pattern) = strings!("haaaaaaaaarderr", "h*a*r*derr");
38+
assert!(uc.metai_match(s, pattern));
39+
40+
let (s, pattern) = strings!("haaaaaaaaarder0r", "h*a*r*derr");
41+
assert!(!uc.metai_match(s, pattern));
42+
43+
let mut buf1 = [0; 13];
44+
let s = CStr16::from_str_with_buf("HeLlO World!", &mut buf1).unwrap();
45+
46+
let mut buf2 = [0; 12];
47+
assert_eq!(
48+
uc.str_lwr(s, &mut buf2),
49+
Err(StrConversionError::BufferTooSmall)
50+
);
51+
52+
let mut buf2 = [0; 13];
53+
let lower_s = uc.str_lwr(s, &mut buf2).unwrap();
54+
assert_eq!(
55+
lower_s,
56+
CStr16::from_str_with_buf("hello world!", &mut [0; 13]).unwrap()
57+
);
58+
59+
let mut buf = [0; 12];
60+
assert_eq!(
61+
uc.str_upr(s, &mut buf),
62+
Err(StrConversionError::BufferTooSmall)
63+
);
64+
65+
let mut buf = [0; 13];
66+
let upper_s = uc.str_upr(s, &mut buf).unwrap();
67+
assert_eq!(
68+
upper_s,
69+
CStr16::from_str_with_buf("HELLO WORLD!", &mut [0; 13]).unwrap()
70+
);
71+
72+
let s = CStr8::from_bytes_with_nul(b"Hello World!0円").unwrap();
73+
assert_eq!(
74+
uc.fat_to_str(s, &mut [0; 12]),
75+
Err(StrConversionError::BufferTooSmall)
76+
);
77+
78+
assert_eq!(
79+
uc.fat_to_str(s, &mut [0; 13]).unwrap(),
80+
CStr16::from_str_with_buf("Hello World!", &mut [0; 13]).unwrap()
81+
);
82+
83+
let mut buf = [0; 13];
84+
let s = CStr16::from_str_with_buf("Hello World!", &mut buf).unwrap();
85+
let mut buf = [0; 12];
86+
assert_eq!(
87+
uc.str_to_fat(s, &mut buf),
88+
Err(StrConversionError::BufferTooSmall)
89+
);
90+
let mut buf = [0; 13];
91+
assert_eq!(
92+
uc.str_to_fat(s, &mut buf).unwrap(),
93+
CStr8::from_bytes_with_nul(b"HELLOWORLD!0円").unwrap()
94+
);
95+
}
96+
} else {
97+
warn!("The Unicode Collation protocol is not supported");
98+
}
99+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /