erlang-etf 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|