erlang_rb 1.3.2 → 1.3.3
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.
- data.tar.gz.sig +0 -0
- data/README.markdown +1 -0
- data/lib/erlang.rb +232 -101
- data/tests/erlang_tests.rb +620 -0
- metadata +5 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/README.markdown
CHANGED
@@ -5,3 +5,4 @@ Provides all encoding and decoding for the Erlang Binary Term Format
|
|
5
5
|
(as defined at [http://erlang.org/doc/apps/erts/erl_ext_dist.html](http://erlang.org/doc/apps/erts/erl_ext_dist.html))
|
6
6
|
in a single Ruby module.
|
7
7
|
|
8
|
+
Available as a [Ruby gem at `https://rubygems.org/gems/erlang_rb`](https://rubygems.org/gems/erlang_rb).
|
data/lib/erlang.rb
CHANGED
@@ -38,48 +38,28 @@
|
|
38
38
|
# DAMAGE.
|
39
39
|
#
|
40
40
|
|
41
|
-
|
41
|
+
require 'zlib'
|
42
42
|
|
43
|
-
|
44
|
-
def initialize(value)
|
45
|
-
@value = value
|
46
|
-
end
|
47
|
-
def to_s
|
48
|
-
arity = @value.length
|
49
|
-
if arity == 0
|
50
|
-
return TAG_NIL_EXT.chr
|
51
|
-
else
|
52
|
-
arity_packed = [arity].pack('N')
|
53
|
-
list_packed = @value.map{ |element|
|
54
|
-
term_to_binary_(element)
|
55
|
-
}.join
|
56
|
-
return "#{TAG_LIST_EXT.chr}#{arity_packed}#{list_packed}#{TAG_NIL_EXT.chr}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
def hash
|
60
|
-
return to_s.hash
|
61
|
-
end
|
62
|
-
def ==(other)
|
63
|
-
return to_s == other.to_s
|
64
|
-
end
|
65
|
-
alias eql? ==
|
66
|
-
end
|
43
|
+
module Erlang
|
67
44
|
|
68
45
|
class OtpErlangAtom
|
69
46
|
def initialize(value)
|
70
47
|
@value = value
|
71
48
|
end
|
72
|
-
|
49
|
+
attr_reader :value
|
50
|
+
def binary
|
73
51
|
if @value.kind_of?(Integer)
|
74
52
|
return "#{TAG_ATOM_CACHE_REF.chr}#{@value.chr}"
|
75
53
|
elsif @value.kind_of?(String)
|
76
54
|
size = @value.bytesize
|
77
55
|
if @value.encoding.name == 'UTF-8'
|
78
56
|
if size < 256
|
79
|
-
return "#{TAG_SMALL_ATOM_UTF8_EXT.chr}#{size.chr}
|
57
|
+
return "#{TAG_SMALL_ATOM_UTF8_EXT.chr}#{size.chr}" \
|
58
|
+
"#{@value}"
|
80
59
|
else
|
81
60
|
size_packed = [size].pack('n')
|
82
|
-
return "#{TAG_ATOM_UTF8_EXT.chr}#{size_packed}
|
61
|
+
return "#{TAG_ATOM_UTF8_EXT.chr}#{size_packed}" \
|
62
|
+
"#{@value}"
|
83
63
|
end
|
84
64
|
else
|
85
65
|
if size < 256
|
@@ -93,34 +73,90 @@ module Erlang
|
|
93
73
|
raise OutputException, 'unknown atom type', caller
|
94
74
|
end
|
95
75
|
end
|
76
|
+
def to_s
|
77
|
+
return "#{self.class.name}('#{@value.to_s}')"
|
78
|
+
end
|
96
79
|
def hash
|
97
|
-
return
|
80
|
+
return binary.hash
|
98
81
|
end
|
99
82
|
def ==(other)
|
100
|
-
return
|
83
|
+
return binary == other.binary
|
101
84
|
end
|
102
85
|
alias eql? ==
|
103
86
|
end
|
104
87
|
|
88
|
+
class OtpErlangList
|
89
|
+
def initialize(value, improper = false)
|
90
|
+
@value = value
|
91
|
+
@improper = improper
|
92
|
+
end
|
93
|
+
attr_reader :value
|
94
|
+
attr_reader :improper
|
95
|
+
def binary
|
96
|
+
if @value.kind_of?(Array)
|
97
|
+
length = @value.length
|
98
|
+
if length == 0
|
99
|
+
return TAG_NIL_EXT.chr
|
100
|
+
elsif @improper
|
101
|
+
length_packed = [length - 1].pack('N')
|
102
|
+
list_packed = @value.map{ |element|
|
103
|
+
Erlang::term_to_binary_(element)
|
104
|
+
}.join
|
105
|
+
return "#{TAG_LIST_EXT.chr}#{length_packed}#{list_packed}"
|
106
|
+
else
|
107
|
+
length_packed = [length].pack('N')
|
108
|
+
list_packed = @value.map{ |element|
|
109
|
+
Erlang::term_to_binary_(element)
|
110
|
+
}.join
|
111
|
+
return "#{TAG_LIST_EXT.chr}#{length_packed}" \
|
112
|
+
"#{list_packed}#{TAG_NIL_EXT.chr}"
|
113
|
+
end
|
114
|
+
else
|
115
|
+
raise OutputException, 'unknown list type', caller
|
116
|
+
end
|
117
|
+
end
|
118
|
+
def to_s
|
119
|
+
return "#{self.class.name}" \
|
120
|
+
"(#{@value.to_s},improper=#{@improper.to_s})"
|
121
|
+
end
|
122
|
+
def hash
|
123
|
+
return binary.hash
|
124
|
+
end
|
125
|
+
def ==(other)
|
126
|
+
return binary == other.binary
|
127
|
+
end
|
128
|
+
alias eql? ==
|
129
|
+
end
|
130
|
+
|
105
131
|
class OtpErlangBinary
|
106
132
|
def initialize(value, bits = 8)
|
107
133
|
@value = value
|
108
134
|
@bits = bits # bits in last byte
|
109
135
|
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
if @
|
114
|
-
|
136
|
+
attr_reader :value
|
137
|
+
attr_reader :bits
|
138
|
+
def binary
|
139
|
+
if @value.kind_of?(String)
|
140
|
+
size = @value.bytesize
|
141
|
+
size_packed = [size].pack('N')
|
142
|
+
if @bits != 8
|
143
|
+
return "#{TAG_BIT_BINARY_EXT.chr}#{size_packed}" \
|
144
|
+
"#{@bits.chr}#{@value}"
|
145
|
+
else
|
146
|
+
return "#{TAG_BINARY_EXT.chr}#{size_packed}#{@value}"
|
147
|
+
end
|
115
148
|
else
|
116
|
-
|
149
|
+
raise OutputException, 'unknown binary type', caller
|
117
150
|
end
|
118
151
|
end
|
152
|
+
def to_s
|
153
|
+
return "#{self.class.name}('#{@value.to_s}',bits=#{@bits.to_s})"
|
154
|
+
end
|
119
155
|
def hash
|
120
|
-
return
|
156
|
+
return binary.hash
|
121
157
|
end
|
122
158
|
def ==(other)
|
123
|
-
return
|
159
|
+
return binary == other.binary
|
124
160
|
end
|
125
161
|
alias eql? ==
|
126
162
|
end
|
@@ -130,14 +166,19 @@ module Erlang
|
|
130
166
|
@tag = tag
|
131
167
|
@value = value
|
132
168
|
end
|
133
|
-
|
169
|
+
attr_reader :tag
|
170
|
+
attr_reader :value
|
171
|
+
def binary
|
134
172
|
return "#{@tag.chr}#{@value}"
|
135
173
|
end
|
174
|
+
def to_s
|
175
|
+
return "#{self.class.name}('#{@tag.to_s}','#{@value.to_s}')"
|
176
|
+
end
|
136
177
|
def hash
|
137
|
-
return
|
178
|
+
return binary.hash
|
138
179
|
end
|
139
180
|
def ==(other)
|
140
|
-
return
|
181
|
+
return binary == other.binary
|
141
182
|
end
|
142
183
|
alias eql? ==
|
143
184
|
end
|
@@ -148,20 +189,29 @@ module Erlang
|
|
148
189
|
@id = id
|
149
190
|
@creation = creation
|
150
191
|
end
|
151
|
-
|
192
|
+
attr_reader :node
|
193
|
+
attr_reader :id
|
194
|
+
attr_reader :creation
|
195
|
+
def binary
|
152
196
|
size = @id.bytesize / 4
|
153
197
|
if size > 1
|
154
198
|
size_packed = [size].pack('n')
|
155
|
-
return "#{TAG_NEW_REFERENCE_EXT.chr}#{size_packed}
|
199
|
+
return "#{TAG_NEW_REFERENCE_EXT.chr}#{size_packed}" \
|
200
|
+
"#{@node.binary}#{@creation}#{@id}"
|
156
201
|
else
|
157
|
-
return "#{TAG_REFERENCE_EXT.chr}
|
202
|
+
return "#{TAG_REFERENCE_EXT.chr}" \
|
203
|
+
"#{@node.binary}#{@id}#{@creation}"
|
158
204
|
end
|
159
205
|
end
|
206
|
+
def to_s
|
207
|
+
return "#{self.class.name}" \
|
208
|
+
"('#{@node.to_s}','#{@id.to_s}','#{@creation.to_s}')"
|
209
|
+
end
|
160
210
|
def hash
|
161
|
-
return
|
211
|
+
return binary.hash
|
162
212
|
end
|
163
213
|
def ==(other)
|
164
|
-
return
|
214
|
+
return binary == other.binary
|
165
215
|
end
|
166
216
|
alias eql? ==
|
167
217
|
end
|
@@ -172,14 +222,21 @@ module Erlang
|
|
172
222
|
@id = id
|
173
223
|
@creation = creation
|
174
224
|
end
|
225
|
+
attr_reader :node
|
226
|
+
attr_reader :id
|
227
|
+
attr_reader :creation
|
228
|
+
def binary
|
229
|
+
return "#{TAG_PORT_EXT.chr}#{@node.binary}#{@id}#{@creation}"
|
230
|
+
end
|
175
231
|
def to_s
|
176
|
-
return "#{
|
232
|
+
return "#{self.class.name}" \
|
233
|
+
"('#{@node.to_s}','#{@id.to_s}','#{@creation.to_s}')"
|
177
234
|
end
|
178
235
|
def hash
|
179
|
-
return
|
236
|
+
return binary.hash
|
180
237
|
end
|
181
238
|
def ==(other)
|
182
|
-
return
|
239
|
+
return binary == other.binary
|
183
240
|
end
|
184
241
|
alias eql? ==
|
185
242
|
end
|
@@ -191,39 +248,75 @@ module Erlang
|
|
191
248
|
@serial = serial
|
192
249
|
@creation = creation
|
193
250
|
end
|
251
|
+
attr_reader :node
|
252
|
+
attr_reader :id
|
253
|
+
attr_reader :serial
|
254
|
+
attr_reader :creation
|
255
|
+
def binary
|
256
|
+
return "#{TAG_PID_EXT.chr}" \
|
257
|
+
"#{@node.binary}#{@id}#{@serial}#{@creation}"
|
258
|
+
end
|
194
259
|
def to_s
|
195
|
-
return "#{
|
260
|
+
return "#{self.class.name}" \
|
261
|
+
"('#{@node.to_s}','#{@id.to_s}','#{@serial.to_s}'," \
|
262
|
+
"'#{@creation.to_s}')"
|
196
263
|
end
|
197
264
|
def hash
|
198
|
-
return
|
265
|
+
return binary.hash
|
199
266
|
end
|
200
267
|
def ==(other)
|
201
|
-
return
|
268
|
+
return binary == other.binary
|
202
269
|
end
|
203
270
|
alias eql? ==
|
204
271
|
end
|
205
272
|
|
206
|
-
def binary_to_term(data)
|
273
|
+
def self.binary_to_term(data)
|
274
|
+
size = data.bytesize
|
275
|
+
if size <= 1
|
276
|
+
raise ParseException, 'null input', caller
|
277
|
+
end
|
207
278
|
if data[0].ord != TAG_VERSION
|
208
279
|
raise ParseException, 'invalid version', caller
|
209
280
|
end
|
210
|
-
|
211
|
-
|
212
|
-
|
281
|
+
begin
|
282
|
+
result = binary_to_term_(1, data)
|
283
|
+
if result[0] != size
|
284
|
+
raise ParseException, 'unparsed data', caller
|
285
|
+
end
|
286
|
+
return result[1]
|
287
|
+
rescue NoMethodError => e
|
288
|
+
raise ParseException, 'missing data', e.backtrace
|
289
|
+
rescue TypeError => e
|
290
|
+
raise ParseException, 'missing data', e.backtrace
|
291
|
+
rescue ArgumentError => e
|
292
|
+
raise ParseException, 'missing data', e.backtrace
|
213
293
|
end
|
214
|
-
return result[1]
|
215
294
|
end
|
216
295
|
|
217
|
-
def term_to_binary(term)
|
218
|
-
|
219
|
-
|
296
|
+
def self.term_to_binary(term, compressed = false)
|
297
|
+
data_uncompressed = term_to_binary_(term)
|
298
|
+
if compressed == false
|
299
|
+
return "#{TAG_VERSION.chr}#{data_uncompressed}"
|
300
|
+
else
|
301
|
+
if compressed == true
|
302
|
+
compressed = 6
|
303
|
+
end
|
304
|
+
if compressed < 0 or compressed > 9
|
305
|
+
raise InputException, 'compressed in [0..9]', caller
|
306
|
+
end
|
307
|
+
data_compressed = Zlib::Deflate.deflate(data_uncompressed,
|
308
|
+
compressed)
|
309
|
+
size_uncompressed_packed = [data_uncompressed.bytesize].pack('N')
|
310
|
+
return "#{TAG_VERSION.chr}#{TAG_COMPRESSED_ZLIB.chr}" \
|
311
|
+
"#{size_uncompressed_packed}#{data_compressed}"
|
312
|
+
end
|
220
313
|
end
|
221
314
|
|
222
315
|
private
|
223
316
|
|
224
317
|
# binary_to_term
|
225
318
|
|
226
|
-
def binary_to_term_(i, data)
|
319
|
+
def self.binary_to_term_(i, data)
|
227
320
|
tag = data[i].ord
|
228
321
|
i += 1
|
229
322
|
if tag == TAG_NEW_FLOAT_EXT
|
@@ -237,13 +330,10 @@ module Erlang
|
|
237
330
|
elsif tag == TAG_ATOM_CACHE_REF
|
238
331
|
return [i + 1, OtpErlangAtom.new(ord(data[i,1]))]
|
239
332
|
elsif tag == TAG_SMALL_INTEGER_EXT
|
240
|
-
return [i + 1,
|
333
|
+
return [i + 1, data[i].ord]
|
241
334
|
elsif tag == TAG_INTEGER_EXT
|
242
|
-
value = data[i,4].unpack('
|
243
|
-
|
244
|
-
value = -1 * (value & 0x7fffffff)
|
245
|
-
end
|
246
|
-
return [i + 4, Fixnum.induced_from(value)]
|
335
|
+
value = data[i,4].unpack('i>')[0]
|
336
|
+
return [i + 4, value]
|
247
337
|
elsif tag == TAG_FLOAT_EXT
|
248
338
|
value = data[i,31].partition(0.chr)[0].to_f
|
249
339
|
return [i + 31, value]
|
@@ -252,7 +342,7 @@ module Erlang
|
|
252
342
|
i += 2
|
253
343
|
atom_name = data[i,j].force_encoding('ISO-8859-1')
|
254
344
|
if atom_name.valid_encoding?
|
255
|
-
return [i + j,
|
345
|
+
return [i + j, atom_name.to_sym]
|
256
346
|
else
|
257
347
|
raise ParseException, 'invalid atom_name latin1', caller
|
258
348
|
end
|
@@ -302,10 +392,13 @@ module Erlang
|
|
302
392
|
i = result[0]; tmp = result[1]
|
303
393
|
result = binary_to_term_(i, data)
|
304
394
|
i = result[0]; tail = result[1]
|
305
|
-
if tail.
|
306
|
-
tmp.
|
395
|
+
if tail.kind_of?(OtpErlangList) == false or tail.value != []
|
396
|
+
tmp.push(tail)
|
397
|
+
tmp = OtpErlangList.new(tmp, improper=true)
|
398
|
+
else
|
399
|
+
tmp = OtpErlangList.new(tmp)
|
307
400
|
end
|
308
|
-
return [i,
|
401
|
+
return [i, tmp]
|
309
402
|
elsif tag == TAG_BINARY_EXT
|
310
403
|
j = data[i,4].unpack('N')[0]
|
311
404
|
i += 4
|
@@ -319,15 +412,15 @@ module Erlang
|
|
319
412
|
i += 4
|
320
413
|
end
|
321
414
|
sign = data[i].ord
|
322
|
-
i += 1
|
323
415
|
bignum = 0
|
324
416
|
(0...j).each do |bignum_index|
|
325
|
-
digit = data[i
|
417
|
+
digit = data[i + j - bignum_index].ord
|
326
418
|
bignum = bignum * 256 + digit
|
327
419
|
end
|
328
|
-
if sign
|
420
|
+
if sign == 1
|
329
421
|
bignum *= -1
|
330
422
|
end
|
423
|
+
i += 1
|
331
424
|
return [i + j, bignum]
|
332
425
|
elsif tag == TAG_NEW_FUN_EXT
|
333
426
|
size = data[i,4].unpack('N')[0]
|
@@ -359,7 +452,14 @@ module Erlang
|
|
359
452
|
i += 1
|
360
453
|
atom_name = data[i,j].force_encoding('ISO-8859-1')
|
361
454
|
if atom_name.valid_encoding?
|
362
|
-
|
455
|
+
if atom_name == 'true'
|
456
|
+
tmp = true
|
457
|
+
elsif atom_name == 'false'
|
458
|
+
tmp = false
|
459
|
+
else
|
460
|
+
tmp = atom_name.to_sym
|
461
|
+
end
|
462
|
+
return [i + j, tmp]
|
363
463
|
else
|
364
464
|
raise ParseException, 'invalid atom_name latin1', caller
|
365
465
|
end
|
@@ -408,22 +508,40 @@ module Erlang
|
|
408
508
|
else
|
409
509
|
raise ParseException, 'invalid atom_name unicode', caller
|
410
510
|
end
|
511
|
+
elsif tag == TAG_COMPRESSED_ZLIB
|
512
|
+
size_uncompressed = data[i,4].unpack('N')[0]
|
513
|
+
if size_uncompressed == 0
|
514
|
+
raise ParseException, 'compressed data null', caller
|
515
|
+
end
|
516
|
+
i += 4
|
517
|
+
data_compressed = data[i..-1]
|
518
|
+
j = data_compressed.bytesize
|
519
|
+
data_uncompressed = Zlib::Inflate.inflate(data_compressed)
|
520
|
+
if size_uncompressed != data_uncompressed.bytesize
|
521
|
+
raise ParseException, 'compression corrupt', caller
|
522
|
+
end
|
523
|
+
result = binary_to_term_(0, data_uncompressed)
|
524
|
+
i_new = result[0]; term = result[1]
|
525
|
+
if i_new != size_uncompressed
|
526
|
+
raise ParseException, 'unparsed data', caller
|
527
|
+
end
|
528
|
+
return [i + j, term]
|
411
529
|
else
|
412
530
|
raise ParseException, 'invalid tag', caller
|
413
531
|
end
|
414
532
|
end
|
415
533
|
|
416
|
-
def binary_to_term_sequence(i, arity, data)
|
534
|
+
def self.binary_to_term_sequence(i, arity, data)
|
417
535
|
sequence = []
|
418
536
|
(0...arity).each do |arity_index|
|
419
537
|
result = binary_to_term_(i, data)
|
420
538
|
i = result[0]; element = result[1]
|
421
|
-
sequence.
|
539
|
+
sequence.push(element)
|
422
540
|
end
|
423
541
|
return [i, sequence]
|
424
542
|
end
|
425
543
|
|
426
|
-
def binary_to_integer(i, data)
|
544
|
+
def self.binary_to_integer(i, data)
|
427
545
|
tag = data[i].ord
|
428
546
|
i += 1
|
429
547
|
if tag == TAG_SMALL_INTEGER_EXT
|
@@ -439,7 +557,7 @@ module Erlang
|
|
439
557
|
end
|
440
558
|
end
|
441
559
|
|
442
|
-
def binary_to_pid(i, data)
|
560
|
+
def self.binary_to_pid(i, data)
|
443
561
|
tag = data[i].ord
|
444
562
|
i += 1
|
445
563
|
if tag == TAG_PID_EXT
|
@@ -457,7 +575,7 @@ module Erlang
|
|
457
575
|
end
|
458
576
|
end
|
459
577
|
|
460
|
-
def binary_to_atom(i, data)
|
578
|
+
def self.binary_to_atom(i, data)
|
461
579
|
tag = data[i].ord
|
462
580
|
i += 1
|
463
581
|
if tag == TAG_ATOM_EXT
|
@@ -495,11 +613,9 @@ module Erlang
|
|
495
613
|
|
496
614
|
# term_to_binary
|
497
615
|
|
498
|
-
def term_to_binary_(term)
|
616
|
+
def self.term_to_binary_(term)
|
499
617
|
if term.kind_of?(String)
|
500
618
|
return string_to_binary(term)
|
501
|
-
elsif term.kind_of?(OtpErlangList)
|
502
|
-
return term.to_s
|
503
619
|
elsif term.kind_of?(Array)
|
504
620
|
return tuple_to_binary(term)
|
505
621
|
elsif term.kind_of?(Float)
|
@@ -509,29 +625,35 @@ module Erlang
|
|
509
625
|
elsif term.kind_of?(Hash)
|
510
626
|
return hash_to_binary(term)
|
511
627
|
elsif term.kind_of?(Symbol)
|
512
|
-
return OtpErlangAtom.new(term.to_s).
|
628
|
+
return OtpErlangAtom.new(term.to_s).binary
|
513
629
|
elsif term.kind_of?(TrueClass)
|
514
|
-
return OtpErlangAtom.new(
|
630
|
+
return OtpErlangAtom.new(
|
631
|
+
'true'.force_encoding('ISO-8859-1')
|
632
|
+
).binary
|
515
633
|
elsif term.kind_of?(FalseClass)
|
516
|
-
return OtpErlangAtom.new(
|
634
|
+
return OtpErlangAtom.new(
|
635
|
+
'false'.force_encoding('ISO-8859-1')
|
636
|
+
).binary
|
517
637
|
elsif term.kind_of?(OtpErlangAtom)
|
518
|
-
return term.
|
638
|
+
return term.binary
|
639
|
+
elsif term.kind_of?(OtpErlangList)
|
640
|
+
return term.binary
|
519
641
|
elsif term.kind_of?(OtpErlangBinary)
|
520
|
-
return term.
|
642
|
+
return term.binary
|
521
643
|
elsif term.kind_of?(OtpErlangFunction)
|
522
|
-
return term.
|
644
|
+
return term.binary
|
523
645
|
elsif term.kind_of?(OtpErlangReference)
|
524
|
-
return term.
|
646
|
+
return term.binary
|
525
647
|
elsif term.kind_of?(OtpErlangPort)
|
526
|
-
return term.
|
648
|
+
return term.binary
|
527
649
|
elsif term.kind_of?(OtpErlangPid)
|
528
|
-
return term.
|
650
|
+
return term.binary
|
529
651
|
else
|
530
652
|
raise OutputException, 'unknown ruby type', caller
|
531
653
|
end
|
532
654
|
end
|
533
655
|
|
534
|
-
def string_to_binary(term)
|
656
|
+
def self.string_to_binary(term)
|
535
657
|
arity = term.bytesize
|
536
658
|
if arity == 0
|
537
659
|
return TAG_NIL_EXT.chr
|
@@ -543,11 +665,12 @@ module Erlang
|
|
543
665
|
term_packed = term.unpack("C#{arity}").map{ |c|
|
544
666
|
"#{TAG_SMALL_INTEGER_EXT.chr}#{c}"
|
545
667
|
}.join
|
546
|
-
return "#{TAG_LIST_EXT.chr}#{arity_packed}#{term_packed}
|
668
|
+
return "#{TAG_LIST_EXT.chr}#{arity_packed}#{term_packed}" \
|
669
|
+
"#{TAG_NIL_EXT.chr}"
|
547
670
|
end
|
548
671
|
end
|
549
672
|
|
550
|
-
def tuple_to_binary(term)
|
673
|
+
def self.tuple_to_binary(term)
|
551
674
|
arity = term.length
|
552
675
|
term_packed = term.map{ |element|
|
553
676
|
term_to_binary_(element)
|
@@ -560,7 +683,7 @@ module Erlang
|
|
560
683
|
end
|
561
684
|
end
|
562
685
|
|
563
|
-
def integer_to_binary(term)
|
686
|
+
def self.integer_to_binary(term)
|
564
687
|
if 0 <= term and term <= 255
|
565
688
|
return "#{TAG_SMALL_INTEGER_EXT.chr}#{term.chr}"
|
566
689
|
elsif -2147483648 <= term and term <= 2147483647
|
@@ -571,9 +694,9 @@ module Erlang
|
|
571
694
|
end
|
572
695
|
end
|
573
696
|
|
574
|
-
def bignum_to_binary(term)
|
697
|
+
def self.bignum_to_binary(term)
|
575
698
|
bignum = term.abs
|
576
|
-
size =
|
699
|
+
size = (bignum_bit_length(bignum) / 8.0).ceil.to_i
|
577
700
|
if term < 0
|
578
701
|
sign = 1.chr
|
579
702
|
else
|
@@ -581,7 +704,7 @@ module Erlang
|
|
581
704
|
end
|
582
705
|
l = [sign]
|
583
706
|
(0...size).each do |byte|
|
584
|
-
l.
|
707
|
+
l.push((bignum & 255).chr)
|
585
708
|
bignum >>= 8
|
586
709
|
end
|
587
710
|
if size < 256
|
@@ -591,13 +714,17 @@ module Erlang
|
|
591
714
|
return "#{TAG_LARGE_BIG_EXT.chr}#{size_packed}#{l.join}"
|
592
715
|
end
|
593
716
|
end
|
717
|
+
|
718
|
+
def self.bignum_bit_length(bignum)
|
719
|
+
return bignum.to_s(2).bytesize
|
720
|
+
end
|
594
721
|
|
595
|
-
def float_to_binary(term)
|
722
|
+
def self.float_to_binary(term)
|
596
723
|
term_packed = [term].pack('G')
|
597
724
|
return "#{TAG_NEW_FLOAT_EXT.chr}#{term_packed}"
|
598
725
|
end
|
599
726
|
|
600
|
-
def hash_to_binary(term)
|
727
|
+
def self.hash_to_binary(term)
|
601
728
|
arity = term.length
|
602
729
|
term_packed = term.to_a.map{ |element|
|
603
730
|
key_packed = term_to_binary_(element[0])
|
@@ -613,11 +740,15 @@ module Erlang
|
|
613
740
|
class ParseException < SyntaxError
|
614
741
|
end
|
615
742
|
|
743
|
+
class InputException < ArgumentError
|
744
|
+
end
|
745
|
+
|
616
746
|
class OutputException < TypeError
|
617
747
|
end
|
618
748
|
|
619
749
|
# tag values here http://www.erlang.org/doc/apps/erts/erl_ext_dist.html
|
620
750
|
TAG_VERSION = 131
|
751
|
+
TAG_COMPRESSED_ZLIB = 80
|
621
752
|
TAG_NEW_FLOAT_EXT = 70
|
622
753
|
TAG_BIT_BINARY_EXT = 77
|
623
754
|
TAG_ATOM_CACHE_REF = 78
|
@@ -0,0 +1,620 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#-*-Mode:ruby;coding:binary;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
|
3
|
+
# ex: set ft=ruby fenc=binary sts=4 ts=4 sw=4 et:
|
4
|
+
#
|
5
|
+
# BSD LICENSE
|
6
|
+
#
|
7
|
+
# Copyright (c) 2014, Michael Truog <mjtruog at gmail dot com>
|
8
|
+
# Copyright (c) 2009-2013, Dmitry Vasiliev <dima@hlabs.org>
|
9
|
+
# All rights reserved.
|
10
|
+
#
|
11
|
+
# Redistribution and use in source and binary forms, with or without
|
12
|
+
# modification, are permitted provided that the following conditions are met
|
13
|
+
#
|
14
|
+
# * Redistributions of source code must retain the above copyright
|
15
|
+
# notice, this list of conditions and the following disclaimer.
|
16
|
+
# * Redistributions in binary form must reproduce the above copyright
|
17
|
+
# notice, this list of conditions and the following disclaimer in
|
18
|
+
# the documentation and/or other materials provided with the
|
19
|
+
# distribution.
|
20
|
+
# * All advertising materials mentioning features or use of this
|
21
|
+
# software must display the following acknowledgment
|
22
|
+
# This product includes software developed by Michael Truog
|
23
|
+
# * The name of the author may not be used to endorse or promote
|
24
|
+
# products derived from this software without specific prior
|
25
|
+
# written permission
|
26
|
+
#
|
27
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
28
|
+
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
29
|
+
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
30
|
+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
31
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
32
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
33
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
34
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
35
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
36
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
37
|
+
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
38
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
39
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
40
|
+
# DAMAGE.
|
41
|
+
#
|
42
|
+
|
43
|
+
path = File.split(File.dirname(__FILE__)); path.pop(1)
|
44
|
+
$:.unshift File.join(*path, *%w[lib])
|
45
|
+
require 'test/unit'
|
46
|
+
require 'erlang'
|
47
|
+
|
48
|
+
# many of the test cases were adapted
|
49
|
+
# from erlport (https://github.com/hdima/erlport)
|
50
|
+
# to make the tests more exhaustive
|
51
|
+
|
52
|
+
class AtomTestCase < Test::Unit::TestCase
|
53
|
+
def test_atom
|
54
|
+
atom1 = Erlang::OtpErlangAtom.new('test')
|
55
|
+
assert(atom1.kind_of?(Erlang::OtpErlangAtom))
|
56
|
+
assert_equal(Erlang::OtpErlangAtom.new('test'), atom1)
|
57
|
+
assert_equal("Erlang::OtpErlangAtom('test')", atom1.to_s)
|
58
|
+
atom2 = Erlang::OtpErlangAtom.new('test2')
|
59
|
+
atom1_new = Erlang::OtpErlangAtom.new('test')
|
60
|
+
assert_not_equal(atom1, atom2)
|
61
|
+
assert_not_equal(atom1.hash, atom2.hash)
|
62
|
+
assert_equal(atom1, atom1_new)
|
63
|
+
assert_equal(atom1.hash, atom1_new.hash)
|
64
|
+
assert_equal('X' * 255, Erlang::OtpErlangAtom.new('X' * 255).value)
|
65
|
+
assert_equal('X' * 256, Erlang::OtpErlangAtom.new('X' * 256).value)
|
66
|
+
end
|
67
|
+
def test_invalid_atom
|
68
|
+
assert_raise(Erlang::OutputException){
|
69
|
+
Erlang::OtpErlangAtom.new([1, 2]).binary
|
70
|
+
}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class ListTestCase < Test::Unit::TestCase
|
75
|
+
def test_list
|
76
|
+
lst = Erlang::OtpErlangList.new([116, 101, 115, 116])
|
77
|
+
assert(lst.kind_of?(Erlang::OtpErlangList))
|
78
|
+
assert_equal(Erlang::OtpErlangList.new([116, 101, 115, 116]), lst)
|
79
|
+
assert_equal([116, 101, 115, 116], lst.value)
|
80
|
+
assert_equal('Erlang::OtpErlangList([116, 101, 115, 116],' \
|
81
|
+
'improper=false)', lst.to_s)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class ImproperListTestCase < Test::Unit::TestCase
|
86
|
+
def test_improper_list
|
87
|
+
lst = Erlang::OtpErlangList.new([1, 2, 3, 4], improper=true)
|
88
|
+
assert(lst.kind_of?(Erlang::OtpErlangList))
|
89
|
+
assert_equal(Erlang::OtpErlangList.new([1, 2, 3, 4]).value, lst.value)
|
90
|
+
assert_equal(4, lst.value[-1])
|
91
|
+
assert_equal('Erlang::OtpErlangList([1, 2, 3, 4],' \
|
92
|
+
'improper=true)', lst.to_s)
|
93
|
+
end
|
94
|
+
def test_comparison
|
95
|
+
lst = Erlang::OtpErlangList.new([1, 2, 3, 4], improper=true)
|
96
|
+
assert_equal(lst, lst)
|
97
|
+
assert_equal(lst,
|
98
|
+
Erlang::OtpErlangList.new([1, 2, 3, 4], improper=true))
|
99
|
+
assert_not_equal(lst,
|
100
|
+
Erlang::OtpErlangList.new([1, 2, 3, 5], improper=true))
|
101
|
+
assert_not_equal(lst,
|
102
|
+
Erlang::OtpErlangList.new([1, 2, 3], improper=true))
|
103
|
+
end
|
104
|
+
def test_errors
|
105
|
+
assert_raise(Erlang::OutputException){
|
106
|
+
Erlang::OtpErlangList.new('invalid', improper=true).binary
|
107
|
+
}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class DecodeTestCase < Test::Unit::TestCase
|
112
|
+
def test_binary_to_term
|
113
|
+
assert_raise(Erlang::ParseException){
|
114
|
+
Erlang::binary_to_term("")
|
115
|
+
}
|
116
|
+
assert_raise(Erlang::ParseException){
|
117
|
+
Erlang::binary_to_term("\0")
|
118
|
+
}
|
119
|
+
assert_raise(Erlang::ParseException){
|
120
|
+
Erlang::binary_to_term("\x83")
|
121
|
+
}
|
122
|
+
assert_raise(Erlang::ParseException){
|
123
|
+
Erlang::binary_to_term("\x83z")
|
124
|
+
}
|
125
|
+
end
|
126
|
+
def test_binary_to_term_atom
|
127
|
+
assert_raise(Erlang::ParseException){
|
128
|
+
Erlang::binary_to_term("\x83d")
|
129
|
+
}
|
130
|
+
assert_raise(Erlang::ParseException){
|
131
|
+
Erlang::binary_to_term("\x83d\0")
|
132
|
+
}
|
133
|
+
assert_raise(Erlang::ParseException){
|
134
|
+
Erlang::binary_to_term("\x83d\0\1")
|
135
|
+
}
|
136
|
+
assert_equal(:'', Erlang::binary_to_term("\x83d\0\0"))
|
137
|
+
assert_equal(:'', Erlang::binary_to_term("\x83s\0"))
|
138
|
+
assert_equal(:test, Erlang::binary_to_term("\x83d\0\4test"))
|
139
|
+
assert_equal(:test, Erlang::binary_to_term("\x83s\4test"))
|
140
|
+
end
|
141
|
+
def test_binary_to_term_predefined_atoms
|
142
|
+
assert_equal(true,
|
143
|
+
Erlang::binary_to_term("\x83s\4true"))
|
144
|
+
assert_equal(false,
|
145
|
+
Erlang::binary_to_term("\x83s\5false"))
|
146
|
+
assert_equal(:undefined,
|
147
|
+
Erlang::binary_to_term("\x83d\0\11undefined"))
|
148
|
+
end
|
149
|
+
def test_binary_to_term_empty_list
|
150
|
+
assert_equal(Erlang::OtpErlangList.new([]),
|
151
|
+
Erlang::binary_to_term("\x83j"))
|
152
|
+
end
|
153
|
+
def test_binary_to_term_string_list
|
154
|
+
assert_raise(Erlang::ParseException){
|
155
|
+
Erlang::binary_to_term("\x83k")
|
156
|
+
}
|
157
|
+
assert_raise(Erlang::ParseException){
|
158
|
+
Erlang::binary_to_term("\x83k\0")
|
159
|
+
}
|
160
|
+
assert_raise(Erlang::ParseException){
|
161
|
+
Erlang::binary_to_term("\x83k\0\1")
|
162
|
+
}
|
163
|
+
assert_equal('', Erlang::binary_to_term("\x83k\0\0"))
|
164
|
+
assert_equal('test', Erlang::binary_to_term("\x83k\0\4test"))
|
165
|
+
end
|
166
|
+
def test_binary_to_term_list
|
167
|
+
assert_raise(Erlang::ParseException){
|
168
|
+
Erlang::binary_to_term("\x83l")
|
169
|
+
}
|
170
|
+
assert_raise(Erlang::ParseException){
|
171
|
+
Erlang::binary_to_term("\x83l\0")
|
172
|
+
}
|
173
|
+
assert_raise(Erlang::ParseException){
|
174
|
+
Erlang::binary_to_term("\x83l\0\0")
|
175
|
+
}
|
176
|
+
assert_raise(Erlang::ParseException){
|
177
|
+
Erlang::binary_to_term("\x83l\0\0\0")
|
178
|
+
}
|
179
|
+
assert_raise(Erlang::ParseException){
|
180
|
+
Erlang::binary_to_term("\x83l\0\0\0\0")
|
181
|
+
}
|
182
|
+
assert_equal(Erlang::OtpErlangList.new([]),
|
183
|
+
Erlang::binary_to_term("\x83l\0\0\0\0j"))
|
184
|
+
assert_equal(Erlang::OtpErlangList.new([Erlang::OtpErlangList.new([]),
|
185
|
+
Erlang::OtpErlangList.new([])]),
|
186
|
+
Erlang::binary_to_term("\x83l\0\0\0\2jjj"))
|
187
|
+
end
|
188
|
+
def test_binary_to_term_improper_list
|
189
|
+
assert_raise(Erlang::ParseException){
|
190
|
+
Erlang::binary_to_term("\x83l\0\0\0\0k")
|
191
|
+
}
|
192
|
+
lst = Erlang::binary_to_term("\x83l\0\0\0\1jd\0\4tail")
|
193
|
+
assert(lst.kind_of?(Erlang::OtpErlangList))
|
194
|
+
assert_equal([Erlang::OtpErlangList.new([]), :tail], lst.value)
|
195
|
+
assert_equal(true, lst.improper)
|
196
|
+
end
|
197
|
+
def test_binary_to_term_small_tuple
|
198
|
+
assert_raise(Erlang::ParseException){
|
199
|
+
Erlang::binary_to_term("\x83h")
|
200
|
+
}
|
201
|
+
assert_raise(Erlang::ParseException){
|
202
|
+
Erlang::binary_to_term("\x83h\1")
|
203
|
+
}
|
204
|
+
assert(Erlang::binary_to_term("\x83h\0").kind_of?(Array))
|
205
|
+
assert_equal([], Erlang::binary_to_term("\x83h\0"))
|
206
|
+
assert_equal([Erlang::OtpErlangList.new([]),
|
207
|
+
Erlang::OtpErlangList.new([])],
|
208
|
+
Erlang::binary_to_term("\x83h\2jj"))
|
209
|
+
end
|
210
|
+
def test_binary_to_term_large_tuple
|
211
|
+
assert_raise(Erlang::ParseException){
|
212
|
+
Erlang::binary_to_term("\x83i")
|
213
|
+
}
|
214
|
+
assert_raise(Erlang::ParseException){
|
215
|
+
Erlang::binary_to_term("\x83i\0")
|
216
|
+
}
|
217
|
+
assert_raise(Erlang::ParseException){
|
218
|
+
Erlang::binary_to_term("\x83i\0\0")
|
219
|
+
}
|
220
|
+
assert_raise(Erlang::ParseException){
|
221
|
+
Erlang::binary_to_term("\x83i\0\0\0")
|
222
|
+
}
|
223
|
+
assert_raise(Erlang::ParseException){
|
224
|
+
Erlang::binary_to_term("\x83i\0\0\0\1")
|
225
|
+
}
|
226
|
+
assert_equal([], Erlang::binary_to_term("\x83i\0\0\0\0"))
|
227
|
+
assert_equal([Erlang::OtpErlangList.new([]),
|
228
|
+
Erlang::OtpErlangList.new([])],
|
229
|
+
Erlang::binary_to_term("\x83i\0\0\0\2jj"))
|
230
|
+
end
|
231
|
+
def test_binary_to_term_small_integer
|
232
|
+
assert_raise(Erlang::ParseException){
|
233
|
+
Erlang::binary_to_term("\x83a")
|
234
|
+
}
|
235
|
+
assert_equal(0, Erlang::binary_to_term("\x83a\0"))
|
236
|
+
assert_equal(255, Erlang::binary_to_term("\x83a\xff"))
|
237
|
+
end
|
238
|
+
def test_binary_to_term_integer
|
239
|
+
assert_raise(Erlang::ParseException){
|
240
|
+
Erlang::binary_to_term("\x83b")
|
241
|
+
}
|
242
|
+
assert_raise(Erlang::ParseException){
|
243
|
+
Erlang::binary_to_term("\x83b\0")
|
244
|
+
}
|
245
|
+
assert_raise(Erlang::ParseException){
|
246
|
+
Erlang::binary_to_term("\x83b\0\0")
|
247
|
+
}
|
248
|
+
assert_raise(Erlang::ParseException){
|
249
|
+
Erlang::binary_to_term("\x83b\0\0\0")
|
250
|
+
}
|
251
|
+
assert_equal(0, Erlang::binary_to_term("\x83b\0\0\0\0"))
|
252
|
+
assert_equal(2147483647,
|
253
|
+
Erlang::binary_to_term("\x83b\x7f\xff\xff\xff"))
|
254
|
+
assert_equal(-2147483648,
|
255
|
+
Erlang::binary_to_term("\x83b\x80\0\0\0"))
|
256
|
+
assert_equal(-1, Erlang::binary_to_term("\x83b\xff\xff\xff\xff"))
|
257
|
+
end
|
258
|
+
def test_binary_to_term_binary
|
259
|
+
assert_raise(Erlang::ParseException){
|
260
|
+
Erlang::binary_to_term("\x83m")
|
261
|
+
}
|
262
|
+
assert_raise(Erlang::ParseException){
|
263
|
+
Erlang::binary_to_term("\x83m\0")
|
264
|
+
}
|
265
|
+
assert_raise(Erlang::ParseException){
|
266
|
+
Erlang::binary_to_term("\x83m\0\0")
|
267
|
+
}
|
268
|
+
assert_raise(Erlang::ParseException){
|
269
|
+
Erlang::binary_to_term("\x83m\0\0\0")
|
270
|
+
}
|
271
|
+
assert_raise(Erlang::ParseException){
|
272
|
+
Erlang::binary_to_term("\x83m\0\0\0\1")
|
273
|
+
}
|
274
|
+
assert_equal(Erlang::OtpErlangBinary.new(""),
|
275
|
+
Erlang::binary_to_term("\x83m\0\0\0\0"))
|
276
|
+
assert_equal(Erlang::OtpErlangBinary.new("data"),
|
277
|
+
Erlang::binary_to_term("\x83m\0\0\0\4data"))
|
278
|
+
end
|
279
|
+
def test_binary_to_term_float
|
280
|
+
assert_raise(Erlang::ParseException){
|
281
|
+
Erlang::binary_to_term("\x83F")
|
282
|
+
}
|
283
|
+
assert_raise(Erlang::ParseException){
|
284
|
+
Erlang::binary_to_term("\x83F\0")
|
285
|
+
}
|
286
|
+
assert_raise(Erlang::ParseException){
|
287
|
+
Erlang::binary_to_term("\x83F\0\0")
|
288
|
+
}
|
289
|
+
assert_raise(Erlang::ParseException){
|
290
|
+
Erlang::binary_to_term("\x83F\0\0\0")
|
291
|
+
}
|
292
|
+
assert_raise(Erlang::ParseException){
|
293
|
+
Erlang::binary_to_term("\x83F\0\0\0\0")
|
294
|
+
}
|
295
|
+
assert_raise(Erlang::ParseException){
|
296
|
+
Erlang::binary_to_term("\x83F\0\0\0\0\0")
|
297
|
+
}
|
298
|
+
assert_raise(Erlang::ParseException){
|
299
|
+
Erlang::binary_to_term("\x83F\0\0\0\0\0\0")
|
300
|
+
}
|
301
|
+
assert_raise(Erlang::ParseException){
|
302
|
+
Erlang::binary_to_term("\x83F\0\0\0\0\0\0\0")
|
303
|
+
}
|
304
|
+
assert_equal(0.0, Erlang::binary_to_term("\x83F\0\0\0\0\0\0\0\0"))
|
305
|
+
assert_equal(1.5, Erlang::binary_to_term("\x83F?\xf8\0\0\0\0\0\0"))
|
306
|
+
end
|
307
|
+
def test_binary_to_term_small_big_integer
|
308
|
+
assert_raise(Erlang::ParseException){
|
309
|
+
Erlang::binary_to_term("\x83n")
|
310
|
+
}
|
311
|
+
assert_raise(Erlang::ParseException){
|
312
|
+
Erlang::binary_to_term("\x83n\0")
|
313
|
+
}
|
314
|
+
assert_raise(Erlang::ParseException){
|
315
|
+
Erlang::binary_to_term("\x83n\1\0")
|
316
|
+
}
|
317
|
+
assert_equal(0, Erlang::binary_to_term("\x83n\0\0"))
|
318
|
+
assert_equal(6618611909121,
|
319
|
+
Erlang::binary_to_term("\x83n\6\0\1\2\3\4\5\6"))
|
320
|
+
assert_equal(-6618611909121,
|
321
|
+
Erlang::binary_to_term("\x83n\6\1\1\2\3\4\5\6"))
|
322
|
+
end
|
323
|
+
def test_binary_to_term_big_integer
|
324
|
+
assert_raise(Erlang::ParseException){
|
325
|
+
Erlang::binary_to_term("\x83o")
|
326
|
+
}
|
327
|
+
assert_raise(Erlang::ParseException){
|
328
|
+
Erlang::binary_to_term("\x83o\0")
|
329
|
+
}
|
330
|
+
assert_raise(Erlang::ParseException){
|
331
|
+
Erlang::binary_to_term("\x83o\0\0")
|
332
|
+
}
|
333
|
+
assert_raise(Erlang::ParseException){
|
334
|
+
Erlang::binary_to_term("\x83o\0\0\0")
|
335
|
+
}
|
336
|
+
assert_raise(Erlang::ParseException){
|
337
|
+
Erlang::binary_to_term("\x83o\0\0\0\0")
|
338
|
+
}
|
339
|
+
assert_raise(Erlang::ParseException){
|
340
|
+
Erlang::binary_to_term("\x83o\0\0\0\1\0")
|
341
|
+
}
|
342
|
+
assert_equal(0, Erlang::binary_to_term("\x83o\0\0\0\0\0"))
|
343
|
+
assert_equal(6618611909121,
|
344
|
+
Erlang::binary_to_term("\x83o\0\0\0\6\0\1\2\3\4\5\6"))
|
345
|
+
assert_equal(-6618611909121,
|
346
|
+
Erlang::binary_to_term("\x83o\0\0\0\6\1\1\2\3\4\5\6"))
|
347
|
+
end
|
348
|
+
def test_binary_to_term_compressed_term
|
349
|
+
assert_raise(Erlang::ParseException){
|
350
|
+
Erlang::binary_to_term("\x83P")
|
351
|
+
}
|
352
|
+
assert_raise(Erlang::ParseException){
|
353
|
+
Erlang::binary_to_term("\x83P\0")
|
354
|
+
}
|
355
|
+
assert_raise(Erlang::ParseException){
|
356
|
+
Erlang::binary_to_term("\x83P\0\0")
|
357
|
+
}
|
358
|
+
assert_raise(Erlang::ParseException){
|
359
|
+
Erlang::binary_to_term("\x83P\0\0\0")
|
360
|
+
}
|
361
|
+
assert_raise(Erlang::ParseException){
|
362
|
+
Erlang::binary_to_term("\x83P\0\0\0\0")
|
363
|
+
}
|
364
|
+
assert_raise(Erlang::ParseException){
|
365
|
+
Erlang::binary_to_term("\x83P\0\0\0\x16\x78\xda\xcb\x66" \
|
366
|
+
"\x10\x49\xc1\2\0\x5d\x60\x08\x50")
|
367
|
+
}
|
368
|
+
assert_equal("d" * 20,
|
369
|
+
Erlang::binary_to_term("\x83P\0\0\0\x17\x78\xda\xcb\x66" \
|
370
|
+
"\x10\x49\xc1\2\0\x5d\x60\x08\x50")
|
371
|
+
)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
class EncodeTestCase < Test::Unit::TestCase
|
376
|
+
def test_term_to_binary_tuple
|
377
|
+
assert_equal("\x83h\0", Erlang::term_to_binary([]))
|
378
|
+
assert_equal("\x83h\2h\0h\0",
|
379
|
+
Erlang::term_to_binary([[], []]))
|
380
|
+
assert_equal("\x83h\xff" + "h\0" * 255,
|
381
|
+
Erlang::term_to_binary([[]] * 255))
|
382
|
+
assert_equal("\x83i\0\0\1\0" + "h\0" * 256,
|
383
|
+
Erlang::term_to_binary([[]] * 256))
|
384
|
+
end
|
385
|
+
def test_term_to_binary_empty_list
|
386
|
+
assert_equal("\x83j",
|
387
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([])))
|
388
|
+
end
|
389
|
+
def test_term_to_binary_string_list
|
390
|
+
assert_equal("\x83k\0\1\0", Erlang::term_to_binary("\0"))
|
391
|
+
s = (0...256).to_a.map{ |i| i.chr }.join
|
392
|
+
assert_equal("\x83k\1\0" + s, Erlang::term_to_binary(s))
|
393
|
+
end
|
394
|
+
def test_term_to_binary_list_basic
|
395
|
+
assert_equal("\x83\x6A",
|
396
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([])))
|
397
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x6A\x6A",
|
398
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([""])))
|
399
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x61\x01\x6A",
|
400
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([1])))
|
401
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x61\xFF\x6A",
|
402
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([255])))
|
403
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x62\x00\x00\x01\x00\x6A",
|
404
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([256])))
|
405
|
+
assert_equal(
|
406
|
+
"\x83\x6C\x00\x00\x00\x01\x62\x7F\xFF\xFF\xFF\x6A",
|
407
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([2147483647]))
|
408
|
+
)
|
409
|
+
assert_equal(
|
410
|
+
"\x83\x6C\x00\x00\x00\x01\x6E\x04\x00\x00\x00\x00\x80\x6A",
|
411
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([2147483648]))
|
412
|
+
)
|
413
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x61\x00\x6A",
|
414
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([0])))
|
415
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x62\xFF\xFF\xFF\xFF\x6A",
|
416
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([-1])))
|
417
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x62\xFF\xFF\xFF\x00\x6A",
|
418
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([-256])))
|
419
|
+
assert_equal("\x83\x6C\x00\x00\x00\x01\x62\xFF\xFF\xFE\xFF\x6A",
|
420
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([-257])))
|
421
|
+
assert_equal(
|
422
|
+
"\x83\x6C\x00\x00\x00\x01\x62\x80\x00\x00\x00\x6A",
|
423
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([-2147483648]))
|
424
|
+
)
|
425
|
+
assert_equal(
|
426
|
+
"\x83\x6C\x00\x00\x00\x01\x6E\x04\x01\x01\x00\x00\x80\x6A",
|
427
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([-2147483649]))
|
428
|
+
)
|
429
|
+
assert_equal(
|
430
|
+
"\x83\x6C\x00\x00\x00\x01\x6B\x00\x04\x74\x65\x73\x74\x6A",
|
431
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new(["test"]))
|
432
|
+
)
|
433
|
+
assert_equal(
|
434
|
+
"\x83\x6C\x00\x00\x00\x02\x62\x00\x00\x01\x75\x62\x00\x00" \
|
435
|
+
"\x01\xC7\x6A",
|
436
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([373, 455]))
|
437
|
+
)
|
438
|
+
assert_equal(
|
439
|
+
"\x83\x6C\x00\x00\x00\x01\x6A\x6A",
|
440
|
+
Erlang::term_to_binary(
|
441
|
+
Erlang::OtpErlangList.new([Erlang::OtpErlangList.new([])])
|
442
|
+
)
|
443
|
+
)
|
444
|
+
assert_equal(
|
445
|
+
"\x83\x6C\x00\x00\x00\x02\x6A\x6A\x6A",
|
446
|
+
Erlang::term_to_binary(
|
447
|
+
Erlang::OtpErlangList.new([Erlang::OtpErlangList.new([]),
|
448
|
+
Erlang::OtpErlangList.new([])])
|
449
|
+
)
|
450
|
+
)
|
451
|
+
assert_equal(
|
452
|
+
"\x83\x6C\x00\x00\x00\x03\x6C\x00\x00\x00\x02\x6B\x00\x04\x74\x68" \
|
453
|
+
"\x69\x73\x6B\x00\x02\x69\x73\x6A\x6C\x00\x00\x00\x01\x6C\x00\x00" \
|
454
|
+
"\x00\x01\x6B\x00\x01\x61\x6A\x6A\x6B\x00\x04\x74\x65\x73\x74\x6A",
|
455
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([
|
456
|
+
Erlang::OtpErlangList.new(["this", "is"]),
|
457
|
+
Erlang::OtpErlangList.new([
|
458
|
+
Erlang::OtpErlangList.new(["a"])
|
459
|
+
]),
|
460
|
+
"test"
|
461
|
+
]))
|
462
|
+
)
|
463
|
+
end
|
464
|
+
def test_term_to_binary_list
|
465
|
+
assert_equal(
|
466
|
+
"\x83l\0\0\0\1jj",
|
467
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([
|
468
|
+
Erlang::OtpErlangList.new([])
|
469
|
+
]))
|
470
|
+
)
|
471
|
+
assert_equal(
|
472
|
+
"\x83l\0\0\0\5jjjjjj",
|
473
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([
|
474
|
+
Erlang::OtpErlangList.new([]),
|
475
|
+
Erlang::OtpErlangList.new([]),
|
476
|
+
Erlang::OtpErlangList.new([]),
|
477
|
+
Erlang::OtpErlangList.new([]),
|
478
|
+
Erlang::OtpErlangList.new([])
|
479
|
+
]))
|
480
|
+
)
|
481
|
+
end
|
482
|
+
def test_term_to_binary_improper_list
|
483
|
+
assert_equal(
|
484
|
+
"\x83l\0\0\0\1h\0h\0",
|
485
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([
|
486
|
+
[], []
|
487
|
+
], improper=true))
|
488
|
+
)
|
489
|
+
assert_equal(
|
490
|
+
"\x83l\0\0\0\1a\0a\1",
|
491
|
+
Erlang::term_to_binary(Erlang::OtpErlangList.new([
|
492
|
+
0, 1
|
493
|
+
], improper=true))
|
494
|
+
)
|
495
|
+
end
|
496
|
+
def test_term_to_binary_atom
|
497
|
+
assert_equal("\x83s\0", Erlang::term_to_binary(:""))
|
498
|
+
assert_equal("\x83s\4test", Erlang::term_to_binary(:test))
|
499
|
+
end
|
500
|
+
def test_term_to_binary_string_basic
|
501
|
+
assert_equal("\x83\x6A", Erlang::term_to_binary(""))
|
502
|
+
assert_equal("\x83\x6B\x00\x04\x74\x65\x73\x74",
|
503
|
+
Erlang::term_to_binary("test"))
|
504
|
+
assert_equal(
|
505
|
+
"\x83\x6B\x00\x09\x74\x77\x6F\x20\x77\x6F\x72\x64\x73",
|
506
|
+
Erlang::term_to_binary("two words")
|
507
|
+
)
|
508
|
+
assert_equal(
|
509
|
+
"\x83\x6B\x00\x16\x74\x65\x73\x74\x69\x6E\x67\x20\x6D\x75\x6C\x74" \
|
510
|
+
"\x69\x70\x6C\x65\x20\x77\x6F\x72\x64\x73",
|
511
|
+
Erlang::term_to_binary("testing multiple words")
|
512
|
+
)
|
513
|
+
assert_equal("\x83\x6B\x00\x01\x20",
|
514
|
+
Erlang::term_to_binary(" "))
|
515
|
+
assert_equal("\x83\x6B\x00\x02\x20\x20",
|
516
|
+
Erlang::term_to_binary(" "))
|
517
|
+
assert_equal("\x83\x6B\x00\x01\x31",
|
518
|
+
Erlang::term_to_binary("1"))
|
519
|
+
assert_equal("\x83\x6B\x00\x02\x33\x37",
|
520
|
+
Erlang::term_to_binary("37"))
|
521
|
+
assert_equal("\x83\x6B\x00\x07\x6F\x6E\x65\x20\x3D\x20\x31",
|
522
|
+
Erlang::term_to_binary("one = 1"))
|
523
|
+
assert_equal(
|
524
|
+
"\x83\x6B\x00\x20\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x5F\x2B" \
|
525
|
+
"\x2D\x3D\x5B\x5D\x7B\x7D\x5C\x7C\x3B\x27\x3A\x22\x2C\x2E\x2F\x3C" \
|
526
|
+
"\x3E\x3F\x7E\x60",
|
527
|
+
Erlang::term_to_binary("!@#\$%^&*()_+-=[]{}\\|;':\",./<>?~`")
|
528
|
+
)
|
529
|
+
assert_equal(
|
530
|
+
"\x83\x6B\x00\x09\x22\x08\x0C\x0A\x0D\x09\x0B\x53\x12",
|
531
|
+
Erlang::term_to_binary("\"\b\f\n\r\t\v\123\x12")
|
532
|
+
)
|
533
|
+
end
|
534
|
+
def test_term_to_binary_string
|
535
|
+
assert_equal("\x83j", Erlang::term_to_binary(''))
|
536
|
+
assert_equal("\x83k\0\1\0",
|
537
|
+
Erlang::term_to_binary("\0"))
|
538
|
+
assert_equal("\x83k\0\4test",
|
539
|
+
Erlang::term_to_binary('test'))
|
540
|
+
end
|
541
|
+
def test_term_to_binary_boolean
|
542
|
+
assert_equal("\x83s\4true", Erlang::term_to_binary(true))
|
543
|
+
assert_equal("\x83s\5false", Erlang::term_to_binary(false))
|
544
|
+
end
|
545
|
+
def test_term_to_binary_short_integer
|
546
|
+
assert_equal("\x83a\0", Erlang::term_to_binary(0))
|
547
|
+
assert_equal("\x83a\xff", Erlang::term_to_binary(255))
|
548
|
+
end
|
549
|
+
def test_term_to_binary_integer
|
550
|
+
assert_equal("\x83b\xff\xff\xff\xff", Erlang::term_to_binary(-1))
|
551
|
+
assert_equal("\x83b\x80\0\0\0",
|
552
|
+
Erlang::term_to_binary(-2147483648))
|
553
|
+
assert_equal("\x83b\0\0\1\0",
|
554
|
+
Erlang::term_to_binary(256))
|
555
|
+
assert_equal("\x83b\x7f\xff\xff\xff",
|
556
|
+
Erlang::term_to_binary(2147483647))
|
557
|
+
end
|
558
|
+
def test_term_to_binary_long_integer
|
559
|
+
assert_equal("\x83n\4\0\0\0\0\x80",
|
560
|
+
Erlang::term_to_binary(2147483648))
|
561
|
+
assert_equal("\x83n\4\1\1\0\0\x80",
|
562
|
+
Erlang::term_to_binary(-2147483649))
|
563
|
+
assert_equal("\x83o\0\0\1\0\0" + "\0" * 255 + "\1",
|
564
|
+
Erlang::term_to_binary(2 ** 2040))
|
565
|
+
assert_equal("\x83o\0\0\1\0\1" + "\0" * 255 + "\1",
|
566
|
+
Erlang::term_to_binary(-2 ** 2040))
|
567
|
+
end
|
568
|
+
def test_term_to_binary_float
|
569
|
+
assert_equal("\x83F\0\0\0\0\0\0\0\0",
|
570
|
+
Erlang::term_to_binary(0.0))
|
571
|
+
assert_equal("\x83F?\xe0\0\0\0\0\0\0",
|
572
|
+
Erlang::term_to_binary(0.5))
|
573
|
+
assert_equal("\x83F\xbf\xe0\0\0\0\0\0\0",
|
574
|
+
Erlang::term_to_binary(-0.5))
|
575
|
+
assert_equal("\x83F@\t!\xfbM\x12\xd8J",
|
576
|
+
Erlang::term_to_binary(3.1415926))
|
577
|
+
assert_equal("\x83F\xc0\t!\xfbM\x12\xd8J",
|
578
|
+
Erlang::term_to_binary(-3.1415926))
|
579
|
+
end
|
580
|
+
def test_term_to_binary_compressed_term
|
581
|
+
assert_equal(
|
582
|
+
"\x83P\x00\x00\x00\x15x\x9c\xcba``\xe0\xcfB\x03\x00B@\x07\x1c",
|
583
|
+
Erlang::term_to_binary(
|
584
|
+
Erlang::OtpErlangList.new([
|
585
|
+
Erlang::OtpErlangList.new([])
|
586
|
+
] * 15), compressed=true
|
587
|
+
)
|
588
|
+
)
|
589
|
+
assert_equal(
|
590
|
+
"\x83P\x00\x00\x00\x15x\x9c\xcba``\xe0\xcfB\x03\x00B@\x07\x1c",
|
591
|
+
Erlang::term_to_binary(
|
592
|
+
Erlang::OtpErlangList.new([
|
593
|
+
Erlang::OtpErlangList.new([])
|
594
|
+
] * 15), compressed=6
|
595
|
+
)
|
596
|
+
)
|
597
|
+
assert_equal(
|
598
|
+
"\x83P\x00\x00\x00\x15x\xda\xcba``\xe0\xcfB\x03\x00B@\x07\x1c",
|
599
|
+
Erlang::term_to_binary(
|
600
|
+
Erlang::OtpErlangList.new([
|
601
|
+
Erlang::OtpErlangList.new([])
|
602
|
+
] * 15), compressed=9
|
603
|
+
)
|
604
|
+
)
|
605
|
+
assert_equal(
|
606
|
+
"\x83P\x00\x00\x00\x15x\x01\x01\x15\x00\xea\xffl\x00\x00\x00" \
|
607
|
+
"\x0fjjjjjjjjjjjjjjjjB@\x07\x1c",
|
608
|
+
Erlang::term_to_binary(
|
609
|
+
Erlang::OtpErlangList.new([
|
610
|
+
Erlang::OtpErlangList.new([])
|
611
|
+
] * 15), compressed=0
|
612
|
+
)
|
613
|
+
)
|
614
|
+
assert_equal(
|
615
|
+
"\x83P\0\0\0\x17\x78\xda\xcb\x66\x10\x49\xc1\2\0\x5d\x60\x08\x50",
|
616
|
+
Erlang::term_to_binary("d" * 20, compressed=9)
|
617
|
+
)
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erlang_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -50,7 +50,7 @@ cert_chain:
|
|
50
50
|
-----END CERTIFICATE-----
|
51
51
|
|
52
52
|
'
|
53
|
-
date: 2014-
|
53
|
+
date: 2014-09-30 00:00:00.000000000 Z
|
54
54
|
dependencies: []
|
55
55
|
description: Erlang Binary Term Format for Ruby
|
56
56
|
email: mjtruog@gmail.com
|
@@ -61,6 +61,7 @@ extra_rdoc_files:
|
|
61
61
|
files:
|
62
62
|
- lib/erlang.rb
|
63
63
|
- README.markdown
|
64
|
+
- tests/erlang_tests.rb
|
64
65
|
homepage: https://github.com/okeuday/erlang_rb
|
65
66
|
licenses:
|
66
67
|
- BSD
|
@@ -86,4 +87,5 @@ rubygems_version: 1.8.11
|
|
86
87
|
signing_key:
|
87
88
|
specification_version: 3
|
88
89
|
summary: Erlang
|
89
|
-
test_files:
|
90
|
+
test_files:
|
91
|
+
- tests/erlang_tests.rb
|
metadata.gz.sig
CHANGED
Binary file
|