Class: Erlectricity::Encoder

Inherits:
Object
  • Object
show all
Includes:
Erlectricity::External::Types
Defined in:
lib/erlectricity/encoder.rb

Constant Summary

Constants included from Erlectricity::External::Types

Erlectricity::External::Types::ATOM, Erlectricity::External::Types::BIN, Erlectricity::External::Types::FLOAT, Erlectricity::External::Types::FUN, Erlectricity::External::Types::INT, Erlectricity::External::Types::LARGE_BIGNUM, Erlectricity::External::Types::LARGE_TUPLE, Erlectricity::External::Types::LIST, Erlectricity::External::Types::NEW_FUN, Erlectricity::External::Types::NEW_REF, Erlectricity::External::Types::NIL, Erlectricity::External::Types::PID, Erlectricity::External::Types::PORT, Erlectricity::External::Types::REF, Erlectricity::External::Types::SMALL_BIGNUM, Erlectricity::External::Types::SMALL_INT, Erlectricity::External::Types::SMALL_TUPLE, Erlectricity::External::Types::STRING

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(out) ⇒ Encoder

Returns a new instance of Encoder.



7
8
9
# File 'lib/erlectricity/encoder.rb', line 7

def initialize(out)
  self.out = out
end

Instance Attribute Details

#outObject

Returns the value of attribute out.



5
6
7
# File 'lib/erlectricity/encoder.rb', line 5

def out
  @out
end

Class Method Details

.encode(data) ⇒ Object



11
12
13
14
15
# File 'lib/erlectricity/encoder.rb', line 11

def self.encode(data)
  io = StringIO.new
  self.new(io).write_any(data)
  io.string
end

Instance Method Details

#write_1(byte) ⇒ Object



39
40
41
# File 'lib/erlectricity/encoder.rb', line 39

def write_1(byte)
  out.write([byte].pack("C"))
end

#write_2(short) ⇒ Object



43
44
45
# File 'lib/erlectricity/encoder.rb', line 43

def write_2(short)
  out.write([short].pack("n"))
end

#write_4(long) ⇒ Object



47
48
49
# File 'lib/erlectricity/encoder.rb', line 47

def write_4(long)
  out.write([long].pack("N"))
end

#write_any(obj) ⇒ Object



17
18
19
20
# File 'lib/erlectricity/encoder.rb', line 17

def write_any obj
  write_1 Erlectricity::External::VERSION
  write_any_raw obj
end

#write_any_raw(obj) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/erlectricity/encoder.rb', line 22

def write_any_raw obj
  case obj
    when Symbol then write_symbol(obj)
    when Fixnum, Bignum then write_fixnum(obj)
    when Float then write_float(obj)
    when Erlectricity::NewReference then write_new_reference(obj)
    when Erlectricity::Pid then write_pid(obj)
    when Erlectricity::List then write_list(obj)
    when Array then write_tuple(obj)
    when String then write_binary(obj)
    when Time then write_any_raw(obj.to_i.divmod(1000000) + [obj.usec])
    when TrueClass, FalseClass then write_boolean(obj)
    else
      fail(obj)
  end
end

#write_bignum(num) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/erlectricity/encoder.rb', line 84

def write_bignum(num)
  if num.is_a?(Bignum)
    n = num.size
  else
    n = (num.to_s(2).size / 8.0).ceil
  end
  if n <= 256
    write_1 SMALL_BIGNUM
    write_1 n
    write_bignum_guts(num)
  else
    write_1 LARGE_BIGNUM
    write_4 n
    write_bignum_guts(num)
  end
end

#write_bignum_guts(num) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/erlectricity/encoder.rb', line 101

def write_bignum_guts(num)
  write_1 (num >= 0 ? 0 : 1)
  num = num.abs
  while num != 0
    rem = num % 256
    write_1 rem
    num = num >> 8
  end
end

#write_binary(data) ⇒ Object



152
153
154
155
156
# File 'lib/erlectricity/encoder.rb', line 152

def write_binary(data)
  write_1 BIN
  write_4 data.length
  write_string data
end

#write_boolean(bool) ⇒ Object



55
56
57
# File 'lib/erlectricity/encoder.rb', line 55

def write_boolean(bool)
  write_symbol(bool.to_s.to_sym)
end

#write_fixnum(num) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/erlectricity/encoder.rb', line 67

def write_fixnum(num)
  if num >= 0 && num < 256
    write_1 SMALL_INT
    write_1 num
  elsif num <= Erlectricity::External::MAX_INT && num >= Erlectricity::External::MIN_INT
    write_1 INT
    write_4 num
  else
    write_bignum num
  end
end

#write_float(float) ⇒ Object



79
80
81
82
# File 'lib/erlectricity/encoder.rb', line 79

def write_float(float)
  write_1 FLOAT
  write_string format("%15.15e", float).ljust(31, "\000")
end

#write_list(data) ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/erlectricity/encoder.rb', line 143

def write_list(data)
  fail(data) unless data.is_a? Array
  write_1 NIL and return if data.empty?
  write_1 LIST
  write_4 data.length
  data.each{|e| write_any_raw e }
  write_1 NIL
end

#write_new_reference(ref) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/erlectricity/encoder.rb', line 111

def write_new_reference(ref)
  fail(ref) unless ref.is_a?(Erlectricity::NewReference)
  write_1 NEW_REF
  write_2 ref.id.length
  write_symbol(ref.node)
  write_1 ref.creation
  write_string ref.id.pack('N' * ref.id.length)
end

#write_pid(pid) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/erlectricity/encoder.rb', line 120

def write_pid(pid)
  fail(pid) unless pid.is_a? Erlectricity::Pid
  write_1 PID
  write_symbol(pid.node)
  write_4 pid.id
  write_4 pid.serial
  write_1 pid.creation
end

#write_string(string) ⇒ Object



51
52
53
# File 'lib/erlectricity/encoder.rb', line 51

def write_string(string)
  out.write(string)
end

#write_symbol(sym) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/erlectricity/encoder.rb', line 59

def write_symbol(sym)
  fail(sym) unless sym.is_a?(Symbol)
  data = sym.to_s
  write_1 ATOM
  write_2 data.length
  write_string data
end

#write_tuple(data) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/erlectricity/encoder.rb', line 129

def write_tuple(data)
  fail(data) unless data.is_a? Array

  if data.length < 256
    write_1 SMALL_TUPLE
    write_1 data.length
  else
    write_1 LARGE_TUPLE
    write_4 data.length
  end

  data.each { |e| write_any_raw e }
end