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.
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