add set_stream_position/2
This commit is contained in:
@@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user