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/list.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4
|
6
|
-
# --- |
|
7
|
-
# 108 |
|
5
|
+
# | 1 | 4 | | |
|
6
|
+
# | --- | ------ | -------- | ---- |
|
7
|
+
# | 108 | Length | Elements | Tail |
|
8
8
|
#
|
9
9
|
# `Length` is the number of elements that follows in the `Elements`
|
10
10
|
# section. `Tail` is the final tail of the list; it is [`NIL_EXT`] for a
|
@@ -17,39 +17,69 @@ module Erlang
|
|
17
17
|
# [`LIST_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#LIST_EXT
|
18
18
|
#
|
19
19
|
class List
|
20
|
-
include Term
|
20
|
+
include Erlang::ETF::Term
|
21
21
|
|
22
|
-
|
22
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
class << self
|
25
|
+
def [](term, elements = nil, tail = nil)
|
26
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
27
|
+
term = Erlang.from(term)
|
28
|
+
return new(term, elements, tail)
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
def erlang_load(buffer)
|
32
|
+
length, = buffer.read(4).unpack(UINT32BE)
|
33
|
+
elements = Array.new(length)
|
34
|
+
length.times { |i| elements[i] = Erlang::ETF.read_term(buffer) }
|
35
|
+
tail = Erlang::ETF.read_term(buffer)
|
36
|
+
return tail if length == 0
|
37
|
+
list = Erlang::List.from_enum(elements) + tail
|
38
|
+
return new(list, elements, tail)
|
34
39
|
end
|
35
|
-
deserialize_tail(buffer)
|
36
|
-
self
|
37
40
|
end
|
38
41
|
|
39
|
-
|
42
|
+
def initialize(term, elements = nil, tail = nil)
|
43
|
+
raise ArgumentError, "term must be of any type" if not Erlang.is_any(term)
|
44
|
+
@term = term
|
45
|
+
@elements = elements.freeze
|
46
|
+
@tail = tail.freeze
|
47
|
+
end
|
40
48
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
49
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
50
|
+
buffer << LIST_EXT
|
51
|
+
elements = nil
|
52
|
+
tail = nil
|
53
|
+
if not Erlang.is_list(term)
|
54
|
+
elements = @elements || []
|
55
|
+
tail = @tail || @term
|
56
|
+
else
|
57
|
+
elements = @elements || (@term.improper? ? @term.to_proper_list : @term)
|
58
|
+
tail = @tail || (@term.improper? ? @term.last(true) : Erlang::Nil)
|
59
|
+
end
|
60
|
+
length = elements.size
|
61
|
+
buffer << [length].pack(UINT32BE)
|
62
|
+
elements.each { |element| Erlang::ETF.write_term(element, buffer) }
|
63
|
+
Erlang::ETF.write_term(tail, buffer)
|
64
|
+
return buffer
|
44
65
|
end
|
45
66
|
|
46
|
-
def
|
47
|
-
|
67
|
+
def inspect
|
68
|
+
if @elements.nil? and @tail.nil?
|
69
|
+
return super
|
70
|
+
else
|
71
|
+
return "#{self.class}[#{@term.inspect}, #{@elements.inspect}, #{@tail.inspect}]"
|
72
|
+
end
|
48
73
|
end
|
49
74
|
|
50
|
-
def
|
51
|
-
|
75
|
+
def pretty_print(pp)
|
76
|
+
state = [@term]
|
77
|
+
state.push(@elements, @tail) if not @elements.nil? or not @tail.nil?
|
78
|
+
return pp.group(1, "#{self.class}[", "]") do
|
79
|
+
pp.breakable ''
|
80
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
81
|
+
end
|
52
82
|
end
|
53
83
|
end
|
54
84
|
end
|
55
|
-
end
|
85
|
+
end
|
data/lib/erlang/etf/map.rb
CHANGED
@@ -2,50 +2,80 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4
|
6
|
-
# --- |
|
7
|
-
# 116 |
|
5
|
+
# | 1 | 4 | N |
|
6
|
+
# | --- | ----- | ----- |
|
7
|
+
# | 116 | Arity | Pairs |
|
8
8
|
#
|
9
|
-
# The
|
10
|
-
#
|
9
|
+
# `MAP_EXT` encodes a map. The `Arity` field is an unsigned 4 byte integer
|
10
|
+
# in big endian format that determines the number of key-value pairs in the
|
11
|
+
# map. Key and value pairs (`Ki => Vi`) are encoded in the `Pairs` section
|
12
|
+
# in the following order: `K1, V1, K2, V2,..., Kn, Vn`. Duplicate keys are
|
13
|
+
# **not allowed** within the same map.
|
11
14
|
#
|
12
15
|
# (see [`MAP_EXT`])
|
13
16
|
#
|
14
17
|
# [`MAP_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#MAP_EXT
|
15
18
|
#
|
16
19
|
class Map
|
17
|
-
include Term
|
20
|
+
include Erlang::ETF::Term
|
18
21
|
|
19
|
-
|
22
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
deserialize do |buffer|
|
27
|
-
size, = buffer.read(BYTES_32).unpack(UINT32BE_PACK)
|
28
|
-
self.keys = []
|
29
|
-
size.times do
|
30
|
-
self.keys << Terms.deserialize(buffer)
|
24
|
+
class << self
|
25
|
+
def [](term, pairs = nil)
|
26
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
27
|
+
term = Erlang.from(term)
|
28
|
+
return new(term, pairs)
|
31
29
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
|
31
|
+
def erlang_load(buffer)
|
32
|
+
arity, = buffer.read(4).unpack(UINT32BE)
|
33
|
+
pairs = Array.new(arity * 2)
|
34
|
+
(arity * 2).times { |i| pairs[i] = Erlang::ETF.read_term(buffer) }
|
35
|
+
map = Erlang::Map[*pairs]
|
36
|
+
return new(map, pairs)
|
35
37
|
end
|
36
|
-
self
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
def initialize(term, pairs = nil)
|
41
|
+
raise ArgumentError, "term must be of type Map" if not Erlang.is_map(term)
|
42
|
+
@term = term
|
43
|
+
@pairs = pairs.freeze
|
44
|
+
end
|
40
45
|
|
41
|
-
def
|
42
|
-
|
43
|
-
@
|
46
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
47
|
+
buffer << MAP_EXT
|
48
|
+
if @pairs
|
49
|
+
arity = @pairs.length.div(2)
|
50
|
+
buffer << [arity].pack(UINT32BE)
|
51
|
+
(arity * 2).times { |i| Erlang::ETF.write_term(@pairs[i], buffer) }
|
52
|
+
else
|
53
|
+
arity = @term.size
|
54
|
+
buffer << [arity].pack(UINT32BE)
|
55
|
+
@term.sort.each { |key, val|
|
56
|
+
Erlang::ETF.write_term(key, buffer)
|
57
|
+
Erlang::ETF.write_term(val, buffer)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
return buffer
|
44
61
|
end
|
45
62
|
|
46
|
-
def
|
47
|
-
|
63
|
+
def inspect
|
64
|
+
if @pairs.nil?
|
65
|
+
return super
|
66
|
+
else
|
67
|
+
return "#{self.class}[#{@term.inspect}, #{@pairs.inspect}]"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def pretty_print(pp)
|
72
|
+
state = [@term]
|
73
|
+
state.push(@pairs) if not @pairs.nil?
|
74
|
+
return pp.group(1, "#{self.class}[", "]") do
|
75
|
+
pp.breakable ''
|
76
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
77
|
+
end
|
48
78
|
end
|
49
79
|
end
|
50
80
|
end
|
51
|
-
end
|
81
|
+
end
|
data/lib/erlang/etf/new_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 | 8
|
8
|
-
# --- | ----------
|
9
|
-
# 70 | IEEE Float
|
5
|
+
# | 1 | 8 |
|
6
|
+
# | --- | ---------- |
|
7
|
+
# | 70 | IEEE Float |
|
10
8
|
#
|
11
9
|
# A float is stored as 8 bytes in big-endian IEEE format.
|
12
10
|
#
|
@@ -17,21 +15,34 @@ module Erlang
|
|
17
15
|
# [`NEW_FLOAT_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#NEW_FLOAT_EXT
|
18
16
|
#
|
19
17
|
class NewFloat
|
20
|
-
include Term
|
18
|
+
include Erlang::ETF::Term
|
21
19
|
|
22
|
-
|
20
|
+
DOUBLEBE = Erlang::ETF::Term::DOUBLEBE
|
23
21
|
|
24
|
-
|
22
|
+
class << self
|
23
|
+
def [](term)
|
24
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
25
|
+
term = Erlang.from(term)
|
26
|
+
return new(term)
|
27
|
+
end
|
25
28
|
|
26
|
-
|
29
|
+
def erlang_load(buffer)
|
30
|
+
float, = buffer.read(8).unpack(DOUBLEBE)
|
31
|
+
term = Erlang::Float[float]
|
32
|
+
return new(term)
|
33
|
+
end
|
34
|
+
end
|
27
35
|
|
28
|
-
def initialize(
|
29
|
-
|
36
|
+
def initialize(term)
|
37
|
+
raise ArgumentError, "term must be of type Erlang::Float" if not Erlang.is_float(term) or term.old
|
38
|
+
@term = term
|
30
39
|
end
|
31
40
|
|
32
|
-
def
|
33
|
-
|
41
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
42
|
+
buffer << NEW_FLOAT_EXT
|
43
|
+
buffer << [@term.data].pack(DOUBLEBE)
|
44
|
+
return buffer
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|
37
|
-
end
|
48
|
+
end
|
data/lib/erlang/etf/new_fun.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 4 | 1 | 16 | 4 | 4 | N1 | N2 | N3 | N4 | N5
|
6
|
-
# --- | ---- | ----- | ---- | ----- | ------- | ------ | -------- | ------- | --- | ---------
|
7
|
-
# 112 | Size | Arity | Uniq | Index | NumFree | Module | Oldindex | OldUniq | Pid | Free Vars
|
5
|
+
# | 1 | 4 | 1 | 16 | 4 | 4 | N1 | N2 | N3 | N4 | N5 |
|
6
|
+
# | --- | ---- | ----- | ---- | ----- | ------- | ------ | -------- | ------- | --- | --------- |
|
7
|
+
# | 112 | Size | Arity | Uniq | Index | NumFree | Module | Oldindex | OldUniq | Pid | Free Vars |
|
8
8
|
#
|
9
9
|
# This is the new encoding of internal funs:
|
10
10
|
#
|
@@ -60,61 +60,84 @@ module Erlang
|
|
60
60
|
# [`NEW_FUN_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#NEW_FUN_EXT
|
61
61
|
#
|
62
62
|
class NewFun
|
63
|
-
include Term
|
63
|
+
include Erlang::ETF::Term
|
64
64
|
|
65
|
-
|
65
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
66
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
67
|
+
UINT128BE = Erlang::ETF::Term::UINT128BE
|
68
|
+
HEAD = (UINT32BE + UINT8 + UINT128BE + UINT32BE + UINT32BE).freeze
|
66
69
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
70
|
+
class << self
|
71
|
+
def [](term, arity = nil, uniq = nil, index = nil, mod = nil, old_index = nil, old_uniq = nil, pid = nil, free_vars = nil)
|
72
|
+
return new(term, arity, uniq, index, mod, old_index, old_uniq, pid, free_vars)
|
73
|
+
end
|
74
|
+
|
75
|
+
def erlang_load(buffer)
|
76
|
+
_, arity, uniq_hi, uniq_lo, index, num_free = buffer.read(29).unpack(HEAD)
|
77
|
+
uniq = (uniq_hi << 64) + uniq_lo
|
78
|
+
mod = Erlang::ETF.read_term(buffer)
|
79
|
+
old_index = Erlang::ETF.read_term(buffer)
|
80
|
+
old_uniq = Erlang::ETF.read_term(buffer)
|
81
|
+
pid = Erlang::ETF.read_term(buffer)
|
82
|
+
free_vars = Array.new(num_free); num_free.times { |i| free_vars[i] = Erlang::ETF.read_term(buffer) }
|
83
|
+
term = Erlang::Function[arity: Erlang.from(arity), uniq: Erlang.from(uniq), index: Erlang.from(index), mod: Erlang.from(mod), old_index: Erlang.from(old_index), old_uniq: Erlang.from(old_uniq), pid: Erlang.from(pid), free_vars: Erlang.from(free_vars)]
|
84
|
+
return new(term, arity, uniq, index, mod, old_index, old_uniq, pid, free_vars)
|
85
|
+
end
|
77
86
|
end
|
78
87
|
|
79
|
-
|
80
|
-
|
81
|
-
|
88
|
+
def initialize(term, arity = nil, uniq = nil, index = nil, mod = nil, old_index = nil, old_uniq = nil, pid = nil, free_vars = nil)
|
89
|
+
raise ArgumentError, "term must be of type Erlang::Function" if not term.kind_of?(Erlang::Function) or not term.new_function?
|
90
|
+
@term = term
|
91
|
+
@arity = arity
|
92
|
+
@uniq = uniq
|
93
|
+
@index = index
|
94
|
+
@mod = mod
|
95
|
+
@old_index = old_index
|
96
|
+
@old_uniq = old_uniq
|
97
|
+
@pid = pid
|
98
|
+
@free_vars = free_vars
|
82
99
|
end
|
83
100
|
|
84
|
-
|
85
|
-
|
86
|
-
|
101
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
102
|
+
buffer << NEW_FUN_EXT
|
103
|
+
size = 0
|
104
|
+
arity = @arity || @term.arity
|
105
|
+
uniq = @uniq || @term.uniq
|
106
|
+
index = @index || @term.index
|
107
|
+
free_vars = @free_vars || @term.free_vars
|
108
|
+
num_free = free_vars.length
|
109
|
+
sizestart = buffer.bytesize
|
110
|
+
buffer << [size, arity, uniq >> 64, uniq, index, num_free].pack(HEAD)
|
111
|
+
Erlang::ETF.write_term(@mod || @term.mod, buffer)
|
112
|
+
Erlang::ETF.write_term(@old_index || @term.old_index, buffer)
|
113
|
+
Erlang::ETF.write_term(@old_uniq || @term.old_uniq, buffer)
|
114
|
+
Erlang::ETF.write_term(@pid || @term.pid, buffer)
|
115
|
+
num_free.times { |i| Erlang::ETF.write_term(free_vars[i], buffer) }
|
116
|
+
sizeend = buffer.bytesize
|
117
|
+
size = sizeend - sizestart
|
118
|
+
buffer.setbyte(sizestart + 0, size >> 24)
|
119
|
+
buffer.setbyte(sizestart + 1, size >> 16)
|
120
|
+
buffer.setbyte(sizestart + 2, size >> 8)
|
121
|
+
buffer.setbyte(sizestart + 3, size)
|
122
|
+
return buffer
|
87
123
|
end
|
88
124
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
num_free, = buffer.read(BYTES_32).unpack(UINT32BE_PACK)
|
95
|
-
deserialize_mod(buffer)
|
96
|
-
deserialize_old_index(buffer)
|
97
|
-
deserialize_old_uniq(buffer)
|
98
|
-
deserialize_pid(buffer)
|
99
|
-
self.free_vars = []
|
100
|
-
num_free.times do
|
101
|
-
self.free_vars << Terms.deserialize(buffer)
|
125
|
+
def inspect
|
126
|
+
if @arity.nil? and @uniq.nil? and @index.nil? and @mod.nil? and @old_index.nil? and @old_uniq.nil? and @pid.nil? and @free_vars.nil?
|
127
|
+
return super
|
128
|
+
else
|
129
|
+
return "#{self.class}[#{@term.inspect}, #{@arity.inspect}, #{@uniq.inspect}, #{@index.inspect}, #{@mod.inspect}, #{@old_index.inspect}, #{@old_uniq.inspect}, #{@pid.inspect}, #{@free_vars.inspect}]"
|
102
130
|
end
|
103
|
-
self
|
104
131
|
end
|
105
132
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
self.
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
self.old_index = old_index
|
114
|
-
self.old_uniq = old_uniq
|
115
|
-
self.pid = pid
|
116
|
-
self.free_vars = free_vars
|
133
|
+
def pretty_print(pp)
|
134
|
+
state = [@term]
|
135
|
+
state.push(@arity, @uniq, @index, @mod, @old_index, @old_uniq, @pid, @free_vars) if not @arity.nil? or not @uniq.nil? or not @index.nil? or not @mod.nil? or not @old_index.nil? or not @old_uniq.nil? or not @pid.nil? or not @free_vars.nil?
|
136
|
+
return pp.group(1, "#{self.class}[", "]") do
|
137
|
+
pp.breakable ''
|
138
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
139
|
+
end
|
117
140
|
end
|
118
141
|
end
|
119
142
|
end
|
120
|
-
end
|
143
|
+
end
|
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 2 | N | 1 | N'
|
6
|
-
# --- | --- | ---- | -------- | ------
|
7
|
-
# 114 | Len | Node | Creation | ID ...
|
5
|
+
# | 1 | 2 | N | 1 | N' |
|
6
|
+
# | --- | --- | ---- | -------- | ------ |
|
7
|
+
# | 114 | Len | Node | Creation | ID ... |
|
8
8
|
#
|
9
9
|
# `Node` and `Creation` are as in [`REFERENCE_EXT`].
|
10
10
|
#
|
@@ -29,36 +29,63 @@ module Erlang
|
|
29
29
|
# [`NEW_REFERENCE_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#NEW_REFERENCE_EXT
|
30
30
|
#
|
31
31
|
class NewReference
|
32
|
-
include Term
|
32
|
+
include Erlang::ETF::Term
|
33
33
|
|
34
|
-
|
34
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
35
|
+
UINT16BE = Erlang::ETF::Term::UINT16BE
|
36
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
int8 :creation, maximum: (1 << 2) - 1
|
41
|
-
|
42
|
-
uint32be :ids, type: :array, default: []
|
38
|
+
class << self
|
39
|
+
def [](term, node = nil, creation = nil, ids = nil)
|
40
|
+
return new(term, node, creation, ids)
|
41
|
+
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
self.ids << buffer.read(BYTES_32).unpack(UINT32BE_PACK).at(0)
|
43
|
+
def erlang_load(buffer)
|
44
|
+
length, = buffer.read(2).unpack(UINT16BE)
|
45
|
+
node = Erlang::ETF.read_term(buffer)
|
46
|
+
creation, *ids = buffer.read(1 + (4 * length)).unpack("#{UINT8}#{UINT32BE}#{length}")
|
47
|
+
term = Erlang::Reference[Erlang.from(node), Erlang.from(creation), Erlang.from(ids)]
|
48
|
+
return new(term, node, creation, ids)
|
51
49
|
end
|
52
|
-
self
|
53
50
|
end
|
54
51
|
|
55
|
-
|
56
|
-
|
57
|
-
|
52
|
+
def initialize(term, node = nil, creation = nil, ids = nil)
|
53
|
+
raise ArgumentError, "term must be of type Erlang::Reference" if not term.kind_of?(Erlang::Reference) or not term.new_reference?
|
54
|
+
@term = term
|
58
55
|
@node = node
|
59
56
|
@creation = creation
|
60
57
|
@ids = ids
|
61
58
|
end
|
59
|
+
|
60
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
61
|
+
buffer << NEW_REFERENCE_EXT
|
62
|
+
ids = @ids || @term.ids
|
63
|
+
length = ids.size
|
64
|
+
buffer << [length].pack(UINT16BE)
|
65
|
+
Erlang::ETF.write_term(@node || @term.node, buffer)
|
66
|
+
buffer << [
|
67
|
+
@creation || @term.creation,
|
68
|
+
*ids
|
69
|
+
].pack("#{UINT8}#{UINT32BE}#{length}")
|
70
|
+
return buffer
|
71
|
+
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
if @node.nil? and @creation.nil? and @ids.nil?
|
75
|
+
return super
|
76
|
+
else
|
77
|
+
return "#{self.class}[#{@term.inspect}, #{@node.inspect}, #{@creation.inspect}, #{@ids.inspect}]"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def pretty_print(pp)
|
82
|
+
state = [@term]
|
83
|
+
state.push(@node, @creation, @ids) if not @node.nil? or not @creation.nil? or not @ids.nil?
|
84
|
+
return pp.group(1, "#{self.class}[", "]") do
|
85
|
+
pp.breakable ''
|
86
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
87
|
+
end
|
88
|
+
end
|
62
89
|
end
|
63
90
|
end
|
64
|
-
end
|
91
|
+
end
|