scale.rb 0.2.14 → 0.2.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/.gitignore +1 -0
- data/Cargo.lock +2007 -11
- data/Cargo.toml +9 -2
- data/Dockerfile +4 -1
- data/Gemfile.lock +45 -46
- data/README.md +28 -1
- data/exe/scale +39 -70
- data/lib/address.rb +3 -0
- data/lib/common.rb +163 -0
- data/lib/helper.rb +128 -0
- data/lib/metadata/metadata.rb +15 -1
- data/lib/scale.rb +105 -33
- data/lib/scale/base.rb +52 -13
- data/lib/scale/block.rb +17 -27
- data/lib/scale/types.rb +71 -4
- data/lib/scale/version.rb +1 -1
- data/lib/substrate_client.rb +170 -0
- data/lib/type_registry/{crab-28.json → crab.json} +474 -126
- data/lib/type_registry/darwinia.json +701 -136
- data/lib/type_registry/default.json +2 -2
- data/lib/type_registry/pangolin.json +332 -0
- data/scale.gemspec +7 -5
- data/scripts/block_events.rb +2 -3
- data/src/lib.rs +42 -1
- data/src/storage_key.rs +41 -0
- metadata +52 -26
- data/.DS_Store +0 -0
- data/lib/type_registry/darwinia-8.json +0 -662
- data/lib/type_registry/edgeware.json +0 -124
- data/lib/type_registry/joystream.json +0 -49
- data/lib/type_registry/kulupu.json +0 -15
- data/lib/type_registry/plasm.json +0 -89
- data/lib/type_registry/robonomics.json +0 -39
- data/lib/type_registry/westend.json +0 -63
data/lib/helper.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
|
2
|
+
class SubstrateClient::Helper
|
3
|
+
class << self
|
4
|
+
def generate_storage_key_from_metadata(metadata, module_name, storage_name, params = nil)
|
5
|
+
# find the storage item from metadata
|
6
|
+
metadata_modules = metadata.value.value[:metadata][:modules]
|
7
|
+
metadata_module = metadata_modules.detect { |mm| mm[:name] == module_name }
|
8
|
+
raise "Module '#{module_name}' not exist" unless metadata_module
|
9
|
+
storage_item = metadata_module[:storage][:items].detect { |item| item[:name] == storage_name }
|
10
|
+
raise "Storage item '#{storage_name}' not exist. \n#{metadata_module.inspect}" unless storage_item
|
11
|
+
|
12
|
+
if storage_item[:type][:Plain]
|
13
|
+
return_type = storage_item[:type][:Plain]
|
14
|
+
elsif map = storage_item[:type][:Map]
|
15
|
+
raise "Storage call of type \"Map\" requires 1 parameter" if params.nil? || params.length != 1
|
16
|
+
|
17
|
+
hasher = map[:hasher]
|
18
|
+
return_type = map[:value]
|
19
|
+
# TODO: decode to account id if param is address
|
20
|
+
# params[0] = decode(params[0]) if map[:key] == "AccountId"
|
21
|
+
type = Scale::Types.get(map[:key])
|
22
|
+
params[0] = type.new(params[0]).encode
|
23
|
+
elsif map = storage_item[:type][:DoubleMap]
|
24
|
+
raise "Storage call of type \"DoubleMapType\" requires 2 parameters" if params.nil? || params.length != 2
|
25
|
+
|
26
|
+
hasher = map[:hasher]
|
27
|
+
hasher2 = map[:key2Hasher]
|
28
|
+
return_type = map[:value]
|
29
|
+
params[0] = Scale::Types.get(map[:key1]).new(params[0]).encode
|
30
|
+
params[1] = Scale::Types.get(map[:key2]).new(params[1]).encode
|
31
|
+
else
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
storage_prefix = metadata_module[:storage][:prefix]
|
36
|
+
storage_key = generate_storage_key(
|
37
|
+
storage_prefix.nil? ? module_name : storage_prefix,
|
38
|
+
storage_name,
|
39
|
+
params,
|
40
|
+
hasher,
|
41
|
+
hasher2,
|
42
|
+
metadata.value.value[:metadata][:version]
|
43
|
+
)
|
44
|
+
[storage_key, return_type]
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_storage_key(module_name, storage_name, params = nil, hasher = nil, hasher2 = nil, metadata_version = nil)
|
48
|
+
metadata_version = 12 if metadata_version.nil?
|
49
|
+
if metadata_version and metadata_version >= 9
|
50
|
+
storage_key = Crypto.twox128(module_name) + Crypto.twox128(storage_name)
|
51
|
+
|
52
|
+
params&.each_with_index do |param, index|
|
53
|
+
if index == 0
|
54
|
+
param_hasher = hasher
|
55
|
+
elsif index == 1
|
56
|
+
param_hasher = hasher2
|
57
|
+
else
|
58
|
+
raise "Unexpected third parameter for storage call"
|
59
|
+
end
|
60
|
+
|
61
|
+
param_key = if param.class == String && param.start_with?("0x")
|
62
|
+
param.hex_to_bytes
|
63
|
+
else
|
64
|
+
param.encode().hex_to_bytes
|
65
|
+
end
|
66
|
+
param_hasher = "Twox128" if param_hasher.nil?
|
67
|
+
storage_key += Crypto.send(param_hasher.underscore2, param_key)
|
68
|
+
end
|
69
|
+
|
70
|
+
"0x#{storage_key}"
|
71
|
+
else
|
72
|
+
# TODO: add test
|
73
|
+
storage_key = module_name + " " + storage_name
|
74
|
+
|
75
|
+
unless params.nil?
|
76
|
+
params = [params] if params.class != ::Array
|
77
|
+
params_key = params.join("")
|
78
|
+
hasher = "Twox128" if hasher.nil?
|
79
|
+
storage_key += params_key.hex_to_bytes.bytes_to_utf8
|
80
|
+
end
|
81
|
+
|
82
|
+
"0x#{Crypto.send( hasher.underscore2, storage_key )}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def compose_call_from_metadata(metadata, module_name, call_name, params)
|
87
|
+
call = metadata.get_module_call(module_name, call_name)
|
88
|
+
|
89
|
+
value = {
|
90
|
+
call_index: call[:lookup],
|
91
|
+
module_name: module_name,
|
92
|
+
call_name: call_name,
|
93
|
+
params: []
|
94
|
+
}
|
95
|
+
|
96
|
+
params.keys.each_with_index do |call_param_name, i|
|
97
|
+
param_value = params[call_param_name]
|
98
|
+
value[:params] << {
|
99
|
+
name: call_param_name.to_s,
|
100
|
+
type: call[:args][i][:type],
|
101
|
+
value: param_value
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
Scale::Types::Extrinsic.new(value).encode
|
106
|
+
end
|
107
|
+
|
108
|
+
def decode_block(block)
|
109
|
+
block["block"]["header"]["number"] = block["block"]["header"]["number"].to_i(16)
|
110
|
+
|
111
|
+
block["block"]["extrinsics_decoded"] = []
|
112
|
+
block["block"]["extrinsics"].each_with_index do |hex, i|
|
113
|
+
scale_bytes = Scale::Bytes.new(hex)
|
114
|
+
block["block"]["extrinsics_decoded"][i] = Scale::Types::Extrinsic.decode(scale_bytes).to_human
|
115
|
+
end
|
116
|
+
|
117
|
+
block['block']['header']["digest"]["logs_decoded"] = []
|
118
|
+
block['block']['header']["digest"]["logs"].each_with_index do |hex, i|
|
119
|
+
scale_bytes = Scale::Bytes.new(hex)
|
120
|
+
log = Scale::Types::LogDigest.decode(scale_bytes).to_human
|
121
|
+
block['block']['header']["digest"]["logs_decoded"][i] = log
|
122
|
+
end
|
123
|
+
|
124
|
+
block
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
data/lib/metadata/metadata.rb
CHANGED
@@ -7,7 +7,7 @@ module Scale
|
|
7
7
|
bytes = scale_bytes.get_next_bytes(4)
|
8
8
|
if bytes.bytes_to_utf8 == "meta"
|
9
9
|
metadata_version = Scale::Types.type_of("Enum", %w[MetadataV0 MetadataV1 MetadataV2 MetadataV3 MetadataV4 MetadataV5 MetadataV6 MetadataV7 MetadataV8 MetadataV9 MetadataV10 MetadataV11 MetadataV12]).decode(scale_bytes).value
|
10
|
-
metadata = Metadata.new "Scale::Types::#{metadata_version}".
|
10
|
+
metadata = Metadata.new "Scale::Types::#{metadata_version}".constantize2.decode(scale_bytes)
|
11
11
|
metadata.version = metadata_version[9..].to_i
|
12
12
|
else
|
13
13
|
scale_bytes.reset_offset
|
@@ -35,6 +35,16 @@ module Scale
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
def get_module_storage(module_name, storage_name)
|
40
|
+
the_module = get_module(module_name)
|
41
|
+
if the_module[:storage].class == Array
|
42
|
+
storages = the_module[:storage]
|
43
|
+
else
|
44
|
+
storages = the_module[:storage][:items]
|
45
|
+
end
|
46
|
+
storages.find {|storage| storage[:name] == storage_name}
|
47
|
+
end
|
38
48
|
end
|
39
49
|
|
40
50
|
class MetadataModule
|
@@ -68,6 +78,10 @@ module Scale
|
|
68
78
|
|
69
79
|
MetadataModule.new(result)
|
70
80
|
end
|
81
|
+
|
82
|
+
def get_storage(storage_name)
|
83
|
+
self.value[:storage].find { |storage| storage[:name].downcase == storage_name.downcase }
|
84
|
+
end
|
71
85
|
end
|
72
86
|
|
73
87
|
class MetadataModuleStorage
|
data/lib/scale.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require "scale/version"
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "common"
|
4
|
+
|
4
5
|
require "json"
|
5
|
-
require "active_support"
|
6
|
-
require "active_support/core_ext/string"
|
7
6
|
require "singleton"
|
8
7
|
|
9
8
|
require "scale/base"
|
@@ -26,13 +25,40 @@ require "metadata/metadata_v10"
|
|
26
25
|
require "metadata/metadata_v11"
|
27
26
|
require "metadata/metadata_v12"
|
28
27
|
|
28
|
+
require "substrate_client"
|
29
|
+
require "logger"
|
30
|
+
require "helper"
|
31
|
+
|
32
|
+
class String
|
33
|
+
def upcase_first
|
34
|
+
self.sub(/\S/, &:upcase)
|
35
|
+
end
|
36
|
+
|
37
|
+
def camelize2
|
38
|
+
self.split('_').collect(&:upcase_first).join
|
39
|
+
end
|
40
|
+
|
41
|
+
def underscore2
|
42
|
+
self.gsub(/::/, '/').
|
43
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
44
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
45
|
+
tr("-", "_").
|
46
|
+
downcase
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
29
50
|
module Scale
|
30
51
|
class Error < StandardError; end
|
31
52
|
|
32
53
|
class TypeRegistry
|
33
54
|
include Singleton
|
34
|
-
|
35
|
-
|
55
|
+
|
56
|
+
# init by load, and will not change
|
57
|
+
attr_reader :spec_name, :types
|
58
|
+
attr_reader :versioning, :custom_types # optional
|
59
|
+
|
60
|
+
# will change by different spec version
|
61
|
+
attr_accessor :spec_version # optional
|
36
62
|
attr_accessor :metadata
|
37
63
|
|
38
64
|
def load(spec_name: nil, custom_types: nil)
|
@@ -43,13 +69,18 @@ module Scale
|
|
43
69
|
|
44
70
|
default_types, _, _ = load_chain_spec_types("default")
|
45
71
|
|
46
|
-
if spec_name
|
72
|
+
if spec_name
|
73
|
+
begin
|
74
|
+
@spec_name = spec_name
|
75
|
+
spec_types, @versioning, @spec_version = load_chain_spec_types(spec_name)
|
76
|
+
@types = default_types.merge(spec_types)
|
77
|
+
rescue => ex
|
78
|
+
puts "There is no types json file named #{spec_name}"
|
79
|
+
@types = default_types
|
80
|
+
end
|
81
|
+
else
|
47
82
|
@spec_name = "default"
|
48
83
|
@types = default_types
|
49
|
-
else
|
50
|
-
@spec_name = spec_name
|
51
|
-
spec_types, @versioning, @spec_version = load_chain_spec_types(spec_name)
|
52
|
-
@types = default_types.merge(spec_types)
|
53
84
|
end
|
54
85
|
|
55
86
|
self.custom_types = custom_types
|
@@ -63,7 +94,8 @@ module Scale
|
|
63
94
|
|
64
95
|
if @spec_version && @versioning
|
65
96
|
@versioning.each do |item|
|
66
|
-
if @spec_version >= item["runtime_range"][0] &&
|
97
|
+
if @spec_version >= item["runtime_range"][0] &&
|
98
|
+
( item["runtime_range"][1].nil? || @spec_version <= item["runtime_range"][1] )
|
67
99
|
all_types.merge!(item["types"])
|
68
100
|
end
|
69
101
|
end
|
@@ -176,7 +208,7 @@ module Scale
|
|
176
208
|
types.each do |name, body|
|
177
209
|
if body.class == String
|
178
210
|
target_type = "Scale::Types::#{body}"
|
179
|
-
klass = Class.new(target_type.
|
211
|
+
klass = Class.new(target_type.constantize2) do
|
180
212
|
end
|
181
213
|
elsif body.class == Hash
|
182
214
|
if body["type"] == "struct"
|
@@ -210,12 +242,18 @@ module Scale
|
|
210
242
|
end
|
211
243
|
|
212
244
|
module Types
|
245
|
+
class << self
|
246
|
+
attr_accessor :debug
|
247
|
+
end
|
248
|
+
|
213
249
|
def self.list
|
214
250
|
TypeRegistry.instance.types
|
215
251
|
end
|
216
252
|
|
217
253
|
def self.get(type_name)
|
218
|
-
TypeRegistry.instance.get(type_name)
|
254
|
+
type = TypeRegistry.instance.get(type_name)
|
255
|
+
raise "Type '#{type_name}' not exist" if type.nil?
|
256
|
+
type
|
219
257
|
end
|
220
258
|
|
221
259
|
def self.constantize(type)
|
@@ -240,13 +278,32 @@ module Scale
|
|
240
278
|
type_str = type_strs.first
|
241
279
|
inner_type_str = type_strs.last
|
242
280
|
|
243
|
-
if type_str == "Vec"
|
244
|
-
|
245
|
-
|
246
|
-
|
281
|
+
if type_str == "Vec"
|
282
|
+
name = "#{type_str}<#{inner_type_str.camelize2}>"
|
283
|
+
name = fix(name)
|
284
|
+
|
285
|
+
if !Scale::Types.const_defined?(name)
|
286
|
+
klass = Class.new do
|
287
|
+
include Scale::Types::Vec
|
288
|
+
inner_type inner_type_str
|
289
|
+
end
|
290
|
+
Scale::Types.const_set name, klass
|
291
|
+
else
|
292
|
+
Scale::Types.const_get name
|
293
|
+
end
|
294
|
+
elsif type_str == "Option"
|
295
|
+
name = "#{type_str}<#{inner_type_str.camelize2}>"
|
296
|
+
name = fix(name)
|
297
|
+
|
298
|
+
if !Scale::Types.const_defined?(name)
|
299
|
+
klass = Class.new do
|
300
|
+
include Scale::Types::Option
|
301
|
+
inner_type inner_type_str
|
302
|
+
end
|
303
|
+
Scale::Types.const_set name, klass
|
304
|
+
else
|
305
|
+
Scale::Types.const_get name
|
247
306
|
end
|
248
|
-
name = "#{type_str}_Of_#{inner_type_str.camelize}_#{klass.object_id}"
|
249
|
-
Scale::Types.const_set fix(name), klass
|
250
307
|
else
|
251
308
|
raise "#{type_str} not support inner type: #{type_string}"
|
252
309
|
end
|
@@ -263,12 +320,17 @@ module Scale
|
|
263
320
|
type_str.strip.tr(";", ",")
|
264
321
|
end
|
265
322
|
|
266
|
-
|
267
|
-
|
268
|
-
|
323
|
+
name = "TupleOf#{type_strs.map(&:camelize2).join("")}"
|
324
|
+
name = fix(name)
|
325
|
+
if !Scale::Types.const_defined?(name)
|
326
|
+
klass = Class.new do
|
327
|
+
include Scale::Types::Tuple
|
328
|
+
inner_types *type_strs
|
329
|
+
end
|
330
|
+
Scale::Types.const_set name, klass
|
331
|
+
else
|
332
|
+
Scale::Types.const_get name
|
269
333
|
end
|
270
|
-
name = "Tuple_Of_#{type_strs.map(&:camelize).join("_")}_#{klass.object_id}"
|
271
|
-
Scale::Types.const_set fix(name), klass
|
272
334
|
else
|
273
335
|
if type_string == "Enum"
|
274
336
|
# TODO: combine values to items
|
@@ -280,7 +342,7 @@ module Scale
|
|
280
342
|
values(*values)
|
281
343
|
end
|
282
344
|
end
|
283
|
-
name = values.class == ::Hash ? values.values.map(&:
|
345
|
+
name = values.class == ::Hash ? values.values.map(&:camelize2).join("_") : values.map(&:camelize2).join("_")
|
284
346
|
name = "Enum_Of_#{name}_#{klass.object_id}"
|
285
347
|
Scale::Types.const_set fix(name), klass
|
286
348
|
elsif type_string == "Struct"
|
@@ -288,19 +350,19 @@ module Scale
|
|
288
350
|
include Scale::Types::Struct
|
289
351
|
items values
|
290
352
|
end
|
291
|
-
name = "Struct_Of_#{values.values.map(&:
|
353
|
+
name = "Struct_Of_#{values.values.map(&:camelize2).join("_")}_#{klass.object_id}"
|
292
354
|
Scale::Types.const_set fix(name), klass
|
293
355
|
elsif type_string == "Set"
|
294
356
|
klass = Class.new do
|
295
357
|
include Scale::Types::Set
|
296
358
|
items values, 1
|
297
359
|
end
|
298
|
-
name = "Set_Of_#{values.keys.map(&:
|
360
|
+
name = "Set_Of_#{values.keys.map(&:camelize2).join("_")}_#{klass.object_id}"
|
299
361
|
Scale::Types.const_set fix(name), klass
|
300
362
|
else
|
301
363
|
type_name = (type_string.start_with?("Scale::Types::") ? type_string : "Scale::Types::#{type_string}")
|
302
364
|
begin
|
303
|
-
type_name.
|
365
|
+
type_name.constantize2
|
304
366
|
rescue NameError => e
|
305
367
|
puts "#{type_string} is not defined"
|
306
368
|
end
|
@@ -311,12 +373,20 @@ module Scale
|
|
311
373
|
|
312
374
|
end
|
313
375
|
|
376
|
+
# def fix(name)
|
377
|
+
# name
|
378
|
+
# .gsub("<", "˂").gsub(">", "˃")
|
379
|
+
# .gsub("(", "⁽").gsub(")", "⁾")
|
380
|
+
# .gsub(" ", "").gsub(",", "‚")
|
381
|
+
# .gsub(":", "։")
|
382
|
+
# end
|
383
|
+
|
314
384
|
def fix(name)
|
315
385
|
name
|
316
|
-
.gsub("<", "
|
317
|
-
.gsub("(", "
|
318
|
-
.gsub(" ", "").gsub(",", "
|
319
|
-
.gsub(":", "
|
386
|
+
.gsub("<", "").gsub(">", "")
|
387
|
+
.gsub("(", "").gsub(")", "")
|
388
|
+
.gsub(" ", "").gsub(",", "")
|
389
|
+
.gsub(":", "")
|
320
390
|
end
|
321
391
|
|
322
392
|
def rename(type)
|
@@ -342,7 +412,7 @@ def rename(type)
|
|
342
412
|
return "AccountData" if type == "AccountData<Balance>"
|
343
413
|
|
344
414
|
if type =~ /\[U\d+; \d+\]/
|
345
|
-
byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first
|
415
|
+
byte_length = type.scan(/\[U\d+; (\d+)\]/).first.first.to_i
|
346
416
|
return "VecU8Length#{byte_length}"
|
347
417
|
end
|
348
418
|
|
@@ -394,3 +464,5 @@ class ::Hash
|
|
394
464
|
Hash[h]
|
395
465
|
end
|
396
466
|
end
|
467
|
+
|
468
|
+
Scale::Types.debug = false
|
data/lib/scale/base.rb
CHANGED
@@ -33,6 +33,17 @@ module Scale
|
|
33
33
|
@value
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
module ClassMethods
|
38
|
+
def inherited(child)
|
39
|
+
child.const_set(:TYPE_NAME, child.name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.included(base)
|
44
|
+
base.extend(ClassMethods)
|
45
|
+
base.const_set(:TYPE_NAME, base.name)
|
46
|
+
end
|
36
47
|
end
|
37
48
|
|
38
49
|
# value: one of nil, false, true, scale object
|
@@ -41,19 +52,24 @@ module Scale
|
|
41
52
|
|
42
53
|
module ClassMethods
|
43
54
|
def decode(scale_bytes)
|
55
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
44
56
|
byte = scale_bytes.get_next_bytes(1)
|
45
57
|
if byte == [0]
|
58
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
46
59
|
new(nil)
|
47
60
|
elsif byte == [1]
|
48
61
|
if self::INNER_TYPE_STR == "boolean"
|
62
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
49
63
|
new(false)
|
50
64
|
else
|
51
65
|
# big process
|
52
66
|
value = Scale::Types.get(self::INNER_TYPE_STR).decode(scale_bytes)
|
67
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
53
68
|
new(value)
|
54
69
|
end
|
55
70
|
elsif byte == [2]
|
56
71
|
if self::INNER_TYPE_STR == "boolean"
|
72
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
57
73
|
new(true)
|
58
74
|
else
|
59
75
|
raise "bad data"
|
@@ -89,9 +105,11 @@ module Scale
|
|
89
105
|
|
90
106
|
module ClassMethods
|
91
107
|
def decode(scale_bytes)
|
108
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
92
109
|
bytes = scale_bytes.get_next_bytes self::BYTE_LENGTH
|
93
110
|
bit_length = bytes.length.to_i * 8
|
94
111
|
value = bytes.reverse.bytes_to_hex.to_i(16).to_signed(bit_length)
|
112
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
95
113
|
new(value)
|
96
114
|
end
|
97
115
|
end
|
@@ -117,10 +135,15 @@ module Scale
|
|
117
135
|
attr_accessor :byte_length
|
118
136
|
|
119
137
|
def decode(scale_bytes)
|
138
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
120
139
|
bytes = scale_bytes.get_next_bytes self::BYTE_LENGTH
|
121
140
|
bytes_reversed = bytes.reverse
|
122
141
|
hex = bytes_reversed.reduce("0x") { |hex, byte| hex + byte.to_s(16).rjust(2, "0") }
|
123
|
-
new(hex.to_i(16))
|
142
|
+
result = new(hex.to_i(16))
|
143
|
+
|
144
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
145
|
+
|
146
|
+
result
|
124
147
|
end
|
125
148
|
end
|
126
149
|
|
@@ -142,9 +165,14 @@ module Scale
|
|
142
165
|
include SingleValue
|
143
166
|
# new(1.to_u32, U32(69))
|
144
167
|
module ClassMethods
|
168
|
+
def inherited(child)
|
169
|
+
child.const_set(:TYPE_NAME, child.name)
|
170
|
+
end
|
171
|
+
|
145
172
|
def decode(scale_bytes)
|
173
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
146
174
|
item_values = self::ITEM_TYPE_STRS.map do |item_type_str|
|
147
|
-
type = Scale::
|
175
|
+
type = Scale::Types.get(item_type_str)
|
148
176
|
type.decode(scale_bytes)
|
149
177
|
end
|
150
178
|
|
@@ -157,6 +185,7 @@ module Scale
|
|
157
185
|
value.each_pair do |attr, val|
|
158
186
|
result.send "#{attr}=", val
|
159
187
|
end
|
188
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
160
189
|
result
|
161
190
|
end
|
162
191
|
|
@@ -177,6 +206,7 @@ module Scale
|
|
177
206
|
|
178
207
|
def self.included(base)
|
179
208
|
base.extend ClassMethods
|
209
|
+
base.const_set(:TYPE_NAME, base.name)
|
180
210
|
end
|
181
211
|
|
182
212
|
def encode
|
@@ -193,9 +223,11 @@ module Scale
|
|
193
223
|
|
194
224
|
module ClassMethods
|
195
225
|
def decode(scale_bytes)
|
226
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
196
227
|
values = self::TYPE_STRS.map do |type_str|
|
197
228
|
Scale::Types.get(type_str).decode(scale_bytes)
|
198
229
|
end
|
230
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
199
231
|
new(values)
|
200
232
|
end
|
201
233
|
|
@@ -218,6 +250,7 @@ module Scale
|
|
218
250
|
|
219
251
|
module ClassMethods
|
220
252
|
def decode(scale_bytes)
|
253
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
221
254
|
index = scale_bytes.get_next_bytes(1)[0]
|
222
255
|
if const_defined? "ITEM_TYPE_STRS"
|
223
256
|
item_type_str = self::ITEM_TYPE_STRS[index]
|
@@ -226,7 +259,9 @@ module Scale
|
|
226
259
|
else
|
227
260
|
value = self::VALUES[index]
|
228
261
|
end
|
229
|
-
new(value)
|
262
|
+
result = new(value)
|
263
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
264
|
+
result
|
230
265
|
end
|
231
266
|
|
232
267
|
def items(items)
|
@@ -279,6 +314,7 @@ module Scale
|
|
279
314
|
|
280
315
|
module ClassMethods
|
281
316
|
def decode(scale_bytes, raw = false)
|
317
|
+
puts "BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
282
318
|
number = Scale::Types::Compact.decode(scale_bytes).value
|
283
319
|
items = []
|
284
320
|
number.times do
|
@@ -286,6 +322,7 @@ module Scale
|
|
286
322
|
item = type.decode(scale_bytes)
|
287
323
|
items << item
|
288
324
|
end
|
325
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
289
326
|
raw ? items : new(items)
|
290
327
|
end
|
291
328
|
|
@@ -313,10 +350,12 @@ module Scale
|
|
313
350
|
|
314
351
|
module ClassMethods
|
315
352
|
def decode(scale_bytes)
|
316
|
-
|
353
|
+
puts " BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
354
|
+
value = "Scale::Types::U#{self::BYTE_LENGTH * 8}".constantize2.decode(scale_bytes).value
|
317
355
|
return new [] unless value || value <= 0
|
318
356
|
|
319
357
|
result = self::ITEMS.select { |_, mask| value & mask > 0 }.keys
|
358
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
320
359
|
new result
|
321
360
|
end
|
322
361
|
|
@@ -340,7 +379,7 @@ module Scale
|
|
340
379
|
|
341
380
|
def encode
|
342
381
|
value = self.class::ITEMS.select { |key, _| self.value.include?(key) }.values.sum
|
343
|
-
"Scale::Types::U#{self.class::BYTE_LENGTH * 8}".
|
382
|
+
"Scale::Types::U#{self.class::BYTE_LENGTH * 8}".constantize2.new(value).encode
|
344
383
|
end
|
345
384
|
end
|
346
385
|
|
@@ -349,15 +388,17 @@ module Scale
|
|
349
388
|
|
350
389
|
module ClassMethods
|
351
390
|
def decode(scale_bytes)
|
352
|
-
|
353
|
-
|
354
|
-
byte_length
|
391
|
+
puts " BEGIN " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
392
|
+
byte_length = self::BYTE_LENGTH
|
393
|
+
raise "#{self.name} byte length is wrong: #{byte_length}" unless %w[2 3 4 8 16 20 32 64 128 256].include?(byte_length.to_s)
|
355
394
|
|
356
395
|
bytes = scale_bytes.get_next_bytes(byte_length)
|
357
396
|
str = bytes.pack("C*").force_encoding("utf-8")
|
358
397
|
if str.valid_encoding?
|
398
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
359
399
|
new str
|
360
400
|
else
|
401
|
+
puts " END " + self::TYPE_NAME + ": #{scale_bytes}" if Scale::Types.debug == true
|
361
402
|
new bytes.bytes_to_hex
|
362
403
|
end
|
363
404
|
end
|
@@ -368,12 +409,10 @@ module Scale
|
|
368
409
|
end
|
369
410
|
|
370
411
|
def encode
|
371
|
-
|
372
|
-
length
|
373
|
-
raise "length is wrong: #{length}" unless %w[2 3 4 8 16 20 32 64].include?(length)
|
374
|
-
length = length.to_i
|
412
|
+
byte_length = self.class::BYTE_LENGTH
|
413
|
+
raise "#{self.class.name}'s byte length is wrong: #{byte_length}" unless %w[2 3 4 8 16 20 32 64 128 256].include?(byte_length.to_s)
|
375
414
|
|
376
|
-
if value.start_with?("0x") && value.length == (
|
415
|
+
if value.start_with?("0x") && value.length == (byte_length * 2 + 2)
|
377
416
|
value[2..]
|
378
417
|
else
|
379
418
|
bytes = value.unpack("C*")
|