bytemapper 1.0.13 → 1.0.19
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 +4 -4
- data/lib/bytemapper.rb +72 -39
- data/lib/bytemapper/chunk.rb +18 -7
- data/lib/bytemapper/registry.rb +62 -38
- data/lib/bytemapper/shape.rb +30 -0
- data/lib/bytemapper/type.rb +26 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9651d363a3ac3e436372c5527f7f8bed34015ea0687eaa93b3b89b31bd0bce81
|
4
|
+
data.tar.gz: 7ed18fc3bfd35527aea3eef93e038adc785019ae4857d00008639512d18bf974
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d1b379ef5e3322c9b010377702cc7d4c5d1043ebbb9038a56e723df6537c558e6c4ca9b8f0b812015de4dc1199cb7043ada03f00d3850292ef60e55949ab20f
|
7
|
+
data.tar.gz: 93db768253293483ff66349868b577704e75cce5f18169cd7b0eb3fc7e52906ebb1c0d0a28b944d260918bbc21987a59d84dfff1f3de08af7d30ff37be0b84a0
|
data/lib/bytemapper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Bytemapper - Model arbitrary bytestrings as Ruby objects.
|
1
|
+
# Bytemapper - Model arbitrary bytestrings as Ruby objects.
|
2
2
|
# Copyright (C) 2020 Jefferson Hudson
|
3
3
|
#
|
4
4
|
# This program is free software: you can redistribute it and/or modify it under
|
@@ -16,54 +16,87 @@
|
|
16
16
|
|
17
17
|
module Bytemapper
|
18
18
|
require 'bytemapper/registry'
|
19
|
+
require 'bytemapper/shape'
|
20
|
+
require 'bytemapper/type'
|
19
21
|
require 'bytemapper/nameable'
|
20
|
-
require 'bytemapper/flattenable'
|
21
22
|
require 'bytemapper/chunk'
|
22
23
|
|
23
24
|
@@registry = Registry.new
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
class << self
|
27
|
+
|
28
|
+
def register(obj, name, fqname = [])
|
29
|
+
return if obj.nil?
|
30
|
+
name = name.downcase.to_sym unless name.nil?
|
31
|
+
fqname << name unless name.nil?
|
32
|
+
if is_a_type?(obj)
|
33
|
+
name = fqname.size > 1 ? fqname.join('.') : fqname.first
|
34
|
+
obj = Type.new(obj)
|
35
|
+
put(obj, name)
|
36
|
+
elsif is_a_name?(obj)
|
37
|
+
register(get(obj), nil, fqname)
|
38
|
+
elsif is_a_shape?(obj)
|
39
|
+
if registered?(obj)
|
40
|
+
obj = get(obj)
|
41
|
+
put(obj, name)
|
42
|
+
else
|
43
|
+
shape = Shape.new
|
44
|
+
obj.each do |k,v|
|
45
|
+
shape[k] = register(v, k, [].concat(fqname))
|
46
|
+
end
|
47
|
+
put(shape, name)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
put(obj, name)
|
33
51
|
end
|
34
|
-
wrapper.extend(Flattenable)
|
35
|
-
obj = registry.put(wrapper, name)
|
36
|
-
else
|
37
|
-
raise ArgumentError.new "Invalid object"
|
38
52
|
end
|
39
|
-
|
40
|
-
end
|
53
|
+
alias :wrap :register
|
41
54
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
55
|
+
def is_a_type?(obj)
|
56
|
+
obj.is_a?(Type) ||
|
57
|
+
obj.is_a?(Array) &&
|
58
|
+
obj.size == 2 &&
|
59
|
+
obj.first.is_a?(Integer) &&
|
60
|
+
obj.last.is_a?(String)
|
61
|
+
end
|
48
62
|
|
49
|
-
|
50
|
-
|
51
|
-
|
63
|
+
def is_a_shape?(obj)
|
64
|
+
obj.is_a?(Hash)
|
65
|
+
end
|
66
|
+
|
67
|
+
def is_a_name?(obj)
|
68
|
+
obj.is_a?(String) || obj.is_a?(Symbol)
|
69
|
+
end
|
70
|
+
|
71
|
+
def map(bytes, shape, name = nil)
|
72
|
+
bytes.force_encoding(Encoding::ASCII_8BIT)
|
73
|
+
bytes = StringIO.new(bytes)
|
74
|
+
shape = wrap(shape, name)
|
75
|
+
Chunk.new(bytes, shape, name)
|
76
|
+
end
|
77
|
+
|
78
|
+
def registered?(obj)
|
79
|
+
registry.registered?(obj)
|
80
|
+
end
|
81
|
+
|
82
|
+
def get(obj)
|
83
|
+
registry.get(obj)
|
84
|
+
end
|
85
|
+
|
86
|
+
def put(obj, name)
|
87
|
+
registry.put(obj, name)
|
88
|
+
end
|
89
|
+
|
90
|
+
def print
|
91
|
+
registry.print
|
92
|
+
end
|
93
|
+
|
94
|
+
def registry
|
95
|
+
@@registry
|
96
|
+
end
|
52
97
|
|
53
|
-
|
54
|
-
|
55
|
-
[:uint8_t, [8,'C']],
|
56
|
-
[:bool, [8,'C']],
|
57
|
-
[:uint16_t, [16,'S']],
|
58
|
-
[:uint32_t, [32,'L']],
|
59
|
-
[:uint64_t, [64,'Q']],
|
60
|
-
[:int8_t, [8,'c']],
|
61
|
-
[:int16_t, [16,'s']],
|
62
|
-
[:int32_t, [32,'l']],
|
63
|
-
[:int64_t, [64,'q']]
|
64
|
-
].each do |name, type|
|
65
|
-
@@registry.put(type, name)
|
98
|
+
def reset(with_basic_types = true)
|
99
|
+
@@registry = Registry.new(with_basic_types)
|
66
100
|
end
|
67
|
-
@@registry
|
68
101
|
end
|
69
102
|
end
|
data/lib/bytemapper/chunk.rb
CHANGED
@@ -15,17 +15,25 @@
|
|
15
15
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
16
16
|
|
17
17
|
module Bytemapper
|
18
|
-
|
18
|
+
require 'bytemapper/flattenable'
|
19
|
+
class Chunk < Hash
|
20
|
+
include Flattenable
|
19
21
|
attr_reader :bytes, :shape, :name
|
20
22
|
|
21
23
|
def initialize(bytes, shape, name)
|
22
|
-
@bytes = bytes
|
23
|
-
@shape = shape
|
24
24
|
@name = name
|
25
|
-
|
26
|
-
|
25
|
+
@shape = shape
|
26
|
+
@bytes = bytes.is_a?(StringIO) ? bytes : StringIO.new(bytes)
|
27
|
+
@bytes.truncate(shape.size)
|
28
|
+
replace(shape)
|
29
|
+
each_pair do |k,v|
|
30
|
+
self[k] = if v.is_a?(Hash)
|
31
|
+
Chunk.new(@bytes.read(v.size), v, k)
|
32
|
+
else
|
33
|
+
unpack(v)
|
34
|
+
end
|
27
35
|
singleton_class.instance_eval { attr_reader k }
|
28
|
-
instance_variable_set("@#{k.to_s}",
|
36
|
+
instance_variable_set("@#{k.to_s}", self[k])
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
@@ -42,7 +50,10 @@ module Bytemapper
|
|
42
50
|
end
|
43
51
|
|
44
52
|
def size
|
45
|
-
|
53
|
+
bytes.size
|
54
|
+
end
|
55
|
+
|
56
|
+
def print
|
46
57
|
end
|
47
58
|
|
48
59
|
def unpack(value, endian = nil)
|
data/lib/bytemapper/registry.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
|
-
# Bytemapper - Model arbitrary bytestrings as Ruby objects.
|
1
|
+
# Bytemapper - Model arbitrary bytestrings as Ruby objects.
|
2
2
|
# Copyright (C) 2020 Jefferson Hudson
|
3
3
|
#
|
4
4
|
# This program is free software: you can redistribute it and/or modify it under
|
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
|
class Registry
|
18
19
|
require 'bytemapper/nameable'
|
@@ -36,56 +37,62 @@ module Bytemapper
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def registered?(obj)
|
39
|
-
|
40
|
+
v = registered_name?(obj) if obj.respond_to?(:to_sym)
|
41
|
+
v || registered_obj?(obj)
|
40
42
|
end
|
41
43
|
|
42
|
-
def get(obj
|
43
|
-
if
|
44
|
-
|
45
|
-
|
46
|
-
elsif
|
47
|
-
|
48
|
-
key = obj.hash
|
44
|
+
def get(obj)
|
45
|
+
if registered_name?(obj)
|
46
|
+
obj = obj.to_sym.downcase
|
47
|
+
@objects.fetch(@names[obj]) unless obj.nil?
|
48
|
+
elsif registered_obj?(obj)
|
49
|
+
@objects.fetch(obj.hash)
|
49
50
|
else
|
50
|
-
|
51
|
+
nil
|
51
52
|
end
|
52
|
-
@objects[key]
|
53
53
|
end
|
54
54
|
|
55
55
|
def put(obj, name = nil)
|
56
56
|
obj = register_obj(obj)
|
57
|
-
register_name(obj, name)
|
57
|
+
register_name(obj, name) unless name.nil?
|
58
58
|
obj
|
59
59
|
end
|
60
60
|
|
61
61
|
def registered_name?(name)
|
62
|
-
|
62
|
+
if name.respond_to?(:to_sym)
|
63
|
+
name = name.to_sym.downcase
|
64
|
+
@names.key?(name)
|
65
|
+
else
|
66
|
+
false
|
67
|
+
end
|
63
68
|
end
|
64
69
|
|
65
70
|
def registered_obj?(obj)
|
66
|
-
@objects.key?(obj.hash)
|
71
|
+
@objects.key?(obj.hash)
|
67
72
|
end
|
68
73
|
|
69
74
|
def register_obj(obj)
|
70
75
|
unless registered_obj?(obj)
|
71
|
-
|
72
|
-
|
76
|
+
begin
|
77
|
+
obj.extend(Nameable)
|
78
|
+
obj.names = Set.new
|
79
|
+
rescue TypeError
|
80
|
+
end
|
73
81
|
end
|
74
82
|
@objects[obj.hash] ||= obj
|
75
83
|
end
|
76
84
|
|
77
85
|
def register_name(obj, name)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
obj.names << name
|
85
|
-
end
|
86
|
+
if registered_name?(name) && get(name) != obj
|
87
|
+
raise ArgumentError.new 'Name is already registered'
|
88
|
+
else
|
89
|
+
name = name.to_sym.downcase
|
90
|
+
@names[name] ||= obj.hash
|
91
|
+
obj.names << name if obj.respond_to?(:names)
|
86
92
|
end
|
87
93
|
obj
|
88
94
|
end
|
95
|
+
alias :register_alias :register_name
|
89
96
|
|
90
97
|
def print
|
91
98
|
puts to_s
|
@@ -97,7 +104,7 @@ module Bytemapper
|
|
97
104
|
# Buffer to build up output.
|
98
105
|
buf = StringIO.new
|
99
106
|
|
100
|
-
# Calculate the width of each column.
|
107
|
+
# Calculate the true max width of each column.
|
101
108
|
widths = [
|
102
109
|
@names.keys.size.zero? ? 0 : @names.keys.map(&:size).max + 1, # add space for the `:`
|
103
110
|
7, # length of ID to print
|
@@ -105,6 +112,10 @@ module Bytemapper
|
|
105
112
|
@objects.values.map { |v| v.to_s.size }.max
|
106
113
|
]
|
107
114
|
|
115
|
+
# Truncate more than `max_width` num chars
|
116
|
+
max_width = 60
|
117
|
+
widths = widths.map { |w| w > max_width ? max_width : w }
|
118
|
+
|
108
119
|
# Add an extra space at the beginning and end of each column.
|
109
120
|
widths = widths.map { |p| p += 2 }
|
110
121
|
|
@@ -125,21 +136,29 @@ module Bytemapper
|
|
125
136
|
|
126
137
|
# Fixup the id string so it pads nicely
|
127
138
|
idstr = id.positive? ? id.to_s[..5] : id.to_s[..6]
|
128
|
-
idstr = id.positive? ? "
|
139
|
+
idstr = id.positive? ? " #{idstr}" : "#{idstr}"
|
129
140
|
|
130
|
-
#
|
141
|
+
# Generate the column values
|
131
142
|
values = [
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
143
|
+
name.empty? ? name : ":#{name}",
|
144
|
+
idstr,
|
145
|
+
"#{obj.class.to_s}",
|
146
|
+
"#{obj.to_s}"
|
136
147
|
]
|
137
|
-
|
138
|
-
#
|
139
|
-
|
148
|
+
|
149
|
+
# Pad the values to fit in their respective columns, truncating as
|
150
|
+
# needed to stay within `max_width`
|
151
|
+
values = widths.zip(values).map do |w,v|
|
152
|
+
q = w - v.size
|
153
|
+
if q < 2
|
154
|
+
" #{v[..w-7]} ... "
|
155
|
+
else
|
156
|
+
" #{v}#{" "*(q-1)}"
|
157
|
+
end
|
158
|
+
end
|
140
159
|
|
141
160
|
values.size.times do |i|
|
142
|
-
buf << "#{values[i]}
|
161
|
+
buf << "#{values[i]}|"
|
143
162
|
end
|
144
163
|
buf << "\n"
|
145
164
|
end
|
@@ -163,15 +182,20 @@ module Bytemapper
|
|
163
182
|
def register_basic_types
|
164
183
|
[
|
165
184
|
[:uint8_t, [8,'C']],
|
185
|
+
[:uchar, [8,'C']],
|
166
186
|
[:bool, [8,'C']],
|
167
187
|
[:uint16_t, [16,'S']],
|
168
188
|
[:uint32_t, [32,'L']],
|
169
189
|
[:uint64_t, [64,'Q']],
|
170
190
|
[:int8_t, [8,'c']],
|
191
|
+
[:char, [8,'c']],
|
171
192
|
[:int16_t, [16,'s']],
|
172
193
|
[:int32_t, [32,'l']],
|
173
194
|
[:int64_t, [64,'q']]
|
174
|
-
].each
|
195
|
+
].each do |name, type|
|
196
|
+
type = Type.new(type)
|
197
|
+
put(type, name)
|
198
|
+
end
|
175
199
|
end
|
176
200
|
end
|
177
201
|
end
|
@@ -0,0 +1,30 @@
|
|
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
|
+
require 'bytemapper/flattenable'
|
19
|
+
require 'bytemapper/nameable'
|
20
|
+
class Shape < Hash
|
21
|
+
include Flattenable
|
22
|
+
include Nameable
|
23
|
+
|
24
|
+
def []=(k,v)
|
25
|
+
super
|
26
|
+
singleton_class.instance_eval { attr_reader k }
|
27
|
+
instance_variable_set("@#{k.to_s}", self[k])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
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
|
+
require 'bytemapper/nameable'
|
19
|
+
class Type < Array
|
20
|
+
include Nameable
|
21
|
+
|
22
|
+
def size
|
23
|
+
first / 8
|
24
|
+
end
|
25
|
+
end
|
26
|
+
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.
|
4
|
+
version: 1.0.19
|
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-
|
11
|
+
date: 2020-06-01 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
|
@@ -21,6 +21,8 @@ files:
|
|
21
21
|
- lib/bytemapper/flattenable.rb
|
22
22
|
- lib/bytemapper/nameable.rb
|
23
23
|
- lib/bytemapper/registry.rb
|
24
|
+
- lib/bytemapper/shape.rb
|
25
|
+
- lib/bytemapper/type.rb
|
24
26
|
homepage: https://github.com/l4cr0ss/bytemapper
|
25
27
|
licenses:
|
26
28
|
- AGPL-3.0-or-later
|