add set_stream_position/2

This commit is contained in:
Mark Thom
2020-05-09 14:20:32 -06:00
parent 034f5b16bd
commit 6f927b9941
5 changed files with 88 additions and 5 deletions

View File

@@ -468,9 +468,11 @@ pub enum Permission {
Modify,
Open,
OutputStream,
Reposition,
}
impl Permission {
#[inline]
pub fn as_str(self) -> &'static str {
match self {
Permission::Access => "access",
@@ -479,6 +481,7 @@ impl Permission {
Permission::Modify => "modify",
Permission::Open => "open",
Permission::OutputStream => "output",
Permission::Reposition => "reposition",
}
}
}

View File

@@ -27,6 +27,15 @@ impl StreamType {
#[inline]
pub(crate)
fn as_str(&self) -> &'static str {
match self {
StreamType::Binary => "binary_stream",
StreamType::Text => "text_stream",
}
}
#[inline]
pub(crate)
fn as_property_str(&self) -> &'static str {
match self {
StreamType::Binary => "binary",
StreamType::Text => "text",
@@ -296,6 +305,22 @@ impl Stream {
}
}
#[inline]
pub(crate)
fn set_position(&mut self, position: u64) {
match self.stream_inst.0.borrow_mut().deref_mut() {
(past_end_of_stream, StreamInstance::InputFile(_, ref mut file)) => {
file.seek(SeekFrom::Start(position)).unwrap();
if let Ok(metadata) = file.metadata() {
*past_end_of_stream = position > metadata.len();
}
}
_ => {
}
}
}
#[inline]
pub(crate)
fn past_end_of_stream(&self) -> bool {

View File

@@ -4556,6 +4556,49 @@ impl MachineState {
}
}
}
&SystemClauseType::SetStreamPosition => {
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
indices,
"set_stream_position",
2,
)?;
if !stream.options.reposition {
let stub = MachineError::functor_stub(clause_name!("set_stream_position"), 2);
let err = MachineError::permission_error(
self.heap.h(),
Permission::Reposition,
"stream",
vec![HeapCellValue::Stream(stream)],
);
return Err(self.error_form(err, stub));
}
let position = self.store(self.deref(self[temp_v!(2)]));
let position =
match Number::try_from((position, &self.heap)) {
Ok(Number::Fixnum(n)) => {
n as u64
}
Ok(Number::Integer(n)) => {
if let Some(n) = n.to_u64() {
n
} else {
self.fail = true;
return Ok(());
}
}
_ => {
unreachable!()
}
};
stream.set_position(position);
}
&SystemClauseType::StreamProperty => {
let mut stream = self.get_stream_or_alias(
self[temp_v!(1)],
@@ -4648,7 +4691,7 @@ impl MachineState {
}
"type" => {
HeapCellValue::Atom(
clause_name!(stream.options.stream_type.as_str()),
clause_name!(stream.options.stream_type.as_property_str()),
None,
)
}