bindata 1.8.3 → 2.0.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.

@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a1591b7284eb5311a1577007b50506a3169849cc
4
+ data.tar.gz: a60a5656dcb5586f12bc7fe88e98af7d12652d7a
5
+ SHA512:
6
+ metadata.gz: 57b52b55ca1ab97820293d9c73b3e085542a955052b64e3873a87e7b8f0fdd84635a33843ad4aeb92dd7b089a7b988e2b9fe236c265189dbe310766811d7c5cc
7
+ data.tar.gz: 01a0327084e334cd02459daf396253b11f266a3c443dcf3f57e144dea6f653e98e5aa4d03249a8f5794bd867e727df609137b5e7519b400aa00cdec9c2cfc64b
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
3
+ - 1.9.3
4
4
  - 2.0.0
5
5
  - jruby
@@ -1,21 +1,12 @@
1
1
  = BinData Changelog
2
2
 
3
- == Version 1.8.3 (2014-04-16)
4
-
5
- * #eval_parameters can now call private methods. Requested by Ole Rasmussen.
6
- * Can now determine state of :onlyif fields. Requested by Ole Rasmussen.
7
- * Renamed #offset to #abs_offset for clarity. #offset is now deprecated.
8
- * Support :byte_align for fields in structs. Requested by Igor Yamolov.
9
- * Added bit fields with dynamic length. Requested by Jacob Dam.
10
-
11
- == Version 1.8.2 (2014-02-02)
12
-
13
- * Virtual fields can now have values.
14
- * Bug fixes.
15
-
16
- == Version 1.8.1 (2014-01-15)
3
+ == Version 2.0.0 (2014-02-02)
17
4
 
5
+ * Ruby 1.8 now has its own separate branch.
6
+ * Struct now uses symbols for field names instead of strings.
18
7
  * Added signed bitfields. Requested by redood.
8
+ * Virtual fields can now have names.
9
+ * Bug fixes.
19
10
 
20
11
  == Version 1.8.0 (2014-01-06)
21
12
 
data/INSTALL CHANGED
@@ -1,11 +1,12 @@
1
- This package is designed to be installed with rubygems. If you don't
2
- have rubygems installed on your system, the older setup.rb is
3
- included as a convenience.
1
+ This package is designed to be installed with rubygems.
4
2
 
5
- ($ su)
6
- # ruby setup.rb
3
+ $ gem install bindata
7
4
 
8
- This simple step installs bindata under the default location for Ruby
9
- libraries. You can also customize the installation by supplying some
10
- options to setup.rb.
11
- Try "ruby setup.rb --help".
5
+ If you are using ruby 1.8
6
+
7
+ $ gem install bindata -v '~> 1.8.0'
8
+
9
+ If you are not using rubygems, you may like to install BinData with
10
+ Minero Aoki's setup.rb found at:
11
+
12
+ https://github.com/rubyworks/setup
data/NEWS.rdoc CHANGED
@@ -1,3 +1,22 @@
1
+ = 2.0.0
2
+
3
+ BinData 2.0.0 requires ruby 1.9 or greater. Support for ruby 1.8 is found in
4
+ BinData versions 1.8.x.
5
+
6
+ Prior to version 2.0.0, BinData used the Ruby 1.8 conversion of strings for
7
+ method names. As of 2.0.0, BinData uses symbols.
8
+
9
+ class A < BinData::Record
10
+ uint8 :a
11
+ uint8 :b
12
+ end
13
+
14
+ # BinData 1.8.x
15
+ A.read "\001\002" #=> {"a"=>1, "b"=>2}
16
+
17
+ # BinData >= 2.0.0
18
+ A.read "\001\002" #=> {:a=>1, :b=>2}
19
+
1
20
  = 1.6.0
2
21
 
3
22
  Added :assert as a replacement for :check_value. Note that :assert performs
data/README.md CHANGED
@@ -43,18 +43,14 @@ for dependent and variable length fields is built in.
43
43
 
44
44
  $ gem install bindata
45
45
 
46
- -or-
46
+ or if running ruby 1.8
47
47
 
48
- $ sudo ruby setup.rb
48
+ $ gem install bindata -v '~> 1.8.0'
49
49
 
50
50
  # Documentation
51
51
 
