@@ -5,54 +5,71 @@ use crate::os::uefi;
55use crate :: ptr:: NonNull ;
66
77pub struct Stdin {
8- pending : Option < char > ,
8+ pending : [ Option < u8 > ; 2 ] ,
99}
1010
1111pub struct Stdout ;
1212pub struct Stderr ;
1313
1414impl Stdin {
1515 pub const fn new ( ) -> Stdin {
16- Stdin { pending : None }
16+ Stdin { pending : [ None ; 2 ] }
1717 }
1818}
1919
2020impl io:: Read for Stdin {
21- fn read ( & mut self , mut buf : & mut [ u8 ] ) -> io:: Result < usize > {
21+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
22+ if buf. is_empty ( ) {
23+ return Ok ( 0 ) ;
24+ }
25+
2226 let st: NonNull < r_efi:: efi:: SystemTable > = uefi:: env:: system_table ( ) . cast ( ) ;
2327 let stdin = unsafe { ( * st. as_ptr ( ) ) . con_in } ;
28+ let mut count: usize = 0 ;
2429
2530 // Write any pending character
26- if let Some ( ch) = self . pending {
27- if ch. len_utf8 ( ) > buf. len ( ) {
28- return Ok ( 0 ) ;
31+ while let Some ( byte) = self . pending [ 0 ] {
32+ buf[ count] = byte;
33+ count += 1 ;
34+ self . pending [ 0 ] = self . pending [ 1 ] . take ( ) ;
35+
36+ if count >= buf. len ( ) {
37+ return Ok ( count) ;
2938 }
30- ch. encode_utf8 ( buf) ;
31- buf = & mut buf[ ch. len_utf8 ( ) ..] ;
32- self . pending = None ;
3339 }
3440
35- // Try reading any pending data
36- let inp = read ( stdin) ?;
37-
38- // Check if the key is printiable character
41+ // Try reading new character
42+ let inp = simple_text_input_read ( stdin) ?;
3943 if inp == 0x00 {
4044 return Err ( io:: const_io_error!( io:: ErrorKind :: Interrupted , "Special Key Press" ) ) ;
4145 }
4246
43- // The option unwrap is safe since iterator will have 1 element.
44- let ch: char = char:: decode_utf16 ( [ inp] )
45- . next ( )
46- . unwrap ( )
47- . map_err ( |_| io:: const_io_error!( io:: ErrorKind :: InvalidInput , "Invalid Input" ) ) ?;
48- if ch. len_utf8 ( ) > buf. len ( ) {
49- self . pending = Some ( ch) ;
50- return Ok ( 0 ) ;
47+ let Some ( Ok ( ch) ) = char:: decode_utf16 ( [ inp] ) . next ( ) else {
48+ return Err ( io:: const_io_error!( io:: ErrorKind :: InvalidInput , "Invalid Input" ) ) ;
49+ } ;
50+
51+ // This will always be > 0
52+ let buf_free_count = buf. len ( ) - count;
53+ assert ! ( buf_free_count > 0 ) ;
54+
55+ if ch. len_utf8 ( ) > buf_free_count {
56+ let mut temp = [ 0u8 ; 3 ] ;
57+ ch. encode_utf8 ( & mut temp) ;
58+
59+ buf[ count..] . copy_from_slice ( & temp[ ..buf_free_count] ) ;
60+ count += buf_free_count;
61+
62+ for ( i, v) in temp[ buf_free_count..] . into_iter ( ) . enumerate ( ) {
63+ self . pending [ i] = Some ( * v) ;
64+ }
65+
66+ return Ok ( count) ;
5167 }
5268
5369 ch. encode_utf8 ( buf) ;
70+ count += ch. len_utf8 ( ) ;
5471
55- Ok ( ch . len_utf8 ( ) )
72+ Ok ( count )
5673 }
5774}
5875
@@ -97,8 +114,8 @@ impl io::Write for Stderr {
97114// UCS-2 character should occupy 3 bytes at most in UTF-8
98115pub const STDIN_BUF_SIZE : usize = 3 ;
99116
100- pub fn is_ebadf ( err : & io:: Error ) -> bool {
101- err . raw_os_error ( ) == Some ( r_efi :: efi :: Status :: UNSUPPORTED . as_usize ( ) )
117+ pub fn is_ebadf ( _err : & io:: Error ) -> bool {
118+ false
102119}
103120
104121pub fn panic_output ( ) -> Option < impl io:: Write > {
@@ -116,6 +133,7 @@ fn write(
116133 } ;
117134
118135 let mut utf16: Vec < u16 > = utf8. encode_utf16 ( ) . collect ( ) ;
136+ // NULL terminate the string
119137 utf16. push ( 0 ) ;
120138
121139 unsafe { simple_text_output ( protocol, & mut utf16) } ?;
@@ -131,7 +149,9 @@ unsafe fn simple_text_output(
131149 if res. is_error ( ) { Err ( io:: Error :: from_raw_os_error ( res. as_usize ( ) ) ) } else { Ok ( ( ) ) }
132150}
133151
134- fn read ( stdin : * mut r_efi:: protocols:: simple_text_input:: Protocol ) -> io:: Result < u16 > {
152+ fn simple_text_input_read (
153+ stdin : * mut r_efi:: protocols:: simple_text_input:: Protocol ,
154+ ) -> io:: Result < u16 > {
135155 loop {
136156 match read_key_stroke ( stdin) {
137157 Ok ( x) => return Ok ( x. unicode_char ) ,
0 commit comments