Class: OpenDal::IO
- Inherits:
-
Object
- Object
- OpenDal::IO
- Defined in:
- src/io.rs,
lib/opendal_ruby/io.rb
Overview
OpenDal::IO
is similar to Ruby's IO
and StringIO
for accessing files.
You can't create an instance of OpenDal::IO
except using Operator#open.
Constraints:
- Only available for reading and writing
- Writing doesn't support seek.
Instance Method Summary collapse
-
#binmode ⇒ nil
Enables binary mode for the stream.
-
#binmode? ⇒ Boolean
Returns if the stream is on binary mode.
-
#close ⇒ nil
Close streams.
-
#close_read ⇒ nil
Closes the read stream.
-
#close_write ⇒ nil
Closes the write stream.
-
#closed? ⇒ Boolean
Returns if streams are closed.
-
#closed_read? ⇒ Boolean
Returns if the read stream is closed.
-
#closed_write? ⇒ Boolean
Returns if the write stream is closed.
-
#eof ⇒ Boolean
(also: #eof?)
Checks if the stream is at the end of the file.
-
#length ⇒ Integer
(also: #size)
Returns the total length of the stream.
-
#pos=(new_position) ⇒ Object
Sets the file position to
new_position
. -
#readline ⇒ String
Reads a single line from the stream.
-
#readlines ⇒ Array<String>
Reads all lines from the stream into an array.
-
#rewind ⇒ Object
Rewinds the stream to the beginning.
-
#seek(offset, whence) ⇒ Integer
Moves the file position based on the offset and whence.
-
#tell ⇒ Integer
(also: #pos)
Returns the current reader_position of the file pointer in the stream.
-
#write(buffer) ⇒ Integer
Writes data to the stream.
Instance Method Details
#binmode ⇒ nil
Enables binary mode for the stream.
136 137 138 139 140 141 142 143 |
# File 'src/io.rs', line 136
fn binary_mode(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
let mut handle = rb_self.0.borrow_mut();
if let FileState::Closed = handle.state {
return Err(Error::new(ruby.exception_io_error(), "closed stream"));
}
handle.fmode = FMode::new(handle.fmode.bits() | FMode::BINARY_MODE);
Ok(())
}
|
#binmode? ⇒ Boolean
Returns if the stream is on binary mode.
150 151 152 153 154 155 156 |
# File 'src/io.rs', line 150
fn is_binary_mode(ruby: &Ruby, rb_self: &Self) -> Result<bool, Error> {
let handle = rb_self.0.borrow();
if let FileState::Closed = handle.state {
return Err(Error::new(ruby.exception_io_error(), "closed stream"));
}
Ok(handle.fmode.contains(FMode::BINARY_MODE))
}
|
#close ⇒ nil
Close streams.
162 163 164 165 166 167 168 169 |
# File 'src/io.rs', line 162
fn close(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
let mut handle = rb_self.0.borrow_mut();
if let FileState::Writer(writer) = &mut handle.state {
writer.close().map_err(|err| format_io_error(ruby, err))?;
}
handle.state = FileState::Closed;
Ok(())
}
|
#close_read ⇒ nil
Closes the read stream.
175 176 177 178 179 180 181 |
# File 'src/io.rs', line 175
fn close_read(&self) -> Result<(), Error> {
let mut handle = self.0.borrow_mut();
if let FileState::Reader(_) = &handle.state {
handle.state = FileState::Closed;
}
Ok(())
}
|
#close_write ⇒ nil
Closes the write stream.
187 188 189 190 191 192 193 194 |
# File 'src/io.rs', line 187
fn close_write(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
let mut handle = rb_self.0.borrow_mut();
if let FileState::Writer(writer) = &mut handle.state {
writer.close().map_err(|err| format_io_error(ruby, err))?;
handle.state = FileState::Closed;
}
Ok(())
}
|
#closed? ⇒ Boolean
Returns if streams are closed.
200 201 202 203 |
# File 'src/io.rs', line 200
fn is_closed(&self) -> Result<bool, Error> {
let handle = self.0.borrow();
Ok(matches!(handle.state, FileState::Closed))
}
|
#closed_read? ⇒ Boolean
Returns if the read stream is closed.
209 210 211 212 |
# File 'src/io.rs', line 209
fn is_closed_read(&self) -> Result<bool, Error> {
let handle = self.0.borrow();
Ok(!matches!(handle.state, FileState::Reader(_)))
}
|
#closed_write? ⇒ Boolean
Returns if the write stream is closed.
218 219 220 221 222 |
# File 'src/io.rs', line 218
fn is_closed_write(&self) -> Result<bool, Error> {
let handle = self.0.borrow();
Ok(!matches!(handle.state, FileState::Writer(_)))
}
}
|
#eof ⇒ Boolean Also known as: eof?
Checks if the stream is at the end of the file.
52 53 54 55 56 |
# File 'lib/opendal_ruby/io.rb', line 52 def eof position = tell seek(0, ::IO::SEEK_END) tell == position end |
#length ⇒ Integer Also known as: size
Returns the total length of the stream.
62 63 64 65 66 |
# File 'lib/opendal_ruby/io.rb', line 62 def length current_position = tell seek(0, ::IO::SEEK_END) tell.tap { self.pos = current_position } end |
#pos=(new_position) ⇒ Object
Sets the file position to new_position
.
44 45 46 |
# File 'lib/opendal_ruby/io.rb', line 44 def pos=(new_position) seek(new_position, ::IO::SEEK_SET) end |
#readline ⇒ String
Reads a single line from the stream.
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'src/io.rs', line 289
fn readline(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
let mut handle = rb_self.0.borrow_mut();
if let FileState::Reader(reader) = &mut handle.state {
let mut buffer = String::new();
let size = reader
.read_line(&mut buffer)
.map_err(|err| format_io_error(ruby, err))?;
if size == 0 {
return Err(Error::new(
ruby.exception_eof_error(),
"end of file reached",
));
}
Ok(buffer)
} else {
Err(Error::new(
ruby.exception_runtime_error(),
"I/O operation failed for reading on write-only file.",
))
}
}
|
#readlines ⇒ Array<String>
Reads all lines from the stream into an array.
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/opendal_ruby/io.rb', line 25 def readlines results = [] loop do results << readline rescue EOFError break end results end |
#rewind ⇒ Object
Rewinds the stream to the beginning.
38 39 40 |
# File 'lib/opendal_ruby/io.rb', line 38 def rewind seek(0, ::IO::SEEK_SET) end |
#seek(offset, whence) ⇒ Integer
Moves the file position based on the offset and whence.
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'src/io.rs', line 347
fn seek(ruby: &Ruby, rb_self: &Self, offset: i64, whence: u8) -> Result<u8, Error> {
let mut handle = rb_self.0.borrow_mut();
if let FileState::Reader(reader) = &mut handle.state {
// Calculate the new position first
let new_reader_position = match whence {
0 => {
// SEEK_SET - absolute position
if offset < 0 {
return Err(Error::new(
ruby.exception_runtime_error(),
"Cannot seek to negative reader_position.",
));
}
offset as u64
}
1 => {
// SEEK_CUR - relative to current position
let position = reader
.stream_position()
.map_err(|err| format_io_error(ruby, err))?;
if offset < 0 && (-offset as u64) > position {
return Err(Error::new(
ruby.exception_runtime_error(),
"Cannot seek before start of stream.",
));
}
(position as i64 + offset) as u64
}
2 => {
// SEEK_END
let end_pos = reader
.seek(SeekFrom::End(0))
.map_err(|err| format_io_error(ruby, err))?;
if offset < 0 && (-offset as u64) > end_pos {
return Err(Error::new(
ruby.exception_runtime_error(),
"Cannot seek before start of stream.",
));
}
(end_pos as i64 + offset) as u64
}
_ => return Err(Error::new(ruby.exception_arg_error(), "invalid whence")),
};
let _ = reader.seek(std::io::SeekFrom::Start(new_reader_position));
} else {
return Err(Error::new(
ruby.exception_runtime_error(),
"Cannot seek from end on write-only stream.",
));
}
Ok(0)
}
|
#tell ⇒ Integer Also known as: pos
Returns the current reader_position of the file pointer in the stream.
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'src/io.rs', line 408
fn tell(ruby: &Ruby, rb_self: &Self) -> Result<u64, Error> {
let mut handle = rb_self.0.borrow_mut();
match &mut handle.state {
FileState::Reader(reader) => Ok(reader
.stream_position()
.map_err(|err| format_io_error(ruby, err))?),
FileState::Writer(_) => Err(Error::new(
ruby.exception_runtime_error(),
"I/O operation failed for reading on write only file.",
)),
FileState::Closed => Err(Error::new(
ruby.exception_runtime_error(),
"I/O operation failed for tell on closed stream.",
)),
}
}
|
#write(buffer) ⇒ Integer
Writes data to the stream.
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'src/io.rs', line 318
fn write(ruby: &Ruby, rb_self: &Self, bs: String) -> Result<usize, Error> {
let mut handle = rb_self.0.borrow_mut();
if let FileState::Writer(writer) = &mut handle.state {
let bytes_written = bs.len();
writer
.write_all(bs.as_bytes())
.map_err(|err| format_io_error(ruby, err))?;
Ok(bytes_written)
} else {
Err(Error::new(
ruby.exception_runtime_error(),
"I/O operation failed for writing on read-only file.",
))
}
}
}
|