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.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +20 -0
  3. data/.gitignore +10 -18
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +15 -4
  7. data/CHANGELOG.md +7 -0
  8. data/Gemfile +10 -6
  9. data/LICENSE.txt +1 -1
  10. data/README.md +13 -13
  11. data/Rakefile +8 -6
  12. data/erlang-etf.gemspec +10 -10
  13. data/lib/erlang-etf.rb +1 -0
  14. data/lib/erlang/etf.rb +363 -30
  15. data/lib/erlang/etf/atom.rb +28 -48
  16. data/lib/erlang/etf/atom_utf8.rb +28 -48
  17. data/lib/erlang/etf/binary.rb +24 -23
  18. data/lib/erlang/etf/bit_binary.rb +35 -27
  19. data/lib/erlang/etf/compressed.rb +61 -35
  20. data/lib/erlang/etf/export.rb +44 -21
  21. data/lib/erlang/etf/float.rb +33 -29
  22. data/lib/erlang/etf/fun.rb +54 -32
  23. data/lib/erlang/etf/integer.rb +24 -12
  24. data/lib/erlang/etf/large_big.rb +31 -37
  25. data/lib/erlang/etf/large_tuple.rb +41 -30
  26. data/lib/erlang/etf/list.rb +55 -25
  27. data/lib/erlang/etf/map.rb +58 -28
  28. data/lib/erlang/etf/new_float.rb +25 -14
  29. data/lib/erlang/etf/new_fun.rb +70 -47
  30. data/lib/erlang/etf/new_reference.rb +51 -24
  31. data/lib/erlang/etf/nil.rb +21 -6
  32. data/lib/erlang/etf/pid.rb +48 -21
  33. data/lib/erlang/etf/port.rb +49 -13
  34. data/lib/erlang/etf/reference.rb +49 -13
  35. data/lib/erlang/etf/small_atom.rb +31 -27
  36. data/lib/erlang/etf/small_atom_utf8.rb +31 -27
  37. data/lib/erlang/etf/small_big.rb +30 -39
  38. data/lib/erlang/etf/small_integer.rb +27 -12
  39. data/lib/erlang/etf/small_tuple.rb +41 -30
  40. data/lib/erlang/etf/string.rb +23 -23
  41. data/lib/erlang/etf/term.rb +109 -70
  42. data/lib/erlang/etf/version.rb +1 -1
  43. metadata +33 -169
  44. data/.rspec +0 -2
  45. data/lib/erlang/etf/bert.rb +0 -74
  46. data/lib/erlang/etf/extensions.rb +0 -144
  47. data/lib/erlang/etf/extensions/array.rb +0 -27
  48. data/lib/erlang/etf/extensions/big_decimal.rb +0 -20
  49. data/lib/erlang/etf/extensions/erlang-export.rb +0 -24
  50. data/lib/erlang/etf/extensions/erlang-list.rb +0 -29
  51. data/lib/erlang/etf/extensions/erlang-map.rb +0 -26
  52. data/lib/erlang/etf/extensions/erlang-nil.rb +0 -20
  53. data/lib/erlang/etf/extensions/erlang-pid.rb +0 -20
  54. data/lib/erlang/etf/extensions/erlang-string.rb +0 -31
  55. data/lib/erlang/etf/extensions/erlang-tuple.rb +0 -29
  56. data/lib/erlang/etf/extensions/false_class.rb +0 -26
  57. data/lib/erlang/etf/extensions/float.rb +0 -18
  58. data/lib/erlang/etf/extensions/hash.rb +0 -30
  59. data/lib/erlang/etf/extensions/integer.rb +0 -46
  60. data/lib/erlang/etf/extensions/nil_class.rb +0 -27
  61. data/lib/erlang/etf/extensions/object.rb +0 -22
  62. data/lib/erlang/etf/extensions/regexp.rb +0 -32
  63. data/lib/erlang/etf/extensions/string.rb +0 -33
  64. data/lib/erlang/etf/extensions/symbol.rb +0 -43
  65. data/lib/erlang/etf/extensions/time.rb +0 -27
  66. data/lib/erlang/etf/extensions/true_class.rb +0 -26
  67. data/lib/erlang/etf/terms.rb +0 -132
  68. data/spec/erlang/etf/atom_spec.rb +0 -90
  69. data/spec/erlang/etf/atom_utf8_spec.rb +0 -90
  70. data/spec/erlang/etf/binary_spec.rb +0 -90
  71. data/spec/erlang/etf/bit_binary_spec.rb +0 -99
  72. data/spec/erlang/etf/compressed_spec.rb +0 -37
  73. data/spec/erlang/etf/export_spec.rb +0 -58
  74. data/spec/erlang/etf/extensions/array_spec.rb +0 -40
  75. data/spec/erlang/etf/extensions/big_decimal_spec.rb +0 -26
  76. data/spec/erlang/etf/extensions/erlang-export_spec.rb +0 -32
  77. data/spec/erlang/etf/extensions/erlang-list_spec.rb +0 -76
  78. data/spec/erlang/etf/extensions/erlang-map_spec.rb +0 -48
  79. data/spec/erlang/etf/extensions/erlang-nil_spec.rb +0 -24
  80. data/spec/erlang/etf/extensions/erlang-pid_spec.rb +0 -33
  81. data/spec/erlang/etf/extensions/erlang-string_spec.rb +0 -41
  82. data/spec/erlang/etf/extensions/erlang-tuple_spec.rb +0 -57
  83. data/spec/erlang/etf/extensions/false_class_spec.rb +0 -29
  84. data/spec/erlang/etf/extensions/float_spec.rb +0 -24
  85. data/spec/erlang/etf/extensions/hash_spec.rb +0 -90
  86. data/spec/erlang/etf/extensions/integer_spec.rb +0 -259
  87. data/spec/erlang/etf/extensions/nil_class_spec.rb +0 -29
  88. data/spec/erlang/etf/extensions/object_spec.rb +0 -30
  89. data/spec/erlang/etf/extensions/regexp_spec.rb +0 -35
  90. data/spec/erlang/etf/extensions/string_spec.rb +0 -43
  91. data/spec/erlang/etf/extensions/symbol_spec.rb +0 -64
  92. data/spec/erlang/etf/extensions/time_spec.rb +0 -32
  93. data/spec/erlang/etf/extensions/true_class_spec.rb +0 -29
  94. data/spec/erlang/etf/float_spec.rb +0 -92
  95. data/spec/erlang/etf/fun_spec.rb +0 -132
  96. data/spec/erlang/etf/integer_spec.rb +0 -57
  97. data/spec/erlang/etf/large_big_spec.rb +0 -67
  98. data/spec/erlang/etf/large_tuple_spec.rb +0 -119
  99. data/spec/erlang/etf/list_spec.rb +0 -159
  100. data/spec/erlang/etf/map_spec.rb +0 -100
  101. data/spec/erlang/etf/new_float_spec.rb +0 -92
  102. data/spec/erlang/etf/new_fun_spec.rb +0 -146
  103. data/spec/erlang/etf/new_reference_spec.rb +0 -60
  104. data/spec/erlang/etf/nil_spec.rb +0 -50
  105. data/spec/erlang/etf/pid_spec.rb +0 -61
  106. data/spec/erlang/etf/port_spec.rb +0 -58
  107. data/spec/erlang/etf/reference_spec.rb +0 -58
  108. data/spec/erlang/etf/small_atom_spec.rb +0 -90
  109. data/spec/erlang/etf/small_atom_utf8_spec.rb +0 -90
  110. data/spec/erlang/etf/small_big_spec.rb +0 -67
  111. data/spec/erlang/etf/small_integer_spec.rb +0 -57
  112. data/spec/erlang/etf/small_tuple_spec.rb +0 -112
  113. data/spec/erlang/etf/string_spec.rb +0 -92
  114. data/spec/erlang/etf/term_spec.rb +0 -27
  115. data/spec/erlang/etf/terms_spec.rb +0 -23
  116. data/spec/erlang/etf_spec.rb +0 -23
  117. data/spec/erlang_spec.rb +0 -95
  118. data/spec/spec_helper.rb +0 -31
