bytemapper 1.0.19 → 1.0.26

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9651d363a3ac3e436372c5527f7f8bed34015ea0687eaa93b3b89b31bd0bce81
4
- data.tar.gz: 7ed18fc3bfd35527aea3eef93e038adc785019ae4857d00008639512d18bf974
3
+ metadata.gz: 76c2e215cabd7c201c72481a89a032dcd6034512b4242eb821fe097914c7f69f
4
+ data.tar.gz: 31615cfac602b73c2d3d36f1c9a0b4bc9ca55befec6cad72c4fae2fd7f39df80
5
5
  SHA512:
6
- metadata.gz: 6d1b379ef5e3322c9b010377702cc7d4c5d1043ebbb9038a56e723df6537c558e6c4ca9b8f0b812015de4dc1199cb7043ada03f00d3850292ef60e55949ab20f
7
- data.tar.gz: 93db768253293483ff66349868b577704e75cce5f18169cd7b0eb3fc7e52906ebb1c0d0a28b944d260918bbc21987a59d84dfff1f3de08af7d30ff37be0b84a0
6
+ metadata.gz: 4b8d9c242406a8d80d30e901231fe674b2d689c8d0f44310e5e021f305c23f1ea508ee0d9f607ec6c19b187c64d060f40b2b970e3ca7f99ab5ced89a48713d84
7
+ data.tar.gz: ed768686f5c64498d0c382a57ba92e292ef1a6fcf72fe69ded983378805aac32056e3e78e79be51c3d534bd222b448f6c69b193f49033e7775e90ea22177ecb7
@@ -15,11 +15,13 @@
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
 
17
17
  module Bytemapper
18
+ require 'refinements'
18
19
  require 'bytemapper/registry'
19
20
  require 'bytemapper/shape'
20
21
  require 'bytemapper/type'
21
22
  require 'bytemapper/nameable'
22
23
  require 'bytemapper/chunk'
24
+ require 'bytemapper/table'
23
25
 
24
26
  @@registry = Registry.new
25
27
 
@@ -71,8 +73,18 @@ module Bytemapper
71
73
  def map(bytes, shape, name = nil)
72
74
  bytes.force_encoding(Encoding::ASCII_8BIT)
73
75
  bytes = StringIO.new(bytes)
74
- shape = wrap(shape, name)
75
- Chunk.new(bytes, shape, name)
76
+ if shape.is_a?(Array)
77
+ chunks = []
78
+ shape.each { |s| chunks << Chunk.new(bytes.read(s.size), s, name) }
79
+ chunks
80
+ else
81
+ shape = wrap(shape, name)
82
+ Chunk.new(bytes, shape, name)
83
+ end
84
+ end
85
+
86
+ def repeat(obj, times = nil)
87
+ Table.new(obj, times)
76
88
  end
77
89
 
78
90
  def registered?(obj)
@@ -87,6 +99,10 @@ module Bytemapper
87
99
  registry.put(obj, name)
88
100
  end
89
101
 
102
+ def names(filter_key = nil)
103
+ registry.names.keys
104
+ end
105
+
90
106
  def print
91
107
  registry.print
92
108
  end
@@ -98,5 +114,21 @@ module Bytemapper
98
114
  def reset(with_basic_types = true)
99
115
  @@registry = Registry.new(with_basic_types)
100
116
  end
117
+
118
+ def reverse_lookup(prefix, value = nil)
119
+ @@rl_cache ||= {}
120
+ prefix = "#{prefix.to_s}_"
121
+ lookup = @@rl_cache[prefix]
122
+
123
+ if lookup.nil?
124
+ labels = names.filter { |n| n.start_with?(prefix) }
125
+ values = labels.map { |l| get(l) }
126
+ lookup = Hash[values.zip(labels)]
127
+ @@rl_cache[prefix] = lookup
128
+ end
129
+
130
+ value.nil? ? lookup : lookup[value]
131
+ end
132
+
101
133
  end
