Class: Rumai::IXP::Agent::FidStream

Inherits:
Object
  • Object
show all
Defined in:
lib/rumai/ixp/transport.rb

Overview

Note:

this class is NOT thread safe!

Encapsulates I/O access over a file handle (fid).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(agent, path_fid, message_size) ⇒ FidStream

Returns a new instance of FidStream.



243
244
245
246
247
248
249
250
# File 'lib/rumai/ixp/transport.rb', line 243

def initialize agent, path_fid, message_size
  @agent  = agent
  @fid    = path_fid
  @msize  = message_size
  @stat   = @agent.stat_fid(@fid)
  @closed = false
  rewind
end

Instance Attribute Details

#eofObject (readonly) Also known as: eof?

Returns the value of attribute eof.



237
238
239
# File 'lib/rumai/ixp/transport.rb', line 237

def eof
  @eof
end

#fidObject (readonly)

Returns the value of attribute fid.



235
236
237
# File 'lib/rumai/ixp/transport.rb', line 235

def fid
  @fid
end

#posObject Also known as: tell

Returns the value of attribute pos.



240
241
242
# File 'lib/rumai/ixp/transport.rb', line 240

def pos
  @pos
end

#statObject (readonly)

Returns the value of attribute stat.



235
236
237
# File 'lib/rumai/ixp/transport.rb', line 235

def stat
  @stat
end

Instance Method Details

#closeObject

Closes this stream.



263
264
265
266
267
268
269
# File 'lib/rumai/ixp/transport.rb', line 263

def close
  unless @closed
    @agent.clunk @fid
    @closed = true
    @eof = true
  end
end

#closed?Boolean

Returns true if this stream is closed.

Returns:

  • (Boolean)


274
275
276
# File 'lib/rumai/ixp/transport.rb', line 274

def closed?
  @closed
end

#read(partial = false) ⇒ Object

Reads some data from this stream at the current position. If this stream corresponds to a directory, then an Array of Stat (one for each file in the directory) will be returned.

Parameters:

  • partial (Boolean) (defaults to: false)

    When false, the entire content of this stream is read and returned.

    When true, the maximum amount of content that can fit inside a single 9P2000 message is read and returned.



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/rumai/ixp/transport.rb', line 291

def read partial = false
  raise 'cannot read from a closed stream' if @closed

  content = ''
  begin
    req = Tread.new(
      :fid    => @fid,
      :offset => @pos,
      :count  => @msize
    )
    rsp = @agent.talk(req)

    content << rsp.data
    count = rsp.count
    @pos += count
  end until @eof = count.zero? or partial

  # the content of a directory is a sequence
  # of Stat for all files in that directory
  if @stat.directory?
    buffer = StringIO.new(content)
    content = []

    until buffer.eof?
      content << Stat.from_9p(buffer)
    end
  end

  content
end

#rewindObject

Rewinds the stream to the beginning.



255
256
257
258
# File 'lib/rumai/ixp/transport.rb', line 255

def rewind
  @pos = 0
  @eof = false
end

#write(content) ⇒ Object Also known as: <<

Writes the given content at the current position in this stream.



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/rumai/ixp/transport.rb', line 325

def write content
  raise 'cannot write to a closed stream' if @closed
  raise 'cannot write to a directory' if @stat.directory?

  data = content.to_s
  limit = data.bytesize + @pos

  while @pos < limit
    chunk = data.byteslice(@pos, @msize)

    req = Twrite.new(
      :fid    => @fid,
      :offset => @pos,
      :count  => chunk.bytesize,
      :data   => chunk
    )
    rsp = @agent.talk(req)

    @pos += rsp.count
  end
end