use std::io::{stdout, Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
use std::hash::{Hash, Hasher};
use std::net::{Shutdown, TcpStream};
+use std::ops::DerefMut;
use std::rc::Rc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
}
#[derive(Debug, Clone)]
-struct WrappedStreamInstance(Rc<RefCell<StreamInstance>>);
+struct WrappedStreamInstance(Rc<RefCell<(bool, StreamInstance)>>);
impl WrappedStreamInstance {
#[inline]
fn new(stream_inst: StreamInstance) -> Self {
- WrappedStreamInstance(Rc::new(RefCell::new(stream_inst)))
+ WrappedStreamInstance(
+ Rc::new(RefCell::new((false, stream_inst)))
+ )
}
}
#[derive(Debug, Clone, Hash)]
pub struct Stream {
- pub past_end_of_stream: bool,
pub options: StreamOptions,
stream_inst: WrappedStreamInstance,
}
#[inline]
pub(crate)
fn position(&mut self) -> Option<u64> {
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::InputFile(_, ref mut file) => {
file.seek(SeekFrom::Current(0)).ok()
}
}
}
+ #[inline]
+ pub(crate)
+ fn past_end_of_stream(&self) -> bool {
+ self.stream_inst.0.borrow_mut().0
+ }
+
+ #[inline]
+ pub(crate)
+ fn set_past_end_of_stream(&mut self) {
+ self.stream_inst.0.borrow_mut().0 = true;
+ }
+
#[inline]
pub(crate)
fn position_relative_to_end(&mut self) -> AtEndOfStream {
- if self.past_end_of_stream {
+ if self.past_end_of_stream() {
return AtEndOfStream::Past;
}
- match *self.stream_inst.0.borrow_mut() {
- StreamInstance::InputFile(_, ref mut file) => {
+ match self.stream_inst.0.borrow_mut().deref_mut() {
+ (past_end_of_stream, StreamInstance::InputFile(_, ref mut file)) => {
match file.metadata() {
Ok(metadata) => {
if let Ok(position) = file.seek(SeekFrom::Current(0)) {
AtEndOfStream::Not
}
Ordering::Greater => {
- self.past_end_of_stream = true;
+ *past_end_of_stream = true; //self.set_past_end_of_stream();
AtEndOfStream::Past
}
};
} else {
- self.past_end_of_stream = true;
+ *past_end_of_stream = true; //self.set_past_end_of_stream();
AtEndOfStream::Past
}
}
_ => {
- self.past_end_of_stream = true;
+ *past_end_of_stream = true; //self.set_past_end_of_stream();
AtEndOfStream::Past
}
}
#[inline]
pub(crate)
fn file_name(&self) -> Option<ClauseName> {
- match *self.stream_inst.0.borrow() {
+ match self.stream_inst.0.borrow().1 {
StreamInstance::InputFile(ref name, _) => {
Some(name.clone())
}
#[inline]
pub(crate)
fn mode(&self) -> &'static str {
- match *self.stream_inst.0.borrow() {
+ match self.stream_inst.0.borrow().1 {
StreamInstance::Bytes(_) |
StreamInstance::ReadlineStream(_) |
StreamInstance::DynReadSource(_) |
#[inline]
fn from_inst(stream_inst: StreamInstance) -> Self {
Stream {
- past_end_of_stream: false,
options: StreamOptions::default(),
stream_inst: WrappedStreamInstance::new(stream_inst)
}
#[inline]
pub(crate)
fn is_stdout(&self) -> bool {
- match *self.stream_inst.0.borrow() {
+ match self.stream_inst.0.borrow().1 {
StreamInstance::Stdout => {
true
}
#[inline]
pub(crate)
fn is_stdin(&self) -> bool {
- match *self.stream_inst.0.borrow() {
+ match self.stream_inst.0.borrow().1 {
//StreamInstance::Stdin |
StreamInstance::ReadlineStream(_) => {
true
#[inline]
pub(crate)
fn close(&mut self) {
- *self.stream_inst.0.borrow_mut() = StreamInstance::Null;
- self.past_end_of_stream = true;
+ self.stream_inst.0.borrow_mut().1 = StreamInstance::Null;
}
#[inline]
pub(crate)
fn is_null_stream(&self) -> bool {
- if let StreamInstance::Null = *self.stream_inst.0.borrow() {
+ if let StreamInstance::Null = self.stream_inst.0.borrow().1 {
true
} else {
false
#[inline]
pub(crate)
fn is_input_stream(&self) -> bool {
- match *self.stream_inst.0.borrow() {
+ match self.stream_inst.0.borrow().1 {
// StreamInstance::Stdin |
StreamInstance::TcpStream(..) |
StreamInstance::Bytes(_) |
#[inline]
pub(crate)
fn is_output_stream(&self) -> bool {
- match *self.stream_inst.0.borrow() {
+ match self.stream_inst.0.borrow().1 {
StreamInstance::Stdout
| StreamInstance::TcpStream(..)
| StreamInstance::Bytes(_)
// returns true on success.
#[inline]
fn reset(&mut self) -> bool {
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::Bytes(ref mut cursor) => {
cursor.set_position(0);
true
#[inline]
pub(crate)
fn peek_byte(&mut self) -> std::io::Result<u8> {
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::Bytes(ref mut cursor) => {
let mut b = [0u8; 1];
let pos = cursor.position();
fn peek_char(&mut self) -> std::io::Result<char> {
use unicode_reader::CodePoints;
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::InputFile(_, ref mut file) => {
let c = {
let mut iter = CodePoints::from(&*file);
) -> CallResult {
match stream.options.eof_action {
EOFAction::Error => {
- stream.past_end_of_stream = true;
+ stream.set_past_end_of_stream();
return Err(self.open_past_eos_error(stream.clone(), caller, arity));
}
EOFAction::EOFCode => {
HeapCellValue::Atom(clause_name!("end_of_file"), None)
);
- stream.past_end_of_stream = true;
+ stream.set_past_end_of_stream();
Ok(self.unify(result, end_of_stream))
}
EOFAction::Reset => {
- stream.past_end_of_stream = !stream.reset();
- Ok(self.fail = stream.past_end_of_stream)
+ if !stream.reset() {
+ stream.set_past_end_of_stream();
+ }
+
+ Ok(self.fail = stream.past_end_of_stream())
}
}
}
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, ref spec) = self.heap.clone(h) {
match indices.stream_aliases.get(atom) {
- Some(stream) => {
+ Some(stream) if !stream.is_null_stream() => {
stream.clone()
}
- None => {
+ _ => {
let stub = MachineError::functor_stub(clause_name!(caller), arity);
let addr = self.heap.to_unifiable(
}
if let Some(input) = input {
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
self.eof_action(
input,
stream,
impl Read for Stream {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::InputFile(_, ref mut file) => {
file.read(buf)
}
impl Write for Stream {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::OutputFile(_, ref mut file, _) => {
file.write(buf)
}
}
fn flush(&mut self) -> std::io::Result<()> {
- match *self.stream_inst.0.borrow_mut() {
+ match self.stream_inst.0.borrow_mut().1 {
StreamInstance::OutputFile(_, ref mut file, _) => {
file.flush()
}
2,
)?;
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options.eof_action {
return return_from_clause!(self.last_call, self);
} else if self.fail {
2,
)?;
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options.eof_action {
return return_from_clause!(self.last_call, self);
} else if self.fail {
2,
)?;
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options.eof_action {
return return_from_clause!(self.last_call, self);
} else if self.fail {
2,
)?;
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options.eof_action {
return return_from_clause!(self.last_call, self);
} else if self.fail {
2,
)?;
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options.eof_action {
return return_from_clause!(self.last_call, self);
} else if self.fail {
2,
)?;
- if stream.past_end_of_stream {
+ if stream.past_end_of_stream() {
if EOFAction::Reset != stream.options.eof_action {
return return_from_clause!(self.last_call, self);
} else if self.fail {
indices.streams.insert(current_output_stream.clone());
}
- stream.close();
+ if !stream.is_stdin() && !stream.is_stdout() {
+ stream.close();
- if let Some(alias) = stream.options.alias {
- indices.stream_aliases.remove(&alias);
+ if let Some(alias) = stream.options.alias {
+ indices.stream_aliases.remove(&alias);
+ }
}
}
&SystemClauseType::CopyToLiftedHeap => {