Class: Obuf::Lens

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/obuf/lens.rb

Overview

Provides a per-object iterator on top of any IO object or pipe

Direct Known Subclasses

ProtectedLens

Constant Summary collapse

NothingToRecover =
Class.new(StandardError)
DELIM =
"\t"
END_RECORD =
"\n"

Instance Method Summary collapse

Constructor Details

#initialize(io_or_pipe) ⇒ Lens

Creates a new Lens on top of a File object, IO object or pipe. The object given should support seek, gets, and read to recover objects, and write to dump objects.



14
15
16
# File 'lib/obuf/lens.rb', line 14

def initialize(io_or_pipe)
  @io = io_or_pipe
end

Instance Method Details

#<<(object_to_store) ⇒ Object

Store an object



19
20
21
22
23
24
25
26
# File 'lib/obuf/lens.rb', line 19

def <<(object_to_store)
  blob = marshal_object(object_to_store)
  @io.write(blob.size)
  @io.write(DELIM)
  @io.write(blob)
  @io.write(END_RECORD)
  object_to_store
end

#eachObject



55
56
57
58
59
60
# File 'lib/obuf/lens.rb', line 55

def each
  begin
    loop { yield(recover_object) }
  rescue NothingToRecover
  end
end

#recover_at(idx) ⇒ Object

Recover Nth object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/obuf/lens.rb', line 29

def recover_at(idx)
  @io.seek(0)
  # Do not unmarshal anything but wind the IO in fixed offsets
  idx.times do
    skip_bytes = @io.gets("\t").to_i
    @io.seek(@io.pos + skip_bytes + 1)
  end
  
  recover_object
rescue NothingToRecover # TODO: we need to honor this exception in the future
  nil
end

#recover_objectObject

Recover the object at the current position in the IO. Returns nil if there is nothing to recover or the backing buffer is empty.

Raises:



44
45
46
47
48
49
50
51
52
53
# File 'lib/obuf/lens.rb', line 44

def recover_object
  # Up to the tab is the amount of bytes to read
  demarshal_bytes = @io.gets("\t").to_i
  
  # When at end of IO return nil
  raise NothingToRecover if demarshal_bytes.zero?
  
  blob = @io.read(demarshal_bytes)
  demarshal_object(blob)
end