Class: FFI::Libfuse::FuseBufVec

Inherits:
Struct
  • Object
show all
Includes:
Accessors
Defined in:
lib/ffi/libfuse/fuse_buf_vec.rb

Overview

Data buffer vector

An list of io buffers, each containing a memory pointer or a file descriptor.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Accessors

#fill, included, #inspect, #to_h

Instance Attribute Details

#countInteger (readonly)

Returns the number of buffers in the array.

Returns:

  • (Integer)

    the number of buffers in the array



# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 29

#idxInteger (readonly) Also known as: index

Returns index of current buffer within the array.

Returns:

  • (Integer)

    index of current buffer within the array



35
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 35

alias index idx

#offInteger (readonly) Also known as: offset

Returns current offset within the current buffer.

Returns:

  • (Integer)

    current offset within the current buffer



40
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 40

alias offset off

Class Method Details

.create(io, size, offset = nil) ⇒ FuseBufVec

Note:

The returned object's memory is not auto-released, and thus suitable for use with FFI::Libfuse::FuseOperations#read_buf where the buffers are cleared by libfuse library..

Create and initialise from a ruby object that quacks like File, IO, or String

Parameters:

  • io (Object)
    • Integer file descriptor or File like object that returns one via :fileno
    • Otherwise something to pass to IO.read(io, size, offset) to create a memory based buffer
  • size (Integer)
  • offset (Integer) (defaults to: nil)

Returns:



55
56
57
58
59
60
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 55

def self.create(io, size, offset = nil)
  fd = io.respond_to?(:fileno) ? io.fileno : io
  return init(autorelease: false, size: size, fd: fd, pos: offset || 0) if fd.is_a?(Integer)

  init(autorelease: false, str: Libfuse::IO.read(io, size, offset))
end

.init(autorelease: true, count: 1, **buf_options) ⇒ FuseBufVec

Create and initialise a new FuseBufVec

Parameters:

Returns:



69
70
71
72
73
74
75
76
77
78
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 69

def self.init(autorelease: true, count: 1, **buf_options)
  bufvec_ptr = FFI::MemoryPointer.new(:uchar, FuseBufVec.size + (FuseBuf::Native.size * (count - 1)), true)
  bufvec_ptr.autorelease = autorelease
  bufvec = new(bufvec_ptr)
  bufvec[:count] = count
  bufvec[:idx] = 0
  bufvec[:off] = 0
  bufvec.buffers[0].fill(**buf_options) unless buf_options.empty?
  bufvec
end

Instance Method Details

#buf_sizeInteger

Returns total size of io in a fuse buffer vector (ie the size of all the fuse buffers).

Returns:

  • (Integer)

    total size of io in a fuse buffer vector (ie the size of all the fuse buffers)



81
82
83
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 81

def buf_size
  Libfuse.fuse_buf_size(self)
end

#buffersArray<FuseBuf>

Returns list of buffers.

Returns:

  • (Array<FuseBuf>)

    list of buffers



209
210
211
212
213
214
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 209

def buffers
  @buffers ||= Array.new(count) do |i|
    native = i.zero? ? self[:buf].first : FuseBuf::Native.new(self[:buf].to_ptr + (i * FuseBuf::Native.size))
    FuseBuf.new(native)
  end.freeze
end

#copy_from(src, *flags) ⇒ Integer

Copy from another set of buffers to this one

Parameters:

  • src (FuseBufVec)

    source buffers

  • flags (Array<Symbol>)

Returns:

  • (Integer)

    number of bytes written

See Also:



164
165
166
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 164

def copy_from(src, *flags)
  Libfuse.fuse_buf_copy(self, src, flags)
end

#copy_to(dst, *flags) ⇒ Integer

Copy data from this set of buffers to another set

Parameters:

  • dst (FuseBufVec)

    destination buffers

  • flags (Array<Symbol>)

    Buffer copy flags

    • :no_splice Don't use splice(2)

    Always fall back to using read and write instead of splice(2) to copy io from one file descriptor to another.

    If this flag is not set, then only fall back if splice is unavailable.

    • :force_splice

    Always use splice(2) to copy io from one file descriptor to another. If splice is not available, return -EINVAL.

    • :splice_move

    Try to move io with splice.

    If splice is used, try to move pages from the source to the destination instead of copying. See documentation of SPLICE_F_MOVE in splice(2) man page.

    • :splice_nonblock

    Don't block on the pipe when copying io with splice

    Makes the operations on the pipe non-blocking (if the pipe is full or empty). See SPLICE_F_NONBLOCK in the splice(2) man page.

Returns:

  • (Integer)

    actual number of bytes copied or -errno on error



136
137
138
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 136

def copy_to(dst, *flags)
  Libfuse.fuse_buf_copy(dst, self, flags)
end

#copy_to_fd(fileno, offset = nil, *flags) ⇒ Integer

Copy direct to file descriptor

Parameters:

  • fileno (Integer)

    a file descriptor

  • offset (nil, Integer) (defaults to: nil)

    if non nil will first seek to offset

  • flags (Array<Symbol>)

Returns:

  • (Integer)

    number of bytes copied



145
146
147
148
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 145

def copy_to_fd(fileno, offset = nil, *flags)
  dst = self.class.init(size: buf_size, fd: fileno, pos: offset)
  copy_to(dst, *flags)
end

#copy_to_io(io, *flags) ⇒ Integer #copy_to_io(io, offset = nil, *flags) ⇒ Integer

Write data from these buffers to another object

Parameters:

  • io (Object)

    one of

  • offset (nil, Integer) (defaults to: nil)

    position in io to begin writing at, or nil if io is already positioned

  • flags (Array<Symbol>)

Returns:

  • (Integer)

    number of bytes written

Raises:

  • (Errno::EBADF)

    if io is not a valid target



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 191

def copy_to_io(io, offset = nil, *flags)
  if offset.is_a?(Symbol)
    flags.unshift(offset)
    offset = nil
  end

  if io.is_a?(FuseBufVec)
    io.seek(offset) if offset
    return copy_to(io, *flags)
  end

  fd = (io.respond_to?(:fileno) ? io.fileno : io)
  return copy_to_fd(fd, offset || 0, *flags) if fd.is_a?(Integer)

  Libfuse::IO.write(io, copy_to_str(*flags), offset)
end

#copy_to_str(*flags) ⇒ String

Copy to string via a temporary buffer

Parameters:

  • flags (Array<Symbol>)

Returns:

  • (String)

    the extracted data



153
154
155
156
157
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 153

def copy_to_str(*flags)
  dst = self.class.init(size: buf_size)
  copied = copy_to(dst, *flags)
  dst.buffers.first.memory.read_string(copied)
end

#seek(pos) ⇒ self

Set #index/#offset for reading/writing from pos

Parameters:

  • pos (Integer)

Returns:

  • (self)

Raises:

  • (Errno::ERANGE)

    if seek past end of file



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 89

def seek(pos)
  buffers.each_with_index do |b, i|
    if pos < b.size
      self[:idx] = i
      self[:off] = pos
      return self
    else
      pos -= b.size
    end
  end
  raise Errno::ERANGE
end

#store_to(bufp) ⇒ void

This method returns an undefined value.

Store ourself into a pointer location as received by FFI::Libfuse::FuseOperations#read_buf

Parameters:



171
172
173
# File 'lib/ffi/libfuse/fuse_buf_vec.rb', line 171

def store_to(bufp)
  bufp.write_pointer(to_ptr)
end