erlang_rb 1.3.2

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 (5) hide show
  1. data/README.markdown +7 -0
  2. data/lib/erlang.rb +649 -0
  3. data.tar.gz.sig +0 -0
  4. metadata +89 -0
  5. metadata.gz.sig +4 -0
data/README.markdown ADDED
@@ -0,0 +1,7 @@
1
+ Erlang Binary Term Format for Ruby
2
+ ==================================
3
+
4
+ Provides all encoding and decoding for the Erlang Binary Term Format
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
+ in a single Ruby module.
7
+
data/lib/erlang.rb ADDED
@@ -0,0 +1,649 @@
1
+ #-*-Mode:ruby;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
2
+ # ex: set ft=ruby fenc=utf-8 sts=4 ts=4 sw=4 et:
3
+ #
4
+ # BSD LICENSE
5
+ #
6
+ # Copyright (c) 2011-2014, Michael Truog <mjtruog at gmail dot com>
7
+ # All rights reserved.
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions are met
11
+ #
12
+ # * Redistributions of source code must retain the above copyright
13
+ # notice, this list of conditions and the following disclaimer.
14
+ # * Redistributions in binary form must reproduce the above copyright
15
+ # notice, this list of conditions and the following disclaimer in
16
+ # the documentation and/or other materials provided with the
17
+ # distribution.
18
+ # * All advertising materials mentioning features or use of this
19
+ # software must display the following acknowledgment
20
+ # This product includes software developed by Michael Truog
21
+ # * The name of the author may not be used to endorse or promote
22
+ # products derived from this software without specific prior
23
+ # written permission
24
+ #
25
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26
+ # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
30
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38
+ # DAMAGE.
39
+ #
40
+
41
+ module Erlang
42
+
43
+ class OtpErlangList
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
67
+
68
+ class OtpErlangAtom
69
+ def initialize(value)
70
+ @value = value
71
+ end
72
+ def to_s
73
+ if @value.kind_of?(Integer)
74
+ return "#{TAG_ATOM_CACHE_REF.chr}#{@value.chr}"
75
+ elsif @value.kind_of?(String)
76
+ size = @value.bytesize
77
+ if @value.encoding.name == 'UTF-8'
78
+ if size < 256
79
+ return "#{TAG_SMALL_ATOM_UTF8_EXT.chr}#{size.chr}#{@value}"
80
+ else
81
+ size_packed = [size].pack('n')
82
+ return "#{TAG_ATOM_UTF8_EXT.chr}#{size_packed}#{@value}"
83
+ end
84
+ else
85
+ if size < 256
86
+ return "#{TAG_SMALL_ATOM_EXT.chr}#{size.chr}#{@value}"
87
+ else
88
+ size_packed = [size].pack('n')
89
+ return "#{TAG_ATOM_EXT.chr}#{size_packed}#{@value}"
90
+ end
91
+ end
92
+ else
93
+ raise OutputException, 'unknown atom type', caller
94
+ end
95
+ end
96
+ def hash
97
+ return to_s.hash
98
+ end
99
+ def ==(other)
100
+ return to_s == other.to_s
101
+ end
102
+ alias eql? ==
103
+ end
104
+
105
+ class OtpErlangBinary
106
+ def initialize(value, bits = 8)
107
+ @value = value
108
+ @bits = bits # bits in last byte
109
+ end
110
+ def to_s
111
+ size = @value.bytesize
112
+ size_packed = [size].pack('N')
113
+ if @bits != 8
114
+ return "#{TAG_BIT_BINARY_EXT.chr}#{size_packed}#{@bits.chr}#{@value}"
115
+ else
116
+ return "#{TAG_BINARY_EXT.chr}#{size_packed}#{@value}"
117
+ end
118
+ end
119
+ def hash
120
+ return to_s.hash
121
+ end
122
+ def ==(other)
123
+ return to_s == other.to_s
124
+ end
125
+ alias eql? ==
126
+ end
127
+
128
+ class OtpErlangFunction
129
+ def initialize(tag, value)
130
+ @tag = tag
131
+ @value = value
132
+ end
133
+ def to_s
134
+ return "#{@tag.chr}#{@value}"
135
+ end
136
+ def hash
137
+ return to_s.hash
138
+ end
139
+ def ==(other)
140
+ return to_s == other.to_s
141
+ end
142
+ alias eql? ==
143
+ end
144
+
145
+ class OtpErlangReference
146
+ def initialize(node, id, creation)
147
+ @node = node
148
+ @id = id
149
+ @creation = creation
150
+ end
151
+ def to_s
152
+ size = @id.bytesize / 4
153
+ if size > 1
154
+ size_packed = [size].pack('n')
155
+ return "#{TAG_NEW_REFERENCE_EXT.chr}#{size_packed}#{@node.to_s}#{@creation}#{@id}"
156
+ else
157
+ return "#{TAG_REFERENCE_EXT.chr}#{@node.to_s}#{@id}#{@creation}"
158
+ end
159
+ end
160
+ def hash
161
+ return to_s.hash
162
+ end
163
+ def ==(other)
164
+ return to_s == other.to_s
165
+ end
166
+ alias eql? ==
167
+ end
168
+
169
+ class OtpErlangPort
170
+ def initialize(node, id, creation)
171
+ @node = node
172
+ @id = id
173
+ @creation = creation
174
+ end
175
+ def to_s
176
+ return "#{TAG_PORT_EXT.chr}#{@node.to_s}#{@id}#{@creation}"
177
+ end
178
+ def hash
179
+ return to_s.hash
180
+ end
181
+ def ==(other)
182
+ return to_s == other.to_s
183
+ end
184
+ alias eql? ==
185
+ end
186
+
187
+ class OtpErlangPid
188
+ def initialize(node, id, serial, creation)
189
+ @node = node
190
+ @id = id
191
+ @serial = serial
192
+ @creation = creation
193
+ end
194
+ def to_s
195
+ return "#{TAG_PID_EXT.chr}#{@node.to_s}#{@id}#{@serial}#{@creation}"
196
+ end
197
+ def hash
198
+ return to_s.hash
199
+ end
200
+ def ==(other)
201
+ return to_s == other.to_s
202
+ end
203
+ alias eql? ==
204
+ end
205
+
206
+ def binary_to_term(data)
207
+ if data[0].ord != TAG_VERSION
208
+ raise ParseException, 'invalid version', caller
209
+ end
210
+ result = binary_to_term_(1, data)
211
+ if result[0] != data.bytesize
212
+ raise ParseException, 'unparsed data', caller
213
+ end
214
+ return result[1]
215
+ end
216
+
217
+ def term_to_binary(term)
218
+ term_packed = term_to_binary_(term)
219
+ return "#{TAG_VERSION.chr}#{term_packed}"
220
+ end
221
+
222
+ private
223
+
224
+ # binary_to_term
225
+
226
+ def binary_to_term_(i, data)
227
+ tag = data[i].ord
228
+ i += 1
229
+ if tag == TAG_NEW_FLOAT_EXT
230
+ return [i + 8, data[i,8].unpack('G')[0]]
231
+ elsif tag == TAG_BIT_BINARY_EXT
232
+ j = data[i,4].unpack('N')[0]
233
+ i += 4
234
+ bits = data[i].ord
235
+ i += 1
236
+ return [i + j, OtpErlangBinary.new(data[i,j], bits)]
237
+ elsif tag == TAG_ATOM_CACHE_REF
238
+ return [i + 1, OtpErlangAtom.new(ord(data[i,1]))]
239
+ elsif tag == TAG_SMALL_INTEGER_EXT
240
+ return [i + 1, ord(data[i])]
241
+ elsif tag == TAG_INTEGER_EXT
242
+ value = data[i,4].unpack('N')[0]
243
+ if value & 0x80000000
244
+ value = -1 * (value & 0x7fffffff)
245
+ end
246
+ return [i + 4, Fixnum.induced_from(value)]
247
+ elsif tag == TAG_FLOAT_EXT
248
+ value = data[i,31].partition(0.chr)[0].to_f
249
+ return [i + 31, value]
250
+ elsif tag == TAG_ATOM_EXT
251
+ j = data[i,2].unpack('n')[0]
252
+ i += 2
253
+ atom_name = data[i,j].force_encoding('ISO-8859-1')
254
+ if atom_name.valid_encoding?
255
+ return [i + j, OtpErlangAtom.new(atom_name)]
256
+ else
257
+ raise ParseException, 'invalid atom_name latin1', caller
258
+ end
259
+ elsif tag == TAG_REFERENCE_EXT or tag == TAG_PORT_EXT
260
+ result = binary_to_atom(i, data)
261
+ i = result[0]; node = result[1]
262
+ id = data[i,4]
263
+ i += 4
264
+ creation = data[i]
265
+ i += 1
266
+ if tag == TAG_REFERENCE_EXT
267
+ return [i, OtpErlangReference.new(node, id, creation)]
268
+ elsif tag == TAG_PORT_EXT
269
+ return [i, OtpErlangPort.new(node, id, creation)]
270
+ end
271
+ elsif tag == TAG_PID_EXT
272
+ result = binary_to_atom(i, data)
273
+ i = result[0]; node = result[1]
274
+ id = data[i,4]
275
+ i += 4
276
+ serial = data[i,4]
277
+ i += 4
278
+ creation = data[i]
279
+ i += 1
280
+ return [i, OtpErlangPid.new(node, id, serial, creation)]
281
+ elsif tag == TAG_SMALL_TUPLE_EXT or tag == TAG_LARGE_TUPLE_EXT
282
+ if tag == TAG_SMALL_TUPLE_EXT
283
+ arity = data[i].ord
284
+ i += 1
285
+ elsif tag == TAG_LARGE_TUPLE_EXT
286
+ arity = data[i,4].unpack('N')[0]
287
+ i += 4
288
+ end
289
+ result = binary_to_term_sequence(i, arity, data)
290
+ i = result[0]; tmp = result[1]
291
+ return [i, tmp]
292
+ elsif tag == TAG_NIL_EXT
293
+ return [i, OtpErlangList.new([])]
294
+ elsif tag == TAG_STRING_EXT
295
+ j = data[i,2].unpack('n')[0]
296
+ i += 2
297
+ return [i + j, data[i,j]]
298
+ elsif tag == TAG_LIST_EXT
299
+ arity = data[i,4].unpack('N')[0]
300
+ i += 4
301
+ result = binary_to_term_sequence(i, arity, data)
302
+ i = result[0]; tmp = result[1]
303
+ result = binary_to_term_(i, data)
304
+ i = result[0]; tail = result[1]
305
+ if tail.iskind?(OtpErlangList) == false
306
+ tmp.append(tail)
307
+ end
308
+ return [i, OtpErlangList.new(tmp)]
309
+ elsif tag == TAG_BINARY_EXT
310
+ j = data[i,4].unpack('N')[0]
311
+ i += 4
312
+ return [i + j, OtpErlangBinary.new(data[i,j], 8)]
313
+ elsif tag == TAG_SMALL_BIG_EXT or tag == TAG_LARGE_BIG_EXT
314
+ if tag == TAG_SMALL_BIG_EXT
315
+ j = data[i].ord
316
+ i += 1
317
+ elsif tag == TAG_LARGE_BIG_EXT
318
+ j = data[i,4].unpack('N')[0]
319
+ i += 4
320
+ end
321
+ sign = data[i].ord
322
+ i += 1
323
+ bignum = 0
324
+ (0...j).each do |bignum_index|
325
+ digit = data[i...(j - bignum_index)].ord
326
+ bignum = bignum * 256 + digit
327
+ end
328
+ if sign
329
+ bignum *= -1
330
+ end
331
+ return [i + j, bignum]
332
+ elsif tag == TAG_NEW_FUN_EXT
333
+ size = data[i,4].unpack('N')[0]
334
+ return [i + size, OtpErlangFunction.new(tag, data[i,size])]
335
+ elsif tag == TAG_EXPORT_EXT
336
+ old_i = i
337
+ result = binary_to_atom(i, data)
338
+ i = result[0]; name_module = result[1]
339
+ result = binary_to_atom(i, data)
340
+ i = result[0]; function = result[1]
341
+ if data[i].ord != TAG_SMALL_INTEGER_EXT
342
+ raise ParseException, 'invalid small integer tag', caller
343
+ end
344
+ i += 1
345
+ arity = data[i].ord
346
+ i += 1
347
+ return [i, OtpErlangFunction.new(tag, data[old_i,i])]
348
+ elsif tag == TAG_NEW_REFERENCE_EXT
349
+ j = data[i,2].unpack('n')[0] * 4
350
+ i += 2
351
+ result = binary_to_atom(i, data)
352
+ i = result[0]; node = result[1]
353
+ creation = data[i]
354
+ i += 1
355
+ id = data[i,j]
356
+ return [i + j, OtpErlangReference.new(node, id, creation)]
357
+ elsif tag == TAG_SMALL_ATOM_EXT
358
+ j = data[i,1].ord
359
+ i += 1
360
+ atom_name = data[i,j].force_encoding('ISO-8859-1')
361
+ if atom_name.valid_encoding?
362
+ return [i + j, OtpErlangAtom.new(atom_name)]
363
+ else
364
+ raise ParseException, 'invalid atom_name latin1', caller
365
+ end
366
+ elsif tag == TAG_MAP_EXT
367
+ arity = data[i,4].unpack('N')[0]
368
+ i += 4
369
+ pairs = Hash.new
370
+ (0...arity).each do |arity_index|
371
+ result = binary_to_term_(i, data)
372
+ i = result[0]; key = result[1]
373
+ result = binary_to_term_(i, data)
374
+ i = result[0]; value = result[1]
375
+ pairs[key] = value
376
+ end
377
+ return [i, pairs]
378
+ elsif tag == TAG_FUN_EXT
379
+ old_i = i
380
+ numfree = data[i,4].unpack('N')[0]
381
+ i += 4
382
+ result = binary_to_pid(i, data)
383
+ i = result[0]; pid = result[1]
384
+ result = binary_to_atom(i, data)
385
+ i = result[0]; name_module = result[1]
386
+ result = binary_to_integer(i, data)
387
+ i = result[0]; index = result[1]
388
+ result = binary_to_integer(i, data)
389
+ i = result[0]; uniq = result[1]
390
+ result = binary_to_term_sequence(i, numfree, data)
391
+ i = result[0]; free = result[1]
392
+ return [i, OtpErlangFunction.new(tag, data[old_i,i])]
393
+ elsif tag == TAG_ATOM_UTF8_EXT
394
+ j = data[i,2].unpack('n')[0]
395
+ i += 2
396
+ atom_name = data[i,j].force_encoding('UTF-8')
397
+ if atom_name.valid_encoding?
398
+ return [i + j, OtpErlangAtom.new(atom_name)]
399
+ else
400
+ raise ParseException, 'invalid atom_name unicode', caller
401
+ end
402
+ elsif tag == TAG_SMALL_ATOM_UTF8_EXT
403
+ j = data[i,1].ord
404
+ i += 1
405
+ atom_name = data[i,j].force_encoding('UTF-8')
406
+ if atom_name.valid_encoding?
407
+ return [i + j, OtpErlangAtom.new(atom_name)]
408
+ else
409
+ raise ParseException, 'invalid atom_name unicode', caller
410
+ end
411
+ else
412
+ raise ParseException, 'invalid tag', caller
413
+ end
414
+ end
415
+
416
+ def binary_to_term_sequence(i, arity, data)
417
+ sequence = []
418
+ (0...arity).each do |arity_index|
419
+ result = binary_to_term_(i, data)
420
+ i = result[0]; element = result[1]
421
+ sequence.append(element)
422
+ end
423
+ return [i, sequence]
424
+ end
425
+
426
+ def binary_to_integer(i, data)
427
+ tag = data[i].ord
428
+ i += 1
429
+ if tag == TAG_SMALL_INTEGER_EXT
430
+ return [i + 1, data[i].ord]
431
+ elsif tag == TAG_INTEGER_EXT
432
+ value = data[i,4].unpack('N')[0]
433
+ if value & 0x80000000
434
+ value = -1 * (value & 0x7fffffff)
435
+ end
436
+ return [i + 4, Fixnum.induced_from(value)]
437
+ else
438
+ raise ParseException, 'invalid integer tag', caller
439
+ end
440
+ end
441
+
442
+ def binary_to_pid(i, data)
443
+ tag = data[i].ord
444
+ i += 1
445
+ if tag == TAG_PID_EXT
446
+ result = binary_to_atom(i, data)
447
+ i = result[0]; node = result[1]
448
+ id = data[i,4]
449
+ i += 4
450
+ serial = data[i,4]
451
+ i += 4
452
+ creation = data[i]
453
+ i += 1
454
+ return [i, OtpErlangPid.new(node, id, serial, creation)]
455
+ else
456
+ raise ParseException, 'invalid pid tag', caller
457
+ end
458
+ end
459
+
460
+ def binary_to_atom(i, data)
461
+ tag = data[i].ord
462
+ i += 1
463
+ if tag == TAG_ATOM_EXT
464
+ j = data[i,2].unpack('n')[0]
465
+ i += 2
466
+ return [i + j, OtpErlangAtom.new(data[i,j])]
467
+ elsif tag == TAG_ATOM_CACHE_REF
468
+ return [i + 1, OtpErlangAtom.new(data[i,1].ord)]
469
+ elsif tag == TAG_SMALL_ATOM_EXT
470
+ j = data[i,1].ord
471
+ i += 1
472
+ return [i + j, OtpErlangAtom.new(data[i,j])]
473
+ elsif tag == TAG_ATOM_UTF8_EXT
474
+ j = data[i,2].unpack('n')[0]
475
+ i += 2
476
+ atom_name = data[i,j].force_encoding('UTF-8')
477
+ if atom_name.valid_encoding?
478
+ return [i + j, OtpErlangAtom.new(atom_name)]
479
+ else
480
+ raise ParseException, 'invalid atom_name unicode', caller
481
+ end
482
+ elsif tag == TAG_SMALL_ATOM_UTF8_EXT
483
+ j = data[i,1].ord
484
+ i += 1
485
+ atom_name = data[i,j].force_encoding('UTF-8')
486
+ if atom_name.valid_encoding?
487
+ return [i + j, OtpErlangAtom.new(atom_name)]
488
+ else
489
+ raise ParseException, 'invalid atom_name unicode', caller
490
+ end
491
+ else
492
+ raise ParseException, 'invalid atom tag', caller
493
+ end
494
+ end
495
+
496
+ # term_to_binary
497
+
498
+ def term_to_binary_(term)
499
+ if term.kind_of?(String)
500
+ return string_to_binary(term)
501
+ elsif term.kind_of?(OtpErlangList)
502
+ return term.to_s
503
+ elsif term.kind_of?(Array)
504
+ return tuple_to_binary(term)
505
+ elsif term.kind_of?(Float)
506
+ return float_to_binary(term)
507
+ elsif term.kind_of?(Integer)
508
+ return integer_to_binary(term)
509
+ elsif term.kind_of?(Hash)
510
+ return hash_to_binary(term)
511
+ elsif term.kind_of?(Symbol)
512
+ return OtpErlangAtom.new(term.to_s).to_s
513
+ elsif term.kind_of?(TrueClass)
514
+ return OtpErlangAtom.new("true").to_s
515
+ elsif term.kind_of?(FalseClass)
516
+ return OtpErlangAtom.new("false").to_s
517
+ elsif term.kind_of?(OtpErlangAtom)
518
+ return term.to_s
519
+ elsif term.kind_of?(OtpErlangBinary)
520
+ return term.to_s
521
+ elsif term.kind_of?(OtpErlangFunction)
522
+ return term.to_s
523
+ elsif term.kind_of?(OtpErlangReference)
524
+ return term.to_s
525
+ elsif term.kind_of?(OtpErlangPort)
526
+ return term.to_s
527
+ elsif term.kind_of?(OtpErlangPid)
528
+ return term.to_s
529
+ else
530
+ raise OutputException, 'unknown ruby type', caller
531
+ end
532
+ end
533
+
534
+ def string_to_binary(term)
535
+ arity = term.bytesize
536
+ if arity == 0
537
+ return TAG_NIL_EXT.chr
538
+ elsif arity < 65536
539
+ arity_packed = [arity].pack('n')
540
+ return "#{TAG_STRING_EXT.chr}#{arity_packed}#{term}"
541
+ else
542
+ arity_packed = [arity].pack('N')
543
+ term_packed = term.unpack("C#{arity}").map{ |c|
544
+ "#{TAG_SMALL_INTEGER_EXT.chr}#{c}"
545
+ }.join
546
+ return "#{TAG_LIST_EXT.chr}#{arity_packed}#{term_packed}#{TAG_NIL_EXT.chr}"
547
+ end
548
+ end
549
+
550
+ def tuple_to_binary(term)
551
+ arity = term.length
552
+ term_packed = term.map{ |element|
553
+ term_to_binary_(element)
554
+ }.join
555
+ if arity < 256
556
+ return "#{TAG_SMALL_TUPLE_EXT.chr}#{arity.chr}#{term_packed}"
557
+ else
558
+ arity_packed = [arity].pack('N')
559
+ return "#{TAG_LARGE_TUPLE_EXT.chr}#{arity_packed}#{term_packed}"
560
+ end
561
+ end
562
+
563
+ def integer_to_binary(term)
564
+ if 0 <= term and term <= 255
565
+ return "#{TAG_SMALL_INTEGER_EXT.chr}#{term.chr}"
566
+ elsif -2147483648 <= term and term <= 2147483647
567
+ term_packed = [term].pack('N')
568
+ return "#{TAG_INTEGER_EXT.chr}#{term_packed}"
569
+ else
570
+ return bignum_to_binary(term)
571
+ end
572
+ end
573
+
574
+ def bignum_to_binary(term)
575
+ bignum = term.abs
576
+ size = Integer.new(Math.log(bignum) / Math.log(256)) + 1
577
+ if term < 0
578
+ sign = 1.chr
579
+ else
580
+ sign = 0.chr
581
+ end
582
+ l = [sign]
583
+ (0...size).each do |byte|
584
+ l.append((bignum & 255).chr)
585
+ bignum >>= 8
586
+ end
587
+ if size < 256
588
+ return "#{TAG_SMALL_BIG_EXT.chr}#{size.chr}#{l.join}"
589
+ else
590
+ size_packed = [size].pack('N')
591
+ return "#{TAG_LARGE_BIG_EXT.chr}#{size_packed}#{l.join}"
592
+ end
593
+ end
594
+
595
+ def float_to_binary(term)
596
+ term_packed = [term].pack('G')
597
+ return "#{TAG_NEW_FLOAT_EXT.chr}#{term_packed}"
598
+ end
599
+
600
+ def hash_to_binary(term)
601
+ arity = term.length
602
+ term_packed = term.to_a.map{ |element|
603
+ key_packed = term_to_binary_(element[0])
604
+ value_packed = term_to_binary_(element[1])
605
+ "#{key_packed}#{value_packed}"
606
+ }.join
607
+ arity_packed = [arity].pack('N')
608
+ return "#{TAG_MAP_EXT.chr}#{arity_packed}#{term_packed}"
609
+ end
610
+
611
+ # exceptions
612
+
613
+ class ParseException < SyntaxError
614
+ end
615
+
616
+ class OutputException < TypeError
617
+ end
618
+
619
+ # tag values here http://www.erlang.org/doc/apps/erts/erl_ext_dist.html
620
+ TAG_VERSION = 131
621
+ TAG_NEW_FLOAT_EXT = 70
622
+ TAG_BIT_BINARY_EXT = 77
623
+ TAG_ATOM_CACHE_REF = 78
624
+ TAG_SMALL_INTEGER_EXT = 97
625
+ TAG_INTEGER_EXT = 98
626
+ TAG_FLOAT_EXT = 99
627
+ TAG_ATOM_EXT = 100
628
+ TAG_REFERENCE_EXT = 101
629
+ TAG_PORT_EXT = 102
630
+ TAG_PID_EXT = 103
631
+ TAG_SMALL_TUPLE_EXT = 104
632
+ TAG_LARGE_TUPLE_EXT = 105
633
+ TAG_NIL_EXT = 106
634
+ TAG_STRING_EXT = 107
635
+ TAG_LIST_EXT = 108
636
+ TAG_BINARY_EXT = 109
637
+ TAG_SMALL_BIG_EXT = 110
638
+ TAG_LARGE_BIG_EXT = 111
639
+ TAG_NEW_FUN_EXT = 112
640
+ TAG_EXPORT_EXT = 113
641
+ TAG_NEW_REFERENCE_EXT = 114
642
+ TAG_SMALL_ATOM_EXT = 115
643
+ TAG_MAP_EXT = 116
644
+ TAG_FUN_EXT = 117
645
+ TAG_ATOM_UTF8_EXT = 118
646
+ TAG_SMALL_ATOM_UTF8_EXT = 119
647
+
648
+ end
649
+
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erlang_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Truog
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - ! '-----BEGIN CERTIFICATE-----
13
+
14
+ MIIDMDCCAhigAwIBAgIBADANBgkqhkiG9w0BAQUFADA+MRAwDgYDVQQDDAdtanRy
15
+
16
+ dW9nMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
17
+
18
+ HhcNMTQwNjI0MjAzMDQ2WhcNMTUwNjI0MjAzMDQ2WjA+MRAwDgYDVQQDDAdtanRy
19
+
20
+ dW9nMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNjb20w
21
+
22
+ ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBOoI/CUuwOhXjks02cT58
23
+
24
+ jLxgsOQ412Xzu4eEKqzNsWMoj/3+qYdb5CR4+51EHtuJHZ8hndL5DTYIO8ylcG11
25
+
26
+ EvyxqOzU+gqC53gCEBhJLivlyMXvGqL8qHPuSKGEMc1Vpzh0WicwNnaT7z3X6aQP
27
+
28
+ UE6qWd1yE9jT7TX+GKcKayBJTufxcBMjtwvzMH4IiVaNjUBHBq2LbeNO1yDPYVzV
29
+
30
+ HWnZCv75vIXdUruFrSZcJgNRYRwzMfHEbf+BcvqqGVV6p3PJgJMrjI8FZ7roIJNf
31
+
32
+ D7ZO96x4ItjGazoTntAZe3EM9QB5Wjsd1cv2IEOISQ6jyvVX5E84Al+MEKhhhFuL
33
+
34
+ AgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFACw0UcBaNl2dQWwgg/Qzeyf
35
+
36
+ cKG7MAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAHjLn+8F8yeOFcKst
37
+
38
+ mKA3m28OIoICMefZOiJfTC9UkVkW+554IXNBu3vVxLc0nlCqmuf/aQGaFBUm9MLA
39
+
40
+ oD5CmlrU9OrEl2fPxqTHAwFgLNre8e2EWtm2OhBg73JTHRVVyBLpSK5GRUDzhJtZ
41
+
42
+ 7a2ocAE2AgFKpISNxIUe4Zz9O2thg3iryLh9prjETJTUfxDjBmHdx+YkNAblRa2w
43
+
44
+ k9A+nCZzZECcR5ZZYSeaK6MCugGmXUhAkDbuWumCzu/RAghlVC9RFFQt7o1SwGQp
45
+
46
+ LdvYOeJbviyiH1q1rC3NAJNC4P7Q41zx1OYa8S9M5qn+JpE0ZsomnZyGunWaya9Q
47
+
48
+ bTD/aw==
49
+
50
+ -----END CERTIFICATE-----
51
+
52
+ '
53
+ date: 2014-06-24 00:00:00.000000000 Z
54
+ dependencies: []
55
+ description: Erlang Binary Term Format for Ruby
56
+ email: mjtruog@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - README.markdown
61
+ files:
62
+ - lib/erlang.rb
63
+ - README.markdown
64
+ homepage: https://github.com/okeuday/erlang_rb
65
+ licenses:
66
+ - BSD
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 1.9.0
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.11
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Erlang
89
+ test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1,4 @@
1
+ ���q���j��ɂߧ�8��;�dtэÎ�c@�c3�-���uTu�v��(:��D`Ŧ�w�nj�SV����%�\>�9�� ���Oqr/��1�k"=��1��*)�q�Ӝ��'~�ω�*�NY �tQ؀o����F�
2
+ /�-�[��
3
+ �8�Bßբ�C��R�������~�n\� ���^��K�%����K҇$ғ,F�#"y�y{��B���]���/��z���Ve0�
4
+ 'w@�thfr���W��