1
1
use alloc:: borrow:: ToOwned ;
2
- use alloc:: string:: String ;
3
2
use alloc:: vec:: Vec ;
4
3
use core:: borrow:: Borrow ;
5
- use core:: fmt:: { Display , Formatter } ;
4
+ use core:: fmt:: { Formatter , Write } ;
6
5
use core:: mem:: transmute;
7
6
use core:: slice:: { from_raw_parts, IterMut } ;
8
7
use core:: str:: FromStr ;
@@ -15,6 +14,7 @@ use core::str::FromStr;
15
14
pub struct EfiStr ( [ u16 ] ) ;
16
15
17
16
impl EfiStr {
17
+ /// An empty string with only NUL character.
18
18
pub const EMPTY : & ' static Self = unsafe { Self :: new_unchecked ( & [ 0 ] ) } ;
19
19
20
20
/// # Safety
@@ -40,17 +40,26 @@ impl EfiStr {
40
40
Self :: new_unchecked ( from_raw_parts ( ptr, len + 1 ) )
41
41
}
42
42
43
+ /// Returnes a pointer to the first character.
43
44
pub const fn as_ptr ( & self ) -> * const u16 {
44
45
self . 0 . as_ptr ( )
45
46
}
46
47
48
+ /// Returnes length of this string without NUL, in character.
47
49
pub const fn len ( & self ) -> usize {
48
50
self . 0 . len ( ) - 1
49
51
}
50
52
53
+ /// Returns `true` if this string contains only NUL character.
51
54
pub const fn is_empty ( & self ) -> bool {
52
55
self . len ( ) == 0
53
56
}
57
+
58
+ /// Returns object that implement [`core::fmt::Display`] for safely printing string that may
59
+ /// contain non-Unicode data.
60
+ pub const fn display ( & self ) -> impl core:: fmt:: Display + ' _ {
61
+ Display ( self )
62
+ }
54
63
}
55
64
56
65
impl AsRef < EfiStr > for EfiStr {
@@ -83,12 +92,24 @@ impl ToOwned for EfiStr {
83
92
}
84
93
}
85
94
86
- impl Display for EfiStr {
95
+ /// Provides [`core::fmt::Display`] to display [`EfiStr`] lossy.
96
+ struct Display < ' a > ( & ' a EfiStr ) ;
97
+
98
+ impl < ' a > core:: fmt:: Display for Display < ' a > {
87
99
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
88
- let d = & self . 0 [ ..( self . 0 . len ( ) - 1 ) ] ; // Exclude NUL.
89
- let s = String :: from_utf16 ( d) . unwrap ( ) ;
100
+ // SAFETY: EfiStr guarantee to have NUL at the end.
101
+ let mut ptr = self . 0 . as_ptr ( ) ;
102
+
103
+ while unsafe { * ptr != 0 } {
104
+ let c = unsafe { * ptr } ;
105
+ let c = char:: from_u32 ( c. into ( ) ) . unwrap_or ( char:: REPLACEMENT_CHARACTER ) ;
106
+
107
+ f. write_char ( c) ?;
108
+
109
+ unsafe { ptr = ptr. add ( 1 ) } ;
110
+ }
90
111
91
- f . write_str ( & s )
112
+ Ok ( ( ) )
92
113
}
93
114
}
94
115
@@ -166,12 +187,6 @@ impl Borrow<EfiStr> for EfiString {
166
187
}
167
188
}
168
189
169
- impl Display for EfiString {
170
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
171
- self . as_ref ( ) . fmt ( f)
172
- }
173
- }
174
-
175
190
/// A non-NUL character in the EFI string.
176
191
#[ repr( transparent) ]
177
192
pub struct EfiChar ( u16 ) ;
0 commit comments