102
134
  end
@@ -17,24 +17,32 @@
17
17
  module Bytemapper
18
18
  require 'bytemapper/flattenable'
19
19
  class Chunk < Hash
20
+ include Nameable
20
21
  include Flattenable
21
- attr_reader :bytes, :shape, :name
22
+ attr_reader :bytes, :shape
22
23
 
23
24
  def initialize(bytes, shape, name)
24
25
  @name = name
25
26
  @shape = shape
26
27
  @bytes = bytes.is_a?(StringIO) ? bytes : StringIO.new(bytes)
27
- @bytes.truncate(shape.size)
28
28
  replace(shape)
29
29
  each_pair do |k,v|
30
30
  self[k] = if v.is_a?(Hash)
31
31
  Chunk.new(@bytes.read(v.size), v, k)
32
+ elsif v.is_a?(Bytemapper::Table)
33
+ if v.unbounded?
34
+ v.populate(@bytes.read(@bytes.size-@bytes.pos))
35
+ else
36
+ v.populate(@bytes.read(v.capacity))
37
+ end
32
38
  else
33
39
  unpack(v)
34
40
  end
35
41
  singleton_class.instance_eval { attr_reader k }
36
42
  instance_variable_set("@#{k.to_s}", self[k])
37
43
  end
44
+
45
+ shape.hooks.each {|h| h.call(self) }
38
46
  end
39
47
 
40
48
  def string
