binary_struct 2.0.0 → 2.1.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.
@@ -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"