jsph_tg_arceos_tutorial_exercise_hashmap_axstd/io/
stdio.rs1use crate::io::{self, BufReader, prelude::*};
2use crate::sync::{Mutex, MutexGuard};
3use lazyinit::LazyInit;
4
5#[cfg(feature = "alloc")]
6use alloc::{string::String, vec::Vec};
7
8struct StdinRaw;
9struct StdoutRaw;
10
11impl Read for StdinRaw {
12 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
14 let mut read_len = 0;
15 while read_len < buf.len() {
16 let len = arceos_api::stdio::ax_console_read_bytes(buf[read_len..].as_mut())?;
17 if len == 0 {
18 break;
19 }
20 read_len += len;
21 }
22 Ok(read_len)
23 }
24}
25
26impl Write for StdoutRaw {
27 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
28 arceos_api::stdio::ax_console_write_bytes(buf)
29 }
30 fn flush(&mut self) -> io::Result<()> {
31 Ok(())
32 }
33}
34
35pub struct Stdin {
37 inner: &'static Mutex<BufReader<StdinRaw>>,
38}
39
40pub struct StdinLock<'a> {
42 inner: MutexGuard<'a, BufReader<StdinRaw>>,
43}
44
45impl Stdin {
46 pub fn lock(&self) -> StdinLock<'static> {
53 StdinLock {
56 inner: self.inner.lock(),
57 }
58 }
59
60 #[cfg(feature = "alloc")]
62 pub fn read_line(&self, buf: &mut String) -> io::Result<usize> {
63 self.inner.lock().read_line(buf)
64 }
65}
66
67impl Read for Stdin {
68 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
70 let read_len = self.inner.lock().read(buf)?;
71 if buf.is_empty() || read_len > 0 {
72 return Ok(read_len);
73 }
74 loop {
76 let read_len = self.inner.lock().read(buf)?;
77 if read_len > 0 {
78 return Ok(read_len);
79 }
80 crate::thread::yield_now();
81 }
82 }
83}
84
85impl Read for StdinLock<'_> {
86 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
87 self.inner.read(buf)
88 }
89}
90
91impl BufRead for StdinLock<'_> {
92 fn fill_buf(&mut self) -> io::Result<&[u8]> {
93 self.inner.fill_buf()
94 }
95
96 fn consume(&mut self, n: usize) {
97 self.inner.consume(n)
98 }
99
100 #[cfg(feature = "alloc")]
101 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
102 self.inner.read_until(byte, buf)
103 }
104
105 #[cfg(feature = "alloc")]
106 fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
107 self.inner.read_line(buf)
108 }
109}
110
111pub struct Stdout {
113 inner: &'static Mutex<StdoutRaw>,
114}
115
116pub struct StdoutLock<'a> {
118 inner: MutexGuard<'a, StdoutRaw>,
119}
120
121impl Stdout {
122 pub fn lock(&self) -> StdoutLock<'static> {
128 StdoutLock {
129 inner: self.inner.lock(),
130 }
131 }
132}
133
134impl Write for Stdout {
135 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
136 self.inner.lock().write(buf)
137 }
138 fn flush(&mut self) -> io::Result<()> {
139 self.inner.lock().flush()
140 }
141}
142
143impl Write for StdoutLock<'_> {
144 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
145 self.inner.write(buf)
146 }
147 fn flush(&mut self) -> io::Result<()> {
148 self.inner.flush()
149 }
150}
151
152pub fn stdin() -> Stdin {
154 static INSTANCE: LazyInit<Mutex<BufReader<StdinRaw>>> = LazyInit::new();
155 if !INSTANCE.is_inited() {
156 INSTANCE.init_once(Mutex::new(BufReader::new(StdinRaw)));
157 }
158 Stdin { inner: &INSTANCE }
159}
160
161pub fn stdout() -> Stdout {
163 static INSTANCE: LazyInit<Mutex<StdoutRaw>> = LazyInit::new();
164 if !INSTANCE.is_inited() {
165 INSTANCE.init_once(Mutex::new(StdoutRaw));
166 }
167 Stdout { inner: &INSTANCE }
168}
169
170#[doc(hidden)]
171pub fn __print_impl(args: core::fmt::Arguments) {
172 if cfg!(feature = "smp") {
173 arceos_api::stdio::ax_console_write_fmt(args).unwrap();
176 } else {
177 stdout().lock().write_fmt(args).unwrap();
178 }
179}