1use crate::prelude::*;
7use crate::sync::Mutex;
8use crate::uaccess::UserSliceReader;
9use core::fmt::{self, Debug, Formatter};
10use core::str::FromStr;
11use core::sync::atomic::{
12 AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU64,
13 AtomicU8, AtomicUsize, Ordering,
14};
15
16pub trait Writer {
26 fn write(&self, f: &mut Formatter<'_>) -> fmt::Result;
28}
29
30impl<T: Writer> Writer for Mutex<T> {
31 fn write(&self, f: &mut Formatter<'_>) -> fmt::Result {
32 self.lock().write(f)
33 }
34}
35
36impl<T: Debug> Writer for T {
37 fn write(&self, f: &mut Formatter<'_>) -> fmt::Result {
38 writeln!(f, "{self:?}")
39 }
40}
41
42pub trait Reader {
49 fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result;
51}
52
53impl<T: FromStr> Reader for Mutex<T> {
54 fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
55 let mut buf = [0u8; 128];
56 if reader.len() > buf.len() {
57 return Err(EINVAL);
58 }
59 let n = reader.len();
60 reader.read_slice(&mut buf[..n])?;
61
62 let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?;
63 let val = s.trim().parse::<T>().map_err(|_| EINVAL)?;
64 *self.lock() = val;
65 Ok(())
66 }
67}
68
69macro_rules! impl_reader_for_atomic {
70 ($(($atomic_type:ty, $int_type:ty)),*) => {
71 $(
72 impl Reader for $atomic_type {
73 fn read_from_slice(&self, reader: &mut UserSliceReader) -> Result {
74 let mut buf = [0u8; 21]; if reader.len() > buf.len() {
76 return Err(EINVAL);
77 }
78 let n = reader.len();
79 reader.read_slice(&mut buf[..n])?;
80
81 let s = core::str::from_utf8(&buf[..n]).map_err(|_| EINVAL)?;
82 let val = s.trim().parse::<$int_type>().map_err(|_| EINVAL)?;
83 self.store(val, Ordering::Relaxed);
84 Ok(())
85 }
86 }
87 )*
88 };
89}
90
91impl_reader_for_atomic!(
92 (AtomicI16, i16),
93 (AtomicI32, i32),
94 (AtomicI64, i64),
95 (AtomicI8, i8),
96 (AtomicIsize, isize),
97 (AtomicU16, u16),
98 (AtomicU32, u32),
99 (AtomicU64, u64),
100 (AtomicU8, u8),
101 (AtomicUsize, usize)
102);