diff options
| -rw-r--r-- | src/libstd/sys/cloudabi/stdio.rs | 16 | ||||
| -rw-r--r-- | src/libstd/sys/redox/stdio.rs | 22 | ||||
| -rw-r--r-- | src/libstd/sys/sgx/stdio.rs | 22 | ||||
| -rw-r--r-- | src/libstd/sys/unix/stdio.rs | 22 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/stdio.rs | 26 | ||||
| -rw-r--r-- | src/libstd/sys/windows/stdio.rs | 81 |
6 files changed, 114 insertions, 75 deletions
diff --git a/src/libstd/sys/cloudabi/stdio.rs b/src/libstd/sys/cloudabi/stdio.rs index 8ec92326dbd..81d79213f61 100644 --- a/src/libstd/sys/cloudabi/stdio.rs +++ b/src/libstd/sys/cloudabi/stdio.rs @@ -9,8 +9,10 @@ impl Stdin { pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) } +} - pub fn read(&self, _: &mut [u8]) -> io::Result<usize> { +impl io::Read for Stdin { + fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } } @@ -19,15 +21,17 @@ impl Stdout { pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) } +} - pub fn write(&self, _: &[u8]) -> io::Result<usize> { +impl io::Write for Stdout { + fn write(&mut self, _buf: &[u8]) -> io::Result<usize> { Err(io::Error::new( io::ErrorKind::BrokenPipe, "Stdout is not connected to any output in this environment", )) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } @@ -36,15 +40,17 @@ impl Stderr { pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) } +} - pub fn write(&self, _: &[u8]) -> io::Result<usize> { +impl io::Write for Stderr { + fn write(&mut self, _buf: &[u8]) -> io::Result<usize> { Err(io::Error::new( io::ErrorKind::BrokenPipe, "Stderr is not connected to any output in this environment", )) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } diff --git a/src/libstd/sys/redox/stdio.rs b/src/libstd/sys/redox/stdio.rs index 66f84e17527..b4eb01fd6cc 100644 --- a/src/libstd/sys/redox/stdio.rs +++ b/src/libstd/sys/redox/stdio.rs @@ -8,10 +8,12 @@ pub struct Stderr(()); impl Stdin { pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) } +} - pub fn read(&self, data: &mut [u8]) -> io::Result<usize> { +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let fd = FileDesc::new(0); - let ret = fd.read(data); + let ret = fd.read(buf); fd.into_raw(); ret } @@ -19,30 +21,34 @@ impl Stdin { impl Stdout { pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { let fd = FileDesc::new(1); - let ret = fd.write(data); + let ret = fd.write(buf); fd.into_raw(); ret } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { cvt(syscall::fsync(1)).and(Ok(())) } } impl Stderr { pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { let fd = FileDesc::new(2); - let ret = fd.write(data); + let ret = fd.write(buf); fd.into_raw(); ret } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { cvt(syscall::fsync(2)).and(Ok(())) } } diff --git a/src/libstd/sys/sgx/stdio.rs b/src/libstd/sys/sgx/stdio.rs index c8efb931d6f..57d66ed9a85 100644 --- a/src/libstd/sys/sgx/stdio.rs +++ b/src/libstd/sys/sgx/stdio.rs @@ -16,32 +16,38 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R { impl Stdin { pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) } +} - pub fn read(&self, data: &mut [u8]) -> io::Result<usize> { - with_std_fd(abi::FD_STDIN, |fd| fd.read(data)) +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + with_std_fd(abi::FD_STDIN, |fd| fd.read(buf)) } } impl Stdout { pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { - with_std_fd(abi::FD_STDOUT, |fd| fd.write(data)) +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + with_std_fd(abi::FD_STDOUT, |fd| fd.write(buf)) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { with_std_fd(abi::FD_STDOUT, |fd| fd.flush()) } } impl Stderr { pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { - with_std_fd(abi::FD_STDERR, |fd| fd.write(data)) +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + with_std_fd(abi::FD_STDERR, |fd| fd.write(buf)) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { with_std_fd(abi::FD_STDERR, |fd| fd.flush()) } } diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs index e23723222be..82bd2fbf776 100644 --- a/src/libstd/sys/unix/stdio.rs +++ b/src/libstd/sys/unix/stdio.rs @@ -8,10 +8,12 @@ pub struct Stderr(()); impl Stdin { pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) } +} - pub fn read(&self, data: &mut [u8]) -> io::Result<usize> { +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let fd = FileDesc::new(libc::STDIN_FILENO); - let ret = fd.read(data); + let ret = fd.read(buf); fd.into_raw(); // do not close this FD ret } @@ -19,30 +21,34 @@ impl Stdin { impl Stdout { pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { let fd = FileDesc::new(libc::STDOUT_FILENO); - let ret = fd.write(data); + let ret = fd.write(buf); fd.into_raw(); // do not close this FD ret } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } impl Stderr { pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { let fd = FileDesc::new(libc::STDERR_FILENO); - let ret = fd.write(data); + let ret = fd.write(buf); fd.into_raw(); // do not close this FD ret } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } diff --git a/src/libstd/sys/wasm/stdio.rs b/src/libstd/sys/wasm/stdio.rs index 015d3f20660..657655004e9 100644 --- a/src/libstd/sys/wasm/stdio.rs +++ b/src/libstd/sys/wasm/stdio.rs @@ -9,9 +9,11 @@ impl Stdin { pub fn new() -> io::Result<Stdin> { Ok(Stdin) } +} - pub fn read(&self, data: &mut [u8]) -> io::Result<usize> { - Ok(ReadSysCall::perform(0, data)) +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + Ok(ReadSysCall::perform(0, buf)) } } @@ -19,13 +21,15 @@ impl Stdout { pub fn new() -> io::Result<Stdout> { Ok(Stdout) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { - WriteSysCall::perform(1, data); - Ok(data.len()) +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + WriteSysCall::perform(1, buf); + Ok(buf.len()) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } @@ -34,13 +38,15 @@ impl Stderr { pub fn new() -> io::Result<Stderr> { Ok(Stderr) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { - WriteSysCall::perform(2, data); - Ok(data.len()) +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + WriteSysCall::perform(2, buf); + Ok(buf.len()) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs index 6b9b36f6a92..5963541a893 100644 --- a/src/libstd/sys/windows/stdio.rs +++ b/src/libstd/sys/windows/stdio.rs @@ -1,6 +1,5 @@ #![unstable(issue = "0", feature = "windows_stdio")] -use cell::Cell; use char::decode_utf16; use cmp; use io; @@ -13,7 +12,7 @@ use sys::handle::Handle; // Don't cache handles but get them fresh for every read/write. This allows us to track changes to // the value over time (such as if a process calls `SetStdHandle` while it's running). See #40490. pub struct Stdin { - high_surrogate: Cell<u16>, + surrogate: u16, } pub struct Stdout; pub struct Stderr; @@ -128,10 +127,12 @@ fn write_u16s(handle: c::HANDLE, data: &[u16]) -> io::Result<usize> { impl Stdin { pub fn new() -> io::Result<Stdin> { - Ok(Stdin { high_surrogate: Cell::new(0) }) + Ok(Stdin { surrogate: 0 }) } +} - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { +impl io::Read for Stdin { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { let handle = get_handle(c::STD_INPUT_HANDLE)?; if !is_console(handle) { let handle = Handle::new(handle); @@ -153,40 +154,44 @@ impl Stdin { // we can read at most a third of `buf.len()` chars and uphold the guarantee no data gets // lost. let amount = cmp::min(buf.len() / 3, utf16_buf.len()); - let read = self.read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount)?; + let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?; utf16_to_utf8(&utf16_buf[..read], buf) } +} - // We assume that if the last `u16` is an unpaired surrogate they got sliced apart by our - // buffer size, and keep it around for the next read hoping to put them together. - // This is a best effort, and may not work if we are not the only reader on Stdin. - fn read_u16s_fixup_surrogates(&self, handle: c::HANDLE, buf: &mut [u16], mut amount: usize) - -> io::Result<usize> - { - // Insert possibly remaining unpaired surrogate from last read. - let mut start = 0; - if self.high_surrogate.get() != 0 { - buf[0] = self.high_surrogate.replace(0); - start = 1; - if amount == 1 { - // Special case: `Stdin::read` guarantees we can always read at least one new `u16` - // and combine it with an unpaired surrogate, because the UTF-8 buffer is at least - // 4 bytes. - amount = 2; - } + +// We assume that if the last `u16` is an unpaired surrogate they got sliced apart by our +// buffer size, and keep it around for the next read hoping to put them together. +// This is a best effort, and may not work if we are not the only reader on Stdin. +fn read_u16s_fixup_surrogates(handle: c::HANDLE, + buf: &mut [u16], + mut amount: usize, + surrogate: &mut u16) -> io::Result<usize> +{ + // Insert possibly remaining unpaired surrogate from last read. + let mut start = 0; + if *surrogate != 0 { + buf[0] = *surrogate; + *surrogate = 0; + start = 1; + if amount == 1 { + // Special case: `Stdin::read` guarantees we can always read at least one new `u16` + // and combine it with an unpaired surrogate, because the UTF-8 buffer is at least + // 4 bytes. + amount = 2; } - let mut amount = read_u16s(handle, &mut buf[start..amount])? + start; + } + let mut amount = read_u16s(handle, &mut buf[start..amount])? + start; - if amount > 0 { - let last_char = buf[amount - 1]; - if last_char >= 0xD800 && last_char <= 0xDBFF { // high surrogate - self.high_surrogate.set(last_char); - amount -= 1; - } + if amount > 0 { + let last_char = buf[amount - 1]; + if last_char >= 0xD800 && last_char <= 0xDBFF { // high surrogate + *surrogate = last_char; + amount -= 1; } - Ok(amount) } + Ok(amount) } fn read_u16s(handle: c::HANDLE, buf: &mut [u16]) -> io::Result<usize> { @@ -241,12 +246,14 @@ impl Stdout { pub fn new() -> io::Result<Stdout> { Ok(Stdout) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { - write(c::STD_OUTPUT_HANDLE, data) +impl io::Write for Stdout { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + write(c::STD_OUTPUT_HANDLE, buf) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } @@ -255,12 +262,14 @@ impl Stderr { pub fn new() -> io::Result<Stderr> { Ok(Stderr) } +} - pub fn write(&self, data: &[u8]) -> io::Result<usize> { - write(c::STD_ERROR_HANDLE, data) +impl io::Write for Stderr { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + write(c::STD_ERROR_HANDLE, buf) } - pub fn flush(&self) -> io::Result<()> { + fn flush(&mut self) -> io::Result<()> { Ok(()) } } |
