bindata 1.0.0 → 1.1.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/ChangeLog +7 -0
- data/README +44 -2
- data/TODO +0 -3
- data/lib/bindata.rb +2 -1
- data/lib/bindata/bits.rb +29 -11
- data/lib/bindata/int.rb +36 -17
- data/lib/bindata/io.rb +21 -10
- data/lib/bindata/primitive.rb +28 -7
- data/lib/bindata/record.rb +34 -8
- data/lib/bindata/registry.rb +13 -21
- data/lib/bindata/sanitize.rb +20 -12
- data/lib/bindata/skip.rb +49 -0
- data/lib/bindata/struct.rb +7 -6
- data/lib/bindata/wrapper.rb +31 -10
- data/manual.haml +10 -0
- data/spec/int_spec.rb +4 -5
- data/spec/io_spec.rb +38 -0
- data/spec/primitive_spec.rb +17 -0
- data/spec/record_spec.rb +49 -0
- data/spec/registry_spec.rb +28 -35
- data/spec/skip_spec.rb +35 -0
- data/spec/struct_spec.rb +26 -0
- data/spec/wrapper_spec.rb +14 -0
- metadata +45 -41
data/ChangeLog
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
= BinData Changelog
|
2
2
|
|
3
|
+
== Version 1.1.0 (2009-11-24)
|
4
|
+
|
5
|
+
* Allow anonymous fields in Records and Primitives.
|
6
|
+
* Add the ability to skip over unused data.
|
7
|
+
* Allow Records, Primitives and Wrappers to be derived from.
|
8
|
+
* Classes for integers are now defined on demand.
|
9
|
+
|
3
10
|
== Version 1.0.0 (2009-09-13)
|
4
11
|
|
5
12
|
* Is now compatible with Ruby 1.9
|
data/README
CHANGED
@@ -48,6 +48,18 @@ Copyright © 2007 - 2009 [Dion Mendel](mailto:dion@lostrealm.com)
|
|
48
48
|
|
49
49
|
---------------------------------------------------------------------------
|
50
50
|
|
51
|
+
# Installation
|
52
|
+
|
53
|
+
You can install BinData via rubygems.
|
54
|
+
|
55
|
+
gem install bindata
|
56
|
+
|
57
|
+
Alternatively, visit the
|
58
|
+
[download](http://rubyforge.org/frs/?group_id=3252) page and download
|
59
|
+
BinData as a tar file.
|
60
|
+
|
61
|
+
---------------------------------------------------------------------------
|
62
|
+
|
51
63
|
# Overview
|
52
64
|
|
53
65
|
BinData declarations are easy to read. Here's an example.
|
@@ -248,8 +260,10 @@ one or more fields.
|
|
248
260
|
converted from `CamelCase` to lowercased `underscore_style`.
|
249
261
|
|
250
262
|
`field_name`
|
251
|
-
: is the name by which you can access the
|
252
|
-
`String` or a `Symbol`.
|
263
|
+
: is the name by which you can access the field. Use either a
|
264
|
+
`String` or a `Symbol`. If name is nil or the empty string, then
|
265
|
+
this particular field is anonymous. An anonymous field is still
|
266
|
+
read and written, but will not appear in `#snapshot`.
|
253
267
|
|
254
268
|
Each field may have optional *parameters* for how to process the data.
|
255
269
|
The parameters are passed as a `Hash` with `Symbols` for keys.
|
@@ -918,6 +932,34 @@ Examples
|
|
918
932
|
|
919
933
|
# Advanced Topics
|
920
934
|
|
935
|
+
## Skipping over unused data
|
936
|
+
|
937
|
+
Some binary structures contain data that is irrelevant to your purposes.
|
938
|
+
|
939
|
+
Say you are interested in 50 bytes of data located 10 megabytes into the
|
940
|
+
stream. One way of accessing this useful data is:
|
941
|
+
|
942
|
+
class MyData < BinData::Record
|
943
|
+
string :length => 10 * 1024 * 1024
|
944
|
+
string :data, :length => 50
|
945
|
+
end
|
946
|
+
{:ruby}
|
947
|
+
|
948
|
+
The advantage of this method is that the irrelevant data is preserved
|
949
|
+
when writing the record. The disadvantage is that even if you don't care
|
950
|
+
about preserving this irrelevant data, it still occupies memory.
|
951
|
+
|
952
|
+
If you don't need to preserve this data, an alternative is to use
|
953
|
+
`skip` instead of `string`. When reading it will seek over the irrelevant
|
954
|
+
data and won't consume space in memory. When writing it will write
|
955
|
+
`:length` number of zero bytes.
|
956
|
+
|
957
|
+
class MyData < BinData::Record
|
958
|
+
skip :length => 10 * 1024 * 1024
|
959
|
+
string :data, :length => 50
|
960
|
+
end
|
961
|
+
{:ruby}
|
962
|
+
|
921
963
|
## Wrappers
|
922
964
|
|
923
965
|
Sometimes you wish to create a new type that is simply an existing type
|
data/TODO
CHANGED
data/lib/bindata.rb
CHANGED
@@ -9,6 +9,7 @@ require 'bindata/int'
|
|
9
9
|
require 'bindata/primitive'
|
10
10
|
require 'bindata/record'
|
11
11
|
require 'bindata/rest'
|
12
|
+
require 'bindata/skip'
|
12
13
|
require 'bindata/string'
|
13
14
|
require 'bindata/stringz'
|
14
15
|
require 'bindata/struct'
|
@@ -29,5 +30,5 @@ require 'bindata/deprecated'
|
|
29
30
|
#
|
30
31
|
# Copyright (c) 2007 - 2009 Dion Mendel.
|
31
32
|
module BinData
|
32
|
-
VERSION = "1.
|
33
|
+
VERSION = "1.1.0"
|
33
34
|
end
|
data/lib/bindata/bits.rb
CHANGED
@@ -8,13 +8,15 @@ module BinData
|
|
8
8
|
def self.define_class(nbits, endian)
|
9
9
|
name = "Bit#{nbits}"
|
10
10
|
name += "le" if endian == :little
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
unless BinData.const_defined?(name)
|
12
|
+
BinData.module_eval <<-END
|
13
|
+
class #{name} < BinData::BasePrimitive
|
14
|
+
register(self.name, self)
|
15
|
+
BitField.create_methods(self, #{nbits}, :#{endian.to_s})
|
16
|
+
end
|
17
|
+
END
|
18
|
+
end
|
19
|
+
BinData.const_get(name)
|
18
20
|
end
|
19
21
|
|
20
22
|
def self.create_methods(bit_class, nbits, endian)
|
@@ -60,9 +62,25 @@ module BinData
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
# Create
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
# Create classes on demand
|
66
|
+
class << self
|
67
|
+
alias_method :const_missing_without_bits, :const_missing
|
68
|
+
def const_missing_with_bits(name)
|
69
|
+
name = name.to_s
|
70
|
+
mappings = {
|
71
|
+
/^Bit(\d+)$/ => :big,
|
72
|
+
/^Bit(\d+)le$/ => :little
|
73
|
+
}
|
74
|
+
|
75
|
+
mappings.each_pair do |regex, endian|
|
76
|
+
if regex =~ name
|
77
|
+
nbits = $1.to_i
|
78
|
+
return BitField.define_class(nbits, endian)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
const_missing_without_bits(name)
|
83
|
+
end
|
84
|
+
alias_method :const_missing, :const_missing_with_bits
|
67
85
|
end
|
68
86
|
end
|
data/lib/bindata/int.rb
CHANGED
@@ -8,17 +8,18 @@ module BinData
|
|
8
8
|
class << self
|
9
9
|
def define_class(nbits, endian, signed)
|
10
10
|
name = class_name(nbits, endian, signed)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
unless BinData.const_defined?(name)
|
12
|
+
int_type = (signed == :signed) ? 'int' : 'uint'
|
13
|
+
creation_method = "create_#{int_type}_methods"
|
14
|
+
|
15
|
+
BinData.module_eval <<-END
|
16
|
+
class #{name} < BinData::BasePrimitive
|
17
|
+
register(self.name, self)
|
18
|
+
Int.#{creation_method}(self, #{nbits}, :#{endian.to_s})
|
19
|
+
end
|
20
|
+
END
|
21
|
+
end
|
22
|
+
BinData.const_get(name)
|
22
23
|
end
|
23
24
|
|
24
25
|
def class_name(nbits, endian, signed)
|
@@ -182,11 +183,29 @@ module BinData
|
|
182
183
|
Int.create_int_methods(self, 8, :little)
|
183
184
|
end
|
184
185
|
|
185
|
-
# Create
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
186
|
+
# Create classes on demand
|
187
|
+
class << self
|
188
|
+
alias_method :const_missing_without_int, :const_missing
|
189
|
+
def const_missing_with_int(name)
|
190
|
+
name = name.to_s
|
191
|
+
mappings = {
|
192
|
+
/^Uint(\d+)be$/ => [:big, :unsigned],
|
193
|
+
/^Uint(\d+)le$/ => [:little, :unsigned],
|
194
|
+
/^Int(\d+)be$/ => [:big, :signed],
|
195
|
+
/^Int(\d+)le$/ => [:little, :signed],
|
196
|
+
}
|
197
|
+
|
198
|
+
mappings.each_pair do |regex, args|
|
199
|
+
if regex =~ name
|
200
|
+
nbits = $1.to_i
|
201
|
+
if (nbits % 8).zero?
|
202
|
+
return Int.define_class(nbits, *args)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
const_missing_without_int(name)
|
208
|
+
end
|
209
|
+
alias_method :const_missing, :const_missing_with_int
|
191
210
|
end
|
192
211
|
end
|
data/lib/bindata/io.rb
CHANGED
@@ -69,7 +69,10 @@ module BinData
|
|
69
69
|
|
70
70
|
# Seek +n+ bytes from the current position in the io stream.
|
71
71
|
def seekbytes(n)
|
72
|
+
reset_read_bits
|
72
73
|
@raw_io.seek(n, ::IO::SEEK_CUR)
|
74
|
+
rescue Errno::ESPIPE, Errno::EPIPE
|
75
|
+
skipbytes(n)
|
73
76
|
end
|
74
77
|
|
75
78
|
# Reads exactly +n+ bytes from +io+.
|
@@ -78,9 +81,7 @@ module BinData
|
|
78
81
|
#
|
79
82
|
# If the data read is too short an IOError is raised.
|
80
83
|
def readbytes(n)
|
81
|
-
|
82
|
-
@rnbits = 0
|
83
|
-
@rval = 0
|
84
|
+
reset_read_bits
|
84
85
|
|
85
86
|
str = @raw_io.read(n)
|
86
87
|
raise EOFError, "End of file reached" if str.nil?
|
@@ -90,10 +91,7 @@ module BinData
|
|
90
91
|
|
91
92
|
# Reads all remaining bytes from the stream.
|
92
93
|
def read_all_bytes
|
93
|
-
|
94
|
-
@rnbits = 0
|
95
|
-
@rval = 0
|
96
|
-
|
94
|
+
reset_read_bits
|
97
95
|
@raw_io.read
|
98
96
|
end
|
99
97
|
|
@@ -102,8 +100,7 @@ module BinData
|
|
102
100
|
def readbits(nbits, endian)
|
103
101
|
if @rendian != endian
|
104
102
|
# don't mix bits of differing endian
|
105
|
-
|
106
|
-
@rval = 0
|
103
|
+
reset_read_bits
|
107
104
|
@rendian = endian
|
108
105
|
end
|
109
106
|
|
@@ -126,7 +123,6 @@ module BinData
|
|
126
123
|
if @wendian != endian
|
127
124
|
# don't mix bits of differing endian
|
128
125
|
flushbits
|
129
|
-
|
130
126
|
@wendian = endian
|
131
127
|
end
|
132
128
|
|
@@ -164,6 +160,21 @@ module BinData
|
|
164
160
|
@positioning_supported
|
165
161
|
end
|
166
162
|
|
163
|
+
def reset_read_bits
|
164
|
+
raise "Internal state error nbits = #{@rnbits}" if @rnbits >= 8
|
165
|
+
@rnbits = 0
|
166
|
+
@rval = 0
|
167
|
+
end
|
168
|
+
|
169
|
+
def skipbytes(n)
|
170
|
+
# skip over data in 8k blocks
|
171
|
+
while n > 0
|
172
|
+
bytes_to_read = [n, 8192].min
|
173
|
+
@raw_io.read(bytes_to_read)
|
174
|
+
n -= bytes_to_read
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
167
178
|
def read_big_endian_bits(nbits)
|
168
179
|
while @rnbits < nbits
|
169
180
|
accumulate_big_endian_bits
|
data/lib/bindata/primitive.rb
CHANGED
@@ -68,7 +68,7 @@ module BinData
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def endian(endian = nil)
|
71
|
-
@endian ||=
|
71
|
+
@endian ||= default_endian
|
72
72
|
if [:little, :big].include?(endian)
|
73
73
|
@endian = endian
|
74
74
|
elsif endian != nil
|
@@ -78,9 +78,18 @@ module BinData
|
|
78
78
|
@endian
|
79
79
|
end
|
80
80
|
|
81
|
+
def fields #:nodoc:
|
82
|
+
@fields ||= default_fields
|
83
|
+
end
|
84
|
+
|
81
85
|
def method_missing(symbol, *args) #:nodoc:
|
82
86
|
name, params = args
|
83
87
|
|
88
|
+
if name.is_a?(Hash)
|
89
|
+
params = name
|
90
|
+
name = nil
|
91
|
+
end
|
92
|
+
|
84
93
|
type = symbol
|
85
94
|
name = name.to_s
|
86
95
|
params ||= {}
|
@@ -99,18 +108,30 @@ module BinData
|
|
99
108
|
#-------------
|
100
109
|
private
|
101
110
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
|
111
|
+
def parent_primitive
|
112
|
+
ancestors[1..-1].find { |cls|
|
113
|
+
cls.ancestors[1..-1].include?(BinData::Primitive)
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def default_endian
|
118
|
+
prim = parent_primitive
|
119
|
+
prim ? prim.endian : nil
|
120
|
+
end
|
121
|
+
|
122
|
+
def default_fields
|
123
|
+
prim = parent_primitive
|
124
|
+
if prim
|
125
|
+
Sanitizer.new.clone_sanitized_fields(prim.fields)
|
126
|
+
else
|
127
|
+
Sanitizer.new.create_sanitized_fields
|
106
128
|
end
|
107
|
-
@fields
|
108
129
|
end
|
109
130
|
|
110
131
|
def append_field(type, name, params)
|
111
132
|
ensure_valid_name(name)
|
112
133
|
|
113
|
-
fields.add_field(type, name, params)
|
134
|
+
fields.add_field(type, name, params, endian)
|
114
135
|
rescue UnknownTypeError => err
|
115
136
|
raise TypeError, "unknown type '#{err.message}' for #{self}", caller(2)
|
116
137
|
end
|
data/lib/bindata/record.rb
CHANGED
@@ -52,7 +52,7 @@ module BinData
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def endian(endian = nil)
|
55
|
-
@endian ||=
|
55
|
+
@endian ||= default_endian
|
56
56
|
if [:little, :big].include?(endian)
|
57
57
|
@endian = endian
|
58
58
|
elsif endian != nil
|
@@ -63,14 +63,23 @@ module BinData
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def hide(*args)
|
66
|
-
@hide ||=
|
66
|
+
@hide ||= default_hide
|
67
67
|
@hide.concat(args.collect { |name| name.to_s })
|
68
68
|
@hide
|
69
69
|
end
|
70
70
|
|
71
|
+
def fields #:nodoc:
|
72
|
+
@fields ||= default_fields
|
73
|
+
end
|
74
|
+
|
71
75
|
def method_missing(symbol, *args) #:nodoc:
|
72
76
|
name, params = args
|
73
77
|
|
78
|
+
if name.is_a?(Hash)
|
79
|
+
params = name
|
80
|
+
name = nil
|
81
|
+
end
|
82
|
+
|
74
83
|
type = symbol
|
75
84
|
name = name.to_s
|
76
85
|
params ||= {}
|
@@ -89,18 +98,35 @@ module BinData
|
|
89
98
|
#-------------
|
90
99
|
private
|
91
100
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
|
101
|
+
def parent_record
|
102
|
+
ancestors[1..-1].find { |cls|
|
103
|
+
cls.ancestors[1..-1].include?(BinData::Record)
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
def default_endian
|
108
|
+
rec = parent_record
|
109
|
+
rec ? rec.endian : nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def default_hide
|
113
|
+
rec = parent_record
|
114
|
+
rec ? rec.hide.dup : []
|
115
|
+
end
|
116
|
+
|
117
|
+
def default_fields
|
118
|
+
rec = parent_record
|
119
|
+
if rec
|
120
|
+
Sanitizer.new.clone_sanitized_fields(rec.fields)
|
121
|
+
else
|
122
|
+
Sanitizer.new.create_sanitized_fields
|
96
123
|
end
|
97
|
-
@fields
|
98
124
|
end
|
99
125
|
|
100
126
|
def append_field(type, name, params)
|
101
127
|
ensure_valid_name(name)
|
102
128
|
|
103
|
-
fields.add_field(type, name, params)
|
129
|
+
fields.add_field(type, name, params, endian)
|
104
130
|
rescue UnknownTypeError => err
|
105
131
|
raise TypeError, "unknown type '#{err.message}' for #{self}", caller(2)
|
106
132
|
end
|
data/lib/bindata/registry.rb
CHANGED
@@ -9,6 +9,8 @@ module BinData
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def register(name, class_to_register)
|
12
|
+
return if class_to_register.nil?
|
13
|
+
|
12
14
|
formatted_name = lookup_key(name)
|
13
15
|
warn_if_name_is_already_registered(formatted_name, class_to_register)
|
14
16
|
|
@@ -17,15 +19,16 @@ module BinData
|
|
17
19
|
|
18
20
|
def lookup(name, endian = nil)
|
19
21
|
key = lookup_key(name, endian)
|
22
|
+
try_registering_key(key) unless @registry.has_key?(key)
|
20
23
|
|
21
|
-
@registry[key]
|
24
|
+
@registry[key]
|
22
25
|
end
|
23
26
|
|
24
27
|
def is_registered?(name, endian = nil)
|
25
|
-
|
28
|
+
lookup(name, endian) != nil
|
26
29
|
end
|
27
30
|
|
28
|
-
# Convert
|
31
|
+
# Convert CamelCase +name+ to underscore style.
|
29
32
|
def underscore_name(name)
|
30
33
|
name.to_s.sub(/.*::/, "").
|
31
34
|
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
@@ -51,29 +54,18 @@ module BinData
|
|
51
54
|
result
|
52
55
|
end
|
53
56
|
|
54
|
-
def
|
55
|
-
if /^
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
if BinData.const_defined?(:Int)
|
61
|
-
BinData::Int.define_class(nbits, endian, signed)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
elsif /^bit(\d+)(le)?$/ =~ key
|
65
|
-
nbits = $1.to_i
|
66
|
-
endian = $2 == "le" ? :little : :big
|
67
|
-
if BinData.const_defined?(:BitField)
|
68
|
-
BinData::BitField.define_class(nbits, endian)
|
57
|
+
def try_registering_key(key)
|
58
|
+
if /^u?int\d+(le|be)$/ =~ key or /^bit\d+(le)?$/ =~ key
|
59
|
+
class_name = key.gsub(/(?:^|_)(.)/) { $1.upcase }
|
60
|
+
begin
|
61
|
+
register(key, BinData::const_get(class_name))
|
62
|
+
rescue NameError
|
69
63
|
end
|
70
64
|
end
|
71
|
-
|
72
|
-
@registry[key]
|
73
65
|
end
|
74
66
|
|
75
67
|
def warn_if_name_is_already_registered(name, class_to_register)
|
76
|
-
if $VERBOSE and @registry
|
68
|
+
if $VERBOSE and @registry[name] != class_to_register
|
77
69
|
prev_class = @registry[name]
|
78
70
|
warn "warning: replacing registered class #{prev_class} " +
|
79
71
|
"with #{class_to_register}"
|
data/lib/bindata/sanitize.rb
CHANGED
@@ -149,8 +149,14 @@ module BinData
|
|
149
149
|
SanitizedChoices.new(self, choices)
|
150
150
|
end
|
151
151
|
|
152
|
-
def create_sanitized_fields
|
153
|
-
SanitizedFields.new(self
|
152
|
+
def create_sanitized_fields
|
153
|
+
SanitizedFields.new(self)
|
154
|
+
end
|
155
|
+
|
156
|
+
def clone_sanitized_fields(fields)
|
157
|
+
new_fields = SanitizedFields.new(self)
|
158
|
+
new_fields.copy_fields(fields)
|
159
|
+
new_fields
|
154
160
|
end
|
155
161
|
|
156
162
|
def create_sanitized_object_prototype(obj_type, obj_params, endian = nil)
|
@@ -192,7 +198,7 @@ module BinData
|
|
192
198
|
class SanitizedParameter; end
|
193
199
|
|
194
200
|
class SanitizedPrototype < SanitizedParameter
|
195
|
-
def initialize(sanitizer, obj_type, obj_params, endian
|
201
|
+
def initialize(sanitizer, obj_type, obj_params, endian)
|
196
202
|
sanitizer.with_endian(endian) do
|
197
203
|
@obj_class = sanitizer.lookup_class(obj_type)
|
198
204
|
@obj_params = sanitizer.create_sanitized_params(obj_params, @obj_class)
|
@@ -206,9 +212,9 @@ module BinData
|
|
206
212
|
#----------------------------------------------------------------------------
|
207
213
|
|
208
214
|
class SanitizedField < SanitizedParameter
|
209
|
-
def initialize(sanitizer, name, field_type, field_params)
|
210
|
-
@name = name.to_s
|
211
|
-
@prototype = sanitizer.create_sanitized_object_prototype(field_type, field_params)
|
215
|
+
def initialize(sanitizer, name, field_type, field_params, endian)
|
216
|
+
@name = (name != nil and name != "") ? name.to_s : nil
|
217
|
+
@prototype = sanitizer.create_sanitized_object_prototype(field_type, field_params, endian)
|
212
218
|
end
|
213
219
|
attr_reader :name
|
214
220
|
|
@@ -219,16 +225,13 @@ module BinData
|
|
219
225
|
#----------------------------------------------------------------------------
|
220
226
|
|
221
227
|
class SanitizedFields < SanitizedParameter
|
222
|
-
def initialize(sanitizer
|
228
|
+
def initialize(sanitizer)
|
223
229
|
@sanitizer = sanitizer
|
224
|
-
@endian = endian
|
225
230
|
@fields = []
|
226
231
|
end
|
227
232
|
|
228
|
-
def add_field(type, name, params)
|
229
|
-
@
|
230
|
-
@fields << SanitizedField.new(@sanitizer, name, type, params)
|
231
|
-
end
|
233
|
+
def add_field(type, name, params, endian)
|
234
|
+
@fields << SanitizedField.new(@sanitizer, name, type, params, endian)
|
232
235
|
end
|
233
236
|
|
234
237
|
def [](idx)
|
@@ -238,6 +241,11 @@ module BinData
|
|
238
241
|
def field_names
|
239
242
|
@fields.collect { |field| field.name }
|
240
243
|
end
|
244
|
+
|
245
|
+
def copy_fields(other)
|
246
|
+
other_fields = other.instance_variable_get(:@fields)
|
247
|
+
@fields.concat(other_fields)
|
248
|
+
end
|
241
249
|
end
|
242
250
|
#----------------------------------------------------------------------------
|
243
251
|
|
data/lib/bindata/skip.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "bindata/base_primitive"
|
2
|
+
|
3
|
+
module BinData
|
4
|
+
# Skip will skip over bytes from the input stream. If the stream is not
|
5
|
+
# seekable, then the bytes are consumed and discarded.
|
6
|
+
#
|
7
|
+
# When writing, skip will write <tt>:length</tt> number of zero bytes.
|
8
|
+
#
|
9
|
+
# require 'bindata'
|
10
|
+
#
|
11
|
+
# class A < BinData::Record
|
12
|
+
# skip :length => 5
|
13
|
+
# string :a, :read_length => 5
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# obj = A.read("abcdefghij")
|
17
|
+
# obj.a #=> "fghij"
|
18
|
+
#
|
19
|
+
# == Parameters
|
20
|
+
#
|
21
|
+
# Skip objects accept all the params that BinData::BasePrimitive
|
22
|
+
# does, as well as the following:
|
23
|
+
#
|
24
|
+
# <tt>:length</tt>:: The number of bytes to skip.
|
25
|
+
#
|
26
|
+
class Skip < BinData::BasePrimitive
|
27
|
+
register(self.name, self)
|
28
|
+
|
29
|
+
mandatory_parameter :length
|
30
|
+
|
31
|
+
#---------------
|
32
|
+
private
|
33
|
+
|
34
|
+
def value_to_binary_string(val)
|
35
|
+
len = eval_parameter(:length)
|
36
|
+
"\000" * len
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_and_return_value(io)
|
40
|
+
len = eval_parameter(:length)
|
41
|
+
io.seekbytes(len)
|
42
|
+
""
|
43
|
+
end
|
44
|
+
|
45
|
+
def sensible_default
|
46
|
+
""
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/bindata/struct.rb
CHANGED
@@ -28,7 +28,8 @@ module BinData
|
|
28
28
|
# params]. Type is a symbol representing a registered
|
29
29
|
# type. Name is the name of this field. Params is an
|
30
30
|
# optional hash of parameters to pass to this field
|
31
|
-
# when instantiating it.
|
31
|
+
# when instantiating it. If name is "" or nil, then
|
32
|
+
# that field is anonymous and behaves as a hidden field.
|
32
33
|
# <tt>:hide</tt>:: A list of the names of fields that are to be hidden
|
33
34
|
# from the outside world. Hidden fields don't appear
|
34
35
|
# in #snapshot or #field_names but are still accessible
|
@@ -88,9 +89,9 @@ module BinData
|
|
88
89
|
if params.needs_sanitizing?(:fields)
|
89
90
|
fields = params[:fields]
|
90
91
|
|
91
|
-
params[:fields] = sanitizer.create_sanitized_fields
|
92
|
+
params[:fields] = sanitizer.create_sanitized_fields
|
92
93
|
fields.each do |ftype, fname, fparams|
|
93
|
-
params[:fields].add_field(ftype, fname, fparams)
|
94
|
+
params[:fields].add_field(ftype, fname, fparams, params[:endian])
|
94
95
|
end
|
95
96
|
|
96
97
|
field_names = sanitized_field_names(params[:fields])
|
@@ -108,7 +109,7 @@ module BinData
|
|
108
109
|
end
|
109
110
|
|
110
111
|
def sanitized_field_names(sanitized_fields)
|
111
|
-
sanitized_fields.field_names
|
112
|
+
sanitized_fields.field_names.compact
|
112
113
|
end
|
113
114
|
|
114
115
|
def hidden_field_names(hidden)
|
@@ -159,10 +160,10 @@ module BinData
|
|
159
160
|
# in the listing.
|
160
161
|
def field_names(include_hidden = false)
|
161
162
|
if include_hidden
|
162
|
-
@field_names.
|
163
|
+
@field_names.compact
|
163
164
|
else
|
164
165
|
hidden = get_parameter(:hide) || []
|
165
|
-
@field_names - hidden
|
166
|
+
@field_names.compact - hidden
|
166
167
|
end
|
167
168
|
end
|
168
169
|
|
data/lib/bindata/wrapper.rb
CHANGED
@@ -28,7 +28,7 @@ module BinData
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def endian(endian = nil)
|
31
|
-
@endian ||=
|
31
|
+
@endian ||= default_endian
|
32
32
|
if [:little, :big].include?(endian)
|
33
33
|
@endian = endian
|
34
34
|
elsif endian != nil
|
@@ -38,17 +38,31 @@ module BinData
|
|
38
38
|
@endian
|
39
39
|
end
|
40
40
|
|
41
|
+
def wrapped(*args)
|
42
|
+
@wrapped ||= default_wrapped
|
43
|
+
if args.length == 2
|
44
|
+
type, params = *args
|
45
|
+
ensure_type_exists(type)
|
46
|
+
|
47
|
+
if wrapped != nil
|
48
|
+
raise SyntaxError, "#{self} can only wrap one type", caller(2)
|
49
|
+
end
|
50
|
+
@wrapped = [type, params]
|
51
|
+
end
|
52
|
+
@wrapped
|
53
|
+
end
|
54
|
+
|
41
55
|
def method_missing(symbol, *args) #:nodoc:
|
42
56
|
type = symbol
|
43
57
|
params = args.length == 0 ? {} : args[0]
|
44
58
|
|
45
|
-
|
59
|
+
wrapped(type, params)
|
46
60
|
end
|
47
61
|
|
48
62
|
def sanitize_parameters!(params, sanitizer) #:nodoc:
|
49
|
-
raise "Nothing to wrap"
|
63
|
+
raise "Nothing to wrap" if wrapped.nil?
|
50
64
|
|
51
|
-
wrapped_type, wrapped_params =
|
65
|
+
wrapped_type, wrapped_params = wrapped
|
52
66
|
wrapped_params = wrapped_params.dup
|
53
67
|
|
54
68
|
params.move_unknown_parameters_to(wrapped_params)
|
@@ -59,13 +73,20 @@ module BinData
|
|
59
73
|
#-------------
|
60
74
|
private
|
61
75
|
|
62
|
-
def
|
63
|
-
|
76
|
+
def parent_wrapper
|
77
|
+
ancestors[1..-1].find { |cls|
|
78
|
+
cls.ancestors[1..-1].include?(BinData::Wrapper)
|
79
|
+
}
|
80
|
+
end
|
64
81
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
82
|
+
def default_endian
|
83
|
+
wrap = parent_wrapper
|
84
|
+
wrap ? wrap.endian : nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def default_wrapped
|
88
|
+
wrap = parent_wrapper
|
89
|
+
wrap ? wrap.wrapped : nil
|
69
90
|
end
|
70
91
|
|
71
92
|
def ensure_type_exists(type)
|
data/manual.haml
CHANGED
@@ -125,6 +125,11 @@
|
|
125
125
|
License
|
126
126
|
.acc-section
|
127
127
|
.acc-content
|
128
|
+
%li
|
129
|
+
%a{ :href => "#installation" }
|
130
|
+
Installation
|
131
|
+
.acc-section
|
132
|
+
.acc-content
|
128
133
|
%li
|
129
134
|
%a{ :href => "#overview" }
|
130
135
|
Overview
|
@@ -247,6 +252,11 @@
|
|
247
252
|
.acc-section
|
248
253
|
.acc-content
|
249
254
|
%ul.level2#menu9
|
255
|
+
%li
|
256
|
+
%a{ :href => "#skipping_over_unused_data" }
|
257
|
+
Skipping over unused data
|
258
|
+
.acc-section
|
259
|
+
.acc-content
|
250
260
|
%li
|
251
261
|
%a{ :href => "#wrappers" }
|
252
262
|
Wrappers
|
data/spec/int_spec.rb
CHANGED
@@ -149,7 +149,6 @@ share_examples_for "All Integers" do
|
|
149
149
|
(1 .. 20).each do |nbytes|
|
150
150
|
nbits = nbytes * 8
|
151
151
|
class_name = "#{base}#{nbits}#{endian_str}"
|
152
|
-
BinData::Int.define_class(nbits, endian, signed_sym)
|
153
152
|
result[BinData.const_get(class_name)] = nbytes
|
154
153
|
end
|
155
154
|
|
@@ -200,19 +199,19 @@ end
|
|
200
199
|
describe "Custom defined integers" do
|
201
200
|
it "should fail unless bits are a multiple of 8" do
|
202
201
|
lambda {
|
203
|
-
BinData::
|
202
|
+
BinData::Uint7le
|
204
203
|
}.should raise_error
|
205
204
|
|
206
205
|
lambda {
|
207
|
-
BinData::
|
206
|
+
BinData::Uint7be
|
208
207
|
}.should raise_error
|
209
208
|
|
210
209
|
lambda {
|
211
|
-
BinData::
|
210
|
+
BinData::Int7le
|
212
211
|
}.should raise_error
|
213
212
|
|
214
213
|
lambda {
|
215
|
-
BinData::
|
214
|
+
BinData::Int7be
|
216
215
|
}.should raise_error
|
217
216
|
end
|
218
217
|
end
|
data/spec/io_spec.rb
CHANGED
@@ -3,6 +3,44 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
4
|
require 'bindata/io'
|
5
5
|
|
6
|
+
describe BinData::IO, "reading from non seekable stream" do
|
7
|
+
before(:each) do
|
8
|
+
@rd, @wr = IO::pipe
|
9
|
+
if fork
|
10
|
+
# parent
|
11
|
+
@wr.close
|
12
|
+
@io = BinData::IO.new(@rd)
|
13
|
+
else
|
14
|
+
# child
|
15
|
+
begin
|
16
|
+
@rd.close
|
17
|
+
@wr.write "a" * 5000
|
18
|
+
@wr.write "b" * 5000
|
19
|
+
@wr.close
|
20
|
+
rescue Exception
|
21
|
+
# ignore it
|
22
|
+
ensure
|
23
|
+
exit!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
after(:each) do
|
29
|
+
@rd.close
|
30
|
+
Process.wait
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should always have an offset of 0" do
|
34
|
+
@io.readbytes(10)
|
35
|
+
@io.offset.should == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should seek" do
|
39
|
+
@io.seekbytes(4999)
|
40
|
+
@io.readbytes(5).should == "abbbb"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
6
44
|
describe BinData::IO do
|
7
45
|
it "should wrap strings in StringIO" do
|
8
46
|
io = BinData::IO.new("abcd")
|
data/spec/primitive_spec.rb
CHANGED
@@ -152,3 +152,20 @@ describe BinData::Primitive, "with custom default parameters" do
|
|
152
152
|
obj.value.should == 7
|
153
153
|
end
|
154
154
|
end
|
155
|
+
|
156
|
+
describe BinData::Primitive, "derived classes" do
|
157
|
+
class ParentDerivedPrimitive < BinData::Primitive
|
158
|
+
uint16be :a
|
159
|
+
def get; self.a; end
|
160
|
+
def set(v); self.a = v; end
|
161
|
+
end
|
162
|
+
|
163
|
+
class ChildDerivedPrimitive < ParentDerivedPrimitive
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should derive" do
|
167
|
+
a = ChildDerivedPrimitive.new
|
168
|
+
a.value = 7
|
169
|
+
a.to_binary_s.should == "\000\007"
|
170
|
+
end
|
171
|
+
end
|
data/spec/record_spec.rb
CHANGED
@@ -71,6 +71,34 @@ describe BinData::Record, "when defining" do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
describe BinData::Record, "with anonymous fields" do
|
75
|
+
class AnonymousRecord < BinData::Record
|
76
|
+
int8 'a', :initial_value => 10
|
77
|
+
int8 ''
|
78
|
+
int8 :value => :a
|
79
|
+
end
|
80
|
+
|
81
|
+
before(:each) do
|
82
|
+
@obj = AnonymousRecord.new
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should only show non anonymous fields" do
|
86
|
+
@obj.field_names.should == ["a"]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should not include anonymous fields in snapshot" do
|
90
|
+
@obj.a = 5
|
91
|
+
@obj.snapshot.should == {"a" => 5}
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should write anonymous fields" do
|
95
|
+
str = "\001\002\003"
|
96
|
+
@obj.read(str)
|
97
|
+
@obj.a.clear
|
98
|
+
@obj.to_binary_s.should == "\012\002\012"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
74
102
|
describe BinData::Record, "with hidden fields" do
|
75
103
|
class HiddenRecord < BinData::Record
|
76
104
|
hide :b, 'c'
|
@@ -350,3 +378,24 @@ describe BinData::Record, "with :onlyif" do
|
|
350
378
|
@obj.to_binary_s.should == "\x03\x05"
|
351
379
|
end
|
352
380
|
end
|
381
|
+
|
382
|
+
describe BinData::Record, "derived classes" do
|
383
|
+
class ParentDerivedRecord < BinData::Record
|
384
|
+
uint8 :a
|
385
|
+
end
|
386
|
+
|
387
|
+
class ChildDerivedRecord < ParentDerivedRecord
|
388
|
+
uint8 :b
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should not affect parent" do
|
392
|
+
parent = ParentDerivedRecord.new
|
393
|
+
parent.field_names.should == ["a"]
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should inherit fields" do
|
397
|
+
child = ChildDerivedRecord.new
|
398
|
+
child.field_names.should == ["a", "b"]
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
data/spec/registry_spec.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), "spec_common"))
|
4
4
|
require 'bindata/bits'
|
5
5
|
require 'bindata/int'
|
6
|
+
require 'bindata/float'
|
6
7
|
require 'bindata/registry'
|
7
8
|
|
8
9
|
describe BinData::Registry do
|
@@ -55,54 +56,46 @@ describe BinData::Registry do
|
|
55
56
|
it "should ignore the outer nestings of classes" do
|
56
57
|
@r.underscore_name('A::B::C').should == 'c'
|
57
58
|
end
|
59
|
+
end
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
@r
|
62
|
-
|
63
|
-
@r.register("Uint24be", C)
|
64
|
-
@r.register("Uint24le", D)
|
61
|
+
describe BinData::Registry, "with numerics" do
|
62
|
+
before(:each) do
|
63
|
+
@r = BinData::RegisteredClasses
|
64
|
+
end
|
65
65
|
|
66
|
-
|
67
|
-
@r.lookup("int24", :
|
68
|
-
@r.lookup("
|
69
|
-
@r.lookup("uint24", :
|
66
|
+
it "should lookup integers with endian" do
|
67
|
+
@r.lookup("int24", :big).to_s.should == "BinData::Int24be"
|
68
|
+
@r.lookup("int24", :little).to_s.should == "BinData::Int24le"
|
69
|
+
@r.lookup("uint24", :big).to_s.should == "BinData::Uint24be"
|
70
|
+
@r.lookup("uint24", :little).to_s.should == "BinData::Uint24le"
|
70
71
|
end
|
71
72
|
|
72
73
|
it "should not lookup integers without endian" do
|
73
|
-
@r.register("Int24be", A)
|
74
|
-
|
75
74
|
@r.lookup("int24").should be_nil
|
76
75
|
end
|
77
76
|
|
78
|
-
it "should lookup
|
79
|
-
@r.
|
80
|
-
@r.
|
81
|
-
@r.
|
82
|
-
@r.register("DoubleLe", D)
|
83
|
-
|
84
|
-
@r.lookup("float", :big).should == A
|
85
|
-
@r.lookup("float", :little).should == B
|
86
|
-
@r.lookup("double", :big).should == C
|
87
|
-
@r.lookup("double", :little).should == D
|
77
|
+
it "should not lookup non byte based integers" do
|
78
|
+
@r.lookup("int3").should be_nil
|
79
|
+
@r.lookup("int3", :big).should be_nil
|
80
|
+
@r.lookup("int3", :little).should be_nil
|
88
81
|
end
|
89
82
|
|
90
|
-
it "should
|
91
|
-
|
92
|
-
@r.lookup("
|
93
|
-
|
83
|
+
it "should lookup floats with endian" do
|
84
|
+
@r.lookup("float", :big).to_s.should == "BinData::FloatBe"
|
85
|
+
@r.lookup("float", :little).to_s.should == "BinData::FloatLe"
|
86
|
+
@r.lookup("double", :big).to_s.should == "BinData::DoubleBe"
|
87
|
+
@r.lookup("double", :little).to_s.should == "BinData::DoubleLe"
|
94
88
|
end
|
95
89
|
|
96
|
-
it "should
|
97
|
-
|
98
|
-
@r.lookup("
|
99
|
-
BinData.const_defined?(:Bit801).should be_true
|
90
|
+
it "should lookup bits" do
|
91
|
+
@r.lookup("bit5").to_s.should == "BinData::Bit5"
|
92
|
+
@r.lookup("bit6le").to_s.should == "BinData::Bit6le"
|
100
93
|
end
|
101
94
|
|
102
|
-
it "should
|
103
|
-
|
104
|
-
@r.lookup("
|
105
|
-
|
95
|
+
it "should lookup bits by ignoring endian" do
|
96
|
+
@r.lookup("bit2", :big).to_s.should == "BinData::Bit2"
|
97
|
+
@r.lookup("bit3le", :big).to_s.should == "BinData::Bit3le"
|
98
|
+
@r.lookup("bit2", :little).to_s.should == "BinData::Bit2"
|
99
|
+
@r.lookup("bit3le", :little).to_s.should == "BinData::Bit3le"
|
106
100
|
end
|
107
|
-
=end
|
108
101
|
end
|
data/spec/skip_spec.rb
ADDED
@@ -0,0 +1,35 @@
|
|
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
|
+
before(:each) do
|
8
|
+
@skip = BinData::Skip.new(:length => 5)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should default to the empty string" do
|
12
|
+
@skip.should == ""
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should skip bytes" do
|
16
|
+
io = StringIO.new("abcdefghij")
|
17
|
+
@skip.read(io)
|
18
|
+
io.pos.should == 5
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have expected binary representation" do
|
22
|
+
@skip.to_binary_s.should == "\000" * 5
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have expected binary representation after setting value" do
|
26
|
+
@skip.value = "123"
|
27
|
+
@skip.to_binary_s.should == "\000" * 5
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have expected binary representation after reading" do
|
31
|
+
io = StringIO.new("abcdefghij")
|
32
|
+
@skip.read(io)
|
33
|
+
@skip.to_binary_s.should == "\000" * 5
|
34
|
+
end
|
35
|
+
end
|
data/spec/struct_spec.rb
CHANGED
@@ -41,6 +41,32 @@ describe BinData::Struct, "when initializing" do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
describe BinData::Struct, "with anonymous fields" do
|
45
|
+
before(:each) do
|
46
|
+
@params = { :fields => [
|
47
|
+
[:int8, :a, {:initial_value => 10}],
|
48
|
+
[:int8, nil],
|
49
|
+
[:int8, '', {:value => :a}]] }
|
50
|
+
@obj = BinData::Struct.new(@params)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should only show non anonymous fields" do
|
54
|
+
@obj.field_names.should == ["a"]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should not include anonymous fields in snapshot" do
|
58
|
+
@obj.a = 5
|
59
|
+
@obj.snapshot.should == {"a" => 5}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should write anonymous fields" do
|
63
|
+
str = "\001\002\003"
|
64
|
+
@obj.read(str)
|
65
|
+
@obj.a.clear
|
66
|
+
@obj.to_binary_s.should == "\012\002\012"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
44
70
|
describe BinData::Struct, "with hidden fields" do
|
45
71
|
before(:each) do
|
46
72
|
@params = { :hide => [:b, 'c'],
|
data/spec/wrapper_spec.rb
CHANGED
@@ -81,3 +81,17 @@ describe BinData::Wrapper, "inside a struct" do
|
|
81
81
|
obj.should == {'b' => 2}
|
82
82
|
end
|
83
83
|
end
|
84
|
+
|
85
|
+
describe BinData::Wrapper, "derived classes" do
|
86
|
+
class ParentDerivedWrapper < BinData::Wrapper
|
87
|
+
uint32le
|
88
|
+
end
|
89
|
+
|
90
|
+
class ChildDerivedWrapper < ParentDerivedWrapper
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should wrap" do
|
94
|
+
a = ChildDerivedWrapper.new
|
95
|
+
a.num_bytes.should == 4
|
96
|
+
end
|
97
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bindata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dion Mendel
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-24 00:00:00 +08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -22,67 +22,71 @@ extensions: []
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- NEWS
|
24
24
|
files:
|
25
|
-
- INSTALL
|
26
|
-
- TODO
|
27
|
-
- GPL
|
28
|
-
- Rakefile
|
29
25
|
- COPYING
|
30
|
-
-
|
26
|
+
- INSTALL
|
31
27
|
- README
|
28
|
+
- NEWS
|
29
|
+
- GPL
|
32
30
|
- ChangeLog
|
33
|
-
-
|
31
|
+
- Rakefile
|
32
|
+
- TODO
|
34
33
|
- examples/ip_address.rb
|
35
|
-
-
|
36
|
-
- spec/record_spec.rb
|
37
|
-
- spec/float_spec.rb
|
38
|
-
- spec/int_spec.rb
|
39
|
-
- spec/registry_spec.rb
|
40
|
-
- spec/lazy_spec.rb
|
41
|
-
- spec/deprecated_spec.rb
|
42
|
-
- spec/array_spec.rb
|
43
|
-
- spec/bits_spec.rb
|
34
|
+
- examples/gzip.rb
|
44
35
|
- spec/io_spec.rb
|
45
|
-
- spec/struct_spec.rb
|
46
|
-
- spec/stringz_spec.rb
|
47
36
|
- spec/rest_spec.rb
|
48
|
-
- spec/
|
37
|
+
- spec/lazy_spec.rb
|
38
|
+
- spec/primitive_spec.rb
|
49
39
|
- spec/wrapper_spec.rb
|
40
|
+
- spec/spec_common.rb
|
41
|
+
- spec/registry_spec.rb
|
42
|
+
- spec/string_spec.rb
|
43
|
+
- spec/stringz_spec.rb
|
50
44
|
- spec/choice_spec.rb
|
51
45
|
- spec/example.rb
|
52
|
-
- spec/system_spec.rb
|
53
|
-
- spec/string_spec.rb
|
54
|
-
- spec/spec_common.rb
|
55
46
|
- spec/base_primitive_spec.rb
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
-
|
61
|
-
-
|
62
|
-
-
|
63
|
-
-
|
47
|
+
- spec/bits_spec.rb
|
48
|
+
- spec/deprecated_spec.rb
|
49
|
+
- spec/base_spec.rb
|
50
|
+
- spec/int_spec.rb
|
51
|
+
- spec/system_spec.rb
|
52
|
+
- spec/record_spec.rb
|
53
|
+
- spec/float_spec.rb
|
54
|
+
- spec/skip_spec.rb
|
55
|
+
- spec/struct_spec.rb
|
56
|
+
- spec/array_spec.rb
|
57
|
+
- lib/bindata/deprecated.rb
|
58
|
+
- lib/bindata/record.rb
|
64
59
|
- lib/bindata/float.rb
|
65
|
-
- lib/bindata/base.rb
|
66
|
-
- lib/bindata/primitive.rb
|
67
60
|
- lib/bindata/registry.rb
|
68
|
-
- lib/bindata/
|
69
|
-
- lib/bindata/
|
61
|
+
- lib/bindata/lazy.rb
|
62
|
+
- lib/bindata/choice.rb
|
63
|
+
- lib/bindata/struct.rb
|
70
64
|
- lib/bindata/params.rb
|
71
|
-
- lib/bindata/
|
65
|
+
- lib/bindata/base_primitive.rb
|
66
|
+
- lib/bindata/bits.rb
|
72
67
|
- lib/bindata/trace.rb
|
68
|
+
- lib/bindata/wrapper.rb
|
69
|
+
- lib/bindata/sanitize.rb
|
70
|
+
- lib/bindata/base.rb
|
71
|
+
- lib/bindata/skip.rb
|
72
|
+
- lib/bindata/rest.rb
|
73
|
+
- lib/bindata/string.rb
|
74
|
+
- lib/bindata/array.rb
|
73
75
|
- lib/bindata/stringz.rb
|
76
|
+
- lib/bindata/primitive.rb
|
77
|
+
- lib/bindata/int.rb
|
74
78
|
- lib/bindata/io.rb
|
75
|
-
- lib/bindata/record.rb
|
76
|
-
- lib/bindata/wrapper.rb
|
77
79
|
- lib/bindata.rb
|
78
80
|
- tasks/rdoc.rake
|
79
81
|
- tasks/manual.rake
|
80
|
-
- tasks/pkg.rake
|
81
82
|
- tasks/rspec.rake
|
83
|
+
- tasks/pkg.rake
|
82
84
|
- setup.rb
|
83
85
|
- manual.haml
|
84
86
|
has_rdoc: true
|
85
87
|
homepage: http://bindata.rubyforge.org
|
88
|
+
licenses: []
|
89
|
+
|
86
90
|
post_install_message:
|
87
91
|
rdoc_options:
|
88
92
|
- --main
|
@@ -104,9 +108,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
108
|
requirements: []
|
105
109
|
|
106
110
|
rubyforge_project: bindata
|
107
|
-
rubygems_version: 1.3.
|
111
|
+
rubygems_version: 1.3.5
|
108
112
|
signing_key:
|
109
|
-
specification_version:
|
113
|
+
specification_version: 3
|
110
114
|
summary: A declarative way to read and write binary file formats
|
111
115
|
test_files: []
|
112
116
|
|