@@ -49,11 +57,20 @@ module Bytemapper
49
57
  bytes.string.split(//).map(&:chr)
50
58
  end
51
59
 
60
+ def capacity
61
+ shape.size
62
+ end
63
+
52
64
  def size
53
65
  bytes.size
54
66
  end
55
67
 
56
- def print
68
+ def consumed
69
+ size
70
+ end
71
+
72
+ def remaining
73
+ capacity - consumed
57
74
  end
58
75
 
59
76
  def unpack(value, endian = nil)
@@ -21,6 +21,8 @@ module Bytemapper
21
21
  k = prefix.nil? ? k : "#{prefix}_#{k}".to_sym
22
22
  if v.is_a?(Hash)
23
23
  v.flatten(flattened, k)
24
+ elsif v.is_a?(Bytemapper::Table)
25
+ v.each_with_index { |e,i| e.flatten(flattened, i) }
24
26
  else
25
27
  flattened[k] = v
26
28
  end
@@ -5,17 +5,22 @@
5
5
  # the terms of the GNU Affero General Public License as published by the Free
6
6
  # Software Foundation, either version 3 of the License, or (at your option) any
7
7
  # later version.
8
-
8
+ #
9
9
  # This program is distributed in the hope that it will be useful, but WITHOUT
10
10
  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
11
  # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
12
12
  # details.
13
-
13
+ #
14
14
  # You should have received a copy of the GNU Affero General Public License
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
16
17
  module Bytemapper
17
18
  module Nameable
19
+ attr_reader :name
18
20
  attr_accessor :names
19
- alias :name :names
21
+
22
+ def name=(v)
23
+ @name ||= v.respond_to?(:to_sym) ? v.to_sym : v
24
+ end
20
25
  end
21
26
  end
@@ -182,16 +182,24 @@ module Bytemapper
182
182
  def register_basic_types
183
183
  [
184
184
  [:uint8_t, [8,'C']],
185
+ [:u8, [8,'C']],
185
186
  [:uchar, [8,'C']],
186
187
  [:bool, [8,'C']],
187
188
  [:uint16_t, [16,'S']],
189
+ [:u16, [16,'S']],
188
190
  [:uint32_t, [32,'L']],
191
+ [:u32, [32,'L']],
189
192
  [:uint64_t, [64,'Q']],
193
+ [:u64, [64,'Q']],
190
194
  [:int8_t, [8,'c']],
195
+ [:i8, [8,'c']],
191
196
  [:char, [8,'c']],
192
197
  [:int16_t, [16,'s']],
198
+ [:i16, [16,'s']],
193
199
  [:int32_t, [32,'l']],
194
- [:int64_t, [64,'q']]
200
+ [:i32, [32,'l']],
201
+ [:int64_t, [64,'q']],
202
+ [:i64, [64,'q']]
195
203
  ].each do |name, type|
196
204
  type = Type.new(type)
197
205
  put(type, name)
@@ -20,11 +20,25 @@ module Bytemapper
20
20
  class Shape < Hash
21
21
  include Flattenable
22
22
  include Nameable
23
+ attr_accessor :hooks
24
+
25
+ def initialize
26
+ super
27
+ @hooks = []
28
+ end
23
29
 
24
30
  def []=(k,v)
25
31
  super
26
32
  singleton_class.instance_eval { attr_reader k }
27
33
  instance_variable_set("@#{k.to_s}", self[k])
28
34
  end
35
+
36
+ def hook(&block)
37
+ @hooks << block if block_given?
38
+ end
39
+
40
+ def size
41
+ flatten.values.map(&:size).reduce(:+)
42
+ end
29
43
  end
30
44
  end
@@ -0,0 +1,32 @@
1
+ module Bytemapper
2
+ using Refinements
3
+
4
+ class Table < Array
5
+ include Flattenable
6
+ include Nameable
7
+ attr_reader :bytes, :shape
8
+
9
+ def initialize(shape, rows = nil)
10
+ @bytes = nil
11
+ @shape = Bytemapper.get(shape)
12
+ end
13
+
14
+ def populate(bytes)
15
+ @bytes = StringIO.from(bytes)
16
+
17
+ table = Table.new(shape)
18
+ table.clear
19
+
20
+ (bytes.size / shape.size).times do
21
+ table << Chunk.new(@bytes.read(shape.size), shape, shape.name)
22
+ end
23
+
24
+ table
25
+ end
26
+
27
+ def size
28
+ empty? ? 0 : map(&:size).reduce(:+)
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ # Bytemapper - Model arbitrary bytestrings as Ruby objects.
2
+ # Copyright (C) 2020 Jefferson Hudson
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify it under
5
+ # the terms of the GNU Affero General Public License as published by the Free
6
+ # Software Foundation, either version 3 of the License, or (at your option) any
7
+ # later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful, but WITHOUT
10
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
12
+ # details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
+
17
+ module Bytemapper
18
+ module Typeable
19
+ attr_accessor :type
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Refinements
2
+ refine StringIO do
3
+ def peek
4
+ string[pos]
5
+ end
6
+
7
+ def extract(offset, length)
8
+ prev = pos
9
+ seek(offset)
10
+ bytes = read(length)
11
+ seek(prev)
12
+ bytes
13
+ end
14
+ end
15
+
16
+ refine StringIO.singleton_class do
17
+ def from(obj)
18
+ obj = obj.nil? ? '' : obj
19
+ obj = obj.is_a?(StringIO) ? obj : new(obj)
20
+ obj.string.force_encoding(Encoding::ASCII_8BIT)
21
+ obj
22
+ end
23
+ end
24
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bytemapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.19
4
+ version: 1.0.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jefferson Hudson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-01 00:00:00.000000000 Z
11
+ date: 2020-08-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Model and interact with bytestrings using Ruby objects.
14
14
  email: jefferson.hudson@gmail.com
@@ -22,7 +22,10 @@ files:
22
22
  - lib/bytemapper/nameable.rb
23
23
  - lib/bytemapper/registry.rb
24
24
  - lib/bytemapper/shape.rb
25
+ - lib/bytemapper/table.rb
25
26
  - lib/bytemapper/type.rb
27
+ - lib/bytemapper/typeable.rb
28
+ - lib/refinements.rb
26
29
  homepage: https://github.com/l4cr0ss/bytemapper
27
30
  licenses:
28
31
  - AGPL-3.0-or-later