52
52
  [Read the wiki](http://github.com/dmendel/bindata/wiki).
53
53
 
54
- -or-
55
-
56
- $ rake manual
57
-
58
54
  # Contact
59
55
 
60
56
  If you have any queries / bug reports / suggestions, please contact me
data/Rakefile CHANGED
@@ -14,5 +14,3 @@ Rake::TestTask.new do |t|
14
14
  end
15
15
 
16
16
  task :default => :test
17
-
18
- Dir['tasks/**/*.rake'].each { |t| load t }
@@ -19,9 +19,6 @@ Gem::Specification.new do |s|
19
19
 
20
20
  s.add_development_dependency('rake')
21
21
  s.add_development_dependency('minitest', "> 5.0.0")
22
- s.add_development_dependency('haml', ["< 4.0.0"])
23
- s.add_development_dependency('maruku')
24
- s.add_development_dependency('syntax')
25
22
  s.description = <<-END.gsub(/^ +/, "")
26
23
  BinData is a declarative way to read and write binary file formats.
27
24
 
@@ -1,115 +1,65 @@
1
1
  require 'bindata'
2
- require 'forwardable'
2
+ require 'zlib'
3
3
 
4
4
  # An example of a reader / writer for the GZIP file format as per rfc1952.
5
- # Note that compression is not implemented to keep the example small.
6
- class Gzip
7
- extend Forwardable
8
-
9
- # Known compression methods
10
- DEFLATE = 8
11
-
12
- class Extra < BinData::Record
13
- endian :little
14
-
15
- uint16 :len, :length => lambda { data.length }
16
- string :data, :read_length => :len
17
- end
18
-
19
- class Header < BinData::Record
20
- endian :little
21
-
22
- uint16 :ident, :asserted_value => 0x8b1f
23
- uint8 :compression_method, :initial_value => DEFLATE
24
-
25
- bit3 :freserved, :asserted_value => 0
26
- bit1 :fcomment, :value => lambda { comment.length > 0 ? 1 : 0 }
27
- bit1 :ffile_name, :value => lambda { file_name.length > 0 ? 1 : 0 }
28
- bit1 :fextra, :value => lambda { extra.len > 0 ? 1 : 0 }
29
- bit1 :fcrc16, :value => 0 # see comment below
30
- bit1 :ftext
31
-
32
- # Never include header crc. This is because the current versions of the
33
- # command-line version of gzip (up through version 1.3.x) do not
34
- # support header crc's, and will report that it is a "multi-part gzip
35
- # file" and give up.
36
-
37
- uint32 :mtime
38
- uint8 :extra_flags
39
- uint8 :os, :initial_value => 255 # unknown OS
40
-
41
- # These fields are optional depending on the bits in flags
42
- extra :extra, :onlyif => lambda { fextra.nonzero? }
43
- stringz :file_name, :onlyif => lambda { ffile_name.nonzero? }
44
- stringz :comment, :onlyif => lambda { fcomment.nonzero? }
45
- uint16 :crc16, :onlyif => lambda { fcrc16.nonzero? }
46
- end
47
-
48
- class Footer < BinData::Record
49
- endian :little
5
+ # See notes at the end of this file for implementation discussions.
6
+ class Gzip < BinData::Record
7
+ # Binary representation of a ruby Time object
8
+ class Mtime < BinData::Primitive
9
+ uint32le :time
10
+
11
+ def set(val)
12
+ self.time = val.to_i
13
+ end
50
14
 
51
- uint32 :crc32
52
- uint32 :uncompressed_size
15
+ def get
16
+ Time.at(time)
17
+ end
53
18
  end
54
19
 
55
- def initialize
56
- @header = Header.new
57
- @footer = Footer.new
58
- end
20
+ # Known compression methods
21
+ DEFLATE = 8
59
22
 
60
- attr_accessor :compressed
61
- def_delegators :@header, :file_name=, :file_name
62
- def_delegators :@header, :comment=, :comment, :comment?
63
- def_delegators :@header, :compression_method
64
- def_delegators :@footer, :crc32, :uncompressed_size
23
+ endian :little
65
24
 
66
- def mtime
67
- Time.at(@header.mtime.snapshot)
68
- end
25
+ uint16 :ident, :asserted_value => 0x8b1f
26
+ uint8 :compression_method, :initial_value => DEFLATE
69
27
 
70
- def mtime=(tm)
71
- @header.mtime = tm.to_i
72
- end
28
+ bit3 :freserved, :asserted_value => 0
29
+ bit1 :fcomment, :value => lambda { comment.length > 0 ? 1 : 0 }
30
+ bit1 :ffile_name, :value => lambda { file_name.length > 0 ? 1 : 0 }
31
+ bit1 :fextra, :value => lambda { extra.len > 0 ? 1 : 0 }
32
+ bit1 :fcrc16, :value => 0 # see note at end of file
33
+ bit1 :ftext
73
34
 
74
- def total_size
75
- @header.num_bytes + @compressed.size + @footer.num_bytes
76
- end
35
+ mtime :mtime
36
+ uint8 :extra_flags
37
+ uint8 :os, :initial_value => 255 # unknown OS
77
38
 
78
- def compressed_data
79
- @compressed
80
- end
39
+ # The following fields are optional depending on the bits in flags
81
40
 
82
- def set_compressed_data(compressed, crc32, uncompressed_size)
83
- @compressed = compressed
84
- @footer.crc32 = crc32
85
- @footer.uncompressed_size = uncompressed_size
41
+ struct :extra, :onlyif => lambda { fextra.nonzero? } do
42
+ uint16 :len, :length => lambda { data.length }
43
+ string :data, :read_length => :len
86
44
  end
45
+ stringz :file_name, :onlyif => lambda { ffile_name.nonzero? }
46
+ stringz :comment, :onlyif => lambda { fcomment.nonzero? }
47
+ uint16 :crc16, :onlyif => lambda { fcrc16.nonzero? }
87
48
 
88
- def read(file_name)
89
- File.open(file_name, "r") do |io|
90
- @header.read(io)
91
-
92
- # Determine the size of the compressed data. This is needed because
93
- # we don't actually uncompress the data. Ideally the uncompression
94
- # method would read the correct number of bytes from the IO and the
95
- # IO would be positioned ready to read the footer.
49
+ # The length of compressed data must be calculated from the current file offset
50
+ count_bytes_remaining :bytes_remaining
51
+ string :compressed_data, :read_length => lambda { bytes_remaining - footer.num_bytes }
96
52
 
97
- pos = io.pos
98
- io.seek(-@footer.num_bytes, IO::SEEK_END)
99
- compressed_size = io.pos - pos
100
- io.seek(pos)
101
-
102
- @compressed = io.read(compressed_size)
103
- @footer.read(io)
104
- end
53
+ struct :footer do
54
+ uint32 :crc32
55
+ uint32 :uncompressed_size
105
56
  end
106
57
 
107
- def write(file_name)
108
- File.open(file_name, "w") do |io|
109
- @header.write(io)
110
- io.write(@compressed)
111
- @footer.write(io)
112
- end
58
+ def data=(data)
59
+ # Zlib.deflate includes a header + footer which we must discard
60
+ self.compressed_data = Zlib::Deflate.deflate(data)[2..-5]
61
+ self.footer.crc32 = Zlib::crc32(data)
62
+ self.footer.uncompressed_size = data.size
113
63
  end
114
64
  end
115
65
 
@@ -117,28 +67,30 @@ if __FILE__ == $0
117
67
  # Write a gzip file.
118
68
  print "Creating a gzip file ... "
119
69
  g = Gzip.new
120
- # Uncompressed data is "the cat sat on the mat"
121
- g.set_compressed_data("+\311HUHN,Q(\006\342\374<\205\022 77\261\004\000",
122
- 3464689835, 22)
70
+ g.data = "the cat sat on the mat"
123
71
  g.file_name = "poetry"
124
72
  g.mtime = Time.now
125
73
  g.comment = "A stunning piece of prose"
126
- g.write("poetry.gz")
74
+ File.open("poetry.gz", "w") do |io|
75
+ g.write(io)
76
+ end
127
77
  puts "done."
128
78
  puts
129
79
 
130
80
  # Read the created gzip file.
131
81
  print "Reading newly created gzip file ... "
132
82
  g = Gzip.new
133
- g.read("poetry.gz")
83
+ File.open("poetry.gz", "r") do |io|
84
+ g.read(io)
85
+ end
134
86
  puts "done."
135
87
  puts
136
88
 
137
89
  puts "Printing gzip file details in the format of gzip -l -v"
138
90
 
139
91
  # compression ratio
140
- ratio = 100.0 * (g.uncompressed_size - g.compressed.size) /
141
- g.uncompressed_size
92
+ ratio = 100.0 * (g.footer.uncompressed_size - g.compressed_data.size) /
93
+ g.footer.uncompressed_size
142
94
 
143
95
  comp_meth = (g.compression_method == Gzip::DEFLATE) ? "defla" : ""
144
96
 
@@ -146,16 +98,28 @@ if __FILE__ == $0
146
98
  puts "method crc date time compressed " +
147
99
  "uncompressed ratio uncompressed_name"
148
100
  puts "%5s %08x %6s %5s %19s %19s %5.1f%% %s" % [comp_meth,
149
- g.crc32,
101
+ g.footer.crc32,
150
102
  g.mtime.strftime('%b %d'),
151
103
  g.mtime.strftime('%H:%M'),
152
- g.total_size,
153
- g.uncompressed_size,
104
+ g.num_bytes,
105
+ g.footer.uncompressed_size,
154
106
  ratio,
155
107
  g.file_name]
156
- puts "Comment: #{g.comment}" if g.comment?
108
+ puts "Comment: #{g.comment}" if g.comment != ""
157
109
  puts
158
110
 
159
111
  puts "Executing gzip -l -v"
160
112
  puts `gzip -l -v poetry.gz`
161
113
  end
114
+
115
+ # Notes:
116
+ #
117
+ # Mtime: A convenience wrapper that allow a ruby Time object to be used instead
118
+ # of manually dealing with the raw form (seconds since 1 Jan 1970)
119
+ #
120
+ # rfc1952 specifies an optional crc16 field. The gzip command line client
121
+ # uses this field for multi-part gzip. Hence we ignore this.
122
+
123
+ # We are cheating and using the Zlib library for compression. We can't use
124
+ # this library for decompression as zlib requires an adler32 checksum while
125
+ # gzip uses crc32.
@@ -39,8 +39,6 @@ end
39
39
 
40
40
  # TCP Protocol Data Unit
41
41
  class TCP_PDU < BinData::Record
42
- mandatory_parameter :packet_length
43
-
44
42
  endian :big
45
43
 
46
44
  uint16 :src_port
@@ -60,7 +58,7 @@ class TCP_PDU < BinData::Record
60
58
  uint16 :checksum
61
59
  uint16 :urg_ptr
62
60
  string :options, :read_length => :options_length_in_bytes
63
- string :payload, :read_length => lambda { packet_length - payload.rel_offset }
61
+ rest :payload
64
62
 
65
63
  def options_length_in_bytes
66
64
  (doff - 5 ) * 4
@@ -69,15 +67,13 @@ end
69
67
 
70
68
  # UDP Protocol Data Unit
71
69
  class UDP_PDU < BinData::Record
72
- mandatory_parameter :packet_length
73
-
74
70
  endian :big
75
71
 
76
72
  uint16 :src_port
77
73
  uint16 :dst_port
78
74
  uint16 :len
79
75
  uint16 :checksum
80
- string :payload, :read_length => lambda { packet_length - payload.rel_offset }
76
+ rest :payload
81
77
  end
82
78
 
83
79
  # IP Protocol Data Unit
@@ -97,10 +93,12 @@ class IP_PDU < BinData::Record
97
93
  ip_addr :src_addr
98
94
  ip_addr :dest_addr
99
95
  string :options, :read_length => :options_length_in_bytes
100
- choice :payload, :selection => :protocol do
101
- tcp_pdu 6, :packet_length => :payload_length_in_bytes
102
- udp_pdu 17, :packet_length => :payload_length_in_bytes
103
- string :default, :read_length => :payload_length_in_bytes
96
+ buffer :payload, :length => :payload_length_in_bytes do
97
+ choice :payload, :selection => :protocol do
98
+ tcp_pdu 6
99
+ udp_pdu 17
100
+ rest :default
101
+ end
104
102
  end
105
103
 
106
104
  def header_length_in_bytes
@@ -1,6 +1,10 @@
1
1
  # BinData -- Binary data manipulator.
2
2
  # Copyright (c) 2007 - 2014 Dion Mendel.
3
3
 
4
+ if RUBY_VERSION <= "1.9"
5
+ fail "BinData requires ruby >= 1.9.3. Use BinData version 1.8.x instead"
6
+ end
7
+
4
8
  require 'bindata/version'
5
9
  require 'bindata/array'
6
10
  require 'bindata/bits'
@@ -233,17 +233,16 @@ module BinData
233
233
  end
234
234
  end
235
235
 
236
- # Returns the offset (in bytes) of this object with respect to its most
237
- # distant ancestor.
238
- def abs_offset
236
+ # Returns the offset of this object wrt to its most distant ancestor.
237
+ def offset
239
238
  if @parent
240
- @parent.abs_offset + @parent.offset_of(self)
239
+ @parent.offset + @parent.offset_of(self)
241
240
  else
242
241
  0
243
242
  end
244
243
  end
245
244
 
246
- # Returns the offset (in bytes) of this object with respect to its parent.
245
+ # Returns the offset of this object wrt to its parent.
247
246
  def rel_offset
248
247
  if @parent
249
248
  @parent.offset_of(self)
@@ -282,11 +281,7 @@ module BinData
282
281
  end
283
282
 
284
283
  def binary_string(str)
285
- if str.respond_to?(:force_encoding)
286
- str.to_s.dup.force_encoding(Encoding::BINARY)
287
- else
288
- str.dup
289
- end
284
+ str.to_s.dup.force_encoding(Encoding::BINARY)
290
285
  end
291
286
  end
292
287
  end