erlectricity 0.2.1 → 1.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.
- data/History.txt +14 -1
- data/LICENSE +20 -0
- data/README.md +130 -0
- data/Rakefile +63 -60
- data/VERSION.yml +4 -0
- data/examples/echo/README.md +12 -0
- data/examples/echo/echo.erl +13 -0
- data/examples/echo/echo.rb +11 -0
- data/examples/gruff/gruff.erl +17 -18
- data/examples/gruff/gruff_provider.rb +12 -19
- data/examples/gruff/{gruff_run.erl → gruff_run.sh} +5 -3
- data/examples/gruff/{stat_run.erl → stat_run.sh} +5 -3
- data/examples/gruff/stat_writer.erl +6 -6
- data/examples/simple/README.md +5 -0
- data/examples/simple/rerl.rb +111 -0
- data/examples/simple/rerl.sh +37 -0
- data/examples/tinderl/README.md +14 -0
- data/examples/tinderl/tinderl.erl +19 -21
- data/examples/tinderl/tinderl.rb +11 -10
- data/ext/decoder.c +67 -60
- data/lib/erlectricity.rb +4 -7
- data/lib/erlectricity/condition.rb +35 -20
- data/lib/erlectricity/conditions/boolean.rb +11 -0
- data/lib/erlectricity/conditions/hash.rb +9 -10
- data/lib/erlectricity/conditions/static.rb +31 -10
- data/lib/erlectricity/conditions/type.rb +14 -14
- data/lib/erlectricity/constants.rb +3 -4
- data/lib/erlectricity/decoder.rb +205 -199
- data/lib/erlectricity/encoder.rb +49 -35
- data/lib/erlectricity/errors/decode_error.rb +1 -1
- data/lib/erlectricity/errors/encode_error.rb +1 -1
- data/lib/erlectricity/errors/erlectricity_error.rb +1 -1
- data/lib/erlectricity/matcher.rb +15 -32
- data/lib/erlectricity/port.rb +11 -11
- data/lib/erlectricity/receiver.rb +54 -64
- data/lib/erlectricity/types/list.rb +3 -1
- data/test/condition_spec.rb +8 -9
- data/test/decode_spec.rb +27 -28
- data/test/encode_spec.rb +31 -24
- data/test/matcher_spec.rb +24 -12
- data/test/port_spec.rb +3 -4
- data/test/receiver_spec.rb +18 -20
- data/test/test_helper.rb +9 -5
- metadata +36 -29
- data/CONTRIBUTORS +0 -2
- data/Manifest.txt +0 -45
- data/README.txt +0 -43
- data/setup.rb +0 -1585
- data/test/test_erlectricity.rb +0 -2
@@ -1,5 +1,7 @@
|
|
1
1
|
#!/usr/bin/env escript
|
2
|
+
|
2
3
|
-export([main/1]).
|
4
|
+
|
3
5
|
main(_Any) ->
|
4
6
|
Data = [
|
5
7
|
{apples, [10, 2, 3, 4, 4, 3]},
|
@@ -9,9 +11,9 @@ main(_Any) ->
|
|
9
11
|
],
|
10
12
|
gruff:start(),
|
11
13
|
Result = gruff:plot(
|
12
|
-
<<"My Charts">>,
|
13
|
-
<<"/Users/scott/Library/Fonts/Arial">>,
|
14
|
-
Data,
|
14
|
+
<<"My Charts">>,
|
15
|
+
<<"/Users/scott/Library/Fonts/Arial">>,
|
16
|
+
Data,
|
15
17
|
[{0, <<"2003">>}, {2, <<"2004">>}, {4, <<"2005">>}]
|
16
18
|
),
|
17
19
|
file:write_file("out.png", Result).
|
@@ -1,13 +1,15 @@
|
|
1
1
|
#!/usr/bin/env escript
|
2
|
+
|
2
3
|
-export([main/1]).
|
4
|
+
|
3
5
|
main(_Any) ->
|
4
6
|
gruff:start(),
|
5
7
|
MemoryWriter = stat_writer:start(<<"Memory Info">>, fun() -> erlang:memory() end),
|
6
|
-
ProcessWriter = stat_writer:start(<<"Process Info">>,
|
7
|
-
fun() ->
|
8
|
+
ProcessWriter = stat_writer:start(<<"Process Info">>,
|
9
|
+
fun() ->
|
8
10
|
{_, QueueLength} = erlang:process_info(erlang:whereis(gruff), message_queue_len),
|
9
11
|
[{processes, erlang:system_info(process_count)},
|
10
|
-
{gruff_queue_length, QueueLength}]
|
12
|
+
{gruff_queue_length, QueueLength}]
|
11
13
|
end
|
12
14
|
),
|
13
15
|
receive
|
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
start(Title, Fun) ->
|
5
5
|
spawn(?MODULE, loop, [Title, Fun, []]).
|
6
|
-
|
7
|
-
loop(Title, Fun, []) ->
|
6
|
+
|
7
|
+
loop(Title, Fun, []) ->
|
8
8
|
Data = accumulate([], Fun()),
|
9
9
|
loop(Title, Fun, Data, 0).
|
10
10
|
|
@@ -12,12 +12,12 @@ loop(Title, Fun, Data, Generation) ->
|
|
12
12
|
receive
|
13
13
|
{stop} -> ok
|
14
14
|
after 3000 ->
|
15
|
-
NewGeneration = Generation + 1,
|
15
|
+
NewGeneration = Generation + 1,
|
16
16
|
NewData = accumulate(Data, Fun()),
|
17
17
|
NewChart = gruff:plot(
|
18
|
-
list_to_binary([Title, << "- Generation" >>, integer_to_list(NewGeneration)]),
|
19
|
-
<<"/Users/scott/Library/Fonts/Arial">>,
|
20
|
-
NewData,
|
18
|
+
list_to_binary([Title, << "- Generation" >>, integer_to_list(NewGeneration)]),
|
19
|
+
<<"/Users/scott/Library/Fonts/Arial">>,
|
20
|
+
NewData,
|
21
21
|
[]
|
22
22
|
),
|
23
23
|
file:write_file(io_lib:format("~s - ~s.png", [Title, integer_to_list(NewGeneration)]),NewChart),
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# rerl.rb, for use with erlang's open_port
|
3
|
+
# spawn using rerl.sh escript:
|
4
|
+
#
|
5
|
+
# $ ./rerl.sh
|
6
|
+
# ./rerl.sh:35: Warning: variable 'Port' is unused
|
7
|
+
# [erlang] ruby is alive
|
8
|
+
# [erlang] sending: test
|
9
|
+
# [erlang] sending: {atom,symbol}
|
10
|
+
# [erlang] sending: {number,1}
|
11
|
+
# [erlang] sending: {string,<<"reverse">>}
|
12
|
+
# [erlang] sending: {array,[1,2,3]}
|
13
|
+
# [erlang] sending: {array,[<<"abc">>,<<"cde">>]}
|
14
|
+
# [erlang] sending: {hash,[{key,val}]}
|
15
|
+
# [erlang] sending: {object,{1,{2},3,<<"four">>}}
|
16
|
+
# [ ruby ] received: test, nil
|
17
|
+
# [ ruby ] sending: test, nil
|
18
|
+
# [erlang] received: test
|
19
|
+
# [ ruby ] received: atom, :symbol
|
20
|
+
# [ ruby ] sending: atom, :lobmys
|
21
|
+
# [erlang] received: {atom,lobmys}
|
22
|
+
# [ ruby ] received: number, 1
|
23
|
+
# [ ruby ] sending: number, 2
|
24
|
+
# [ ruby ] received: string, "reverse"
|
25
|
+
# [erlang] received: {number,2}
|
26
|
+
# [ ruby ] sending: string, "esrever"
|
27
|
+
# [ ruby ] received: array, [1, 2, 3]
|
28
|
+
# [erlang] received: {string,<<"esrever">>}
|
29
|
+
# [ ruby ] sending: array, [3, 2, 1]
|
30
|
+
# [ ruby ] received: array, ["abc", "cde"]
|
31
|
+
# [erlang] received: {array,{3,2,1}}
|
32
|
+
# [ ruby ] sending: array, ["cde", "abc"]
|
33
|
+
# [ ruby ] received: hash, {:key=>:val}
|
34
|
+
# [erlang] received: {array,{<<"cde">>,<<"abc">>}}
|
35
|
+
# [ ruby ] sending: hash, {:key=>:val, :ruby=>:true}
|
36
|
+
# [ ruby ] received: object, [1, [2], 3, "four"]
|
37
|
+
# [erlang] received: {hash,{{key,val},{ruby,true}}}
|
38
|
+
# [ ruby ] sending: object, [1, [2], 3, "four"]
|
39
|
+
# [erlang] received: {object,{1,{2},3,<<"four">>}}
|
40
|
+
#
|
41
|
+
|
42
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w[../../lib])
|
43
|
+
|
44
|
+
require 'rubygems'
|
45
|
+
require 'erlectricity'
|
46
|
+
|
47
|
+
def log arg
|
48
|
+
puts arg
|
49
|
+
# @f ||= File.open('/tmp/rerl.log', 'w')
|
50
|
+
# @f.puts arg
|
51
|
+
# @f.flush
|
52
|
+
end
|
53
|
+
|
54
|
+
def debug meth, got = nil, send = nil
|
55
|
+
log "[ ruby ] received: #{meth}, #{got.inspect}"
|
56
|
+
log "[ ruby ] sending: #{meth}, #{send.inspect}"
|
57
|
+
end
|
58
|
+
|
59
|
+
receive do |f|
|
60
|
+
f.when(:test) do
|
61
|
+
debug(:test)
|
62
|
+
f.send!(:test)
|
63
|
+
f.receive_loop
|
64
|
+
end
|
65
|
+
|
66
|
+
f.when([:atom, Symbol]) do |sym|
|
67
|
+
debug(:atom, sym, sym.to_s.reverse.to_sym)
|
68
|
+
f.send!([:atom, sym.to_s.reverse.to_sym])
|
69
|
+
f.receive_loop
|
70
|
+
end
|
71
|
+
|
72
|
+
f.when([:bool, Erl.boolean]) do |bool|
|
73
|
+
debug(:bool, bool, !bool)
|
74
|
+
f.send!([:bool, !bool])
|
75
|
+
f.receive_loop
|
76
|
+
end
|
77
|
+
|
78
|
+
f.when([:number, Fixnum]) do |num|
|
79
|
+
debug(:number, num, num*2)
|
80
|
+
f.send!([:number, num*2])
|
81
|
+
f.receive_loop
|
82
|
+
end
|
83
|
+
|
84
|
+
f.when([:string, String]) do |str|
|
85
|
+
debug(:string, str, str.reverse)
|
86
|
+
f.send!([:string, str.reverse])
|
87
|
+
f.receive_loop
|
88
|
+
end
|
89
|
+
|
90
|
+
f.when([:array, Array]) do |arr|
|
91
|
+
debug(:array, arr, arr.reverse)
|
92
|
+
f.send!([:array, arr.reverse])
|
93
|
+
f.receive_loop
|
94
|
+
end
|
95
|
+
|
96
|
+
f.when([:hash, Erl.hash]) do |hash|
|
97
|
+
newhash = hash.dup
|
98
|
+
newhash[:ruby] = :true
|
99
|
+
debug(:hash, hash, newhash)
|
100
|
+
f.send!([:hash, newhash.to_a])
|
101
|
+
f.receive_loop
|
102
|
+
end
|
103
|
+
|
104
|
+
f.when([:object, Any]) do |obj|
|
105
|
+
debug(:object, obj, obj)
|
106
|
+
f.send!([:object, obj])
|
107
|
+
f.receive_loop
|
108
|
+
end
|
109
|
+
|
110
|
+
f.send!(:i_am_alive)
|
111
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env escript
|
2
|
+
main(_) ->
|
3
|
+
Cmd = "ruby rerl.rb",
|
4
|
+
Port = open_port({spawn, Cmd}, [{packet, 4}, nouse_stdio, exit_status, binary]),
|
5
|
+
loop(Port).
|
6
|
+
|
7
|
+
send(Port, Message) ->
|
8
|
+
io:format("[erlang] sending: ~p~n", [Message]),
|
9
|
+
% can also use ! instead of port_command
|
10
|
+
% Port ! { self(), { command, term_to_binary(Message) } }.
|
11
|
+
port_command(Port, term_to_binary(Message)).
|
12
|
+
|
13
|
+
loop(Port) ->
|
14
|
+
receive
|
15
|
+
{Port, {data, In}} ->
|
16
|
+
Data = binary_to_term(In),
|
17
|
+
process(Port, Data);
|
18
|
+
Any ->
|
19
|
+
io:format("[erlang] other: ~p~n", [Any])
|
20
|
+
end,
|
21
|
+
loop(Port).
|
22
|
+
|
23
|
+
process(Port, i_am_alive) ->
|
24
|
+
io:format("[erlang] ruby is alive~n"),
|
25
|
+
|
26
|
+
send(Port, test),
|
27
|
+
send(Port, {atom, symbol}),
|
28
|
+
send(Port, {bool, true}),
|
29
|
+
send(Port, {number, 1}),
|
30
|
+
send(Port, {string, <<"reverse">>}),
|
31
|
+
send(Port, {array, [1,2,3]}),
|
32
|
+
send(Port, {array, [<<"abc">>, <<"cde">>]}),
|
33
|
+
send(Port, {hash, [{key,val}]}),
|
34
|
+
send(Port, {object, {1,{2},3,<<"four">>}});
|
35
|
+
|
36
|
+
process(Port, Data) ->
|
37
|
+
io:format("[erlang] received: ~p~n", [Data]).
|
@@ -0,0 +1,14 @@
|
|
1
|
+
This is a more advanced example of Erlectricity that shows how you can
|
2
|
+
integrate with Campfire via the Ruby "tinder" gem.
|
3
|
+
|
4
|
+
$ cd examples/tinderl
|
5
|
+
$ erl
|
6
|
+
Erlang (BEAM) emulator version 5.6.4 [source] [smp:2] [async-threads:0] [kernel-poll:false]
|
7
|
+
|
8
|
+
Eshell V5.6.4 (abort with ^G)
|
9
|
+
1> c(tinderl).
|
10
|
+
{ok,tinderl}
|
11
|
+
2> tinderl:start("example.campfireapp.com", "tom@example.com", "secret", "My Room").
|
12
|
+
<0.38.0>
|
13
|
+
5> tinderl:speak("Hello, World!").
|
14
|
+
{speak,<0.31.0>,<<"Hello, World!">>}
|
@@ -1,17 +1,16 @@
|
|
1
1
|
-module(tinderl).
|
2
2
|
-export([start/4, stop/0, speak/1, paste/1]).
|
3
3
|
|
4
|
-
start(Domain, Email, Password, Room) ->
|
5
|
-
spawn(fun() ->
|
6
|
-
register(tinderl, self()),
|
7
|
-
process_flag(trap_exit, true),
|
4
|
+
start(Domain, Email, Password, Room) ->
|
5
|
+
spawn(fun() ->
|
6
|
+
register(tinderl, self()),
|
7
|
+
process_flag(trap_exit, true),
|
8
8
|
Cmd = lists:flatten(io_lib:format("ruby ./tinderl.rb ~s ~s ~s ~s", [Domain, Email, Password, Room])),
|
9
|
-
Port = open_port({spawn, Cmd}, [{packet, 4},
|
10
|
-
port_loop(Port)
|
11
|
-
end).
|
12
|
-
|
13
|
-
stop() -> tinderl ! stop.
|
9
|
+
Port = open_port({spawn, Cmd}, [{packet, 4}, nouse_stdio, exit_status, binary]),
|
10
|
+
port_loop(Port)
|
11
|
+
end).
|
14
12
|
|
13
|
+
stop() -> tinderl ! stop.
|
15
14
|
|
16
15
|
speak(String) when is_list(String) -> speak(list_to_binary(String));
|
17
16
|
speak(String) when is_binary(String) -> tinderl ! {speak, self(), String}.
|
@@ -23,23 +22,22 @@ port_loop(Port) ->
|
|
23
22
|
receive
|
24
23
|
{speak, _Caller, String} ->
|
25
24
|
Data = term_to_binary({speak, String}),
|
26
|
-
Port ! {self(), {command, Data}},
|
25
|
+
Port ! {self(), {command, Data}},
|
27
26
|
|
28
27
|
port_loop(Port);
|
29
|
-
|
28
|
+
|
30
29
|
{paste, _Caller, String} ->
|
31
30
|
Data = term_to_binary({paste, String}),
|
32
|
-
Port ! {self(), {command, Data}},
|
31
|
+
Port ! {self(), {command, Data}},
|
33
32
|
|
34
33
|
port_loop(Port);
|
35
|
-
|
36
|
-
stop ->
|
37
|
-
Port ! {self(), close},
|
38
|
-
receive
|
39
|
-
{Port, closed} -> exit(normal)
|
40
|
-
end;
|
41
|
-
|
34
|
+
|
35
|
+
stop ->
|
36
|
+
Port ! {self(), close},
|
37
|
+
receive
|
38
|
+
{Port, closed} -> exit(normal)
|
39
|
+
end;
|
40
|
+
|
42
41
|
{'EXIT', Port, Reason} ->
|
43
42
|
exit({port_terminated,Reason})
|
44
|
-
end.
|
45
|
-
|
43
|
+
end.
|
data/examples/tinderl/tinderl.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
$:.unshift(File.dirname(__FILE__)
|
2
|
-
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w[../../lib])
|
2
|
+
|
3
3
|
require 'rubygems'
|
4
|
+
require 'erlectricity'
|
4
5
|
require 'tinder'
|
5
6
|
|
6
7
|
domain, email, password, room_name = *ARGV
|
@@ -9,18 +10,18 @@ campfire.login email, password
|
|
9
10
|
room = campfire.find_room_by_name room_name
|
10
11
|
|
11
12
|
receive do |f|
|
12
|
-
f.when(:speak, Any) do |comment|
|
13
|
-
room.speak
|
13
|
+
f.when([:speak, Any]) do |comment|
|
14
|
+
room.speak(comment)
|
14
15
|
f.receive_loop
|
15
|
-
end
|
16
|
-
|
17
|
-
f.when(:paste, Any) do |comment|
|
18
|
-
room.paste
|
16
|
+
end
|
17
|
+
|
18
|
+
f.when([:paste, Any]) do |comment|
|
19
|
+
room.paste(comment)
|
19
20
|
f.receive_loop
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
f.when(Any) do |obj|
|
23
|
-
|
24
|
+
p obj
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
data/ext/decoder.c
CHANGED
@@ -25,7 +25,7 @@ static VALUE mErlectricity;
|
|
25
25
|
static VALUE cDecoder;
|
26
26
|
void Init_decoder();
|
27
27
|
|
28
|
-
VALUE
|
28
|
+
VALUE method_decode(VALUE klass, VALUE rString);
|
29
29
|
|
30
30
|
VALUE read_any_raw(unsigned char **pData);
|
31
31
|
|
@@ -79,16 +79,16 @@ VALUE read_small_tuple(unsigned char **pData) {
|
|
79
79
|
if(read_1(pData) != ERL_SMALL_TUPLE) {
|
80
80
|
rb_raise(rb_eStandardError, "Invalid Type, not a small tuple");
|
81
81
|
}
|
82
|
-
|
82
|
+
|
83
83
|
int arity = read_1(pData);
|
84
|
-
|
84
|
+
|
85
85
|
VALUE array = rb_ary_new2(arity);
|
86
|
-
|
86
|
+
|
87
87
|
int i;
|
88
88
|
for(i = 0; i < arity; ++i) {
|
89
89
|
rb_ary_store(array, i, read_any_raw(pData));
|
90
90
|
}
|
91
|
-
|
91
|
+
|
92
92
|
return array;
|
93
93
|
}
|
94
94
|
|
@@ -96,16 +96,16 @@ VALUE read_large_tuple(unsigned char **pData) {
|
|
96
96
|
if(read_1(pData) != ERL_LARGE_TUPLE) {
|
97
97
|
rb_raise(rb_eStandardError, "Invalid Type, not a large tuple");
|
98
98
|
}
|
99
|
-
|
99
|
+
|
100
100
|
int arity = read_4(pData);
|
101
|
-
|
101
|
+
|
102
102
|
VALUE array = rb_ary_new2(arity);
|
103
|
-
|
103
|
+
|
104
104
|
int i;
|
105
105
|
for(i = 0; i < arity; ++i) {
|
106
106
|
rb_ary_store(array, i, read_any_raw(pData));
|
107
107
|
}
|
108
|
-
|
108
|
+
|
109
109
|
return array;
|
110
110
|
}
|
111
111
|
|
@@ -113,18 +113,18 @@ VALUE read_list(unsigned char **pData) {
|
|
113
113
|
if(read_1(pData) != ERL_LIST) {
|
114
114
|
rb_raise(rb_eStandardError, "Invalid Type, not an erlang list");
|
115
115
|
}
|
116
|
-
|
116
|
+
|
117
117
|
int size = read_4(pData);
|
118
|
-
|
118
|
+
|
119
119
|
VALUE array = rb_ary_new2(size);
|
120
|
-
|
120
|
+
|
121
121
|
int i;
|
122
122
|
for(i = 0; i < size; ++i) {
|
123
123
|
rb_ary_store(array, i, read_any_raw(pData));
|
124
124
|
}
|
125
|
-
|
125
|
+
|
126
126
|
read_1(pData);
|
127
|
-
|
127
|
+
|
128
128
|
return array;
|
129
129
|
}
|
130
130
|
|
@@ -140,12 +140,12 @@ VALUE read_bin(unsigned char **pData) {
|
|
140
140
|
if(read_1(pData) != ERL_BIN) {
|
141
141
|
rb_raise(rb_eStandardError, "Invalid Type, not an erlang binary");
|
142
142
|
}
|
143
|
-
|
143
|
+
|
144
144
|
int length = read_4(pData);
|
145
|
-
|
145
|
+
|
146
146
|
unsigned char buf[length + 1];
|
147
147
|
read_string_raw(buf, pData, length);
|
148
|
-
|
148
|
+
|
149
149
|
return rb_str_new2((char *) buf);
|
150
150
|
}
|
151
151
|
|
@@ -153,19 +153,19 @@ VALUE read_string(unsigned char **pData) {
|
|
153
153
|
if(read_1(pData) != ERL_STRING) {
|
154
154
|
rb_raise(rb_eStandardError, "Invalid Type, not an erlang string");
|
155
155
|
}
|
156
|
-
|
156
|
+
|
157
157
|
int length = read_2(pData);
|
158
|
-
|
158
|
+
|
159
159
|
unsigned char buf[length + 1];
|
160
160
|
read_string_raw(buf, pData, length);
|
161
|
-
|
161
|
+
|
162
162
|
VALUE array = rb_ary_new2(length);
|
163
|
-
|
163
|
+
|
164
164
|
int i = 0;
|
165
165
|
for(i; i < length; ++i) {
|
166
166
|
rb_ary_store(array, i, INT2NUM(*(buf + i)));
|
167
167
|
}
|
168
|
-
|
168
|
+
|
169
169
|
return array;
|
170
170
|
}
|
171
171
|
|
@@ -173,22 +173,29 @@ VALUE read_atom(unsigned char **pData) {
|
|
173
173
|
if(read_1(pData) != ERL_ATOM) {
|
174
174
|
rb_raise(rb_eStandardError, "Invalid Type, not an atom");
|
175
175
|
}
|
176
|
-
|
176
|
+
|
177
177
|
int length = read_2(pData);
|
178
|
-
|
178
|
+
|
179
179
|
unsigned char buf[length + 1];
|
180
180
|
read_string_raw(buf, pData, length);
|
181
|
-
|
182
|
-
|
181
|
+
|
182
|
+
// Erlang true and false are actually atoms
|
183
|
+
if(strncmp((char *) buf, "true", length) == 0) {
|
184
|
+
return Qtrue;
|
185
|
+
} else if(strncmp((char *) buf, "false", length) == 0) {
|
186
|
+
return Qfalse;
|
187
|
+
} else {
|
188
|
+
return ID2SYM(rb_intern((char *) buf));
|
189
|
+
}
|
183
190
|
}
|
184
191
|
|
185
192
|
VALUE read_small_int(unsigned char **pData) {
|
186
193
|
if(read_1(pData) != ERL_SMALL_INT) {
|
187
194
|
rb_raise(rb_eStandardError, "Invalid Type, not a small int");
|
188
195
|
}
|
189
|
-
|
196
|
+
|
190
197
|
int value = read_1(pData);
|
191
|
-
|
198
|
+
|
192
199
|
return INT2FIX(value);
|
193
200
|
}
|
194
201
|
|
@@ -196,15 +203,15 @@ VALUE read_int(unsigned char **pData) {
|
|
196
203
|
if(read_1(pData) != ERL_INT) {
|
197
204
|
rb_raise(rb_eStandardError, "Invalid Type, not an int");
|
198
205
|
}
|
199
|
-
|
206
|
+
|
200
207
|
long long value = read_4(pData);
|
201
|
-
|
208
|
+
|
202
209
|
long long negative = ((value >> 31) & 0x1 == 1);
|
203
|
-
|
210
|
+
|
204
211
|
if(negative) {
|
205
212
|
value = (value - ((long long) 1 << 32));
|
206
213
|
}
|
207
|
-
|
214
|
+
|
208
215
|
return INT2FIX(value);
|
209
216
|
}
|
210
217
|
|
@@ -212,27 +219,27 @@ VALUE read_small_bignum(unsigned char **pData) {
|
|
212
219
|
if(read_1(pData) != ERL_SMALL_BIGNUM) {
|
213
220
|
rb_raise(rb_eStandardError, "Invalid Type, not a small bignum");
|
214
221
|
}
|
215
|
-
|
222
|
+
|
216
223
|
unsigned int size = read_1(pData);
|
217
224
|
unsigned int sign = read_1(pData);
|
218
|
-
|
225
|
+
|
219
226
|
VALUE num = INT2NUM(0);
|
220
227
|
VALUE tmp;
|
221
|
-
|
228
|
+
|
222
229
|
unsigned char buf[size + 1];
|
223
230
|
read_string_raw(buf, pData, size);
|
224
|
-
|
231
|
+
|
225
232
|
int i;
|
226
233
|
for(i = 0; i < size; ++i) {
|
227
234
|
tmp = INT2FIX(*(buf + i));
|
228
235
|
tmp = rb_funcall(tmp, rb_intern("<<"), 1, INT2NUM(i * 8));
|
229
236
|
num = rb_funcall(num, rb_intern("+"), 1, tmp);
|
230
237
|
}
|
231
|
-
|
238
|
+
|
232
239
|
if(sign) {
|
233
240
|
num = rb_funcall(num, rb_intern("*"), 1, INT2NUM(-1));
|
234
241
|
}
|
235
|
-
|
242
|
+
|
236
243
|
return num;
|
237
244
|
}
|
238
245
|
|
@@ -240,28 +247,28 @@ VALUE read_large_bignum(unsigned char **pData) {
|
|
240
247
|
if(read_1(pData) != ERL_LARGE_BIGNUM) {
|
241
248
|
rb_raise(rb_eStandardError, "Invalid Type, not a small bignum");
|
242
249
|
}
|
243
|
-
|
250
|
+
|
244
251
|
unsigned int size = read_4(pData);
|
245
252
|
unsigned int sign = read_1(pData);
|
246
|
-
|
253
|
+
|
247
254
|
VALUE num = INT2NUM(0);
|
248
255
|
VALUE tmp;
|
249
|
-
|
256
|
+
|
250
257
|
unsigned char buf[size + 1];
|
251
258
|
read_string_raw(buf, pData, size);
|
252
|
-
|
259
|
+
|
253
260
|
int i;
|
254
261
|
for(i = 0; i < size; ++i) {
|
255
262
|
tmp = INT2FIX(*(buf + i));
|
256
263
|
tmp = rb_funcall(tmp, rb_intern("<<"), 1, INT2NUM(i * 8));
|
257
|
-
|
264
|
+
|
258
265
|
num = rb_funcall(num, rb_intern("+"), 1, tmp);
|
259
266
|
}
|
260
|
-
|
267
|
+
|
261
268
|
if(sign) {
|
262
269
|
num = rb_funcall(num, rb_intern("*"), 1, INT2NUM(-1));
|
263
270
|
}
|
264
|
-
|
271
|
+
|
265
272
|
return num;
|
266
273
|
}
|
267
274
|
|
@@ -269,12 +276,12 @@ VALUE read_float(unsigned char **pData) {
|
|
269
276
|
if(read_1(pData) != ERL_FLOAT) {
|
270
277
|
rb_raise(rb_eStandardError, "Invalid Type, not a float");
|
271
278
|
}
|
272
|
-
|
279
|
+
|
273
280
|
unsigned char buf[32];
|
274
281
|
read_string_raw(buf, pData, 31);
|
275
|
-
|
282
|
+
|
276
283
|
VALUE rString = rb_str_new2((char *) buf);
|
277
|
-
|
284
|
+
|
278
285
|
return rb_funcall(rString, rb_intern("to_f"), 0);
|
279
286
|
}
|
280
287
|
|
@@ -282,7 +289,7 @@ VALUE read_nil(unsigned char **pData) {
|
|
282
289
|
if(read_1(pData) != ERL_NIL) {
|
283
290
|
rb_raise(rb_eStandardError, "Invalid Type, not a nil list");
|
284
291
|
}
|
285
|
-
|
292
|
+
|
286
293
|
return rb_ary_new2(0);
|
287
294
|
}
|
288
295
|
|
@@ -292,12 +299,12 @@ VALUE read_pid(unsigned char **pData) {
|
|
292
299
|
if(read_1(pData) != ERL_PID) {
|
293
300
|
rb_raise(rb_eStandardError, "Invalid Type, not a pid");
|
294
301
|
}
|
295
|
-
|
302
|
+
|
296
303
|
VALUE node = read_atom(pData);
|
297
304
|
VALUE id = INT2NUM(read_4(pData));
|
298
305
|
VALUE serial = INT2NUM(read_4(pData));
|
299
306
|
VALUE creation = INT2FIX(read_1(pData));
|
300
|
-
|
307
|
+
|
301
308
|
VALUE pid_class = rb_const_get(mErlectricity, rb_intern("Pid"));
|
302
309
|
return rb_funcall(pid_class, rb_intern("new"), 4, node, id, serial, creation);
|
303
310
|
}
|
@@ -306,17 +313,17 @@ VALUE read_new_reference(unsigned char **pData) {
|
|
306
313
|
if(read_1(pData) != ERL_NEW_REF) {
|
307
314
|
rb_raise(rb_eStandardError, "Invalid Type, not a new-style reference");
|
308
315
|
}
|
309
|
-
|
316
|
+
|
310
317
|
int size = read_2(pData);
|
311
318
|
VALUE node = read_atom(pData);
|
312
319
|
VALUE creation = INT2FIX(read_1(pData));
|
313
|
-
|
320
|
+
|
314
321
|
VALUE id = rb_ary_new2(size);
|
315
322
|
int i;
|
316
323
|
for(i = 0; i < size; ++i) {
|
317
324
|
rb_ary_store(id, i, INT2NUM(read_4(pData)));
|
318
325
|
}
|
319
|
-
|
326
|
+
|
320
327
|
VALUE newref_class = rb_const_get(mErlectricity, rb_intern("NewReference"));
|
321
328
|
return rb_funcall(newref_class, rb_intern("new"), 3, node, creation, id);
|
322
329
|
}
|
@@ -371,21 +378,21 @@ VALUE read_any_raw(unsigned char **pData) {
|
|
371
378
|
return Qnil;
|
372
379
|
}
|
373
380
|
|
374
|
-
VALUE
|
381
|
+
VALUE method_decode(VALUE klass, VALUE rString) {
|
375
382
|
unsigned char *data = (unsigned char *) StringValuePtr(rString);
|
376
|
-
|
383
|
+
|
377
384
|
unsigned char **pData = &data;
|
378
|
-
|
385
|
+
|
379
386
|
// check protocol version
|
380
387
|
if(read_1(pData) != ERL_VERSION) {
|
381
388
|
rb_raise(rb_eStandardError, "Bad Magic");
|
382
389
|
}
|
383
|
-
|
390
|
+
|
384
391
|
return read_any_raw(pData);
|
385
392
|
}
|
386
393
|
|
387
394
|
void Init_decoder() {
|
388
395
|
mErlectricity = rb_const_get(rb_cObject, rb_intern("Erlectricity"));
|
389
396
|
cDecoder = rb_define_class_under(mErlectricity, "Decoder", rb_cObject);
|
390
|
-
rb_define_singleton_method(cDecoder, "
|
391
|
-
}
|
397
|
+
rb_define_singleton_method(cDecoder, "decode", method_decode, 1);
|
398
|
+
}
|