Class: OpenDAL::IO

Inherits:
Object
  • Object
show all
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.

Instance Method Summary collapse

Instance Method Details

#binmodenil

Enables binary mode for the stream.

Returns:

  • (nil)

Raises:

  • (IOError)

    when operate on a closed stream



117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'src/io.rs', line 117

fn binary_mode(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
    let mut cell = rb_self.0.borrow_mut();
    match &mut *cell {
        FileState::Reader(_, ref mut is_binary_mode) => {
            *is_binary_mode = true;
            Ok(())
        }
        FileState::Writer(_, ref mut is_binary_mode) => {
            *is_binary_mode = true;
            Ok(())
        }
        FileState::Closed => Err(Error::new(ruby.exception_io_error(), "closed stream")),
    }
}

#binmode?Boolean

Returns if the stream is on binary mode.

Returns:

  • (Boolean)

Raises:

  • (IOError)

    when operate on a closed stream



137
138
139
140
141
142
143
# File 'src/io.rs', line 137

fn is_binary_mode(ruby: &Ruby, rb_self: &Self) -> Result<bool, Error> {
    match *rb_self.0.borrow() {
        FileState::Reader(_, is_binary_mode) => Ok(is_binary_mode),
        FileState::Writer(_, is_binary_mode) => Ok(is_binary_mode),
        FileState::Closed => Err(Error::new(ruby.exception_io_error(), "closed stream")),
    }
}

#closenil

Close streams.

Returns:

  • (nil)


149
150
151
152
153
154
155
156
157
# File 'src/io.rs', line 149

fn close(&self) -> Result<(), Error> {
    // skips closing reader because `StdReader` doesn't have `close()`.
    let mut cell = self.0.borrow_mut();
    if let FileState::Writer(writer, _) = &mut *cell {
        writer.close().map_err(format_io_error)?;
    }
    *cell = FileState::Closed;
    Ok(())
}

#close_readnil

Closes the read stream.

Returns:

  • (nil)


163
164
165
166
# File 'src/io.rs', line 163

fn close_read(&self) -> Result<(), Error> {
    *self.0.borrow_mut() = FileState::Closed;
    Ok(())
}

#close_writenil

Closes the write stream.

Returns:

  • (nil)


172
173
174
175
176
177
178
179
# File 'src/io.rs', line 172

fn close_write(&self) -> Result<(), Error> {
    let mut cell = self.0.borrow_mut();
    if let FileState::Writer(writer, _) = &mut *cell {
        writer.close().map_err(format_io_error)?;
    }
    *cell = FileState::Closed;
    Ok(())
}

#closed?Boolean

Returns if streams are closed.

Returns:

  • (Boolean)


185
186
187
# File 'src/io.rs', line 185

fn is_closed(&self) -> Result<bool, Error> {
    Ok(matches!(*self.0.borrow(), FileState::Closed))
}

#closed_read?Boolean

Returns if the read stream is closed.

Returns:

  • (Boolean)


193
194
195
# File 'src/io.rs', line 193

fn is_closed_read(&self) -> Result<bool, Error> {
    Ok(!matches!(*self.0.borrow(), FileState::Reader(_, _)))
}

#closed_write?Boolean

Returns if the write stream is closed.

Returns:

  • (Boolean)


201
202
203
204
# File 'src/io.rs', line 201

fn is_closed_write(&self) -> Result<bool, Error> {
        Ok(!matches!(*self.0.borrow(), FileState::Writer(_, _)))
    }
}

#eofBoolean Also known as: eof?

Checks if the stream is at the end of the file.

Returns:

  • (Boolean)


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

#lengthInteger Also known as: size

Returns the total length of the stream.

Returns:

  • (Integer)


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.

Parameters:

  • new_position (Integer)


44
45
46
# File 'lib/opendal_ruby/io.rb', line 44

def pos=(new_position)
  seek(new_position, ::IO::SEEK_SET)
end

#readlineString

Reads a single line from the stream.

Returns:

  • (String)


244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'src/io.rs', line 244

fn readline(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
    if let FileState::Reader(reader, _) = &mut *rb_self.0.borrow_mut() {
        let mut buffer = String::new();
        let size = reader.read_line(&mut buffer).map_err(format_io_error)?;
        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 closed file.",
        ))
    }
}

#readlinesArray<String>

Reads all lines from the stream into an array.

Returns:

  • (Array<String>)

Raises:

  • (EOFError)

    when the end of the file is reached.



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

#rewindObject

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.

Parameters:

  • offset (Integer)

    The position offset.

  • whence (Integer)

    The reference point:

    • 0 = IO:SEEK_SET (Start)
    • 1 = IO:SEEK_CUR (Current position)
    • 2 = IO:SEEK_END (From the end)

Returns:

  • (Integer)

    always 0 if the seek operation is successful



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'src/io.rs', line 294

fn seek(ruby: &Ruby, rb_self: &Self, offset: i64, whence: u8) -> Result<u8, Error> {
    match &mut *rb_self.0.borrow_mut() {
        FileState::Reader(reader, _) => {
            let whence = match whence {
                0 => SeekFrom::Start(offset as u64),
                1 => SeekFrom::Current(offset),
                2 => SeekFrom::End(offset),
                _ => return Err(Error::new(ruby.exception_arg_error(), "invalid whence")),
            };

            reader.seek(whence).map_err(format_io_error)?;

            Ok(0)
        }
        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 reading on closed file.",
        )),
    }
}

#tellInteger Also known as: pos

Returns the current position of the file pointer in the stream.

Returns:

  • (Integer)

    the current position in bytes

Raises:

  • (IOError)

    when cannot operate on the operation mode



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'src/io.rs', line 324

fn tell(ruby: &Ruby, rb_self: &Self) -> Result<u64, Error> {
    match &mut *rb_self.0.borrow_mut() {
        FileState::Reader(reader, _) => {
            Ok(reader.stream_position().map_err(format_io_error)?)
        }
        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 reading on closed file.",
        )),
    }
}

#write(buffer) ⇒ Integer

Writes data to the stream.

Parameters:

  • buffer (String)

Returns:

  • (Integer)

    the written byte size



269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'src/io.rs', line 269

fn write(ruby: &Ruby, rb_self: &Self, bs: String) -> Result<usize, Error> {
        if let FileState::Writer(writer, _) = &mut *rb_self.0.borrow_mut() {
            Ok(writer
                .write_all(bs.as_bytes())
                .map(|_| bs.len())
                .map_err(format_io_error)?)
        } else {
            Err(Error::new(
                ruby.exception_runtime_error(),
                "I/O operation failed for reading on write only file.",
            ))
        }
    }
}