bindata 1.4.0 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bindata might be problematic. Click here for more details.
- data/ChangeLog +6 -0
- data/lib/bindata.rb +2 -1
- data/lib/bindata/base.rb +11 -1
- data/lib/bindata/choice.rb +4 -2
- data/lib/bindata/count_bytes_remaining.rb +35 -0
- data/lib/bindata/io.rb +14 -0
- data/lib/bindata/lazy.rb +1 -21
- data/lib/bindata/params.rb +2 -2
- data/lib/bindata/sanitize.rb +5 -1
- data/manual.haml +11 -1
- data/manual.md +41 -6
- data/spec/choice_spec.rb +20 -0
- data/spec/count_bytes_remaining_spec.rb +41 -0
- data/spec/io_spec.rb +11 -0
- data/spec/lazy_spec.rb +47 -43
- metadata +6 -4
data/ChangeLog
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= BinData Changelog
|
2
2
|
|
3
|
+
== Version 1.4.1 (2011-06-20)
|
4
|
+
|
5
|
+
* Added :default option for Choices.
|
6
|
+
* Added count_bytes_remaining keyword.
|
7
|
+
* Increased speed of lazy evaluation.
|
8
|
+
|
3
9
|
== Version 1.4.0 (2011-06-14)
|
4
10
|
|
5
11
|
* Record#snapshot now returns fields in order.
|
data/lib/bindata.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
require 'bindata/array'
|
5
5
|
require 'bindata/bits'
|
6
6
|
require 'bindata/choice'
|
7
|
+
require 'bindata/count_bytes_remaining'
|
7
8
|
require 'bindata/float'
|
8
9
|
require 'bindata/int'
|
9
10
|
require 'bindata/primitive'
|
@@ -31,5 +32,5 @@ require 'bindata/deprecated'
|
|
31
32
|
#
|
32
33
|
# Copyright (c) 2007 - 2011 Dion Mendel.
|
33
34
|
module BinData
|
34
|
-
VERSION = "1.4.
|
35
|
+
VERSION = "1.4.1"
|
35
36
|
end
|
data/lib/bindata/base.rb
CHANGED
@@ -129,7 +129,17 @@ module BinData
|
|
129
129
|
#
|
130
130
|
# Returns nil if +key+ does not refer to any parameter.
|
131
131
|
def eval_parameter(key, overrides = nil)
|
132
|
-
|
132
|
+
value = get_parameter(key)
|
133
|
+
if value.is_a?(Symbol) or value.respond_to?(:arity)
|
134
|
+
lazy_evaluator.lazy_eval(value, overrides)
|
135
|
+
else
|
136
|
+
value
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns a lazy evaluator for this object.
|
141
|
+
def lazy_evaluator #:nodoc:
|
142
|
+
@lazy ||= LazyEvaluator.new(self)
|
133
143
|
end
|
134
144
|
|
135
145
|
# Returns the parameter referenced by +key+.
|
data/lib/bindata/choice.rb
CHANGED
@@ -49,7 +49,9 @@ module BinData
|
|
49
49
|
# is to have params passed to it, then it should
|
50
50
|
# be provided as [type_symbol, hash_params]. An
|
51
51
|
# implementation constraint is that the hash may
|
52
|
-
# not contain symbols as keys
|
52
|
+
# not contain symbols as keys, with the exception
|
53
|
+
# of :default. :default is to be used when then
|
54
|
+
# :selection does not exist in the :choices hash.
|
53
55
|
# <tt>:selection</tt>:: An index/key into the :choices array/hash which
|
54
56
|
# specifies the currently active choice.
|
55
57
|
# <tt>:copy_on_change</tt>:: If set to true, copy the value of the previous
|
@@ -98,7 +100,7 @@ module BinData
|
|
98
100
|
if choices.has_key?(nil)
|
99
101
|
raise ArgumentError, ":choices hash may not have nil key"
|
100
102
|
end
|
101
|
-
if choices.keys.detect { |key| key.is_a?(Symbol) }
|
103
|
+
if choices.keys.detect { |key| key.is_a?(Symbol) and key != :default }
|
102
104
|
raise ArgumentError, ":choices hash may not have symbols for keys"
|
103
105
|
end
|
104
106
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require "bindata/base_primitive"
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
# Counts the number of bytes remaining in the input stream from the current
|
5
|
+
# position to the end of the stream. This only makes sense for seekable
|
6
|
+
# streams.
|
7
|
+
#
|
8
|
+
# require 'bindata'
|
9
|
+
#
|
10
|
+
# class A < BinData::Record
|
11
|
+
# count_bytes_remaining :bytes_remaining
|
12
|
+
# string :all_data, :read_length => :bytes_remaining
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# obj = A.read("abcdefghij")
|
16
|
+
# obj.all_data #=> "abcdefghij"
|
17
|
+
#
|
18
|
+
class CountBytesRemaining < BinData::BasePrimitive
|
19
|
+
|
20
|
+
#---------------
|
21
|
+
private
|
22
|
+
|
23
|
+
def value_to_binary_string(val)
|
24
|
+
""
|
25
|
+
end
|
26
|
+
|
27
|
+
def read_and_return_value(io)
|
28
|
+
io.num_bytes_remaining
|
29
|
+
end
|
30
|
+
|
31
|
+
def sensible_default
|
32
|
+
0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/bindata/io.rb
CHANGED
@@ -67,6 +67,20 @@ module BinData
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
# The number of bytes remaining in the input stream.
|
71
|
+
def num_bytes_remaining
|
72
|
+
if positioning_supported?
|
73
|
+
pos = @raw_io.pos
|
74
|
+
@raw_io.seek(0, ::IO::SEEK_END)
|
75
|
+
bytes_remaining = @raw_io.pos - pos
|
76
|
+
@raw_io.seek(pos, ::IO::SEEK_SET)
|
77
|
+
|
78
|
+
bytes_remaining
|
79
|
+
else
|
80
|
+
0
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
70
84
|
# Seek +n+ bytes from the current position in the io stream.
|
71
85
|
def seekbytes(n)
|
72
86
|
reset_read_bits
|
data/lib/bindata/lazy.rb
CHANGED
@@ -19,26 +19,6 @@ module BinData
|
|
19
19
|
# <tt>field</tt> instead of <tt>obj.field</tt>.
|
20
20
|
class LazyEvaluator
|
21
21
|
|
22
|
-
class << self
|
23
|
-
# Lazily evaluates +val+ in the context of +obj+, with possibility of
|
24
|
-
# +overrides+.
|
25
|
-
def eval(obj, val, overrides = nil)
|
26
|
-
if can_eval?(val)
|
27
|
-
env = self.new(obj)
|
28
|
-
env.lazy_eval(val, overrides)
|
29
|
-
else
|
30
|
-
val
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
#-------------
|
35
|
-
private
|
36
|
-
|
37
|
-
def can_eval?(val)
|
38
|
-
val.is_a?(Symbol) or val.respond_to?(:arity)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
22
|
# Creates a new evaluator. All lazy evaluation is performed in the
|
43
23
|
# context of +obj+.
|
44
24
|
def initialize(obj)
|
@@ -59,7 +39,7 @@ module BinData
|
|
59
39
|
# Returns a LazyEvaluator for the parent of this data object.
|
60
40
|
def parent
|
61
41
|
if @obj.parent
|
62
|
-
|
42
|
+
@obj.parent.lazy_evaluator
|
63
43
|
else
|
64
44
|
nil
|
65
45
|
end
|
data/lib/bindata/params.rb
CHANGED
@@ -78,8 +78,8 @@ module BinData
|
|
78
78
|
@optional
|
79
79
|
end
|
80
80
|
|
81
|
-
def default(args =
|
82
|
-
if
|
81
|
+
def default(args = nil)
|
82
|
+
if args
|
83
83
|
to_syms(args.keys) # call for side effect of validating names
|
84
84
|
args.each_pair do |param, value|
|
85
85
|
@default[param.to_sym] = value
|
data/lib/bindata/sanitize.rb
CHANGED
data/manual.haml
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
%html{ :xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en" }
|
3
3
|
%head
|
4
4
|
%meta{ :content => "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
|
5
|
-
%meta{ :description =>"How to easily read and write binary data in Ruby" }
|
5
|
+
%meta{ :name => "description", :content =>"How to easily read and write binary data in Ruby" }
|
6
6
|
%meta{ :keywords =>"ruby, binary, binary data, parse binary data, read binary data, write binary data, binary file, read binary file, write binary file" }
|
7
7
|
%title
|
8
8
|
Reading, writing and parsing binary data in Ruby
|
@@ -299,6 +299,11 @@
|
|
299
299
|
Choice parameters
|
300
300
|
.acc-section
|
301
301
|
.acc-content
|
302
|
+
%li
|
303
|
+
%a{ :href => "#default_selection" }
|
304
|
+
Default Selection
|
305
|
+
.acc-section
|
306
|
+
.acc-content
|
302
307
|
%li
|
303
308
|
%a{ :href => "#advanced_topics" }
|
304
309
|
Advanced Topics
|
@@ -352,6 +357,11 @@
|
|
352
357
|
Skipping over unused data
|
353
358
|
.acc-section
|
354
359
|
.acc-content
|
360
|
+
%li
|
361
|
+
%a{ :href => "#determining_stream_length" }
|
362
|
+
Determining stream length
|
363
|
+
.acc-section
|
364
|
+
.acc-content
|
355
365
|
%li
|
356
366
|
%a{ :href => "#bitaligned_records" }
|
357
367
|
Bit-aligned Records
|
data/manual.md
CHANGED
@@ -40,7 +40,7 @@ manipulating.
|
|
40
40
|
It supports all the common datatypes that are found in structured binary
|
41
41
|
data. Support for dependent and variable length fields is built in.
|
42
42
|
|
43
|
-
Last updated: 2011-06-
|
43
|
+
Last updated: 2011-06-20
|
44
44
|
|
45
45
|
## License
|
46
46
|
|
@@ -1085,16 +1085,12 @@ Examples
|
|
1085
1085
|
obj = BinData::Choice.new(:choices => choices, :selection => 1)
|
1086
1086
|
obj # => "Type2"
|
1087
1087
|
|
1088
|
-
choices = [ nil, nil, nil, type1, nil, type2 ]
|
1089
|
-
obj = BinData::Choice.new(:choices => choices, :selection => 3)
|
1090
|
-
obj # => "Type1"
|
1091
|
-
|
1092
1088
|
class MyNumber < BinData::Record
|
1093
1089
|
int8 :is_big_endian
|
1094
1090
|
choice :data, :selection => lambda { is_big_endian != 0 },
|
1095
1091
|
:copy_on_change => true do
|
1096
|
-
int32be true
|
1097
1092
|
int32le false
|
1093
|
+
int32be true
|
1098
1094
|
end
|
1099
1095
|
end
|
1100
1096
|
|
@@ -1107,6 +1103,23 @@ Examples
|
|
1107
1103
|
obj.to_binary_s #=> "\000\005\000\000\000"
|
1108
1104
|
{:ruby}
|
1109
1105
|
|
1106
|
+
## Default selection
|
1107
|
+
|
1108
|
+
A key of `:default` can be specified as a default selection. If the value of the
|
1109
|
+
selection isn't specified then the :default will be used. The previous `MyNumber`
|
1110
|
+
example used a flag for endian. Zero is little endian while any other value
|
1111
|
+
is big endian. This can be concisely written as:
|
1112
|
+
|
1113
|
+
class MyNumber < BinData::Record
|
1114
|
+
int8 :is_big_endian
|
1115
|
+
choice :data, :selection => :is_big_endian,
|
1116
|
+
:copy_on_change => true do
|
1117
|
+
int32le 0 # zero is little endian
|
1118
|
+
int32be :default # anything else is big endian
|
1119
|
+
end
|
1120
|
+
end
|
1121
|
+
{:ruby}
|
1122
|
+
|
1110
1123
|
---------------------------------------------------------------------------
|
1111
1124
|
|
1112
1125
|
# Advanced Topics
|
@@ -1302,6 +1315,28 @@ data and won't consume space in memory. When writing it will write
|
|
1302
1315
|
end
|
1303
1316
|
{:ruby}
|
1304
1317
|
|
1318
|
+
## Determining stream length
|
1319
|
+
|
1320
|
+
Some file formats don't use length fields but rather read until the end
|
1321
|
+
of the file. The stream length is needed when reading these formats. The
|
1322
|
+
`count_bytes_remaining` keyword will give the number of bytes remaining in the
|
1323
|
+
stream.
|
1324
|
+
|
1325
|
+
Consider a string followed by a 2 byte checksum. The length of the string is
|
1326
|
+
not specified but is implied by the file length.
|
1327
|
+
|
1328
|
+
class StringWithChecksum < BinData::Record
|
1329
|
+
count_bytes_remaining :bytes_remaining
|
1330
|
+
string :the_string, :read_length => lambda { bytes_remaining - 2 }
|
1331
|
+
int16le :checksum
|
1332
|
+
end
|
1333
|
+
{:ruby}
|
1334
|
+
|
1335
|
+
These file formats only work with seekable streams (e.g. files). These formats
|
1336
|
+
do not stream well as they must be buffered by the client before being
|
1337
|
+
processed. Consider using an explicit length when creating a new file format
|
1338
|
+
as it is easier to work with.
|
1339
|
+
|
1305
1340
|
## Bit-aligned Records
|
1306
1341
|
|
1307
1342
|
Most structured binary data is byte-aligned. Any bitfields that occur,
|
data/spec/choice_spec.rb
CHANGED
@@ -207,6 +207,20 @@ describe BinData::Choice, "with copy_on_change => true" do
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
+
describe BinData::Choice, "with :default" do
|
211
|
+
let(:choices) { { "a" => :int8, :default => :int16be } }
|
212
|
+
|
213
|
+
it "should select for existing case" do
|
214
|
+
subject = BinData::Choice.new(:selection => "a", :choices => choices)
|
215
|
+
subject.num_bytes.should == 1
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should select for default case" do
|
219
|
+
subject = BinData::Choice.new(:selection => "other", :choices => choices)
|
220
|
+
subject.num_bytes.should == 2
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
210
224
|
describe BinData::Choice, "subclassed with default parameters" do
|
211
225
|
class DerivedChoice < BinData::Choice
|
212
226
|
endian :big
|
@@ -214,6 +228,7 @@ describe BinData::Choice, "subclassed with default parameters" do
|
|
214
228
|
|
215
229
|
uint16 'a'
|
216
230
|
uint32 'b'
|
231
|
+
uint64 :default
|
217
232
|
end
|
218
233
|
|
219
234
|
it "should set initial selection" do
|
@@ -225,4 +240,9 @@ describe BinData::Choice, "subclassed with default parameters" do
|
|
225
240
|
subject = DerivedChoice.new(:selection => 'b')
|
226
241
|
subject.num_bytes.should == 4
|
227
242
|
end
|
243
|
+
|
244
|
+
it "should select default selection" do
|
245
|
+
subject = DerivedChoice.new(:selection => 'z')
|
246
|
+
subject.num_bytes.should == 8
|
247
|
+
end
|
228
248
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/count_bytes_remaining'
|
5
|
+
|
6
|
+
describe BinData::CountBytesRemaining do
|
7
|
+
it { should == 0 }
|
8
|
+
|
9
|
+
it "should count till end of stream" do
|
10
|
+
data = "abcdefghij"
|
11
|
+
subject.read(data).should == 10
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have no size" do
|
15
|
+
subject.num_bytes.should == 0
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not read any data" do
|
19
|
+
io = StringIO.new "abcdefghij"
|
20
|
+
subject.read(io)
|
21
|
+
|
22
|
+
io.pos.should == 0
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not write any data" do
|
26
|
+
subject.to_binary_s.should == ""
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow setting value for completeness" do
|
30
|
+
subject.assign("123")
|
31
|
+
subject.should == "123"
|
32
|
+
subject.to_binary_s.should == ""
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should accept BinData::BasePrimitive parameters" do
|
36
|
+
count = BinData::CountBytesRemaining.new(:check_value => 2)
|
37
|
+
lambda {
|
38
|
+
count.read("xyz")
|
39
|
+
}.should raise_error(BinData::ValidityError)
|
40
|
+
end
|
41
|
+
end
|
data/spec/io_spec.rb
CHANGED
@@ -39,6 +39,10 @@ describe BinData::IO, "reading from non seekable stream" do
|
|
39
39
|
@io.seekbytes(4999)
|
40
40
|
@io.readbytes(5).should == "abbbb"
|
41
41
|
end
|
42
|
+
|
43
|
+
it "should return zero for num bytes remaining" do
|
44
|
+
@io.num_bytes_remaining.should == 0
|
45
|
+
end
|
42
46
|
end
|
43
47
|
|
44
48
|
describe BinData::IO, "when reading" do
|
@@ -76,6 +80,13 @@ describe BinData::IO, "when reading" do
|
|
76
80
|
io.read_all_bytes.should == "abcdefghij"
|
77
81
|
end
|
78
82
|
|
83
|
+
it "should return number of bytes remaining" do
|
84
|
+
stream_length = io.num_bytes_remaining
|
85
|
+
|
86
|
+
io.readbytes(4)
|
87
|
+
io.num_bytes_remaining.should == stream_length - 4
|
88
|
+
end
|
89
|
+
|
79
90
|
it "should raise error when reading at eof" do
|
80
91
|
io.seekbytes(10)
|
81
92
|
lambda {
|
data/spec/lazy_spec.rb
CHANGED
@@ -22,52 +22,56 @@ class MockBinDataObject
|
|
22
22
|
def get_parameter(key)
|
23
23
|
@parameters[key]
|
24
24
|
end
|
25
|
+
|
26
|
+
def lazy_evaluator
|
27
|
+
BinData::LazyEvaluator.new(self)
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
|
-
|
28
|
-
|
31
|
+
def lazy_eval(*rest)
|
32
|
+
subject.lazy_evaluator.lazy_eval(*rest)
|
33
|
+
end
|
29
34
|
|
30
35
|
describe BinData::LazyEvaluator, "with no parents" do
|
31
|
-
|
36
|
+
subject {
|
32
37
|
methods = {:m1 => 'm1', :com => 'mC'}
|
33
38
|
params = {:p1 => 'p1', :com => 'pC'}
|
34
39
|
MockBinDataObject.new(methods, params)
|
35
40
|
}
|
36
41
|
|
37
42
|
it "should evaluate raw value when instantiated" do
|
38
|
-
|
39
|
-
le.lazy_eval(5).should == 5
|
43
|
+
lazy_eval(5).should == 5
|
40
44
|
end
|
41
45
|
|
42
46
|
it "should evaluate raw value" do
|
43
|
-
|
47
|
+
lazy_eval(5).should == 5
|
44
48
|
end
|
45
49
|
|
46
50
|
it "should evaluate value" do
|
47
|
-
|
51
|
+
lazy_eval(lambda { 5 }).should == 5
|
48
52
|
end
|
49
53
|
|
50
54
|
it "should evaluate overrides" do
|
51
|
-
|
55
|
+
lazy_eval(lambda { o1 }, :o1 => 'o1').should == 'o1'
|
52
56
|
end
|
53
57
|
|
54
58
|
it "should not resolve any unknown methods" do
|
55
|
-
lambda {
|
56
|
-
lambda {
|
57
|
-
lambda {
|
59
|
+
lambda { lazy_eval(lambda { unknown }) }.should raise_error(NameError)
|
60
|
+
lambda { lazy_eval(lambda { m1 }) }.should raise_error(NameError)
|
61
|
+
lambda { lazy_eval(lambda { p1 }) }.should raise_error(NameError)
|
58
62
|
end
|
59
63
|
|
60
64
|
it "should not have a parent" do
|
61
|
-
|
65
|
+
lazy_eval(lambda { parent }).should be_nil
|
62
66
|
end
|
63
67
|
|
64
68
|
it "should not resolve #index" do
|
65
|
-
lambda {
|
69
|
+
lambda { lazy_eval(lambda { index }) }.should raise_error(NoMethodError)
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
69
73
|
describe BinData::LazyEvaluator, "with one parent" do
|
70
|
-
|
74
|
+
subject {
|
71
75
|
parent_methods = {:m1 => 'Pm1', :com => 'PmC', :mm => 3}
|
72
76
|
parent_params = {:p1 => 'Pp1', :com => 'PpC'}
|
73
77
|
parent_obj = MockBinDataObject.new(parent_methods, parent_params)
|
@@ -82,52 +86,52 @@ describe BinData::LazyEvaluator, "with one parent" do
|
|
82
86
|
}
|
83
87
|
|
84
88
|
it "should evaluate raw value" do
|
85
|
-
|
89
|
+
lazy_eval(5).should == 5
|
86
90
|
end
|
87
91
|
|
88
92
|
it "should evaluate value" do
|
89
|
-
|
93
|
+
lazy_eval(lambda { 5 }).should == 5
|
90
94
|
end
|
91
95
|
|
92
96
|
it "should evaluate overrides before params" do
|
93
|
-
|
97
|
+
lazy_eval(lambda { p1 }, :p1 => 'o1').should == 'o1'
|
94
98
|
end
|
95
99
|
|
96
100
|
it "should evaluate overrides before methods" do
|
97
|
-
|
101
|
+
lazy_eval(lambda { m1 }, :m1 => 'o1').should == 'o1'
|
98
102
|
end
|
99
103
|
|
100
104
|
it "should not resolve any unknown methods" do
|
101
|
-
lambda {
|
105
|
+
lambda { lazy_eval(lambda { unknown }) }.should raise_error(NameError)
|
102
106
|
end
|
103
107
|
|
104
108
|
it "should resolve parameters in the parent" do
|
105
|
-
|
109
|
+
lazy_eval(lambda { p1 }).should == 'Pp1'
|
106
110
|
end
|
107
111
|
|
108
112
|
it "should resolve methods in the parent" do
|
109
|
-
|
113
|
+
lazy_eval(lambda { m1 }).should == 'Pm1'
|
110
114
|
end
|
111
115
|
|
112
116
|
it "should invoke methods in the parent" do
|
113
|
-
|
117
|
+
lazy_eval(lambda { echo(p1, m1) }).should == ['Pp1', 'Pm1']
|
114
118
|
end
|
115
119
|
|
116
120
|
it "should resolve parameters in preference to methods in the parent" do
|
117
|
-
|
121
|
+
lazy_eval(lambda { com }).should == 'PpC'
|
118
122
|
end
|
119
123
|
|
120
124
|
it "should have a parent" do
|
121
|
-
|
125
|
+
lazy_eval(lambda { parent }).should_not be_nil
|
122
126
|
end
|
123
127
|
|
124
128
|
it "should not resolve #index" do
|
125
|
-
lambda {
|
129
|
+
lambda { lazy_eval(lambda { index }) }.should raise_error(NoMethodError)
|
126
130
|
end
|
127
131
|
end
|
128
132
|
|
129
133
|
describe BinData::LazyEvaluator, "with nested parents" do
|
130
|
-
|
134
|
+
subject {
|
131
135
|
pparent_methods = {:m1 => 'PPm1', :m2 => 'PPm2', :com => 'PPmC'}
|
132
136
|
pparent_params = {:p1 => 'PPp1', :p2 => 'PPp2', :com => 'PPpC'}
|
133
137
|
pparent_obj = MockBinDataObject.new(pparent_methods, pparent_params)
|
@@ -154,58 +158,58 @@ describe BinData::LazyEvaluator, "with nested parents" do
|
|
154
158
|
}
|
155
159
|
|
156
160
|
it "should accept symbols as a shortcut to lambdas" do
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
+
lazy_eval(:p1).should == 'Pp1'
|
162
|
+
lazy_eval(:p2).should == 'PPp2'
|
163
|
+
lazy_eval(:m1).should == 'Pm1'
|
164
|
+
lazy_eval(:m2).should == 'PPm2'
|
161
165
|
end
|
162
166
|
|
163
167
|
it "should not resolve any unknown methods" do
|
164
|
-
lambda {
|
168
|
+
lambda { lazy_eval(lambda { unknown }) }.should raise_error(NameError)
|
165
169
|
end
|
166
170
|
|
167
171
|
it "should resolve parameters in the parent" do
|
168
|
-
|
172
|
+
lazy_eval(lambda { p1 }).should == 'Pp1'
|
169
173
|
end
|
170
174
|
|
171
175
|
it "should resolve methods in the parent" do
|
172
|
-
|
176
|
+
lazy_eval(lambda { m1 }).should == 'Pm1'
|
173
177
|
end
|
174
178
|
|
175
179
|
it "should resolve parameters in the parent's parent" do
|
176
|
-
|
180
|
+
lazy_eval(lambda { p2 }).should == 'PPp2'
|
177
181
|
end
|
178
182
|
|
179
183
|
it "should resolve methods in the parent's parent" do
|
180
|
-
|
184
|
+
lazy_eval(lambda { m2 }).should == 'PPm2'
|
181
185
|
end
|
182
186
|
|
183
187
|
it "should invoke methods in the parent" do
|
184
|
-
|
188
|
+
lazy_eval(lambda { echo(m1) }).should == ['P', 'Pm1']
|
185
189
|
end
|
186
190
|
|
187
191
|
it "should invoke methods in the parent's parent" do
|
188
|
-
|
192
|
+
lazy_eval(lambda { parent.echo(m1) }, { :m1 => 'o1'}).should == ['PP', 'o1']
|
189
193
|
end
|
190
194
|
|
191
195
|
it "should invoke methods in the parent's parent" do
|
192
|
-
|
196
|
+
lazy_eval(lambda { echo2(m1) }).should == ['PP2', 'Pm1']
|
193
197
|
end
|
194
198
|
|
195
199
|
it "should resolve parameters in preference to methods in the parent" do
|
196
|
-
|
200
|
+
lazy_eval(lambda { com }).should == 'PpC'
|
197
201
|
end
|
198
202
|
|
199
203
|
it "should resolve methods in the parent explicitly" do
|
200
|
-
|
204
|
+
lazy_eval(lambda { parent.m1 }).should == 'PPm1'
|
201
205
|
end
|
202
206
|
|
203
207
|
it "should cascade lambdas " do
|
204
|
-
|
205
|
-
|
208
|
+
lazy_eval(lambda { sym1 }).should == 'PPm2'
|
209
|
+
lazy_eval(lambda { sym2 }).should == 'PPm2'
|
206
210
|
end
|
207
211
|
|
208
212
|
it "should not resolve #index" do
|
209
|
-
lambda {
|
213
|
+
lambda { lazy_eval(lambda { index }) }.should raise_error(NoMethodError)
|
210
214
|
end
|
211
215
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bindata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 1.4.
|
9
|
+
- 1
|
10
|
+
version: 1.4.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dion Mendel
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-20 00:00:00 +08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- examples/nbt.rb
|
105
105
|
- examples/NBT.txt
|
106
106
|
- examples/list.rb
|
107
|
+
- spec/count_bytes_remaining_spec.rb
|
107
108
|
- spec/base_spec.rb
|
108
109
|
- spec/string_spec.rb
|
109
110
|
- spec/record_spec.rb
|
@@ -136,6 +137,7 @@ files:
|
|
136
137
|
- lib/bindata/trace.rb
|
137
138
|
- lib/bindata/struct.rb
|
138
139
|
- lib/bindata/lazy.rb
|
140
|
+
- lib/bindata/count_bytes_remaining.rb
|
139
141
|
- lib/bindata/base.rb
|
140
142
|
- lib/bindata/stringz.rb
|
141
143
|
- lib/bindata/string.rb
|