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/nil.rb
CHANGED
@@ -13,15 +13,30 @@ module Erlang
|
|
13
13
|
# [`NIL_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#NIL_EXT
|
14
14
|
#
|
15
15
|
class Nil
|
16
|
-
include Term
|
16
|
+
include Erlang::ETF::Term
|
17
17
|
|
18
|
-
|
18
|
+
class << self
|
19
|
+
def [](term)
|
20
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
21
|
+
term = Erlang.from(term)
|
22
|
+
return new(term)
|
23
|
+
end
|
19
24
|
|
20
|
-
|
25
|
+
def erlang_load(buffer)
|
26
|
+
term = Erlang::Nil
|
27
|
+
return new(term)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(term)
|
32
|
+
raise ArgumentError, "term must be of type Erlang::Nil" if not Erlang::Nil.equal?(term)
|
33
|
+
@term = term
|
34
|
+
end
|
21
35
|
|
22
|
-
def
|
23
|
-
|
36
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
37
|
+
buffer << NIL_EXT
|
38
|
+
return buffer
|
24
39
|
end
|
25
40
|
end
|
26
41
|
end
|
27
|
-
end
|
42
|
+
end
|
data/lib/erlang/etf/pid.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | N | 4 | 4 | 1
|
6
|
-
# --- | ---- | --- | ------ | --------
|
7
|
-
# 103 | Node | ID | Serial | Creation
|
5
|
+
# | 1 | N | 4 | 4 | 1 |
|
6
|
+
# | --- | ---- | --- | ------ | -------- |
|
7
|
+
# | 103 | Node | ID | Serial | Creation |
|
8
8
|
#
|
9
9
|
# Encode a process identifier object (obtained from [`spawn/3`] or
|
10
10
|
# friends). The `ID` and `Creation` fields works just like in
|
@@ -18,34 +18,61 @@ module Erlang
|
|
18
18
|
# [`PID_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#PID_EXT
|
19
19
|
#
|
20
20
|
class Pid
|
21
|
-
include Term
|
21
|
+
include Erlang::ETF::Term
|
22
22
|
|
23
|
-
|
23
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
24
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
25
|
+
HEAD = (UINT32BE + UINT32BE + UINT8).freeze
|
24
26
|
|
25
|
-
|
27
|
+
class << self
|
28
|
+
def [](term, node = nil, id = nil, serial = nil, creation = nil)
|
29
|
+
return new(term, node, id, serial, creation)
|
30
|
+
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
def erlang_load(buffer)
|
33
|
+
node = Erlang::ETF.read_term(buffer)
|
34
|
+
id, serial, creation = buffer.read(9).unpack(HEAD)
|
35
|
+
term = Erlang::Pid[Erlang.from(node), Erlang.from(id), Erlang.from(serial), Erlang.from(creation)]
|
36
|
+
return new(term, node, id, serial, creation)
|
37
|
+
end
|
38
|
+
end
|
33
39
|
|
34
|
-
def initialize(node, id, serial, creation)
|
40
|
+
def initialize(term, node = nil, id = nil, serial = nil, creation = nil)
|
41
|
+
raise ArgumentError, "term must be of type Erlang::Pid" if not term.kind_of?(Erlang::Pid)
|
42
|
+
@term = term
|
35
43
|
@node = node
|
36
44
|
@id = id
|
37
45
|
@serial = serial
|
38
46
|
@creation = creation
|
39
47
|
end
|
40
48
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
50
|
+
buffer << PID_EXT
|
51
|
+
Erlang::ETF.write_term(@node || @term.node, buffer)
|
52
|
+
buffer << [
|
53
|
+
@id || @term.id,
|
54
|
+
@serial || @term.serial,
|
55
|
+
@creation || @term.creation
|
56
|
+
].pack(HEAD)
|
57
|
+
return buffer
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
if @node.nil? and @id.nil? and @serial.nil? and @creation.nil?
|
62
|
+
return super
|
63
|
+
else
|
64
|
+
return "#{self.class}[#{@term.inspect}, #{@node.inspect}, #{@id.inspect}, #{@serial.inspect}, #{@creation.inspect}]"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def pretty_print(pp)
|
69
|
+
state = [@term]
|
70
|
+
state.push(@node, @id, @serial, @creation) if not @node.nil? or not @id.nil? or not @serial.nil? or not @creation.nil?
|
71
|
+
return pp.group(1, "#{self.class}[", "]") do
|
72
|
+
pp.breakable ''
|
73
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
74
|
+
end
|
48
75
|
end
|
49
76
|
end
|
50
77
|
end
|
51
|
-
end
|
78
|
+
end
|
data/lib/erlang/etf/port.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | N | 4 | 1
|
6
|
-
# --- | ---- | --- | --------
|
7
|
-
# 102 | Node | ID | Creation
|
5
|
+
# | 1 | N | 4 | 1 |
|
6
|
+
# | --- | ---- | --- | -------- |
|
7
|
+
# | 102 | Node | ID | Creation |
|
8
8
|
#
|
9
9
|
# Encode a port object (obtained form [`open_port/2`]). The `ID` is a
|
10
10
|
# node specific identifier for a local port. Port operations are
|
@@ -18,23 +18,59 @@ module Erlang
|
|
18
18
|
# [`PORT_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#PORT_EXT
|
19
19
|
#
|
20
20
|
class Port
|
21
|
-
include Term
|
21
|
+
include Erlang::ETF::Term
|
22
22
|
|
23
|
-
|
23
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
24
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
25
|
+
HEAD = (UINT32BE + UINT8).freeze
|
24
26
|
|
25
|
-
|
27
|
+
class << self
|
28
|
+
def [](term, node = nil, id = nil, creation = nil)
|
29
|
+
return new(term, node, id, creation)
|
30
|
+
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
def erlang_load(buffer)
|
33
|
+
node = Erlang::ETF.read_term(buffer)
|
34
|
+
id, creation = buffer.read(5).unpack(HEAD)
|
35
|
+
term = Erlang::Port[Erlang.from(node), Erlang.from(id), Erlang.from(creation)]
|
36
|
+
return new(term, node, id, creation)
|
37
|
+
end
|
38
|
+
end
|
32
39
|
|
33
|
-
def initialize(node, id, creation)
|
40
|
+
def initialize(term, node = nil, id = nil, creation = nil)
|
41
|
+
raise ArgumentError, "term must be of type Erlang::Port" if not term.kind_of?(Erlang::Port)
|
42
|
+
@term = term
|
34
43
|
@node = node
|
35
44
|
@id = id
|
36
45
|
@creation = creation
|
37
46
|
end
|
47
|
+
|
48
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
49
|
+
buffer << PORT_EXT
|
50
|
+
Erlang::ETF.write_term(@node || @term.node, buffer)
|
51
|
+
buffer << [
|
52
|
+
@id || @term.id,
|
53
|
+
@creation || @term.creation
|
54
|
+
].pack(HEAD)
|
55
|
+
return buffer
|
56
|
+
end
|
57
|
+
|
58
|
+
def inspect
|
59
|
+
if @node.nil? and @id.nil? and @creation.nil?
|
60
|
+
return super
|
61
|
+
else
|
62
|
+
return "#{self.class}[#{@term.inspect}, #{@node.inspect}, #{@id.inspect}, #{@creation.inspect}]"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def pretty_print(pp)
|
67
|
+
state = [@term]
|
68
|
+
state.push(@node, @id, @creation) if not @node.nil? or not @id.nil? or not @creation.nil?
|
69
|
+
return pp.group(1, "#{self.class}[", "]") do
|
70
|
+
pp.breakable ''
|
71
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
72
|
+
end
|
73
|
+
end
|
38
74
|
end
|
39
75
|
end
|
40
|
-
end
|
76
|
+
end
|
data/lib/erlang/etf/reference.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | N | 4 | 1
|
6
|
-
# --- | ---- | --- | --------
|
7
|
-
# 101 | Node | ID | Creation
|
5
|
+
# | 1 | N | 4 | 1 |
|
6
|
+
# | --- | ---- | --- | -------- |
|
7
|
+
# | 101 | Node | ID | Creation |
|
8
8
|
#
|
9
9
|
# Encode a reference object (an object generated with [`make_ref/0`]).
|
10
10
|
# The `Node` term is an encoded atom, i.e. [`ATOM_EXT`], [`SMALL_ATOM_EXT`]
|
@@ -28,23 +28,59 @@ module Erlang
|
|
28
28
|
# [`REFERENCE_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#REFERENCE_EXT
|
29
29
|
#
|
30
30
|
class Reference
|
31
|
-
include Term
|
31
|
+
include Erlang::ETF::Term
|
32
32
|
|
33
|
-
|
33
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
34
|
+
UINT32BE = Erlang::ETF::Term::UINT32BE
|
35
|
+
HEAD = (UINT32BE + UINT8).freeze
|
34
36
|
|
35
|
-
|
37
|
+
class << self
|
38
|
+
def [](term, node = nil, id = nil, creation = nil)
|
39
|
+
return new(term, node, id, creation)
|
40
|
+
end
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
def erlang_load(buffer)
|
43
|
+
node = Erlang::ETF.read_term(buffer)
|
44
|
+
id, creation = buffer.read(5).unpack(HEAD)
|
45
|
+
term = Erlang::Reference[Erlang.from(node), Erlang.from(creation), Erlang.from(id)]
|
46
|
+
return new(term, node, id, creation)
|
47
|
+
end
|
48
|
+
end
|
42
49
|
|
43
|
-
def initialize(node, id, creation)
|
50
|
+
def initialize(term, node = nil, id = nil, creation = nil)
|
51
|
+
raise ArgumentError, "term must be of type Erlang::Reference" if not term.kind_of?(Erlang::Reference) or term.new_reference?
|
52
|
+
@term = term
|
44
53
|
@node = node
|
45
54
|
@id = id
|
46
55
|
@creation = creation
|
47
56
|
end
|
57
|
+
|
58
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
59
|
+
buffer << REFERENCE_EXT
|
60
|
+
Erlang::ETF.write_term(@node || @term.node, buffer)
|
61
|
+
buffer << [
|
62
|
+
@id || @term.id,
|
63
|
+
@creation || @term.creation
|
64
|
+
].pack(HEAD)
|
65
|
+
return buffer
|
66
|
+
end
|
67
|
+
|
68
|
+
def inspect
|
69
|
+
if @node.nil? and @id.nil? and @creation.nil?
|
70
|
+
return super
|
71
|
+
else
|
72
|
+
return "#{self.class}[#{@term.inspect}, #{@node.inspect}, #{@id.inspect}, #{@creation.inspect}]"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def pretty_print(pp)
|
77
|
+
state = [@term]
|
78
|
+
state.push(@node, @id, @creation) if not @node.nil? or not @id.nil? or not @creation.nil?
|
79
|
+
return pp.group(1, "#{self.class}[", "]") do
|
80
|
+
pp.breakable ''
|
81
|
+
pp.seplist(state) { |obj| obj.pretty_print(pp) }
|
82
|
+
end
|
83
|
+
end
|
48
84
|
end
|
49
85
|
end
|
50
|
-
end
|
86
|
+
end
|
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 1 | Len
|
6
|
-
# --- | --- | --------
|
7
|
-
# 115 | Len | AtomName
|
5
|
+
# | 1 | 1 | Len |
|
6
|
+
# | --- | --- | -------- |
|
7
|
+
# | 115 | Len | AtomName |
|
8
8
|
#
|
9
9
|
# An atom is stored with a 1 byte unsigned length, followed by `Len`
|
10
10
|
# numbers of 8 bit Latin1 characters that forms the `AtomName`.
|
@@ -22,34 +22,38 @@ module Erlang
|
|
22
22
|
# [`SMALL_ATOM_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#SMALL_ATOM_EXT
|
23
23
|
#
|
24
24
|
class SmallAtom
|
25
|
-
include Term
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
include Erlang::ETF::Term
|
26
|
+
|
27
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def [](term)
|
31
|
+
return term if term.kind_of?(Erlang::ETF::Atom)
|
32
|
+
return term if term.kind_of?(Erlang::ETF::AtomUTF8)
|
33
|
+
return term if term.kind_of?(Erlang::ETF::SmallAtom)
|
34
|
+
return term if term.kind_of?(Erlang::ETF::SmallAtomUTF8)
|
35
|
+
term = Erlang.from(term) if not term.kind_of?(Erlang::Atom)
|
36
|
+
return new(term)
|
37
|
+
end
|
38
|
+
|
39
|
+
def erlang_load(buffer)
|
40
|
+
size, = buffer.read(1).unpack(UINT8)
|
41
|
+
data = buffer.read(size)
|
42
|
+
return new(Erlang::Atom[data])
|
43
|
+
end
|
36
44
|
end
|
37
45
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
finalize
|
44
|
-
|
45
|
-
def initialize(atom_name)
|
46
|
-
@atom_name = atom_name
|
47
|
-
@len = atom_name.to_s.bytesize
|
46
|
+
def initialize(term)
|
47
|
+
raise ArgumentError, "term must be of type Erlang::Atom" if not term.kind_of?(Erlang::Atom)
|
48
|
+
@term = term
|
48
49
|
end
|
49
50
|
|
50
|
-
def
|
51
|
-
|
51
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
52
|
+
buffer << SMALL_ATOM_EXT
|
53
|
+
buffer << [@term.size].pack(UINT8)
|
54
|
+
buffer << Erlang::Terms.binary_encoding(@term.data)
|
55
|
+
return buffer
|
52
56
|
end
|
53
57
|
end
|
54
58
|
end
|
55
|
-
end
|
59
|
+
end
|
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 1 | Len
|
6
|
-
# --- | --- | --------
|
7
|
-
# 119 | Len | AtomName
|
5
|
+
# | 1 | 1 | Len |
|
6
|
+
# | --- | --- | -------- |
|
7
|
+
# | 119 | Len | AtomName |
|
8
8
|
#
|
9
9
|
# An atom is stored with a 1 byte unsigned length, followed by `Len`
|
10
10
|
# bytes containing the `AtomName` encoded in UTF-8. Longer atoms
|
@@ -16,34 +16,38 @@ module Erlang
|
|
16
16
|
# [`SMALL_ATOM_UTF8_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#SMALL_ATOM_UTF8_EXT
|
17
17
|
#
|
18
18
|
class SmallAtomUTF8
|
19
|
-
include Term
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
include Erlang::ETF::Term
|
20
|
+
|
21
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def [](term)
|
25
|
+
return term if term.kind_of?(Erlang::ETF::Atom)
|
26
|
+
return term if term.kind_of?(Erlang::ETF::AtomUTF8)
|
27
|
+
return term if term.kind_of?(Erlang::ETF::SmallAtom)
|
28
|
+
return term if term.kind_of?(Erlang::ETF::SmallAtomUTF8)
|
29
|
+
term = Erlang.from(term) if not term.kind_of?(Erlang::Atom)
|
30
|
+
return new(term)
|
31
|
+
end
|
32
|
+
|
33
|
+
def erlang_load(buffer)
|
34
|
+
size, = buffer.read(1).unpack(UINT8)
|
35
|
+
data = buffer.read(size)
|
36
|
+
return new(Erlang::Atom[data, utf8: true])
|
37
|
+
end
|
30
38
|
end
|
31
39
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
finalize
|
38
|
-
|
39
|
-
def initialize(atom_name)
|
40
|
-
@atom_name = atom_name
|
41
|
-
@len = atom_name.to_s.bytesize
|
40
|
+
def initialize(term)
|
41
|
+
raise ArgumentError, "term must be of type Erlang::Atom" if not term.kind_of?(Erlang::Atom)
|
42
|
+
@term = term
|
42
43
|
end
|
43
44
|
|
44
|
-
def
|
45
|
-
|
45
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
46
|
+
buffer << SMALL_ATOM_UTF8_EXT
|
47
|
+
buffer << [@term.size].pack(UINT8)
|
48
|
+
buffer << Erlang::Terms.binary_encoding(@term.data)
|
49
|
+
return buffer
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
49
|
-
end
|
53
|
+
end
|
data/lib/erlang/etf/small_big.rb
CHANGED
@@ -2,9 +2,9 @@ module Erlang
|
|
2
2
|
module ETF
|
3
3
|
|
4
4
|
#
|
5
|
-
# 1 | 1 | 1 | n
|
6
|
-
# --- | --- | ---- | ---------------
|
7
|
-
# 110 | n | Sign | d(0) ... d(n-1)
|
5
|
+
# | 1 | 1 | 1 | n |
|
6
|
+
# | --- | --- | ---- | --------------- |
|
7
|
+
# | 110 | n | Sign | d(0) ... d(n-1) |
|
8
8
|
#
|
9
9
|
# Bignums are stored in unary form with a `Sign` byte that is 0 if
|
10
10
|
# the binum is positive and 1 if is negative. The digits are
|
@@ -22,46 +22,37 @@ module Erlang
|
|
22
22
|
# [`SMALL_BIG_EXT`]: http://erlang.org/doc/apps/erts/erl_ext_dist.html#SMALL_BIG_EXT
|
23
23
|
#
|
24
24
|
class SmallBig
|
25
|
-
include Term
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
25
|
+
include Erlang::ETF::Term
|
26
|
+
|
27
|
+
UINT8 = Erlang::ETF::Term::UINT8
|
28
|
+
HEAD = (UINT8 + UINT8).freeze
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def [](term)
|
32
|
+
return term if term.kind_of?(Erlang::ETF::Term)
|
33
|
+
term = Erlang.from(term)
|
34
|
+
return new(term)
|
35
|
+
end
|
36
|
+
|
37
|
+
def erlang_load(buffer)
|
38
|
+
n, sign, = buffer.read(2).unpack(HEAD)
|
39
|
+
integer = Erlang::Binary.decode_unsigned(buffer.read(n), :little)
|
40
|
+
integer = -integer if sign == 1
|
41
|
+
return new(integer)
|
42
|
+
end
|
41
43
|
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
buffer[@n_start, BYTES_8] = serialize_n ""
|
47
|
-
end
|
48
|
-
|
49
|
-
deserialize do |buffer|
|
50
|
-
deserialize_n(buffer)
|
51
|
-
sign, = buffer.read(BYTES_8).unpack(UINT8_PACK)
|
52
|
-
self.integer = buffer.read(n).unpack(BIN_LSB_PACK).at(0).reverse!.to_i(2) * ((sign == 0) ? 1 : -1)
|
53
|
-
self
|
54
|
-
end
|
55
|
-
|
56
|
-
finalize
|
57
|
-
|
58
|
-
def initialize(integer)
|
59
|
-
@integer = integer
|
45
|
+
def initialize(term)
|
46
|
+
raise ArgumentError, "term must be of type Integer" if not Erlang.is_integer(term)
|
47
|
+
@term = term
|
60
48
|
end
|
61
49
|
|
62
|
-
def
|
63
|
-
|
50
|
+
def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
|
51
|
+
buffer << SMALL_BIG_EXT
|
52
|
+
buffer << [Erlang::ETF.intlog2div8(@term), (@term < 0) ? 1 : 0].pack(HEAD)
|
53
|
+
buffer << Erlang::Binary.encode_unsigned(@term.abs, :little)
|
54
|
+
return buffer
|
64
55
|
end
|
65
56
|
end
|
66
57
|
end
|
67
|
-
end
|
58
|
+
end
|