erlang-etf 1.1.1 → 2.0.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.
- checksums.yaml +4 -4
- data/.editorconfig +20 -0
- data/.gitignore +10 -18
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +15 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +10 -6
- data/LICENSE.txt +1 -1
- data/README.md +13 -13
- data/Rakefile +8 -6
- data/erlang-etf.gemspec +10 -10
- data/lib/erlang-etf.rb +1 -0
- data/lib/erlang/etf.rb +363 -30
- data/lib/erlang/etf/atom.rb +28 -48
- data/lib/erlang/etf/atom_utf8.rb +28 -48
- data/lib/erlang/etf/binary.rb +24 -23
- data/lib/erlang/etf/bit_binary.rb +35 -27
- data/lib/erlang/etf/compressed.rb +61 -35
- data/lib/erlang/etf/export.rb +44 -21
- data/lib/erlang/etf/float.rb +33 -29
- data/lib/erlang/etf/fun.rb +54 -32
- data/lib/erlang/etf/integer.rb +24 -12
- data/lib/erlang/etf/large_big.rb +31 -37
- data/lib/erlang/etf/large_tuple.rb +41 -30
- data/lib/erlang/etf/list.rb +55 -25
- data/lib/erlang/etf/map.rb +58 -28
- data/lib/erlang/etf/new_float.rb +25 -14
- data/lib/erlang/etf/new_fun.rb +70 -47
- data/lib/erlang/etf/new_reference.rb +51 -24
- data/lib/erlang/etf/nil.rb +21 -6
- data/lib/erlang/etf/pid.rb +48 -21
- data/lib/erlang/etf/port.rb +49 -13
- data/lib/erlang/etf/reference.rb +49 -13
- data/lib/erlang/etf/small_atom.rb +31 -27
- data/lib/erlang/etf/small_atom_utf8.rb +31 -27
- data/lib/erlang/etf/small_big.rb +30 -39
- data/lib/erlang/etf/small_integer.rb +27 -12
- data/lib/erlang/etf/small_tuple.rb +41 -30
- data/lib/erlang/etf/string.rb +23 -23
- data/lib/erlang/etf/term.rb +109 -70
- data/lib/erlang/etf/version.rb +1 -1
- metadata +33 -169
- data/.rspec +0 -2
- data/lib/erlang/etf/bert.rb +0 -74
- data/lib/erlang/etf/extensions.rb +0 -144
- data/lib/erlang/etf/extensions/array.rb +0 -27
- data/lib/erlang/etf/extensions/big_decimal.rb +0 -20
- data/lib/erlang/etf/extensions/erlang-export.rb +0 -24
- data/lib/erlang/etf/extensions/erlang-list.rb +0 -29
- data/lib/erlang/etf/extensions/erlang-map.rb +0 -26
- data/lib/erlang/etf/extensions/erlang-nil.rb +0 -20
- data/lib/erlang/etf/extensions/erlang-pid.rb +0 -20
- data/lib/erlang/etf/extensions/erlang-string.rb +0 -31
- data/lib/erlang/etf/extensions/erlang-tuple.rb +0 -29
- data/lib/erlang/etf/extensions/false_class.rb +0 -26
- data/lib/erlang/etf/extensions/float.rb +0 -18
- data/lib/erlang/etf/extensions/hash.rb +0 -30
- data/lib/erlang/etf/extensions/integer.rb +0 -46
- data/lib/erlang/etf/extensions/nil_class.rb +0 -27
- data/lib/erlang/etf/extensions/object.rb +0 -22
- data/lib/erlang/etf/extensions/regexp.rb +0 -32
- data/lib/erlang/etf/extensions/string.rb +0 -33
- data/lib/erlang/etf/extensions/symbol.rb +0 -43
- data/lib/erlang/etf/extensions/time.rb +0 -27
- data/lib/erlang/etf/extensions/true_class.rb +0 -26
- data/lib/erlang/etf/terms.rb +0 -132
- data/spec/erlang/etf/atom_spec.rb +0 -90
- data/spec/erlang/etf/atom_utf8_spec.rb +0 -90
- data/spec/erlang/etf/binary_spec.rb +0 -90
- data/spec/erlang/etf/bit_binary_spec.rb +0 -99
- data/spec/erlang/etf/compressed_spec.rb +0 -37
- data/spec/erlang/etf/export_spec.rb +0 -58
- data/spec/erlang/etf/extensions/array_spec.rb +0 -40
- data/spec/erlang/etf/extensions/big_decimal_spec.rb +0 -26
- data/spec/erlang/etf/extensions/erlang-export_spec.rb +0 -32
- data/spec/erlang/etf/extensions/erlang-list_spec.rb +0 -76
- data/spec/erlang/etf/extensions/erlang-map_spec.rb +0 -48
- data/spec/erlang/etf/extensions/erlang-nil_spec.rb +0 -24
- data/spec/erlang/etf/extensions/erlang-pid_spec.rb +0 -33
- data/spec/erlang/etf/extensions/erlang-string_spec.rb +0 -41
- data/spec/erlang/etf/extensions/erlang-tuple_spec.rb +0 -57
- data/spec/erlang/etf/extensions/false_class_spec.rb +0 -29
- data/spec/erlang/etf/extensions/float_spec.rb +0 -24
- data/spec/erlang/etf/extensions/hash_spec.rb +0 -90
- data/spec/erlang/etf/extensions/integer_spec.rb +0 -259
- data/spec/erlang/etf/extensions/nil_class_spec.rb +0 -29
- data/spec/erlang/etf/extensions/object_spec.rb +0 -30
- data/spec/erlang/etf/extensions/regexp_spec.rb +0 -35
- data/spec/erlang/etf/extensions/string_spec.rb +0 -43
- data/spec/erlang/etf/extensions/symbol_spec.rb +0 -64
- data/spec/erlang/etf/extensions/time_spec.rb +0 -32
- data/spec/erlang/etf/extensions/true_class_spec.rb +0 -29
- data/spec/erlang/etf/float_spec.rb +0 -92
- data/spec/erlang/etf/fun_spec.rb +0 -132
- data/spec/erlang/etf/integer_spec.rb +0 -57
- data/spec/erlang/etf/large_big_spec.rb +0 -67
- data/spec/erlang/etf/large_tuple_spec.rb +0 -119
- data/spec/erlang/etf/list_spec.rb +0 -159
- data/spec/erlang/etf/map_spec.rb +0 -100
- data/spec/erlang/etf/new_float_spec.rb +0 -92
- data/spec/erlang/etf/new_fun_spec.rb +0 -146
- data/spec/erlang/etf/new_reference_spec.rb +0 -60
- data/spec/erlang/etf/nil_spec.rb +0 -50
- data/spec/erlang/etf/pid_spec.rb +0 -61
- data/spec/erlang/etf/port_spec.rb +0 -58
- data/spec/erlang/etf/reference_spec.rb +0 -58
- data/spec/erlang/etf/small_atom_spec.rb +0 -90
- data/spec/erlang/etf/small_atom_utf8_spec.rb +0 -90
- data/spec/erlang/etf/small_big_spec.rb +0 -67
- data/spec/erlang/etf/small_integer_spec.rb +0 -57
- data/spec/erlang/etf/small_tuple_spec.rb +0 -112
- data/spec/erlang/etf/string_spec.rb +0 -92
- data/spec/erlang/etf/term_spec.rb +0 -27
- data/spec/erlang/etf/terms_spec.rb +0 -23
- data/spec/erlang/etf_spec.rb +0 -23
- data/spec/erlang_spec.rb +0 -95
- data/spec/spec_helper.rb +0 -31
data/lib/erlang/etf/export.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | N1 | N2 | N3
|
6
|
-
# --- | ------ | -------- | -----
|
7
|
-
# 113 | Module | Function | Arity
|
5
|
+
# | 1 | N1 | N2 | N3 |
|
6
|
+
# | --- | ------ | -------- | ----- |
|
7
|
+
# | 113 | Module | Function | Arity |
|
8
8
|
#
|
9
9
|
# This term is the encoding for external funs: `fun M:F/A`.
|
10
10
|
#
|
@@ -22,31 +22,54 @@ module Erlang
|
|
22
22
|
# [`EXPORT_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#EXPORT_EXT
|
23
23
|
#
|
24
24
|
class Export
|
25
|
-
include Term
|
25
|
+
include Erlang::ETF::Term
|
26
26
|
|
27
|
-
|
27
|
+
class << self
|
28
|
+
def [](term, mod = nil, function = nil, arity = nil)
|
29
|
+
return new(term, mod, function, arity)
|
30
|
+
end
|
28
31
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
def erlang_load(buffer)
|
33
|
+
mod = Erlang::ETF.read_term(buffer)
|
34
|
+
function = Erlang::ETF.read_term(buffer)
|
35
|
+
arity = Erlang::ETF.read_term(buffer)
|
36
|
+
term = Erlang::Export[Erlang.from(mod), Erlang.from(function), Erlang.from(arity)]
|
37
|
+
return new(term, mod, function, arity)
|
38
|
+
end
|
39
|
+
end
|
32
40
|
|
33
|
-
term
|
41
|
+
def initialize(term, mod = nil, function = nil, arity = nil)
|
42
|
+
raise ArgumentError, "term must be of type Erlang::Export" if not term.kind_of?(Erlang::Export)
|
43
|
+
@term = term
|
44
|
+
@mod = mod
|
45
|
+
@function = function
|
46
|
+
@arity = arity
|
47
|
+
end
|
34
48
|
|
35
|
-
|
49
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
50
|
+
buffer << EXPORT_EXT
|
51
|
+
Erlang::ETF.write_term(@mod || @term.mod, buffer)
|
52
|
+
Erlang::ETF.write_term(@function || @term.function, buffer)
|
53
|
+
Erlang::ETF.write_term(@arity || @term.arity, buffer)
|
54
|
+
return buffer
|
55
|
+
end
|
36
56
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
57
|
+
def inspect
|
58
|
+
if @mod.nil? and @function.nil? and @arity.nil?
|
59
|
+
return super
|
60
|
+
else
|
61
|
+
return "#{self.class}[#{@term.inspect}, #{@mod.inspect}, #{@function.inspect}, #{@arity.inspect}]"
|
62
|
+
end
|
41
63
|
end
|
42
64
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
65
|
+
def pretty_print(pp)
|
66
|
+
state = [@term]
|
67
|
+
state.push(@mod, @function, @arity) if not @mod.nil? or not @function.nil? or not @arity.nil?
|
68
|
+
return pp.group(1, "#{self.class}[", "]") do
|
69
|
+
pp.breakable ''
|
70
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
71
|
+
end
|
49
72
|
end
|
50
73
|
end
|
51
74
|
end
|
52
|
-
end
|
75
|
+
end
|
data/lib/erlang/etf/float.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
require 'bigdecimal'
|
2
|
-
|
3
1
|
module Erlang
|
4
2
|
module ETF
|
5
3
|
|
6
4
|
#
|
7
|
-
# 1 | 31
|
8
|
-
# --- | ------------
|
9
|
-
# 99 | Float String
|
5
|
+
# | 1 | 31 |
|
6
|
+
# | --- | ------------ |
|
7
|
+
# | 99 | Float String |
|
10
8
|
#
|
11
9
|
# A float is stored in string format. the format used in sprintf
|
12
10
|
# to format the float is "%.20e" (there are more bytes allocated
|
@@ -22,41 +20,47 @@ module Erlang
|
|
22
20
|
# [`FLOAT_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#FLOAT_EXT
|
23
21
|
#
|
24
22
|
class Float
|
25
|
-
include Term
|
26
|
-
|
27
|
-
FLOAT_STRING_FORMAT = "%.20e".freeze
|
28
|
-
|
29
|
-
uint8 :tag, always: Terms::FLOAT_EXT
|
23
|
+
include Erlang::ETF::Term
|
30
24
|
|
31
|
-
|
25
|
+
class << self
|
26
|
+
def [](term, float_string = nil)
|
27
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
28
|
+
term = Erlang.from(term)
|
29
|
+
return new(term, float_string)
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
else
|
38
|
-
buffer << float_string
|
32
|
+
def erlang_load(buffer)
|
33
|
+
float_string = buffer.read(31)
|
34
|
+
term = Erlang::Float[float_string.byteslice(0, float_string.index("\0")), old: true]
|
35
|
+
return new(term, float_string)
|
39
36
|
end
|
40
37
|
end
|
41
38
|
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
def initialize(term, float_string = nil)
|
40
|
+
raise ArgumentError, "term must be of type Erlang::Float" if not Erlang.is_float(term) or not term.old
|
41
|
+
@term = term
|
42
|
+
@float_string = float_string
|
45
43
|
end
|
46
44
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
46
|
+
buffer << FLOAT_EXT
|
47
|
+
buffer << (@float_string || to_float_string)
|
48
|
+
return buffer
|
51
49
|
end
|
52
50
|
|
53
|
-
def
|
54
|
-
if float_string.
|
55
|
-
|
51
|
+
def inspect
|
52
|
+
if @float_string.nil?
|
53
|
+
return "#{self.class}[#{@term.inspect}]"
|
56
54
|
else
|
57
|
-
|
55
|
+
return "#{self.class}[#{@term.inspect}, #{@float_string.inspect}]"
|
58
56
|
end
|
59
57
|
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def to_float_string
|
61
|
+
return @term.to_float_string.ljust(31, "\0")
|
62
|
+
end
|
63
|
+
|
60
64
|
end
|
61
65
|
end
|
62
|
-
end
|
66
|
+
end
|
data/lib/erlang/etf/fun.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4 | N1 | N2 | N3 | N4 | N5
|
6
|
-
# --- | ------- | --- | ------ | ----- | ---- | -------------
|
7
|
-
# 117 | NumFree | Pid | Module | Index | Uniq | Free vars ...
|
5
|
+
# | 1 | 4 | N1 | N2 | N3 | N4 | N5 |
|
6
|
+
# | --- | ------- | --- | ------ | ----- | ---- | ------------- |
|
7
|
+
# | 117 | NumFree | Pid | Module | Index | Uniq | Free vars ... |
|
8
8
|
#
|
9
9
|
# `Pid`
|
10
10
|
# > is a process identifier as in [`PID_EXT`]. It represents the
|
@@ -38,44 +38,66 @@ module Erlang
|
|
38
38
|
# [`FUN_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#FUN_EXT
|
39
39
|
#
|
40
40
|
class Fun
|
41
|
-
include Term
|
41
|
+
include Erlang::ETF::Term
|
42
42
|
|
43
|
-
|
43
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
term :mod # atom, small_atom
|
45
|
+
class << self
|
46
|
+
def [](term, pid = nil, mod = nil, index = nil, uniq = nil, free_vars = nil)
|
47
|
+
return new(term, pid, mod, index, uniq, free_vars)
|
48
|
+
end
|
50
49
|
|
51
|
-
|
50
|
+
def erlang_load(buffer)
|
51
|
+
num_free, = buffer.read(4).unpack(UINT32BE)
|
52
|
+
pid = Erlang::ETF.read_term(buffer)
|
53
|
+
mod = Erlang::ETF.read_term(buffer)
|
54
|
+
index = Erlang::ETF.read_term(buffer)
|
55
|
+
uniq = Erlang::ETF.read_term(buffer)
|
56
|
+
free_vars = Array.new(num_free); num_free.times { |i| free_vars[i] = Erlang::ETF.read_term(buffer) }
|
57
|
+
term = Erlang::Function[pid: Erlang.from(pid), mod: Erlang.from(mod), index: Erlang.from(index), uniq: Erlang.from(uniq), free_vars: Erlang.from(free_vars)]
|
58
|
+
return new(term, pid, mod, index, uniq, free_vars)
|
59
|
+
end
|
60
|
+
end
|
52
61
|
|
53
|
-
term
|
62
|
+
def initialize(term, pid = nil, mod = nil, index = nil, uniq = nil, free_vars = nil)
|
63
|
+
raise ArgumentError, "term must be of type Erlang::Function" if not term.kind_of?(Erlang::Function) or term.new_function?
|
64
|
+
@term = term
|
65
|
+
@pid = pid
|
66
|
+
@mod = mod
|
67
|
+
@index = index
|
68
|
+
@uniq = uniq
|
69
|
+
@free_vars = free_vars
|
70
|
+
end
|
54
71
|
|
55
|
-
|
72
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
73
|
+
buffer << FUN_EXT
|
74
|
+
free_vars = @free_vars || @term.free_vars
|
75
|
+
num_free = free_vars.length
|
76
|
+
buffer << [num_free].pack(UINT32BE)
|
77
|
+
Erlang::ETF.write_term(@pid || @term.pid, buffer)
|
78
|
+
Erlang::ETF.write_term(@mod || @term.mod, buffer)
|
79
|
+
Erlang::ETF.write_term(@index || @term.index, buffer)
|
80
|
+
Erlang::ETF.write_term(@uniq || @term.uniq, buffer)
|
81
|
+
num_free.times { |i| Erlang::ETF.write_term(free_vars[i], buffer) }
|
82
|
+
return buffer
|
83
|
+
end
|
56
84
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
deserialize_uniq(buffer)
|
63
|
-
self.free_vars = []
|
64
|
-
num_free.times do
|
65
|
-
self.free_vars << Terms.deserialize(buffer)
|
85
|
+
def inspect
|
86
|
+
if @pid.nil? and @mod.nil? and @index.nil? and @uniq.nil? and @free_vars.nil?
|
87
|
+
return super
|
88
|
+
else
|
89
|
+
return "#{self.class}[#{@term.inspect}, #{@pid.inspect}, #{@mod.inspect}, #{@index.inspect}, #{@uniq.inspect}, #{@free_vars.inspect}]"
|
66
90
|
end
|
67
|
-
self
|
68
91
|
end
|
69
92
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
self.
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
self.free_vars = free_vars
|
93
|
+
def pretty_print(pp)
|
94
|
+
state = [@term]
|
95
|
+
state.push(@pid, @mod, @index, @uniq, @free_vars) if not @pid.nil? or not @mod.nil? or not @index.nil? or not @uniq.nil? or not @free_vars.nil?
|
96
|
+
return pp.group(1, "#{self.class}[", "]") do
|
97
|
+
pp.breakable ''
|
98
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
99
|
+
end
|
78
100
|
end
|
79
101
|
end
|
80
102
|
end
|
81
|
-
end
|
103
|
+
end
|
data/lib/erlang/etf/integer.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4
|
6
|
-
# --- | ---
|
7
|
-
# 98 | Int
|
5
|
+
# | 1 | 4 |
|
6
|
+
# | --- | --- |
|
7
|
+
# | 98 | Int |
|
8
8
|
#
|
9
9
|
# Signed 32 bit integer in big-endian format (i.e. MSB first)
|
10
10
|
#
|
@@ -13,21 +13,33 @@ module Erlang
|
|
13
13
|
# [`INTEGER_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#INTEGER_EXT
|
14
14
|
#
|
15
15
|
class Integer
|
16
|
-
include Term
|
16
|
+
include Erlang::ETF::Term
|
17
17
|
|
18
|
-
|
18
|
+
INT32BE = Erlang::ETF::Term::INT32BE
|
19
19
|
|
20
|
-
|
20
|
+
class << self
|
21
|
+
def [](term)
|
22
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
23
|
+
term = Erlang.from(term)
|
24
|
+
return new(term)
|
25
|
+
end
|
21
26
|
|
22
|
-
|
27
|
+
def erlang_load(buffer)
|
28
|
+
integer, = buffer.read(4).unpack(INT32BE)
|
29
|
+
return new(integer)
|
30
|
+
end
|
31
|
+
end
|
23
32
|
|
24
|
-
def initialize(
|
25
|
-
|
33
|
+
def initialize(term)
|
34
|
+
raise ArgumentError, "term must be of type Integer" if not Erlang.is_integer(term)
|
35
|
+
@term = term
|
26
36
|
end
|
27
37
|
|
28
|
-
def
|
29
|
-
|
38
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
39
|
+
buffer << INTEGER_EXT
|
40
|
+
buffer << [@term].pack(INT32BE)
|
41
|
+
return buffer
|
30
42
|
end
|
31
43
|
end
|
32
44
|
end
|
33
|
-
end
|
45
|
+
end
|
data/lib/erlang/etf/large_big.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4 | 1 | n
|
6
|
-
# --- | --- | ---- | ---------------
|
7
|
-
# 111 | n | Sign | d(0) ... d(n-1)
|
5
|
+
# | 1 | 4 | 1 | n |
|
6
|
+
# | --- | --- | ---- | --------------- |
|
7
|
+
# | 111 | n | Sign | d(0) ... d(n-1) |
|
8
8
|
#
|
9
9
|
# Same as [`SMALL_BIG_EXT`] with the difference that the length
|
10
10
|
# field is an unsigned 4 byte integer.
|
@@ -15,44 +15,38 @@ module Erlang
|
|
15
15
|
# [`LARGE_BIG_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#LARGE_BIG_EXT
|
16
16
|
#
|
17
17
|
class LargeBig
|
18
|
-
include Term
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
include Erlang::ETF::Term
|
19
|
+
|
20
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
21
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
22
|
+
HEAD = (UINT32BE + UINT8).freeze
|
23
|
+
|
24
|
+
class << self
|
25
|
+
def [](term)
|
26
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
27
|
+
term = Erlang.from(term)
|
28
|
+
return new(term)
|
29
|
+
end
|
30
|
+
|
31
|
+
def erlang_load(buffer)
|
32
|
+
n, sign, = buffer.read(5).unpack(HEAD)
|
33
|
+
integer = Erlang::Binary.decode_unsigned(buffer.read(n), :little)
|
34
|
+
integer = -integer if sign == 1
|
35
|
+
return new(integer)
|
36
|
+
end
|
25
37
|
end
|
26
38
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
buffer << [integer.abs.to_s(2).reverse!].pack(BIN_LSB_PACK)
|
31
|
-
self.n = buffer.bytesize - start
|
32
|
-
buffer
|
33
|
-
end
|
34
|
-
|
35
|
-
undef after_serialize_n
|
36
|
-
def after_serialize_n(buffer)
|
37
|
-
buffer[@n_start, BYTES_32] = serialize_n ""
|
38
|
-
end
|
39
|
-
|
40
|
-
deserialize do |buffer|
|
41
|
-
deserialize_n(buffer)
|
42
|
-
sign, = buffer.read(BYTES_8).unpack(UINT8_PACK)
|
43
|
-
self.integer = buffer.read(n).unpack(BIN_LSB_PACK).at(0).reverse!.to_i(2) * ((sign == 0) ? 1 : -1)
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
finalize
|
48
|
-
|
49
|
-
def initialize(integer)
|
50
|
-
@integer = integer
|
39
|
+
def initialize(term)
|
40
|
+
raise ArgumentError, "term must be of type Integer" if not Erlang.is_integer(term)
|
41
|
+
@term = term
|
51
42
|
end
|
52
43
|
|
53
|
-
def
|
54
|
-
|
44
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
45
|
+
buffer << LARGE_BIG_EXT
|
46
|
+
buffer << [Erlang::ETF.intlog2div8(@term), (@term < 0) ? 1 : 0].pack(HEAD)
|
47
|
+
buffer << Erlang::Binary.encode_unsigned(@term.abs, :little)
|
48
|
+
return buffer
|
55
49
|
end
|
56
50
|
end
|
57
51
|
end
|
58
|
-
end
|
52
|
+
end
|
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4 | N
|
6
|
-
# --- | ----- | --------
|
7
|
-
# 105 | Arity | Elements
|
5
|
+
# | 1 | 4 | N |
|
6
|
+
# | --- | ----- | -------- |
|
7
|
+
# | 105 | Arity | Elements |
|
8
8
|
#
|
9
9
|
# Same as [`SMALL_TUPLE_EXT`] with the exception that `Arity` is an
|
10
10
|
# unsigned 4 byte integer in big endian format.
|
@@ -15,46 +15,57 @@ module Erlang
|
|
15
15
|
# [`LARGE_TUPLE_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#LARGE_TUPLE_EXT
|
16
16
|
#
|
17
17
|
class LargeTuple
|
18
|
-
include Term
|
18
|
+
include Erlang::ETF::Term
|
19
19
|
|
20
|
-
|
20
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
class << self
|
23
|
+
def [](term, elements = nil)
|
24
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
25
|
+
term = Erlang.from(term)
|
26
|
+
return new(term, elements)
|
27
|
+
end
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
def erlang_load(buffer)
|
30
|
+
arity, = buffer.read(4).unpack(UINT32BE)
|
31
|
+
elements = Array.new(arity)
|
32
|
+
arity.times { |i| elements[i] = Erlang::ETF.read_term(buffer) }
|
33
|
+
tuple = Erlang::Tuple[*elements]
|
34
|
+
return new(tuple, elements)
|
31
35
|
end
|
32
|
-
self
|
33
36
|
end
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@elements = elements
|
38
|
+
def initialize(term, elements = nil)
|
39
|
+
raise ArgumentError, "term must be of type Tuple" if not Erlang.is_tuple(term)
|
40
|
+
@term = term
|
41
|
+
@elements = elements.freeze
|
39
42
|
end
|
40
43
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
45
|
+
buffer << LARGE_TUPLE_EXT
|
46
|
+
elements = @elements || @term
|
47
|
+
arity = elements.size
|
48
|
+
buffer << [arity].pack(UINT32BE)
|
49
|
+
elements.each { |element| Erlang::ETF.write_term(element, buffer) }
|
50
|
+
return buffer
|
44
51
|
end
|
45
52
|
|
46
|
-
def
|
47
|
-
elements
|
48
|
-
|
53
|
+
def inspect
|
54
|
+
if @elements.nil?
|
55
|
+
return super
|
56
|
+
else
|
57
|
+
return "#{self.class}[#{@term.inspect}, #{@elements.inspect}]"
|
58
|
+
end
|
49
59
|
end
|
50
60
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
61
|
+
def pretty_print(pp)
|
62
|
+
state = [@term]
|
63
|
+
state.push(@elements) if not @elements.nil?
|
64
|
+
return pp.group(1, "#{self.class}[", "]") do
|
65
|
+
pp.breakable ''
|
66
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
56
67
|
end
|
57
68
|
end
|
58
69
|
end
|
59
70
|
end
|
60
|
-
end
|
71
|
+
end
|