binary_struct 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 390c83f0ae9d53e2c123bfe3190fb1be90573895
4
+ data.tar.gz: 548e8d4c5b6ba5c17af72412fe8ed8c9e15f48f8
5
+ SHA512:
6
+ metadata.gz: fc67fb8689529bb62ecbec209f2b0a14e04ef60d97a4c8c88520aaca0d754ab33f803537609ac658d57a74671bf25f216b0f1d89f1fc065306f897500fb5320d
7
+ data.tar.gz: 150aeaf98ef9a9b483d97fbd6f4a8fee590149da79b6b53189f219dd96b314e12870888a26f2206683a223fbf926f394a2cc75f2a4a064586f5ef5056c0267cb
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # BinaryStruct
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/binary_struct.png)](http://badge.fury.io/rb/binary_struct)
4
- [![Build Status](https://travis-ci.org/ManageIQ/binary_struct.png)](https://travis-ci.org/ManageIQ/binary_struct)
5
- [![Code Climate](https://codeclimate.com/github/ManageIQ/binary_struct.png)](https://codeclimate.com/github/ManageIQ/binary_struct)
6
- [![Coverage Status](https://coveralls.io/repos/ManageIQ/binary_struct/badge.png?branch=master)](https://coveralls.io/r/ManageIQ/binary_struct)
7
- [![Dependency Status](https://gemnasium.com/ManageIQ/binary_struct.png)](https://gemnasium.com/ManageIQ/binary_struct)
3
+ [![Gem Version](https://badge.fury.io/rb/binary_struct.svg)](http://badge.fury.io/rb/binary_struct)
4
+ [![Build Status](https://travis-ci.org/ManageIQ/binary_struct.svg)](https://travis-ci.org/ManageIQ/binary_struct)
5
+ [![Code Climate](http://img.shields.io/codeclimate/github/ManageIQ/binary_struct.svg)](https://codeclimate.com/github/ManageIQ/binary_struct)
6
+ [![Coverage Status](http://img.shields.io/coveralls/ManageIQ/binary_struct.svg)](https://coveralls.io/r/ManageIQ/binary_struct)
7
+ [![Dependency Status](https://gemnasium.com/ManageIQ/binary_struct.svg)](https://gemnasium.com/ManageIQ/binary_struct)
8
8
 
9
9
  BinaryStruct is a class for dealing with binary structured data. It simplifies
10
10
  expressing what the binary structure looks like, with the ability to name the
@@ -65,6 +65,27 @@ File.open("test.gif", "wb") { |f| f.write(header) }
65
65
  => "GIF89a\x10\x00\x10\x00\x80\x00\x00"
66
66
  ```
67
67
 
68
+ ## Note about bit and nibble formats
69
+
70
+ BinaryStruct supports bit formats and nibble formats, however note that the
71
+ underlying Ruby methods, [pack](http://ruby-doc.org/core-2.2.0/Array.html#method-i-pack)
72
+ and [unpack](http://ruby-doc.org/core-2.2.0/String.html#method-i-unpack), support
73
+ less than 8 bits by reading an entire byte, even if all of the bits are not used.
74
+
75
+ For example,
76
+
77
+ ```ruby
78
+ s = "\xFF\x00" # binary: 1111111100000000
79
+ s.unpack("b8b8") # => ["11111111", "00000000"]
80
+ s.unpack("b4b4b4b4") # => ["1111", "0000", "", ""]
81
+ ```
82
+
83
+ One might expect that the latter would read 4 bits, then the next 4 bits, etc,
84
+ yielding `["1111", "1111", "0000", "0000"]`, but that is not the case. Instead,
85
+ the first b4 reads a full byte's worth, then discards the unused 4 bits, and the
86
+ same happens for the next b4. The third and fourth b4 have nothing left to read,
87
+ and so just return empty strings.
88
+
68
89
  ## Installation
69
90
 
70
91
  Add this line to your application's Gemfile:
@@ -5,16 +5,16 @@ class BinaryStruct
5
5
  SIZES = {
6
6
  'A' => 1, # String with trailing NULs and spaces removed
7
7
  'a' => 1, # String
8
- 'B' => nil, # Extract bits from each character (MSB first)
9
- 'b' => nil, # Extract bits from each character (LSB first)
8
+ 'B' => 1, # Extract bits from each character (MSB first)
9
+ 'b' => 1, # Extract bits from each character (LSB first)
10
10
  'C' => 1, # Extract a character as an unsigned integer
11
11
  'c' => 1, # Extract a character as a signed integer
12
12
  'E' => nil, # Treat sizeof(double) characters as a double in little-endian byte order
13
13
  'e' => nil, # Treat sizeof(float) characters as a float in little-endian byte order
14
14
  'G' => nil, # Treat sizeof(double) characters as a double in network byte order
15
15
  'g' => nil, # Treat sizeof(float) characters as a float in network byte order
16
- 'H' => nil, # Extract hex nibbles from each character (most significant first)
17
- 'h' => nil, # Extract hex nibbles from each character (least significant first)
16
+ 'H' => 1, # Extract hex nibbles from each character (most significant first)
17
+ 'h' => 1, # Extract hex nibbles from each character (least significant first)
18
18
  'I' => 4, # Treat sizeof(int) successive characters as an unsigned native integer
19
19
  'i' => 4, # Treat sizeof(int) successive characters as a signed native integer
20
20
  'L' => 4, # Treat 4 successive characters as an unsigned native long integer
@@ -39,7 +39,9 @@ class BinaryStruct
39
39
  'Z' => 1, # String with trailing NULs removed
40
40
  }
41
41
 
42
- STRING_FORMATS = %w(A a M m u)
42
+ STRING_FORMATS = %w(A a B b H h M m u)
43
+ BIT_FORMATS = %w(B b)
44
+ NIBBLE_FORMATS = %w(H h)
43
45
  ENDIAN_FORMATS = %w(I i L l Q q S s)
44
46
  ENDIAN_MODIFIERS = %w(> <)
45
47
  MODIFIERS = ENDIAN_MODIFIERS
@@ -56,6 +58,7 @@ class BinaryStruct
56
58
  if value.kind_of?(self.class)
57
59
  @definition = value.definition.dup
58
60
  else
61
+ value = value.to_a.map(&:reverse).flatten if value.kind_of?(Hash)
59
62
  value = Array(value)
60
63
  self.class.validate_definition(value)
61
64
  @definition = value
@@ -202,7 +205,14 @@ class BinaryStruct
202
205
  modifier, modcount = count[0, 1], count[1..-1]
203
206
  count = modcount if valid_definition_entry_modifier?(modifier)
204
207
  count = count.empty? ? 1 : count.to_i
205
- size += (count * SIZES[type])
208
+ size +=
209
+ if BIT_FORMATS.include?(type)
210
+ (count / 8.0).ceil
211
+ elsif NIBBLE_FORMATS.include?(type)
212
+ (count / 2.0).ceil
213
+ else
214
+ count * SIZES[type]
215
+ end
206
216
  end
207
217
  size
208
218
  end
@@ -1,3 +1,3 @@
1
1
  class BinaryStruct
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -1,29 +1,50 @@
1
1
  describe BinaryStruct do
2
2
  STRUCT_DEF = [
3
- 'Q', :quad,
4
- 'L', 'long',
5
- 'S', :short,
6
- 'C', nil,
3
+ 'Q', :quad,
4
+ 'L', 'long',
5
+ 'S', :short,
6
+ 'C', nil,
7
+ 'b5', :binary,
7
8
  'a0', 'none',
8
- 'a', nil,
9
+ 'a', nil,
9
10
  'a2', 'bc',
10
11
  ]
11
- STRUCT_DEF_SIZE = 18
12
+ STRUCT_DEF_SIZE = 19
13
+
14
+ STRUCT_DEF_HASH = {
15
+ :quad => 'Q',
16
+ 'long' => 'L',
17
+ :short => 'S',
18
+ nil => 'C',
19
+ :binary => 'b5',
20
+ 'none' => 'a0',
21
+ :unused => 'a',
22
+ 'bc' => 'a2',
23
+ }
12
24
 
13
25
  STRUCT_DEF_ASTERISK = ['a*', :word]
14
26
  STRUCT_DEF_ASTERISK_SIZE = 0 # '*' is ignored
15
27
 
16
28
  STRUCT_DEF_UNRECOGNIZED_FORMAT = ['D', nil]
17
- STRUCT_DEF_UNSUPPORTED_FORMAT = ['B', nil]
29
+ STRUCT_DEF_UNSUPPORTED_FORMAT = ['U', nil]
18
30
  STRUCT_DEF_UNSUPPORTED_COUNT_NEG = ['a-1', nil]
19
31
  STRUCT_DEF_UNSUPPORTED_COUNT_INV = ['aX', nil]
20
32
 
21
- STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\0000BC".force_encoding("ASCII-8BIT")
22
- STRUCT_DECODED_HASH = {:quad=>18426034930503010560, "long"=>3683797248, :short=>18688, "bc"=>"BC", "none"=>""}
33
+ STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\000\0320BC".force_encoding("ASCII-8BIT")
34
+ STRUCT_DECODED_HASH = {
35
+ :quad => 18_426_034_930_503_010_560,
36
+ "long" => 3_683_797_248,
37
+ :short => 18_688,
38
+ :binary => "01011",
39
+ "bc" => "BC",
40
+ "none" => ""
41
+ }
42
+ STRUCT_DECODED_HASH2 = STRUCT_DECODED_HASH.merge(:unused => "0")
23
43
 
24
44
  it('.new') { expect { BinaryStruct.new }.not_to raise_error }
25
45
  it('.new with definition') { expect { BinaryStruct.new(STRUCT_DEF) }.not_to raise_error }
26
46
  it('.new with definition with *') { expect { BinaryStruct.new(STRUCT_DEF_ASTERISK) }.not_to raise_error }
47
+ it('.new with Hash defintion') { expect { BinaryStruct.new(STRUCT_DEF_HASH) }.not_to raise_error }
27
48
  it '.new with another BinaryStruct' do
28
49
  s = BinaryStruct.new(STRUCT_DEF)
29
50
  s2 = BinaryStruct.new(s)
@@ -38,6 +59,7 @@ describe BinaryStruct do
38
59
 
39
60
  it('#definition=') { expect { BinaryStruct.new.definition = STRUCT_DEF }.not_to raise_error }
40
61
  it('#definition= with definition with *') { expect { BinaryStruct.new.definition = STRUCT_DEF_ASTERISK }.not_to raise_error }
62
+ it('#definition= with Hash defintion') { expect { BinaryStruct.new.definition = STRUCT_DEF_HASH }.not_to raise_error }
41
63
 
42
64
  it('#definition= with unrecognized format') { expect { BinaryStruct.new.definition = STRUCT_DEF_UNRECOGNIZED_FORMAT }.to raise_error(RuntimeError) }
43
65
  it('#definition= with unsupported format') { expect { BinaryStruct.new.definition = STRUCT_DEF_UNSUPPORTED_FORMAT }.to raise_error(RuntimeError) }
@@ -55,6 +77,10 @@ describe BinaryStruct do
55
77
  expect(BinaryStruct.new(STRUCT_DEF_ASTERISK).decode("Testing")).to eq(:word => "Testing")
56
78
  end
57
79
 
80
+ it '#decode with Hash defintion' do
81
+ expect(BinaryStruct.new(STRUCT_DEF_HASH).decode(STRUCT_ENCODED_STR)).to eq(STRUCT_DECODED_HASH2)
82
+ end
83
+
58
84
  it '#decode against multiple records' do
59
85
  expect(BinaryStruct.new(STRUCT_DEF).decode(STRUCT_ENCODED_STR * 10, 10)).to eq([STRUCT_DECODED_HASH] * 10)
60
86
  end
@@ -1,14 +1,15 @@
1
1
  describe BinaryStruct do
2
2
  BIG_STRUCT_DEF = [
3
- 'Q>', :quad,
4
- 'L>', 'long',
5
- 'S>', :short,
6
- 'C', nil,
7
- 'a0', 'none',
8
- 'a', nil,
9
- 'a2', 'bc',
3
+ 'Q>', :quad,
4
+ 'L>', 'long',
5
+ 'S>', :short,
6
+ 'C', nil,
7
+ 'b5', :binary,
8
+ 'a0', 'none',
9
+ 'a', nil,
10
+ 'a2', 'bc',
10
11
  ]
11
- BIG_STRUCT_DEF_SIZE = 18
12
+ BIG_STRUCT_DEF_SIZE = 19
12
13
 
13
14
  BIG_E_QUAD_STRUCT_DEF = ['Q>2', :quad]
14
15
  BIG_E_QUAD_DEF_SIZE = 16
@@ -21,15 +22,16 @@ describe BinaryStruct do
21
22
  BIG_STRUCT_DEF_INVALID_ENDIAN_MODIFIER = ['Q_', nil]
22
23
 
23
24
  LIL_STRUCT_DEF = [
24
- 'Q<', :quad,
25
- 'L<', 'long',
26
- 'S<', :short,
27
- 'C', nil,
28
- 'a0', 'none',
29
- 'a', nil,
30
- 'a2', 'bc',
25
+ 'Q<', :quad,
26
+ 'L<', 'long',
27
+ 'S<', :short,
28
+ 'C', nil,
29
+ 'b5', :binary,
30
+ 'a0', 'none',
31
+ 'a', nil,
32
+ 'a2', 'bc',
31
33
  ]
32
- LIL_STRUCT_DEF_SIZE = 18
34
+ LIL_STRUCT_DEF_SIZE = 19
33
35
 
34
36
  LIL_E_QUAD_STRUCT_DEF = ['Q<2', :quad]
35
37
  LIL_E_QUAD_DEF_SIZE = 16
@@ -40,18 +42,27 @@ describe BinaryStruct do
40
42
  LIL_STRUCT_DEF_UNRECOG_ENDIAN_FMT = ['Y<', nil]
41
43
  LIL_STRUCT_DEF_UNSUPPORTED_ENDIAN_ATTRIBUTE = ['A<', nil]
42
44
 
43
- END_STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\0000BC"
44
-
45
- LIL_ENDIAN_STRUCT_DECODED_HASH = {:quad => 18_426_034_930_503_010_560,
46
- "long" => 3_683_797_248,
47
- :short => 18_688,
48
- "bc" => "BC",
49
- "none" => ""}
50
- BIG_ENDIAN_STRUCT_DECODED_HASH = {:quad => 20_709_143_206_541_055,
51
- "long" => 4_821_723,
52
- :short => 73,
53
- "none" => "",
54
- "bc" => "BC"}
45
+ END_STRUCT_ENCODED_STR = "\000\111\222\333\444\555\666\777\000\111\222\333\000\111\000\0320BC"
46
+
47
+ LIL_ENDIAN_STRUCT_DECODED_HASH =
48
+ {
49
+ :quad => 18_426_034_930_503_010_560,
50
+ "long" => 3_683_797_248,
51
+ :short => 18_688,
52
+ :binary => "01011",
53
+ "none" => "",
54
+ "bc" => "BC",
55
+ }
56
+
57
+ BIG_ENDIAN_STRUCT_DECODED_HASH =
58
+ {
59
+ :quad => 20_709_143_206_541_055,
60
+ "long" => 4_821_723,
61
+ :short => 73,
62
+ :binary => "01011",
63
+ "none" => "",
64
+ "bc" => "BC"
65
+ }
55
66
 
56
67
  it('.new') { expect { BinaryStruct.new }.not_to raise_error }
57
68
  it('.new with big definition') { expect { BinaryStruct.new(BIG_STRUCT_DEF) }.not_to raise_error }
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binary_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
5
- prerelease:
4
+ version: 2.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Oleg Barenboim
@@ -10,83 +9,70 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-07-18 00:00:00.000000000 Z
12
+ date: 2015-06-18 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: bundler
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ~>
18
+ - - "~>"
21
19
  - !ruby/object:Gem::Version
22
20
  version: '1.3'
23
21
  type: :development
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ~>
25
+ - - "~>"
29
26
  - !ruby/object:Gem::Version
30
27
  version: '1.3'
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: rake
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - ">="
37
33
  - !ruby/object:Gem::Version
38
34
  version: '0'
39
35
  type: :development
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - ">="
45
40
  - !ruby/object:Gem::Version
46
41
  version: '0'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: rspec
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - ">="
53
47
  - !ruby/object:Gem::Version
54
48
  version: '3.0'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - ">="
61
54
  - !ruby/object:Gem::Version
62
55
  version: '3.0'
63
56
  - !ruby/object:Gem::Dependency
64
57
  name: coveralls
65
58
  requirement: !ruby/object:Gem::Requirement
66
- none: false
67
59
  requirements:
68
- - - ! '>='
60
+ - - ">="
69
61
  - !ruby/object:Gem::Version
70
62
  version: '0'
71
63
  type: :development
72
64
  prerelease: false
73
65
  version_requirements: !ruby/object:Gem::Requirement
74
- none: false
75
66
  requirements:
76
- - - ! '>='
67
+ - - ">="
77
68
  - !ruby/object:Gem::Version
78
69
  version: '0'
79
- description: ! '
70
+ description: |2
80
71
 
81
72
  BinaryStruct is a class for dealing with binary structured data. It simplifies
82
-
83
73
  expressing what the binary structure looks like, with the ability to name the
84
-
85
74
  parts. Given this definition, it is easy to encode/decode the binary structure
86
-
87
75
  from/to a Hash.
88
-
89
- '
90
76
  email:
91
77
  - chessbyte@gmail.com
92
78
  - fryguy9@gmail.com
@@ -94,40 +80,39 @@ executables: []
94
80
  extensions: []
95
81
  extra_rdoc_files: []
96
82
  files:
83
+ - ".rspec"
84
+ - LICENSE.txt
85
+ - README.md
97
86
  - lib/binary_struct.rb
98
87
  - lib/binary_struct/version.rb
99
- - README.md
100
- - LICENSE.txt
101
88
  - spec/binary_struct_spec.rb
102
89
  - spec/data/test.gif
103
90
  - spec/endian_spec.rb
104
91
  - spec/gif_spec.rb
105
92
  - spec/spec_helper.rb
106
- - .rspec
107
93
  homepage: http://github.com/ManageIQ/binary_struct
108
94
  licenses:
109
95
  - MIT
96
+ metadata: {}
110
97
  post_install_message:
111
98
  rdoc_options: []
112
99
  require_paths:
113
100
  - lib
114
101
  required_ruby_version: !ruby/object:Gem::Requirement
115
- none: false
116
102
  requirements:
117
- - - ! '>='
103
+ - - ">="
118
104
  - !ruby/object:Gem::Version
119
105
  version: 1.9.3
120
106
  required_rubygems_version: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  requirements: []
127
112
  rubyforge_project:
128
- rubygems_version: 1.8.23.2
113
+ rubygems_version: 2.2.2
129
114
  signing_key:
130
- specification_version: 3
115
+ specification_version: 4
131
116
  summary: BinaryStruct is a class for dealing with binary structured data.
132
117
  test_files:
133
118
  - spec/binary_struct_spec.rb
@@ -135,4 +120,4 @@ test_files:
135
120
  - spec/endian_spec.rb
136
121
  - spec/gif_spec.rb
137
122
  - spec/spec_helper.rb
138
- - .rspec
123
+ - ".rspec"