@@ -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
- uint8 :tag, always: Terms::NIL_EXT
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
- finalize
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 __ruby_evolve__
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
@@ -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
- uint8 :tag, always: Terms::PID_EXT
23
+ UINT8 = Erlang::ETF::Term::UINT8
24
+ UINT32BE = Erlang::ETF::Term::UINT32BE
25
+ HEAD = (UINT32BE + UINT32BE + UINT8).freeze
24
26
 
25
- term :node
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
- uint32be :id, maximum: (1 << 15) - 1
28
- uint32be :serial, maximum: (1 << 13) - 1
29
-
30
- int8 :creation, maximum: (1 << 2) - 1
31
-
32
- finalize
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 __ruby_evolve__
42
- ::Erlang::Pid.new(
43
- node.__ruby_evolve__,
44
- id,
45
- serial,
46
- creation
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
@@ -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
- uint8 :tag, always: Terms::PORT_EXT
23
+ UINT8 = Erlang::ETF::Term::UINT8
24
+ UINT32BE = Erlang::ETF::Term::UINT32BE
25
+ HEAD = (UINT32BE + UINT8).freeze
24
26
 
25
- term :node
27
+ class << self
28
+ def [](term, node = nil, id = nil, creation = nil)
29
+ return new(term, node, id, creation)
30
+ end
26
31
 
27
- uint32be :id, maximum: (1 << 28) - 1
28
-
29
- int8 :creation, maximum: (1 << 2) - 1
30
-
31
- finalize
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
@@ -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
- uint8 :tag, always: Terms::REFERENCE_EXT
33
+ UINT8 = Erlang::ETF::Term::UINT8
34
+ UINT32BE = Erlang::ETF::Term::UINT32BE
35
+ HEAD = (UINT32BE + UINT8).freeze
34
36
 
35
- term :node
37
+ class << self
38
+ def [](term, node = nil, id = nil, creation = nil)
39
+ return new(term, node, id, creation)
40
+ end
36
41
 
37
- uint32be :id, maximum: (1 << 18) - 1
38
-
39
- int8 :creation, maximum: (1 << 2) - 1
40
-
41
- finalize
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
- uint8 :tag, always: Terms::SMALL_ATOM_EXT
28
-
29
- uint8 :len, default: 0 do
30
- string :atom_name
31
- end
32
-
33
- undef deserialize_atom_name
34
- def deserialize_atom_name(buffer)
35
- self.atom_name = buffer.read(len).from_utf8_binary
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
- undef serialize_atom_name
39
- def serialize_atom_name(buffer)
40
- buffer << atom_name.to_utf8_binary
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 __ruby_evolve__
51
- atom_name.intern
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
- uint8 :tag, always: Terms::SMALL_ATOM_UTF8_EXT
22
-
23
- uint8 :len, default: 0 do
24
- string :atom_name
25
- end
26
-
27
- undef deserialize_atom_name
28
- def deserialize_atom_name(buffer)
29
- self.atom_name = buffer.read(len).from_utf8_binary
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
- undef serialize_atom_name
33
- def serialize_atom_name(buffer)
34
- buffer << atom_name.to_utf8_binary
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 __ruby_evolve__
45
- atom_name.intern
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
@@ -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
- uint8 :tag, always: Terms::SMALL_BIG_EXT
28
-
29
- uint8 :n, default: 0 do
30
- uint8 :sign, always: -> { (integer >= 0) ? 0 : 1 }
31
- string :integer
32
- end
33
-
34
- undef serialize_integer
35
-
36
- def serialize_integer(buffer)
37
- start = buffer.bytesize
38
- buffer << [integer.abs.to_s(2).reverse!].pack(BIN_LSB_PACK)
39
- self.n = buffer.bytesize - start
40
- buffer
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
- undef after_serialize_n
44
-
45
- def after_serialize_n(buffer)
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 __ruby_evolve__
63
- integer
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