bindata 1.6.0 → 1.8.0
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/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/ChangeLog.rdoc +9 -0
- data/README.md +8 -1
- data/doc/manual.md +27 -2
- data/examples/tcp_ip.rb +179 -0
- data/lib/bindata.rb +4 -2
- data/lib/bindata/base.rb +2 -2
- data/lib/bindata/buffer.rb +119 -0
- data/lib/bindata/dsl.rb +41 -0
- data/lib/bindata/io.rb +321 -190
- data/lib/bindata/primitive.rb +6 -0
- data/lib/bindata/record.rb +1 -37
- data/lib/bindata/registry.rb +27 -23
- data/lib/bindata/version.rb +1 -1
- data/lib/bindata/virtual.rb +25 -19
- data/test/buffer_test.rb +144 -0
- data/test/common.rb +1 -1
- data/test/io_test.rb +117 -51
- data/test/lazy_test.rb +12 -12
- data/test/primitive_test.rb +20 -0
- data/test/registry_test.rb +23 -0
- data/test/virtual_test.rb +38 -0
- metadata +9 -4
data/lib/bindata/primitive.rb
CHANGED
data/lib/bindata/record.rb
CHANGED
@@ -3,42 +3,6 @@ require 'bindata/sanitize'
|
|
3
3
|
require 'bindata/struct'
|
4
4
|
|
5
5
|
module BinData
|
6
|
-
# Extracts args for Records.
|
7
|
-
#
|
8
|
-
# Foo.new(:bar => "baz) is ambiguous as to whether :bar is a value or parameter.
|
9
|
-
#
|
10
|
-
# BaseArgExtractor always assumes :bar is parameter. This extractor correctly
|
11
|
-
# identifies it as value or parameter.
|
12
|
-
class RecordArgExtractor
|
13
|
-
class << self
|
14
|
-
def extract(the_class, the_args)
|
15
|
-
value, parameters, parent = BaseArgExtractor.extract(the_class, the_args)
|
16
|
-
|
17
|
-
if parameters_is_value?(the_class, value, parameters)
|
18
|
-
value = parameters
|
19
|
-
parameters = {}
|
20
|
-
end
|
21
|
-
|
22
|
-
[value, parameters, parent]
|
23
|
-
end
|
24
|
-
|
25
|
-
def parameters_is_value?(the_class, value, parameters)
|
26
|
-
if value.nil? and parameters.length > 0
|
27
|
-
field_names_in_parameters?(the_class, parameters)
|
28
|
-
else
|
29
|
-
false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def field_names_in_parameters?(the_class, parameters)
|
34
|
-
field_names = the_class.fields.field_names
|
35
|
-
param_keys = parameters.keys
|
36
|
-
|
37
|
-
(field_names & param_keys).length > 0
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
6
|
# A Record is a declarative wrapper around Struct.
|
43
7
|
#
|
44
8
|
# require 'bindata'
|
@@ -68,7 +32,7 @@ module BinData
|
|
68
32
|
class << self
|
69
33
|
|
70
34
|
def arg_extractor
|
71
|
-
|
35
|
+
MultiFieldArgExtractor
|
72
36
|
end
|
73
37
|
|
74
38
|
def sanitize_parameters!(params) #:nodoc:
|
data/lib/bindata/registry.rb
CHANGED
@@ -18,28 +18,29 @@ module BinData
|
|
18
18
|
def register(name, class_to_register)
|
19
19
|
return if class_to_register.nil?
|
20
20
|
|
21
|
-
formatted_name =
|
21
|
+
formatted_name = underscore_name(name)
|
22
22
|
warn_if_name_is_already_registered(formatted_name, class_to_register)
|
23
23
|
|
24
24
|
@registry[formatted_name] = class_to_register
|
25
25
|
end
|
26
26
|
|
27
27
|
def unregister(name)
|
28
|
-
|
29
|
-
@registry.delete(formatted_name)
|
28
|
+
@registry.delete(underscore_name(name))
|
30
29
|
end
|
31
30
|
|
32
31
|
def lookup(name, endian = nil)
|
33
|
-
key =
|
34
|
-
try_registering_key(key) unless @registry.has_key?(key)
|
35
|
-
|
32
|
+
key = normalize_name(name, endian)
|
36
33
|
@registry[key] || raise(UnRegisteredTypeError, name.to_s)
|
37
34
|
end
|
38
35
|
|
39
36
|
def normalize_name(name, endian = nil)
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
name = underscore_name(name)
|
38
|
+
return name if is_registered?(name)
|
39
|
+
|
40
|
+
name = name_with_endian(name, endian)
|
41
|
+
return name if is_registered?(name)
|
42
|
+
|
43
|
+
name
|
43
44
|
end
|
44
45
|
|
45
46
|
# Convert CamelCase +name+ to underscore style.
|
@@ -54,25 +55,28 @@ module BinData
|
|
54
55
|
#---------------
|
55
56
|
private
|
56
57
|
|
57
|
-
def
|
58
|
-
name
|
58
|
+
def name_with_endian(name, endian)
|
59
|
+
return name if endian.nil?
|
59
60
|
|
60
|
-
|
61
|
-
if
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
result = name + ((endian == :little) ? "_le" : "_be")
|
66
|
-
end
|
61
|
+
suffix = (endian == :little) ? "le" : "be"
|
62
|
+
if /^u?int\d+$/ =~ name
|
63
|
+
name + suffix
|
64
|
+
else
|
65
|
+
name + "_" + suffix
|
67
66
|
end
|
68
|
-
result
|
69
67
|
end
|
70
68
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
69
|
+
def is_registered?(name)
|
70
|
+
register_dynamic_class(name) unless @registry.has_key?(name)
|
71
|
+
|
72
|
+
@registry.has_key?(name)
|
73
|
+
end
|
74
|
+
|
75
|
+
def register_dynamic_class(name)
|
76
|
+
if /^u?int\d+(le|be)$/ =~ name or /^bit\d+(le)?$/ =~ name
|
77
|
+
class_name = name.gsub(/(?:^|_)(.)/) { $1.upcase }
|
74
78
|
begin
|
75
|
-
|
79
|
+
BinData::const_get(class_name)
|
76
80
|
rescue NameError
|
77
81
|
end
|
78
82
|
end
|
data/lib/bindata/version.rb
CHANGED
data/lib/bindata/virtual.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "bindata/
|
1
|
+
require "bindata/base"
|
2
2
|
|
3
3
|
module BinData
|
4
4
|
# A virtual field is one that is neither read, written nor occupies space.
|
@@ -17,31 +17,37 @@ module BinData
|
|
17
17
|
# obj.a #=> "abcde"
|
18
18
|
# obj.c.offset #=> 10
|
19
19
|
#
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# obj = A.read("abcdeABCDE") #=> BinData::ValidityError: assertion failed for obj.c
|
21
|
+
#
|
22
|
+
# == Parameters
|
23
|
+
#
|
24
|
+
# Parameters may be provided at initialisation to control the behaviour of
|
25
|
+
# an object. These params include those for BinData::Base as well as:
|
26
|
+
#
|
27
|
+
# [<tt>:assert</tt>] Raise an error when reading or assigning if the value
|
28
|
+
# of this evaluated parameter is false.
|
29
|
+
#
|
30
|
+
class Virtual < BinData::Base
|
23
31
|
|
24
|
-
|
25
|
-
def sanitize_parameters!(params) #:nodoc:
|
26
|
-
if params.has_parameter?(:asserted_value)
|
27
|
-
fail ":asserted_value can not be used on virtual field"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
32
|
+
optional_parameter :assert
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
def clear?; true; end
|
35
|
+
def snapshot; nil; end
|
36
|
+
def do_num_bytes; 0; end
|
37
|
+
def do_write(io); end
|
34
38
|
|
35
|
-
def
|
36
|
-
|
39
|
+
def assign(val)
|
40
|
+
assert!
|
37
41
|
end
|
38
42
|
|
39
|
-
def
|
40
|
-
|
43
|
+
def do_read(io)
|
44
|
+
assert!
|
41
45
|
end
|
42
46
|
|
43
|
-
def
|
44
|
-
|
47
|
+
def assert!
|
48
|
+
if has_parameter?(:assert) and not eval_parameter(:assert)
|
49
|
+
raise ValidityError, "assertion failed for #{debug_name}"
|
50
|
+
end
|
45
51
|
end
|
46
52
|
end
|
47
53
|
end
|
data/test/buffer_test.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "common"))
|
4
|
+
|
5
|
+
describe BinData::Buffer, "when instantiating" do
|
6
|
+
describe "with no mandatory parameters supplied" do
|
7
|
+
it "raises an error" do
|
8
|
+
args = {}
|
9
|
+
lambda { BinData::Buffer.new(args) }.must_raise ArgumentError
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "with some but not all mandatory parameters supplied" do
|
14
|
+
it "raises an error" do
|
15
|
+
args = {:length => 3}
|
16
|
+
lambda { BinData::Buffer.new(args) }.must_raise ArgumentError
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "fails if a given type is unknown" do
|
21
|
+
args = {:type => :does_not_exist, :length => 3}
|
22
|
+
lambda { BinData::Buffer.new(args) }.must_raise BinData::UnRegisteredTypeError
|
23
|
+
end
|
24
|
+
|
25
|
+
it "accepts BinData::Base as :type" do
|
26
|
+
obj = BinData::Int8.new(:initial_value => 5)
|
27
|
+
array = BinData::Buffer.new(:type => obj, :length => 3)
|
28
|
+
array.must_equal 5
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe BinData::Buffer, "subclassed with a single type" do
|
33
|
+
class IntBuffer < BinData::Buffer
|
34
|
+
endian :big
|
35
|
+
default_parameter :length => 5
|
36
|
+
|
37
|
+
uint16
|
38
|
+
end
|
39
|
+
|
40
|
+
it "behaves as type" do
|
41
|
+
obj = IntBuffer.new(3)
|
42
|
+
obj.must_equal 3
|
43
|
+
end
|
44
|
+
|
45
|
+
it "reads data" do
|
46
|
+
obj = IntBuffer.read "\001\002\003\004\005"
|
47
|
+
obj.must_equal 0x0102
|
48
|
+
end
|
49
|
+
|
50
|
+
it "writes data" do
|
51
|
+
obj = IntBuffer.new(3)
|
52
|
+
obj.to_binary_s.must_equal "\000\003\000\000\000"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has total num_bytes" do
|
56
|
+
obj = IntBuffer.new
|
57
|
+
obj.num_bytes.must_equal 5
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe BinData::Buffer, "subclassed with multiple types" do
|
62
|
+
class TupleBuffer < BinData::Buffer
|
63
|
+
endian :big
|
64
|
+
default_parameter :length => 5
|
65
|
+
|
66
|
+
uint16 :a
|
67
|
+
uint16 :b
|
68
|
+
end
|
69
|
+
|
70
|
+
it "behaves as type" do
|
71
|
+
obj = TupleBuffer.new(:a => 1, :b => 2)
|
72
|
+
obj.a.must_equal 1
|
73
|
+
obj.b.must_equal 2
|
74
|
+
end
|
75
|
+
|
76
|
+
it "has total num_bytes" do
|
77
|
+
obj = TupleBuffer.new
|
78
|
+
obj.num_bytes.must_equal 5
|
79
|
+
end
|
80
|
+
|
81
|
+
it "reads data" do
|
82
|
+
obj = TupleBuffer.read "\001\002\003\004\005"
|
83
|
+
obj.a.must_equal 0x0102
|
84
|
+
obj.b.must_equal 0x0304
|
85
|
+
end
|
86
|
+
|
87
|
+
it "writes data" do
|
88
|
+
obj = TupleBuffer.new(:a => 1, :b => 2)
|
89
|
+
obj.to_binary_s.must_equal "\000\001\000\002\000"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe BinData::Buffer, "inside a Record" do
|
94
|
+
class BufferRecord < BinData::Record
|
95
|
+
endian :little
|
96
|
+
|
97
|
+
uint16 :buffer_length, :value => lambda { 2 * list.length + 1 }
|
98
|
+
buffer :list, :length => :buffer_length do
|
99
|
+
array :type => :int16, :read_until => :eof
|
100
|
+
end
|
101
|
+
string :footer, :length => 2, :asserted_value => "ZZ"
|
102
|
+
end
|
103
|
+
|
104
|
+
it "reads" do
|
105
|
+
obj = BufferRecord.read "\007\000\004\000\005\000\006\000\000ZZ"
|
106
|
+
obj.list.must_equal [4, 5, 6]
|
107
|
+
end
|
108
|
+
|
109
|
+
it "writes" do
|
110
|
+
obj = BufferRecord.new(:list => [1, 2, 3, 4, 5])
|
111
|
+
obj.to_binary_s.must_equal "\013\000\001\000\002\000\003\000\004\000\005\000\000ZZ"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe BinData::Buffer, "nested buffers" do
|
116
|
+
class NestedBufferRecord < BinData::Record
|
117
|
+
buffer :a, :length => 10 do
|
118
|
+
buffer :aa, :length => 5 do
|
119
|
+
string :read_length => 5
|
120
|
+
end
|
121
|
+
buffer :bb, :length => 20 do
|
122
|
+
string :read_length => 5
|
123
|
+
end
|
124
|
+
end
|
125
|
+
string :b, :read_length => 5
|
126
|
+
end
|
127
|
+
|
128
|
+
it "restricts large nested buffer" do
|
129
|
+
obj = NestedBufferRecord.read "abcdefghijklmnopqrst"
|
130
|
+
obj.a.aa.must_equal "abcde"
|
131
|
+
obj.a.bb.must_equal "fghij"
|
132
|
+
obj.b.must_equal "klmno"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "restricts oversize writes" do
|
136
|
+
obj = NestedBufferRecord.new
|
137
|
+
obj.a.aa = "abcdefghij"
|
138
|
+
obj.a.bb = "ABCDEFGHIJ"
|
139
|
+
obj.b = "12345"
|
140
|
+
|
141
|
+
obj.to_binary_s.must_equal "abcdeABCDE12345"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
data/test/common.rb
CHANGED
data/test/io_test.rb
CHANGED
@@ -2,63 +2,43 @@
|
|
2
2
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), "common"))
|
4
4
|
|
5
|
-
describe BinData::IO, "reading from non seekable stream" do
|
5
|
+
describe BinData::IO::Read, "reading from non seekable stream" do
|
6
6
|
before do
|
7
7
|
@rd, @wr = IO::pipe
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
else
|
13
|
-
# child
|
14
|
-
begin
|
15
|
-
@rd.close
|
16
|
-
@wr.write "a" * 5000
|
17
|
-
@wr.write "b" * 5000
|
18
|
-
@wr.close
|
19
|
-
rescue Exception
|
20
|
-
# ignore it
|
21
|
-
ensure
|
22
|
-
exit!
|
23
|
-
end
|
24
|
-
end
|
8
|
+
@io = BinData::IO::Read.new(@rd)
|
9
|
+
@wr.write "a" * 2000
|
10
|
+
@wr.write "b" * 2000
|
11
|
+
@wr.close
|
25
12
|
end
|
26
13
|
|
27
14
|
after do
|
28
15
|
@rd.close
|
29
|
-
Process.wait
|
30
16
|
end
|
31
17
|
|
32
|
-
it "
|
18
|
+
it "has correct offset" do
|
33
19
|
@io.readbytes(10)
|
34
|
-
@io.offset.must_equal
|
20
|
+
@io.offset.must_equal 10
|
35
21
|
end
|
36
22
|
|
37
23
|
it "seeks correctly" do
|
38
|
-
@io.seekbytes(
|
24
|
+
@io.seekbytes(1999)
|
39
25
|
@io.readbytes(5).must_equal "abbbb"
|
40
26
|
end
|
41
27
|
|
42
|
-
it "
|
43
|
-
|
28
|
+
it "#num_bytes_remaining raises IOError" do
|
29
|
+
lambda {
|
30
|
+
@io.num_bytes_remaining
|
31
|
+
}.must_raise IOError
|
44
32
|
end
|
45
33
|
end
|
46
34
|
|
47
|
-
describe BinData::IO, "when reading" do
|
35
|
+
describe BinData::IO::Read, "when reading" do
|
48
36
|
let(:stream) { StringIO.new "abcdefghij" }
|
49
|
-
let(:io) { BinData::IO.new(stream) }
|
50
|
-
|
51
|
-
it "wraps strings in StringIO" do
|
52
|
-
io.raw_io.class.must_equal StringIO
|
53
|
-
end
|
37
|
+
let(:io) { BinData::IO::Read.new(stream) }
|
54
38
|
|
55
|
-
it "
|
56
|
-
io.raw_io.must_equal stream
|
57
|
-
end
|
58
|
-
|
59
|
-
it "raises error when io is BinData::IO" do
|
39
|
+
it "raises error when io is BinData::IO::Read" do
|
60
40
|
lambda {
|
61
|
-
BinData::IO.new(BinData::IO.new(""))
|
41
|
+
BinData::IO::Read.new(BinData::IO::Read.new(""))
|
62
42
|
}.must_raise ArgumentError
|
63
43
|
end
|
64
44
|
|
@@ -100,17 +80,69 @@ describe BinData::IO, "when reading" do
|
|
100
80
|
end
|
101
81
|
end
|
102
82
|
|
103
|
-
describe BinData::IO, "
|
104
|
-
let(:stream) { StringIO.new }
|
105
|
-
let(:io) { BinData::IO.new(stream) }
|
83
|
+
describe BinData::IO::Read, "#with_buffer" do
|
84
|
+
let(:stream) { StringIO.new "abcdefghijklmnopqrst" }
|
85
|
+
let(:io) { BinData::IO::Read.new(stream) }
|
86
|
+
|
87
|
+
it "consumes entire buffer on short reads" do
|
88
|
+
io.with_buffer(10) do
|
89
|
+
io.readbytes(4).must_equal "abcd"
|
90
|
+
end
|
91
|
+
io.offset.must_equal(10)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "consumes entire buffer on read_all_bytes" do
|
95
|
+
io.with_buffer(10) do
|
96
|
+
io.read_all_bytes.must_equal "abcdefghij"
|
97
|
+
end
|
98
|
+
io.offset.must_equal(10)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "restricts large reads" do
|
102
|
+
io.with_buffer(10) do
|
103
|
+
lambda {
|
104
|
+
io.readbytes(15)
|
105
|
+
}.must_raise IOError
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "is nestable" do
|
110
|
+
io.with_buffer(10) do
|
111
|
+
io.readbytes(2).must_equal "ab"
|
112
|
+
io.with_buffer(5) do
|
113
|
+
io.read_all_bytes.must_equal "cdefg"
|
114
|
+
end
|
115
|
+
io.offset.must_equal(2 + 5)
|
116
|
+
end
|
117
|
+
io.offset.must_equal(10)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "restricts large nested buffers" do
|
121
|
+
io.with_buffer(10) do
|
122
|
+
io.readbytes(2).must_equal "ab"
|
123
|
+
io.with_buffer(20) do
|
124
|
+
io.read_all_bytes.must_equal "cdefghij"
|
125
|
+
io.offset.must_equal(10)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
io.offset.must_equal(10)
|
129
|
+
end
|
106
130
|
|
107
|
-
it "
|
108
|
-
io.
|
131
|
+
it "restricts large seeks" do
|
132
|
+
io.with_buffer(10) do
|
133
|
+
io.seekbytes(15)
|
134
|
+
end
|
135
|
+
io.offset.must_equal(10)
|
109
136
|
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe BinData::IO::Write, "when writing" do
|
140
|
+
let(:stream) { StringIO.new }
|
141
|
+
let(:io) { BinData::IO::Write.new(stream) }
|
110
142
|
|
111
143
|
it "raises error when io is BinData::IO" do
|
112
144
|
lambda {
|
113
|
-
BinData::IO.new(BinData::IO.new(""))
|
145
|
+
BinData::IO::Write.new(BinData::IO::Write.new(""))
|
114
146
|
}.must_raise ArgumentError
|
115
147
|
end
|
116
148
|
|
@@ -128,11 +160,43 @@ describe BinData::IO, "when writing" do
|
|
128
160
|
end
|
129
161
|
end
|
130
162
|
|
131
|
-
describe BinData::IO, "
|
163
|
+
describe BinData::IO::Write, "#with_buffer" do
|
164
|
+
let(:stream) { StringIO.new }
|
165
|
+
let(:io) { BinData::IO::Write.new(stream) }
|
166
|
+
|
167
|
+
it "pads entire buffer on short reads" do
|
168
|
+
io.with_buffer(10) do
|
169
|
+
io.writebytes "abcde"
|
170
|
+
end
|
171
|
+
|
172
|
+
stream.value.must_equal "abcde\0\0\0\0\0"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "discards excess on large writes" do
|
176
|
+
io.with_buffer(5) do
|
177
|
+
io.writebytes "abcdefghij"
|
178
|
+
end
|
179
|
+
|
180
|
+
stream.value.must_equal "abcde"
|
181
|
+
end
|
182
|
+
|
183
|
+
it "is nestable" do
|
184
|
+
io.with_buffer(10) do
|
185
|
+
io.with_buffer(5) do
|
186
|
+
io.writebytes "abc"
|
187
|
+
end
|
188
|
+
io.writebytes "de"
|
189
|
+
end
|
190
|
+
|
191
|
+
stream.value.must_equal "abc\0\0de\0\0\0"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe BinData::IO::Read, "reading bits in big endian" do
|
132
196
|
let(:b1) { 0b1111_1010 }
|
133
197
|
let(:b2) { 0b1100_1110 }
|
134
198
|
let(:b3) { 0b0110_1010 }
|
135
|
-
let(:io) { BinData::IO.new([b1, b2, b3].pack("CCC")) }
|
199
|
+
let(:io) { BinData::IO::Read.new([b1, b2, b3].pack("CCC")) }
|
136
200
|
|
137
201
|
it "reads a bitfield less than 1 byte" do
|
138
202
|
io.readbits(3, :big).must_equal 0b111
|
@@ -174,11 +238,11 @@ describe BinData::IO, "reading bits in big endian" do
|
|
174
238
|
end
|
175
239
|
end
|
176
240
|
|
177
|
-
describe BinData::IO, "reading bits in little endian" do
|
241
|
+
describe BinData::IO::Read, "reading bits in little endian" do
|
178
242
|
let(:b1) { 0b1111_1010 }
|
179
243
|
let(:b2) { 0b1100_1110 }
|
180
244
|
let(:b3) { 0b0110_1010 }
|
181
|
-
let(:io) { BinData::IO.new([b1, b2, b3].pack("CCC")) }
|
245
|
+
let(:io) { BinData::IO::Read.new([b1, b2, b3].pack("CCC")) }
|
182
246
|
|
183
247
|
it "reads a bitfield less than 1 byte" do
|
184
248
|
io.readbits(3, :little).must_equal 0b010
|
@@ -223,7 +287,7 @@ end
|
|
223
287
|
class BitWriterHelper
|
224
288
|
def initialize
|
225
289
|
@stringio = BinData::IO.create_string_io
|
226
|
-
@io = BinData::IO.new(@stringio)
|
290
|
+
@io = BinData::IO::Write.new(@stringio)
|
227
291
|
end
|
228
292
|
|
229
293
|
def writebits(val, nbits, endian)
|
@@ -241,7 +305,7 @@ class BitWriterHelper
|
|
241
305
|
end
|
242
306
|
end
|
243
307
|
|
244
|
-
describe BinData::IO, "writing bits in big endian" do
|
308
|
+
describe BinData::IO::Write, "writing bits in big endian" do
|
245
309
|
let(:io) { BitWriterHelper.new }
|
246
310
|
|
247
311
|
it "writes a bitfield less than 1 byte" do
|
@@ -286,7 +350,7 @@ describe BinData::IO, "writing bits in big endian" do
|
|
286
350
|
end
|
287
351
|
end
|
288
352
|
|
289
|
-
describe BinData::IO, "writing bits in little endian" do
|
353
|
+
describe BinData::IO::Write, "writing bits in little endian" do
|
290
354
|
let(:io) { BitWriterHelper.new }
|
291
355
|
|
292
356
|
it "writes a bitfield less than 1 byte" do
|
@@ -331,17 +395,19 @@ describe BinData::IO, "writing bits in little endian" do
|
|
331
395
|
end
|
332
396
|
end
|
333
397
|
|
334
|
-
describe BinData::IO, "with changing endian" do
|
398
|
+
describe BinData::IO::Read, "with changing endian" do
|
335
399
|
it "does not mix different endianess when reading" do
|
336
400
|
b1 = 0b0110_1010
|
337
401
|
b2 = 0b1110_0010
|
338
402
|
str = [b1, b2].pack("CC")
|
339
|
-
io = BinData::IO.new(str)
|
403
|
+
io = BinData::IO::Read.new(str)
|
340
404
|
|
341
405
|
io.readbits(3, :big).must_equal 0b011
|
342
406
|
io.readbits(4, :little).must_equal 0b0010
|
343
407
|
end
|
408
|
+
end
|
344
409
|
|
410
|
+
describe BinData::IO::Write, "with changing endian" do
|
345
411
|
it "does not mix different endianess when writing" do
|
346
412
|
io = BitWriterHelper.new
|
347
413
|
io.writebits(0b110, 3, :big)
|