jbangert-bindata 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/BSDL +22 -0
- data/COPYING +52 -0
- data/ChangeLog.rdoc +204 -0
- data/Gemfile +2 -0
- data/INSTALL +11 -0
- data/NEWS.rdoc +164 -0
- data/README.md +54 -0
- data/Rakefile +13 -0
- data/bindata.gemspec +31 -0
- data/doc/manual.haml +407 -0
- data/doc/manual.md +1649 -0
- data/examples/NBT.txt +149 -0
- data/examples/gzip.rb +161 -0
- data/examples/ip_address.rb +22 -0
- data/examples/list.rb +124 -0
- data/examples/nbt.rb +178 -0
- data/lib/bindata.rb +33 -0
- data/lib/bindata/alignment.rb +83 -0
- data/lib/bindata/array.rb +335 -0
- data/lib/bindata/base.rb +388 -0
- data/lib/bindata/base_primitive.rb +214 -0
- data/lib/bindata/bits.rb +87 -0
- data/lib/bindata/choice.rb +216 -0
- data/lib/bindata/count_bytes_remaining.rb +35 -0
- data/lib/bindata/deprecated.rb +50 -0
- data/lib/bindata/dsl.rb +312 -0
- data/lib/bindata/float.rb +80 -0
- data/lib/bindata/int.rb +184 -0
- data/lib/bindata/io.rb +274 -0
- data/lib/bindata/lazy.rb +105 -0
- data/lib/bindata/offset.rb +91 -0
- data/lib/bindata/params.rb +135 -0
- data/lib/bindata/primitive.rb +135 -0
- data/lib/bindata/record.rb +110 -0
- data/lib/bindata/registry.rb +92 -0
- data/lib/bindata/rest.rb +35 -0
- data/lib/bindata/sanitize.rb +290 -0
- data/lib/bindata/skip.rb +48 -0
- data/lib/bindata/string.rb +145 -0
- data/lib/bindata/stringz.rb +96 -0
- data/lib/bindata/struct.rb +388 -0
- data/lib/bindata/trace.rb +94 -0
- data/lib/bindata/version.rb +3 -0
- data/setup.rb +1585 -0
- data/spec/alignment_spec.rb +61 -0
- data/spec/array_spec.rb +331 -0
- data/spec/base_primitive_spec.rb +238 -0
- data/spec/base_spec.rb +376 -0
- data/spec/bits_spec.rb +163 -0
- data/spec/choice_spec.rb +263 -0
- data/spec/count_bytes_remaining_spec.rb +38 -0
- data/spec/deprecated_spec.rb +31 -0
- data/spec/example.rb +21 -0
- data/spec/float_spec.rb +37 -0
- data/spec/int_spec.rb +216 -0
- data/spec/io_spec.rb +352 -0
- data/spec/lazy_spec.rb +217 -0
- data/spec/primitive_spec.rb +202 -0
- data/spec/record_spec.rb +530 -0
- data/spec/registry_spec.rb +108 -0
- data/spec/rest_spec.rb +26 -0
- data/spec/skip_spec.rb +27 -0
- data/spec/spec_common.rb +58 -0
- data/spec/string_spec.rb +300 -0
- data/spec/stringz_spec.rb +118 -0
- data/spec/struct_spec.rb +350 -0
- data/spec/system_spec.rb +380 -0
- data/tasks/manual.rake +36 -0
- data/tasks/rspec.rake +17 -0
- metadata +208 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/bits'
|
5
|
+
require 'bindata/int'
|
6
|
+
require 'bindata/float'
|
7
|
+
require 'bindata/registry'
|
8
|
+
|
9
|
+
describe BinData::Registry do
|
10
|
+
A = Class.new
|
11
|
+
B = Class.new
|
12
|
+
C = Class.new
|
13
|
+
D = Class.new
|
14
|
+
|
15
|
+
let(:r) { BinData::Registry.new }
|
16
|
+
|
17
|
+
it "lookups registered names" do
|
18
|
+
r.register('ASubClass', A)
|
19
|
+
r.register('AnotherSubClass', B)
|
20
|
+
|
21
|
+
r.lookup('ASubClass').should == A
|
22
|
+
r.lookup('a_sub_class').should == A
|
23
|
+
r.lookup('AnotherSubClass').should == B
|
24
|
+
r.lookup('another_sub_class').should == B
|
25
|
+
end
|
26
|
+
|
27
|
+
it "does not lookup unregistered names" do
|
28
|
+
expect {
|
29
|
+
r.lookup('a_non_existent_sub_class')
|
30
|
+
}.to raise_error(BinData::UnRegisteredTypeError)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "unregisters names" do
|
34
|
+
r.register('ASubClass', A)
|
35
|
+
r.unregister('ASubClass')
|
36
|
+
|
37
|
+
expect {
|
38
|
+
r.lookup('ASubClass')
|
39
|
+
}.to raise_error(BinData::UnRegisteredTypeError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "allows overriding of registered classes" do
|
43
|
+
r.register('A', A)
|
44
|
+
r.register('A', B)
|
45
|
+
|
46
|
+
r.lookup('a').should == B
|
47
|
+
end
|
48
|
+
|
49
|
+
it "converts CamelCase to underscores" do
|
50
|
+
r.underscore_name('CamelCase').should == 'camel_case'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "converts adjacent caps camelCase to underscores" do
|
54
|
+
r.underscore_name('XYZCamelCase').should == 'xyz_camel_case'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "ignores the outer nestings of classes" do
|
58
|
+
r.underscore_name('A::B::C').should == 'c'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe BinData::Registry, "with numerics" do
|
63
|
+
let(:r) { BinData::RegisteredClasses }
|
64
|
+
|
65
|
+
it "lookup integers with endian" do
|
66
|
+
r.lookup("int24", :big).to_s.should == "BinData::Int24be"
|
67
|
+
r.lookup("int24", :little).to_s.should == "BinData::Int24le"
|
68
|
+
r.lookup("uint24", :big).to_s.should == "BinData::Uint24be"
|
69
|
+
r.lookup("uint24", :little).to_s.should == "BinData::Uint24le"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "does not lookup integers without endian" do
|
73
|
+
expect {
|
74
|
+
r.lookup("int24")
|
75
|
+
}.to raise_error(BinData::UnRegisteredTypeError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "does not lookup non byte based integers" do
|
79
|
+
expect {
|
80
|
+
r.lookup("int3")
|
81
|
+
}.to raise_error(BinData::UnRegisteredTypeError)
|
82
|
+
expect {
|
83
|
+
r.lookup("int3", :big)
|
84
|
+
}.to raise_error(BinData::UnRegisteredTypeError)
|
85
|
+
expect {
|
86
|
+
r.lookup("int3", :little)
|
87
|
+
}.to raise_error(BinData::UnRegisteredTypeError)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "lookup floats with endian" do
|
91
|
+
r.lookup("float", :big).to_s.should == "BinData::FloatBe"
|
92
|
+
r.lookup("float", :little).to_s.should == "BinData::FloatLe"
|
93
|
+
r.lookup("double", :big).to_s.should == "BinData::DoubleBe"
|
94
|
+
r.lookup("double", :little).to_s.should == "BinData::DoubleLe"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "lookup bits" do
|
98
|
+
r.lookup("bit5").to_s.should == "BinData::Bit5"
|
99
|
+
r.lookup("bit6le").to_s.should == "BinData::Bit6le"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "lookup bits by ignoring endian" do
|
103
|
+
r.lookup("bit2", :big).to_s.should == "BinData::Bit2"
|
104
|
+
r.lookup("bit3le", :big).to_s.should == "BinData::Bit3le"
|
105
|
+
r.lookup("bit2", :little).to_s.should == "BinData::Bit2"
|
106
|
+
r.lookup("bit3le", :little).to_s.should == "BinData::Bit3le"
|
107
|
+
end
|
108
|
+
end
|
data/spec/rest_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/rest'
|
5
|
+
|
6
|
+
describe BinData::Rest do
|
7
|
+
it { should == "" }
|
8
|
+
|
9
|
+
it "reads till end of stream" do
|
10
|
+
data = "abcdefghij"
|
11
|
+
subject.read(data).should == data
|
12
|
+
end
|
13
|
+
|
14
|
+
it "allows setting value for completeness" do
|
15
|
+
subject.assign("123")
|
16
|
+
subject.should == "123"
|
17
|
+
subject.to_binary_s.should == "123"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "accepts BinData::BasePrimitive parameters" do
|
21
|
+
rest = BinData::Rest.new(:check_value => "abc")
|
22
|
+
expect {
|
23
|
+
rest.read("xyz")
|
24
|
+
}.to raise_error(BinData::ValidityError)
|
25
|
+
end
|
26
|
+
end
|
data/spec/skip_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/skip'
|
5
|
+
|
6
|
+
describe BinData::Skip do
|
7
|
+
subject { BinData::Skip.new(:length => 5) }
|
8
|
+
let(:io) { StringIO.new("abcdefghij") }
|
9
|
+
|
10
|
+
it { should == "" }
|
11
|
+
its(:to_binary_s) { should == "\000" * 5 }
|
12
|
+
|
13
|
+
it "skips bytes" do
|
14
|
+
subject.read(io)
|
15
|
+
io.pos.should == 5
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has expected binary representation after setting value" do
|
19
|
+
subject.assign("123")
|
20
|
+
subject.to_binary_s.should == "\000" * 5
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has expected binary representation after reading" do
|
24
|
+
subject.read(io)
|
25
|
+
subject.to_binary_s.should == "\000" * 5
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_common.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/autorun'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
class Object
|
8
|
+
def expose_methods_for_testing
|
9
|
+
cls = (Class === self) ? self : (class << self ; self; end)
|
10
|
+
private_method_names = cls.private_instance_methods - Object.private_instance_methods
|
11
|
+
cls.send(:public, *private_method_names)
|
12
|
+
|
13
|
+
protected_method_names = cls.protected_instance_methods - Object.protected_instance_methods
|
14
|
+
cls.send(:public, *protected_method_names)
|
15
|
+
end
|
16
|
+
|
17
|
+
def value_read_from_written
|
18
|
+
self.class.read(self.to_binary_s)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class StringIO
|
23
|
+
# Returns the value that was written to the io
|
24
|
+
def value
|
25
|
+
rewind
|
26
|
+
read
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def exception_line(ex)
|
31
|
+
idx = ex.backtrace.find_index { |bt| /:in `should'$/ =~ bt }
|
32
|
+
|
33
|
+
if idx
|
34
|
+
line_num_regex = /.*:(\d+)(:.*|$)/
|
35
|
+
|
36
|
+
err_line = line_num_regex.match(ex.backtrace[0])[1].to_i
|
37
|
+
ref_line = line_num_regex.match(ex.backtrace[idx + 1])[1].to_i
|
38
|
+
|
39
|
+
err_line - ref_line
|
40
|
+
else
|
41
|
+
raise "Required calling pattern is lambda { xxx }.should raise_error_on_line(...)"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def raise_error_on_line(exception, line, &block)
|
46
|
+
raise_exception(exception) do |err|
|
47
|
+
exception_line(err).should == line
|
48
|
+
block.call(err) if block_given?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def binary(str)
|
53
|
+
if str.respond_to?(:force_encoding)
|
54
|
+
str.dup.force_encoding(Encoding::BINARY)
|
55
|
+
else
|
56
|
+
str
|
57
|
+
end
|
58
|
+
end
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,300 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
|
+
require 'bindata/io'
|
5
|
+
require 'bindata/string'
|
6
|
+
|
7
|
+
describe BinData::String, "with mutually exclusive parameters" do
|
8
|
+
it ":value and :initial_value" do
|
9
|
+
params = {:value => "", :initial_value => ""}
|
10
|
+
expect { BinData::String.new(params) }.to raise_error(ArgumentError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it ":length and :read_length" do
|
14
|
+
params = {:length => 5, :read_length => 5}
|
15
|
+
expect { BinData::String.new(params) }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it ":value and :length" do
|
19
|
+
params = {:value => "", :length => 5}
|
20
|
+
expect { BinData::String.new(params) }.to raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe BinData::String, "when assigning" do
|
25
|
+
let(:small) { BinData::String.new(:length => 3, :pad_byte => "A") }
|
26
|
+
let(:large) { BinData::String.new(:length => 5, :pad_byte => "B") }
|
27
|
+
|
28
|
+
it "copies data from small to large" do
|
29
|
+
large.assign(small)
|
30
|
+
large.should == "AAABB"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "copies data from large to small" do
|
34
|
+
small.assign(large)
|
35
|
+
small.should == "BBB"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe BinData::String do
|
40
|
+
subject { BinData::String.new("testing") }
|
41
|
+
|
42
|
+
it "compares with regexp" do
|
43
|
+
(/es/ =~ subject).should == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
it "compares with regexp" do
|
47
|
+
(subject =~ /es/).should == 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe BinData::String, "with :read_length" do
|
52
|
+
subject { BinData::String.new(:read_length => 5) }
|
53
|
+
|
54
|
+
its(:num_bytes) { should == 0 }
|
55
|
+
its(:value) { should == "" }
|
56
|
+
|
57
|
+
it "reads :read_length bytes" do
|
58
|
+
subject.read("abcdefghij")
|
59
|
+
subject.should == "abcde"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "remembers :read_length after value is cleared" do
|
63
|
+
subject.assign("abc")
|
64
|
+
subject.num_bytes.should == 3
|
65
|
+
subject.clear
|
66
|
+
|
67
|
+
subject.read("abcdefghij")
|
68
|
+
subject.should == "abcde"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe BinData::String, "with :length" do
|
73
|
+
subject { BinData::String.new(:length => 5) }
|
74
|
+
|
75
|
+
its(:num_bytes) { should == 5 }
|
76
|
+
its(:value) { should == "\0\0\0\0\0" }
|
77
|
+
|
78
|
+
it "retains :length after value is set" do
|
79
|
+
subject.assign("abcdefghij")
|
80
|
+
subject.num_bytes.should == 5
|
81
|
+
end
|
82
|
+
|
83
|
+
it "reads :length bytes" do
|
84
|
+
subject.read("abcdefghij")
|
85
|
+
subject.should == "abcde"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "pads values less than :length" do
|
89
|
+
subject.assign("abc")
|
90
|
+
subject.should == "abc\0\0"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "accepts values exactly :length" do
|
94
|
+
subject.assign("abcde")
|
95
|
+
subject.should == "abcde"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "truncates values greater than :length" do
|
99
|
+
subject.assign("abcdefghij")
|
100
|
+
subject.should == "abcde"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe BinData::String, "with :read_length and :initial_value" do
|
105
|
+
subject { BinData::String.new(:read_length => 5, :initial_value => "abcdefghij") }
|
106
|
+
|
107
|
+
its(:num_bytes) { should == 10 }
|
108
|
+
its(:value) { should == "abcdefghij" }
|
109
|
+
|
110
|
+
it "uses :read_length for reading" do
|
111
|
+
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
112
|
+
subject.read(io)
|
113
|
+
io.pos.should == 5
|
114
|
+
end
|
115
|
+
|
116
|
+
it "forgets :initial_value after reading" do
|
117
|
+
subject.read("ABCDEFGHIJKLMNOPQRST")
|
118
|
+
subject.num_bytes.should == 5
|
119
|
+
subject.should == "ABCDE"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe BinData::String, "with :read_length and :value" do
|
124
|
+
subject { BinData::String.new(:read_length => 5, :value => "abcdefghij") }
|
125
|
+
|
126
|
+
its(:num_bytes) { should == 10 }
|
127
|
+
its(:value) { should == "abcdefghij" }
|
128
|
+
|
129
|
+
it "uses :read_length for reading" do
|
130
|
+
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
131
|
+
subject.read(io)
|
132
|
+
io.pos.should == 5
|
133
|
+
end
|
134
|
+
|
135
|
+
context "after reading" do
|
136
|
+
before(:each) do
|
137
|
+
subject.read("ABCDEFGHIJKLMNOPQRST")
|
138
|
+
end
|
139
|
+
|
140
|
+
it "is not affected by :read_length after reading" do
|
141
|
+
subject.num_bytes.should == 10
|
142
|
+
subject.should == "abcdefghij"
|
143
|
+
end
|
144
|
+
|
145
|
+
it "returns read value while reading" do
|
146
|
+
subject.stub(:reading?).and_return(true)
|
147
|
+
subject.should == "ABCDE"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe BinData::String, "with :length and :initial_value" do
|
153
|
+
subject { BinData::String.new(:length => 5, :initial_value => "abcdefghij") }
|
154
|
+
|
155
|
+
its(:num_bytes) { should == 5 }
|
156
|
+
its(:value) { should == "abcde" }
|
157
|
+
|
158
|
+
it "forgets :initial_value after reading" do
|
159
|
+
io = StringIO.new("ABCDEFGHIJKLMNOPQRST")
|
160
|
+
subject.read(io)
|
161
|
+
io.pos.should == 5
|
162
|
+
subject.num_bytes.should == 5
|
163
|
+
subject.should == "ABCDE"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe BinData::String, "with :pad_byte" do
|
168
|
+
it "accepts a numeric value for :pad_byte" do
|
169
|
+
str = BinData::String.new(:length => 5, :pad_byte => 6)
|
170
|
+
str.assign("abc")
|
171
|
+
str.should == "abc\x06\x06"
|
172
|
+
end
|
173
|
+
|
174
|
+
it "accepts a character for :pad_byte" do
|
175
|
+
str = BinData::String.new(:length => 5, :pad_byte => "R")
|
176
|
+
str.assign("abc")
|
177
|
+
str.should == "abcRR"
|
178
|
+
end
|
179
|
+
|
180
|
+
it "does not accept a string for :pad_byte" do
|
181
|
+
params = {:length => 5, :pad_byte => "RR"}
|
182
|
+
lambda { BinData::String.new(params) }.should raise_error(ArgumentError)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe BinData::String, "with :trim_padding" do
|
187
|
+
it "set false is the default" do
|
188
|
+
str1 = BinData::String.new(:length => 5)
|
189
|
+
str2 = BinData::String.new(:length => 5, :trim_padding => false)
|
190
|
+
str1.assign("abc")
|
191
|
+
str2.assign("abc")
|
192
|
+
str1.should == "abc\0\0"
|
193
|
+
str2.should == "abc\0\0"
|
194
|
+
end
|
195
|
+
|
196
|
+
context "trim padding set" do
|
197
|
+
subject { BinData::String.new(:pad_byte => 'R', :trim_padding => true) }
|
198
|
+
|
199
|
+
it "trims the value" do
|
200
|
+
subject.assign("abcRR")
|
201
|
+
subject.should == "abc"
|
202
|
+
end
|
203
|
+
|
204
|
+
it "does not affect num_bytes" do
|
205
|
+
subject.assign("abcRR")
|
206
|
+
subject.num_bytes.should == 5
|
207
|
+
end
|
208
|
+
|
209
|
+
it "trims if last char is :pad_byte" do
|
210
|
+
subject.assign("abcRR")
|
211
|
+
subject.should == "abc"
|
212
|
+
end
|
213
|
+
|
214
|
+
it "does not trim if value contains :pad_byte not at the end" do
|
215
|
+
subject.assign("abcRRde")
|
216
|
+
subject.should == "abcRRde"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe BinData::String, "with :pad_front" do
|
222
|
+
it "set false is the default" do
|
223
|
+
str1 = BinData::String.new(:length => 5)
|
224
|
+
str2 = BinData::String.new(:length => 5, :pad_front => false)
|
225
|
+
str1.assign("abc")
|
226
|
+
str2.assign("abc")
|
227
|
+
str1.should == "abc\0\0"
|
228
|
+
str2.should == "abc\0\0"
|
229
|
+
end
|
230
|
+
|
231
|
+
it "pads to the front" do
|
232
|
+
str = BinData::String.new(:length => 5, :pad_byte => 'R', :pad_front => true)
|
233
|
+
str.assign("abc")
|
234
|
+
str.should == "RRabc"
|
235
|
+
end
|
236
|
+
|
237
|
+
it "can alternatively be accesses by :pad_left" do
|
238
|
+
str = BinData::String.new(:length => 5, :pad_byte => 'R', :pad_left => true)
|
239
|
+
str.assign("abc")
|
240
|
+
str.should == "RRabc"
|
241
|
+
end
|
242
|
+
|
243
|
+
context "and :trim_padding" do
|
244
|
+
subject { BinData::String.new(:length => 5, :pad_byte => 'R', :pad_front => true, :trim_padding => true) }
|
245
|
+
|
246
|
+
it "assigns" do
|
247
|
+
subject.assign("abc")
|
248
|
+
subject.should == "abc"
|
249
|
+
end
|
250
|
+
|
251
|
+
it "has to_binary_s" do
|
252
|
+
subject.assign("abc")
|
253
|
+
subject.to_binary_s.should == "RRabc"
|
254
|
+
end
|
255
|
+
|
256
|
+
it "reads" do
|
257
|
+
subject.read "RRabc"
|
258
|
+
subject.should == "abc"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe BinData::String, "with Ruby 1.9 encodings" do
|
264
|
+
if RUBY_VERSION >= "1.9"
|
265
|
+
class UTF8String < BinData::String
|
266
|
+
def snapshot
|
267
|
+
super.force_encoding('UTF-8')
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
subject { UTF8String.new }
|
272
|
+
let(:binary_str) { binary("\xC3\x85\xC3\x84\xC3\x96") }
|
273
|
+
let(:utf8_str) { binary_str.dup.force_encoding('UTF-8') }
|
274
|
+
|
275
|
+
it "stores assigned values as binary" do
|
276
|
+
subject.assign(utf8_str)
|
277
|
+
subject.to_binary_s.should == binary_str
|
278
|
+
end
|
279
|
+
|
280
|
+
it "stores read values as binary" do
|
281
|
+
subject = UTF8String.new(:read_length => binary_str.length)
|
282
|
+
subject.read(binary_str)
|
283
|
+
|
284
|
+
subject.to_binary_s.should == binary_str
|
285
|
+
end
|
286
|
+
|
287
|
+
it "returns values in correct encoding" do
|
288
|
+
subject.assign(utf8_str)
|
289
|
+
|
290
|
+
subject.snapshot.should == utf8_str
|
291
|
+
end
|
292
|
+
|
293
|
+
it "has correct num_bytes" do
|
294
|
+
subject.assign(utf8_str)
|
295
|
+
|
296
|
+
subject.num_bytes.should == binary_str.length
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|