93 lines
3.1 KiB
Diff
93 lines
3.1 KiB
Diff
|
Index: lib/bindata/array.rb
|
||
|
===================================================================
|
||
|
--- lib/bindata/array.rb (revision 94)
|
||
|
+++ lib/bindata/array.rb (working copy)
|
||
|
@@ -27,6 +27,10 @@
|
||
|
# obj.read(data)
|
||
|
# obj.snapshot #=> [3, 4, 5, 6, 7]
|
||
|
#
|
||
|
+ # obj = BinData::Array.new(:type => :int8, :read_until => :eof)
|
||
|
+ # obj.read(data)
|
||
|
+ # obj.snapshot #=> [3, 4, 5, 6, 7, 8, 9]
|
||
|
+ #
|
||
|
# == Parameters
|
||
|
#
|
||
|
# Parameters may be provided at initialisation to control the behaviour of
|
||
|
@@ -42,7 +46,9 @@
|
||
|
# read an array until a sentinel value is found.
|
||
|
# The variables +index+, +element+ and +array+
|
||
|
# are made available to any lambda assigned to
|
||
|
- # this parameter.
|
||
|
+ # this parameter. If the value of this parameter
|
||
|
+ # is the symbol :eof, then the array will read
|
||
|
+ # as much data from the stream as possible.
|
||
|
#
|
||
|
# Each data object in an array has the variable +index+ made available
|
||
|
# to any lambda evaluated as a parameter of that data object.
|
||
|
@@ -249,15 +255,28 @@
|
||
|
def _do_read(io)
|
||
|
if has_param?(:initial_length)
|
||
|
elements.each { |f| f.do_read(io) }
|
||
|
- else # :read_until
|
||
|
- @element_list = nil
|
||
|
- loop do
|
||
|
- element = append_new_element
|
||
|
- element.do_read(io)
|
||
|
- variables = { :index => self.length - 1, :element => self.last,
|
||
|
- :array => self }
|
||
|
- finished = eval_param(:read_until, variables)
|
||
|
- break if finished
|
||
|
+ elsif has_param?(:read_until)
|
||
|
+ if param(:read_until) == :eof
|
||
|
+ @element_list = nil
|
||
|
+ loop do
|
||
|
+ element = append_new_element
|
||
|
+ begin
|
||
|
+ element.do_read(io)
|
||
|
+ rescue
|
||
|
+ @element_list.pop
|
||
|
+ break
|
||
|
+ end
|
||
|
+ end
|
||
|
+ else
|
||
|
+ @element_list = nil
|
||
|
+ loop do
|
||
|
+ element = append_new_element
|
||
|
+ element.do_read(io)
|
||
|
+ variables = { :index => self.length - 1, :element => self.last,
|
||
|
+ :array => self }
|
||
|
+ finished = eval_param(:read_until, variables)
|
||
|
+ break if finished
|
||
|
+ end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
Index: spec/array_spec.rb
|
||
|
===================================================================
|
||
|
--- spec/array_spec.rb (revision 92)
|
||
|
+++ spec/array_spec.rb (working copy)
|
||
|
@@ -264,6 +264,22 @@
|
||
|
end
|
||
|
end
|
||
|
|
||
|
+describe BinData::Array, "with :read_until => :eof" do
|
||
|
+ it "should read records until eof" do
|
||
|
+ obj = BinData::Array.new(:type => :int8, :read_until => :eof)
|
||
|
+ data = "\x01\x02\x03"
|
||
|
+ obj.read(data)
|
||
|
+ obj.snapshot.should == [1, 2, 3]
|
||
|
+ end
|
||
|
+
|
||
|
+ it "should read records until eof, ignoring partial records" do
|
||
|
+ obj = BinData::Array.new(:type => :int16be, :read_until => :eof)
|
||
|
+ data = "\x00\x01\x00\x02\x03"
|
||
|
+ obj.read(data)
|
||
|
+ obj.snapshot.should == [1, 2]
|
||
|
+ end
|
||
|
+end
|
||
|
+
|
||
|
describe BinData::Array, "of bits" do
|
||
|
before(:each) do
|
||
|
@data = BinData::Array.new(:type => :bit1, :initial_length => 15)
|
||
|
|