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
@@ -1,26 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- #
6
- # boolean {bert, true} or {bert, false}
7
- #
8
- # Erlang equates the true and false atoms with booleans while other languages do not have this behavior.
9
- # To disambiguate these cases, booleans are expressed as their own complex type.
10
- #
11
- # See: http://bert-rpc.org/
12
- #
13
- module FalseClass
14
-
15
- def __erlang_type__
16
- :bert_boolean
17
- end
18
-
19
- def __erlang_evolve__
20
- ::Erlang::Tuple[:bert, :false].__erlang_evolve__
21
- end
22
-
23
- end
24
- end
25
- end
26
- end
@@ -1,18 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- module Float
6
-
7
- def __erlang_type__
8
- :new_float
9
- end
10
-
11
- def __erlang_evolve__
12
- ETF::NewFloat.new(self)
13
- end
14
-
15
- end
16
- end
17
- end
18
- end
@@ -1,30 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- #
6
- # dictionary {bert, dict, KeysAndValues}
7
- #
8
- # Dictionaries (hash tables) are expressed via an array of 2-tuples representing the key/value pairs.
9
- # The KeysAndValues array is mandatory, such that an empty dict is expressed as {bert, dict, []}.
10
- # Keys and values may be any term.
11
- # For example, {bert, dict, [{name, <<"Tom">>}, {age, 30}]}.
12
- #
13
- # See: http://bert-rpc.org/
14
- #
15
- module Hash
16
-
17
- def __erlang_type__
18
- :bert_dict
19
- end
20
-
21
- def __erlang_evolve__
22
- ::Erlang::Tuple[:bert, :dict, map do |(key, value)|
23
- ::Erlang::Tuple[key, value]
24
- end].__erlang_evolve__
25
- end
26
-
27
- end
28
- end
29
- end
30
- end
@@ -1,46 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- module Integer
6
-
7
- UINT8_MIN = 0.freeze
8
- UINT8_MAX = (+(1 << 8) - 1).freeze
9
-
10
- INT32_MIN = (-(1 << 31) + 1).freeze
11
- INT32_MAX = (+(1 << 31) - 1).freeze
12
-
13
- SMALL_BIG_N_MAX = 255.freeze
14
-
15
- def __erlang_type__
16
- if self >= UINT8_MIN and self <= UINT8_MAX
17
- :small_integer
18
- elsif self >= INT32_MIN and self <= INT32_MAX
19
- :integer
20
- else
21
- n = (abs.to_s(2).bytesize / 8.0).ceil
22
- if n <= SMALL_BIG_N_MAX
23
- :small_big
24
- else
25
- :large_big
26
- end
27
- end
28
- end
29
-
30
- def __erlang_evolve__
31
- case __erlang_type__
32
- when :small_integer
33
- ETF::SmallInteger.new(self)
34
- when :integer
35
- ETF::Integer.new(self)
36
- when :small_big
37
- ETF::SmallBig.new(self)
38
- when :large_big
39
- ETF::LargeBig.new(self)
40
- end
41
- end
42
-
43
- end
44
- end
45
- end
46
- end
@@ -1,27 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- #
6
- # nil {bert, nil}
7
- #
8
- # Erlang equates nil with the empty array [] while other languages do not.
9
- # Even though NIL appears as a primitive in the serialization specification, BERT only uses it to represent the empty array.
10
- # In order to be language agnostic, nil is encoded as a separate complex type to allow for disambiguation.
11
- #
12
- # See: http://bert-rpc.org/
13
- #
14
- module NilClass
15
-
16
- def __erlang_type__
17
- :bert_nil
18
- end
19
-
20
- def __erlang_evolve__
21
- ::Erlang::Tuple[:bert, :nil].__erlang_evolve__
22
- end
23
-
24
- end
25
- end
26
- end
27
- end
@@ -1,22 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- module Object
6
-
7
- def __erlang_type__
8
- raise NotImplementedError, "#__erlang_type__ undefined for #{inspect} of class #{self.class}"
9
- end
10
-
11
- def __erlang_evolve__
12
- raise NotImplementedError, "#__erlang_evolve__ undefined for #{inspect} of class #{self.class}"
13
- end
14
-
15
- def __erlang_dump__(buffer)
16
- __erlang_evolve__.serialize(buffer)
17
- end
18
-
19
- end
20
- end
21
- end
22
- end
@@ -1,32 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- #
6
- # regex {bert, regex, Source, Options}
7
- #
8
- # Regular expressions are expressed by their source binary and PCRE options.
9
- # Options is a list of atoms representing the PCRE options.
10
- # For example, {bert, regex, <<"^c(a*)t$">>, [caseless]} would represent a case insensitive regular epxression that would match "cat".
11
- # See re:compile/2 for valid options.
12
- #
13
- # See: http://bert-rpc.org/
14
- #
15
- module Regexp
16
-
17
- def __erlang_type__
18
- :bert_regex
19
- end
20
-
21
- def __erlang_evolve__
22
- opts = []
23
- opts << :caseless if (options & ::Regexp::IGNORECASE) != 0
24
- opts << :extended if (options & ::Regexp::EXTENDED) != 0
25
- opts << :multiline if (options & ::Regexp::MULTILINE) != 0
26
- ::Erlang::Tuple[:bert, :regex, source, opts].__erlang_evolve__
27
- end
28
-
29
- end
30
- end
31
- end
32
- end
@@ -1,33 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- BINARY_ENCODING = Encoding.find("binary")
6
- UTF8_ENCODING = Encoding.find("utf-8")
7
-
8
- module String
9
-
10
- def __erlang_type__
11
- :binary
12
- end
13
-
14
- def __erlang_evolve__
15
- ETF::Binary.new(self)
16
- end
17
-
18
- def to_utf8_binary
19
- encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING)
20
- rescue EncodingError
21
- data = dup.force_encoding(UTF8_ENCODING)
22
- raise unless data.valid_encoding?
23
- data.force_encoding(BINARY_ENCODING)
24
- end
25
-
26
- def from_utf8_binary
27
- force_encoding(UTF8_ENCODING).encode!
28
- end
29
-
30
- end
31
- end
32
- end
33
- end
@@ -1,43 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- module Symbol
6
-
7
- def __erlang_type__
8
- if to_s.bytesize < 256
9
- if to_s.ascii_only?
10
- :small_atom
11
- else
12
- :small_atom_utf8
13
- end
14
- else
15
- if to_s.ascii_only?
16
- :atom
17
- else
18
- :atom_utf8
19
- end
20
- end
21
- end
22
-
23
- def __erlang_evolve__
24
- case __erlang_type__
25
- when :atom
26
- ETF::Atom.new(to_s)
27
- when :atom_utf8
28
- ETF::AtomUTF8.new(to_s)
29
- when :small_atom
30
- ETF::SmallAtom.new(to_s)
31
- when :small_atom_utf8
32
- ETF::SmallAtomUTF8.new(to_s)
33
- end
34
- end
35
-
36
- def to_utf8_binary
37
- to_s.to_utf8_binary
38
- end
39
-
40
- end
41
- end
42
- end
43
- end
@@ -1,27 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- #
6
- # time {bert, time, Megaseconds, Seconds, Microseconds}
7
- #
8
- # The given time is the number of Megaseconds + Seconds + Microseconds elapsed since 00:00 GMT, January 1, 1970 (zero hour).
9
- # For example, 2009-10-11 at 14:12:01 and 446,228 microseconds would be expressed as {bert, time, 1255, 295581, 446228}.
10
- # In english, this is 1255 megaseconds (millions of seconds) + 295,581 seconds + 446,228 microseconds (millionths of a second) since zero hour.
11
- #
12
- # See: http://bert-rpc.org/
13
- #
14
- module Time
15
-
16
- def __erlang_type__
17
- :bert_time
18
- end
19
-
20
- def __erlang_evolve__
21
- ::Erlang::Tuple[:bert, :time, to_i / 1_000_000, to_i % 1_000_000, usec].__erlang_evolve__
22
- end
23
-
24
- end
25
- end
26
- end
27
- end
@@ -1,26 +0,0 @@
1
- module Erlang
2
- module ETF
3
- module Extensions
4
-
5
- #
6
- # boolean {bert, true} or {bert, false}
7
- #
8
- # Erlang equates the true and false atoms with booleans while other languages do not have this behavior.
9
- # To disambiguate these cases, booleans are expressed as their own complex type.
10
- #
11
- # See: http://bert-rpc.org/
12
- #
13
- module TrueClass
14
-
15
- def __erlang_type__
16
- :bert_boolean
17
- end
18
-
19
- def __erlang_evolve__
20
- ::Erlang::Tuple[:bert, :true].__erlang_evolve__
21
- end
22
-
23
- end
24
- end
25
- end
26
- end
@@ -1,132 +0,0 @@
1
- module Erlang
2
- module ETF
3
-
4
- #
5
- # See [`erts/emulator/beam/external.h`]
6
- #
7
- # [`erts/emulator/beam/external.h`]: https://github.com/erlang/otp/blob/master/erts/emulator/beam/external.h
8
- #
9
- module Terms
10
- SMALL_INTEGER_EXT = 97.freeze
11
- INTEGER_EXT = 98.freeze
12
- FLOAT_EXT = 99.freeze
13
- ATOM_EXT = 100.freeze
14
- REFERENCE_EXT = 101.freeze
15
- PORT_EXT = 102.freeze
16
- PID_EXT = 103.freeze
17
- SMALL_TUPLE_EXT = 104.freeze
18
- LARGE_TUPLE_EXT = 105.freeze
19
- NIL_EXT = 106.freeze
20
- STRING_EXT = 107.freeze
21
- LIST_EXT = 108.freeze
22
- BINARY_EXT = 109.freeze
23
- SMALL_BIG_EXT = 110.freeze
24
- LARGE_BIG_EXT = 111.freeze
25
- NEW_REFERENCE_EXT = 114.freeze
26
- SMALL_ATOM_EXT = 115.freeze
27
- FUN_EXT = 117.freeze
28
- NEW_FUN_EXT = 112.freeze
29
- EXPORT_EXT = 113.freeze
30
- BIT_BINARY_EXT = 77.freeze
31
- NEW_FLOAT_EXT = 70.freeze
32
- ATOM_UTF8_EXT = 118.freeze
33
- SMALL_ATOM_UTF8_EXT = 119.freeze
34
- MAP_EXT = 116.freeze
35
-
36
- DIST_HEADER = 68.freeze # not implemented
37
- ATOM_CACHE_REF = 82.freeze # not implemented
38
- ATOM_INTERNAL_REF2 = 73.freeze # not implemented
39
- ATOM_INTERNAL_REF3 = 75.freeze # not implemented
40
- BINARY_INTERNAL_REF = 74.freeze # not implemented
41
- BIT_BINARY_INTERNAL_REF = 76.freeze # not implemented
42
- COMPRESSED = 80.freeze
43
- end
44
- end
45
- end
46
-
47
- require "erlang/etf/term"
48
- require "erlang/etf/bert"
49
-
50
- require "erlang/etf/atom"
51
- require "erlang/etf/atom_utf8"
52
- require "erlang/etf/binary"
53
- require "erlang/etf/bit_binary"
54
- require "erlang/etf/compressed"
55
- require "erlang/etf/export"
56
- require "erlang/etf/float"
57
- require "erlang/etf/fun"
58
- require "erlang/etf/integer"
59
- require "erlang/etf/large_big"
60
- require "erlang/etf/large_tuple"
61
- require "erlang/etf/list"
62
- require "erlang/etf/map"
63
- require "erlang/etf/new_float"
64
- require "erlang/etf/new_fun"
65
- require "erlang/etf/new_reference"
66
- require "erlang/etf/nil"
67
- require "erlang/etf/pid"
68
- require "erlang/etf/port"
69
- require "erlang/etf/reference"
70
- require "erlang/etf/small_atom"
71
- require "erlang/etf/small_atom_utf8"
72
- require "erlang/etf/small_big"
73
- require "erlang/etf/small_integer"
74
- require "erlang/etf/small_tuple"
75
- require "erlang/etf/string"
76
-
77
- module Erlang
78
- module ETF
79
- module Terms
80
- MAP = {}
81
-
82
- MAP[SMALL_INTEGER_EXT] = ETF::SmallInteger
83
- MAP[INTEGER_EXT] = ETF::Integer
84
- MAP[FLOAT_EXT] = ETF::Float
85
- MAP[ATOM_EXT] = ETF::Atom
86
- MAP[REFERENCE_EXT] = ETF::Reference
87
- MAP[PORT_EXT] = ETF::Port
88
- MAP[PID_EXT] = ETF::Pid
89
- MAP[SMALL_TUPLE_EXT] = ETF::SmallTuple
90
- MAP[LARGE_TUPLE_EXT] = ETF::LargeTuple
91
- MAP[NIL_EXT] = ETF::Nil
92
- MAP[STRING_EXT] = ETF::String
93
- MAP[LIST_EXT] = ETF::List
94
- MAP[BINARY_EXT] = ETF::Binary
95
- MAP[SMALL_BIG_EXT] = ETF::SmallBig
96
- MAP[LARGE_BIG_EXT] = ETF::LargeBig
97
- MAP[NEW_REFERENCE_EXT] = ETF::NewReference
98
- MAP[SMALL_ATOM_EXT] = ETF::SmallAtom
99
- MAP[FUN_EXT] = ETF::Fun
100
- MAP[NEW_FUN_EXT] = ETF::NewFun
101
- MAP[EXPORT_EXT] = ETF::Export
102
- MAP[BIT_BINARY_EXT] = ETF::BitBinary
103
- MAP[NEW_FLOAT_EXT] = ETF::NewFloat
104
- MAP[ATOM_UTF8_EXT] = ETF::AtomUTF8
105
- MAP[SMALL_ATOM_UTF8_EXT] = ETF::SmallAtomUTF8
106
- MAP[MAP_EXT] = ETF::Map
107
-
108
- # MAP[DIST_HEADER] = NotImplementedError
109
- # MAP[ATOM_CACHE_REF] = NotImplementedError
110
- # MAP[ATOM_INTERNAL_REF2] = NotImplementedError
111
- # MAP[ATOM_INTERNAL_REF3] = NotImplementedError
112
- # MAP[BINARY_INTERNAL_REF] = NotImplementedError
113
- # MAP[BIT_BINARY_INTERNAL_REF] = NotImplementedError
114
- MAP[COMPRESSED] = ETF::Compressed
115
-
116
- MAP.freeze
117
-
118
- def self.deserialize(buffer)
119
- key, = buffer.read(1).unpack(::Binary::Protocol::UINT8_PACK)
120
- if MAP.key?(key)
121
- MAP[key].deserialize(buffer)
122
- else
123
- raise NotImplementedError, "unknown Erlang External Format tag #{key.inspect} (see http://erlang.org/doc/apps/erts/erl_ext_dist.html)"
124
- end
125
- end
126
-
127
- def self.evolve(buffer)
128
- deserialize(buffer).__ruby_evolve__
129
- end
130
- end
131
- end
132
- end