rserve-client 0.1.5 → 0.1.6
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 +1 -2
- data/.gitignore +1 -0
- data/History.txt +15 -2
- data/Manifest.txt +8 -0
- data/README.txt +41 -19
- data/lib/rserve.rb +1 -1
- data/lib/rserve/connection.rb +152 -69
- data/lib/rserve/engine.rb +9 -9
- data/lib/rserve/packet.rb +2 -2
- data/lib/rserve/protocol.rb +51 -46
- data/lib/rserve/protocol/rexpfactory.rb +659 -366
- data/lib/rserve/rexp.rb +175 -156
- data/lib/rserve/rexp/double.rb +45 -38
- data/lib/rserve/rexp/environment.rb +40 -0
- data/lib/rserve/rexp/expressionvector.rb +9 -0
- data/lib/rserve/rexp/genericvector.rb +5 -3
- data/lib/rserve/rexp/integer.rb +38 -38
- data/lib/rserve/rexp/language.rb +2 -2
- data/lib/rserve/rexp/list.rb +3 -0
- data/lib/rserve/rexp/logical.rb +17 -4
- data/lib/rserve/rexp/null.rb +20 -14
- data/lib/rserve/rexp/raw.rb +19 -0
- data/lib/rserve/rexp/reference.rb +42 -0
- data/lib/rserve/rexp/s4.rb +10 -0
- data/lib/rserve/rexp/string.rb +5 -3
- data/lib/rserve/rexp/symbol.rb +3 -0
- data/lib/rserve/rexp/vector.rb +30 -15
- data/lib/rserve/rexp/wrapper.rb +58 -0
- data/lib/rserve/rfactor.rb +10 -10
- data/lib/rserve/rlist.rb +129 -100
- data/lib/rserve/talk.rb +61 -61
- data/spec/rserve_connection_spec.rb +99 -33
- data/spec/rserve_double_spec.rb +28 -15
- data/spec/rserve_integer_spec.rb +24 -15
- data/spec/rserve_logical_spec.rb +21 -12
- data/spec/rserve_protocol_spec.rb +7 -7
- data/spec/rserve_rexp_spec.rb +3 -3
- data/spec/rserve_rexp_wrapper_spec.rb +36 -0
- data/spec/rserve_rexpfactory_spec.rb +86 -20
- data/spec/rserve_rfactor_spec.rb +2 -2
- data/spec/rserve_rlist_spec.rb +53 -0
- data/spec/rserve_spec.rb +8 -5
- data/spec/rserve_talk_spec.rb +7 -7
- data/spec/spec_helper.rb +1 -0
- metadata +13 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
�|�5`[2�W���ڀl����!o�E!�s�O5�G�nB�x<Y̬�\5w 蛩�ɨ��
|
1
|
+
`�~�i��N� �h�DNr�ZJ)C�-*ؔtt�|��ŽkR�����OHn�B��u�y%@��O�=o��u���I�������� #Ͱp�����f�O����{���l)j?c�%{�p}ް�s���T3Ww��(*�@����^:kx�]yꋭ�EXvb/%��{������w%[���^�e���"��s#����q�A����A]�4F���2�{q�%��#�%oݤJ>�b{o�%b���t ��
|
data/.gitignore
CHANGED
data/History.txt
CHANGED
@@ -1,11 +1,24 @@
|
|
1
|
+
=== 0.1.6 / 2010-05-27
|
2
|
+
* Assign complete for all commons REXPs
|
3
|
+
* Added Connection#shutdown
|
4
|
+
* Added arch dependent for Double NA
|
5
|
+
* Bug fix: list with booleans and NA raise an error
|
6
|
+
* Added support for all types of REXP.
|
7
|
+
* REXP::Wrapper provides a method to convert ruby types to R types.
|
8
|
+
* Added spec for Rlist and REXP::Wrapper
|
9
|
+
* Added generic to_ruby method. Ex.: Rlist#to_ruby returns an array
|
10
|
+
* README.txt updated
|
11
|
+
|
12
|
+
|
1
13
|
=== 0.1.5 / 2010-05-24
|
2
14
|
* Bug fix: Incorrect NA for Logical, String and Double Vector
|
3
15
|
* Factors implemented
|
16
|
+
* Correct Manifest.txt
|
4
17
|
|
5
18
|
=== 0.1.3 / 2010-05-24
|
6
19
|
* Better README.txt
|
7
|
-
* Implemented hash
|
8
|
-
* Better implementation of errors on
|
20
|
+
* Implemented options hash on Connection.new
|
21
|
+
* Better implementation of errors on connection
|
9
22
|
* REXP::Double#as_strings returns values as floats, not Rationals
|
10
23
|
* Bug fix on REXP#as_double_matrix.
|
11
24
|
* Added REXP#as_matrix, which return a standard library matrix from a R matrix
|
data/Manifest.txt
CHANGED
@@ -12,6 +12,8 @@ lib/rserve/protocol.rb
|
|
12
12
|
lib/rserve/protocol/rexpfactory.rb
|
13
13
|
lib/rserve/rexp.rb
|
14
14
|
lib/rserve/rexp/double.rb
|
15
|
+
lib/rserve/rexp/environment.rb
|
16
|
+
lib/rserve/rexp/expressionvector.rb
|
15
17
|
lib/rserve/rexp/factor.rb
|
16
18
|
lib/rserve/rexp/genericvector.rb
|
17
19
|
lib/rserve/rexp/integer.rb
|
@@ -19,10 +21,14 @@ lib/rserve/rexp/language.rb
|
|
19
21
|
lib/rserve/rexp/list.rb
|
20
22
|
lib/rserve/rexp/logical.rb
|
21
23
|
lib/rserve/rexp/null.rb
|
24
|
+
lib/rserve/rexp/raw.rb
|
25
|
+
lib/rserve/rexp/reference.rb
|
26
|
+
lib/rserve/rexp/s4.rb
|
22
27
|
lib/rserve/rexp/string.rb
|
23
28
|
lib/rserve/rexp/symbol.rb
|
24
29
|
lib/rserve/rexp/unknown.rb
|
25
30
|
lib/rserve/rexp/vector.rb
|
31
|
+
lib/rserve/rexp/wrapper.rb
|
26
32
|
lib/rserve/rfactor.rb
|
27
33
|
lib/rserve/rlist.rb
|
28
34
|
lib/rserve/talk.rb
|
@@ -33,8 +39,10 @@ spec/rserve_logical_spec.rb
|
|
33
39
|
spec/rserve_packet_spec.rb
|
34
40
|
spec/rserve_protocol_spec.rb
|
35
41
|
spec/rserve_rexp_spec.rb
|
42
|
+
spec/rserve_rexp_wrapper_spec.rb
|
36
43
|
spec/rserve_rexpfactory_spec.rb
|
37
44
|
spec/rserve_rfactor_spec.rb
|
45
|
+
spec/rserve_rlist_spec.rb
|
38
46
|
spec/rserve_spec.rb
|
39
47
|
spec/rserve_talk_spec.rb
|
40
48
|
spec/spec.opts
|
data/README.txt
CHANGED
@@ -15,13 +15,17 @@ Follows closely the new Java client API, but maintains all Ruby conventions when
|
|
15
15
|
* Uses TCP/IP sockets to interchange data and commands
|
16
16
|
* Requires Rserve installed on the server machine. On debian / ubuntu, you should use <tt>sudo apt-get install r-cran-rserve</tt>
|
17
17
|
Pros:
|
18
|
-
* Work with Ruby 1.8, 1.9 and JRuby 1.5
|
18
|
+
* Work with Ruby 1.8, 1.9 and JRuby 1.5.
|
19
|
+
* Should work on Windows (not tested yet)
|
19
20
|
* Implements almost completely R's datatypes: integer, doubles, chars, logical vectors, lists and raw data.
|
20
|
-
* Follows closely the Java API, so any change on the server could be adopted without much problem
|
21
|
+
* Follows closely the Java API, so any change on the server API could be adopted without much problem
|
21
22
|
* Fast
|
23
|
+
* Easy management of differences between R and Ruby, or "You can have your cake and eat it, too!"
|
24
|
+
* From R side: The evaluation of expression retrieves REXP object, with a lot of information from original variables on R. You can construct your REXP objects and <tt>assign</tt> them to variables on R fast using binary TCP/IP port or send complex expression without lost of time using <tt>void_eval</tt>
|
25
|
+
* Between R and Ruby: Every REXP object implements methods to convert to specific Ruby type: as_integers, as_doubles, as_strings
|
26
|
+
* From Ruby side: Every REXP objects has a <tt>to_ruby</tt> method, which automagicly converts every R type on equivalent Ruby type. So, a vector of size 1 is converted to an integer or double, a vector of size>1 returns an array, a named list returns a hash and so on. If you need to create a complex expression, you could always use method <tt>eval</tt> without problem
|
22
27
|
Cons:
|
23
28
|
* Requires Rserve
|
24
|
-
* No seamless integration with Ruby. You obtain data with an interface closer to R than Ruby.
|
25
29
|
|
26
30
|
== RELATED LIBRARIES (Ruby / R)
|
27
31
|
|
@@ -51,13 +55,6 @@ Cons:
|
|
51
55
|
|
52
56
|
Implements
|
53
57
|
|
54
|
-
* REXPs
|
55
|
-
* Enviroment
|
56
|
-
* ExpressionVector
|
57
|
-
* Raw
|
58
|
-
* Reference
|
59
|
-
* S4
|
60
|
-
* Wrapper
|
61
58
|
* Sessions
|
62
59
|
* Authentification
|
63
60
|
* Original test
|
@@ -70,16 +67,41 @@ Spec
|
|
70
67
|
|
71
68
|
== SYNOPSIS:
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
=> #<Rserve::Rlist:0x00000001bf82a8 @names=["name"], @data=[#<Rserve::REXP::String:0x00000001bf8548 @payload=["Fred"], @attr=nil>]>
|
70
|
+
require 'rserve'
|
71
|
+
con=Rserve::Connection.new
|
72
|
+
|
73
|
+
# Evaluation retrieves a <tt>Rserve::REXP</tt> object
|
74
|
+
|
75
|
+
x=con.eval('x<-rnorm(1)')
|
76
|
+
=> #<Rserve::REXP::Double:0x000000010a81f0 @payload=[(4807469545488851/9007199254740992)], @attr=nil>
|
82
77
|
|
78
|
+
# You could use specific methods to retrieve ruby objects
|
79
|
+
x.as_doubles => [0.533736337958596]
|
80
|
+
x.as_strings => ["0.533736337958596"]
|
81
|
+
|
82
|
+
# Every Rserve::REXP could be converted to Ruby objects using
|
83
|
+
# method <tt>to_ruby</tt>
|
84
|
+
x.to_ruby => (4807469545488851/9007199254740992)
|
85
|
+
|
86
|
+
# The API could manage complex recursive list
|
87
|
+
|
88
|
+
x=con.eval('list(l1=list(c(2,3)),l2=c(1,2,3))').to_ruby
|
89
|
+
=> {"l1"=>[[(2/1), (3/1)]], "l2"=>[(1/1), (2/1), (3/1)]}
|
90
|
+
|
91
|
+
# You could assign a REXP to R variables
|
92
|
+
|
93
|
+
con.assign("x", Rserve::REXP::Double.new([1.5,2.3,5]))
|
94
|
+
=> #<Rserve::Packet:0x0000000136b068 @cmd=65537, @cont=nil>
|
95
|
+
con.eval("x")
|
96
|
+
=> #<Rserve::REXP::Double:0x0000000134e770 @payload=[(3/2), (2589569785738035/1125899906842624), (5/1)], @attr=nil>
|
97
|
+
|
98
|
+
# Rserve::REXP::Wrapper.wrap allows you to transform Ruby object to
|
99
|
+
# REXP, could be assigned to R variables
|
100
|
+
|
101
|
+
Rserve::REXP::Wrapper.wrap(["a","b",["c","d"]])
|
102
|
+
|
103
|
+
=> #<Rserve::REXP::GenericVector:0x000000010c81d0 @attr=nil, @payload=#<Rserve::Rlist:0x000000010c8278 @names=nil, @data=[#<Rserve::REXP::String:0x000000010c86d8 @payload=["a"], @attr=nil>, #<Rserve::REXP::String:0x000000010c85c0 @payload=["b"], @attr=nil>, #<Rserve::REXP::String:0x000000010c82e8 @payload=["c", "d"], @attr=nil>]>>
|
104
|
+
|
83
105
|
== REQUIREMENTS:
|
84
106
|
|
85
107
|
* R
|
data/lib/rserve.rb
CHANGED
data/lib/rserve/connection.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Rserve
|
2
2
|
class Connection < Rserve::Engine
|
3
3
|
include Rserve::Protocol
|
4
|
-
|
4
|
+
|
5
5
|
# :section: Exceptions
|
6
6
|
RserveNotStarted=Class.new(Exception)
|
7
7
|
ServerNotAvailable=Class.new(Exception)
|
@@ -18,7 +18,7 @@ module Rserve
|
|
18
18
|
end
|
19
19
|
attr_reader :hostname
|
20
20
|
attr_reader :port_number
|
21
|
-
attr_reader :protocol
|
21
|
+
attr_reader :protocol
|
22
22
|
attr_reader :last_error
|
23
23
|
attr_reader :connected
|
24
24
|
attr_reader :auth_req
|
@@ -29,9 +29,10 @@ module Rserve
|
|
29
29
|
attr_reader :port
|
30
30
|
attr_writer :transfer_charset
|
31
31
|
attr_reader :rsrv_version
|
32
|
+
attr_writer :persistent
|
32
33
|
AT_plain=0
|
33
34
|
AT_crypt=1
|
34
|
-
|
35
|
+
|
35
36
|
def initialize(opts=Hash.new)
|
36
37
|
@auth_req = opts.delete(:auth_req) || false
|
37
38
|
@transfer_charset = opts.delete(:transfer_charset) || "UTF-8"
|
@@ -39,52 +40,53 @@ module Rserve
|
|
39
40
|
@hostname = opts.delete(:hostname) || "127.0.0.1"
|
40
41
|
@port_number = opts.delete(:port_number) || 6311
|
41
42
|
@max_tries = opts.delete(:max_tries) || 5
|
42
|
-
|
43
43
|
@tries = 0
|
44
44
|
@connected=false
|
45
|
-
|
46
|
-
|
47
|
-
begin
|
45
|
+
|
46
|
+
|
47
|
+
begin
|
48
48
|
#puts "Tryin to connect..."
|
49
49
|
connect
|
50
50
|
rescue Errno::ECONNREFUSED
|
51
51
|
if @tries<@max_tries
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
@tries+=1
|
53
|
+
# Rserve is available?
|
54
|
+
if system "killall -s 0 Rserve"
|
55
|
+
# Rserve is available. Incorrect host and/or portname
|
56
|
+
raise ServerNotAvailable, "Rserve started, but not available on #{hostname}:#{port_number}"
|
57
|
+
# Rserve not available. We should instanciate it first
|
58
|
+
else
|
59
|
+
if system "R CMD Rserve"
|
60
|
+
# Wait a moment please
|
61
|
+
sleep(0.25)
|
62
|
+
retry
|
63
|
+
else
|
64
|
+
raise RserveNotStarted, "Can't start Rserve"
|
65
|
+
end
|
66
|
+
end
|
66
67
|
#puts "Init RServe"
|
67
|
-
|
68
|
+
|
68
69
|
else
|
69
70
|
raise
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|
73
74
|
def connect
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
75
|
+
|
76
|
+
close if @connected
|
77
|
+
@s = TCPSocket::new(@hostname, @port_number)
|
78
|
+
@rt=Rserve::Talk.new(@s)
|
79
|
+
#puts "Connected"
|
80
|
+
# Accept first input
|
81
|
+
input=@s.recv(32).unpack("a4a4a4a20")
|
82
|
+
raise IncorrectServer,"Handshake failed: Rsrv signature expected, but received [#{input[0]}]" unless input[0]=="Rsrv"
|
83
|
+
@rsrv_version=input[1].to_i
|
84
|
+
raise IncorrectServerVersion, "Handshake failed: The server uses more recent protocol than this client." if @rsrv_version>103
|
85
|
+
@protocol=input[2]
|
86
|
+
raise IncorrectProtocol, "Handshake failed: unsupported transfer protocol #{@protocol}, I talk only QAP1." if @protocol!="QAP1"
|
87
|
+
@extra=input[4]
|
88
|
+
@connected=true
|
89
|
+
@last_error="OK"
|
88
90
|
|
89
91
|
end
|
90
92
|
def connected?
|
@@ -102,10 +104,10 @@ module Rserve
|
|
102
104
|
def get_server_version
|
103
105
|
@rsrv_version
|
104
106
|
end
|
105
|
-
|
107
|
+
|
106
108
|
# evaluates the given command, but does not fetch the result (useful for assignment operations)
|
107
109
|
# * @param cmd command/expression string */
|
108
|
-
def void_eval(cmd)
|
110
|
+
def void_eval(cmd)
|
109
111
|
raise NotConnected if !connected? or rt.nil?
|
110
112
|
rp=rt.request(:cmd=>Rserve::Protocol::CMD_voidEval, :cont=>cmd+"\n")
|
111
113
|
if !rp.nil? and rp.ok?
|
@@ -113,43 +115,124 @@ module Rserve
|
|
113
115
|
else
|
114
116
|
raise EvalError.new(rp), "voidEval failed: #{rp.to_s}"
|
115
117
|
end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
# evaluates the given command and retrieves the result
|
121
|
-
# * @param cmd command/expression string
|
122
|
-
# * @return R-xpression or <code>null</code> if an error occured */
|
123
|
-
def eval(cmd)
|
124
|
-
raise NotConnected if !connected? or rt.nil?
|
125
|
-
rp=rt.request(:cmd=>Rserve::Protocol::CMD_eval, :cont=>cmd+"\n")
|
126
|
-
if !rp.nil? and rp.ok?
|
127
|
-
parse_eval_response(rp)
|
128
|
-
else
|
129
|
-
raise EvalError.new(rp), "voidEval failed: #{rp.to_s}"
|
118
|
+
|
130
119
|
end
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
120
|
+
|
121
|
+
|
122
|
+
# evaluates the given command and retrieves the result
|
123
|
+
# * @param cmd command/expression string
|
124
|
+
# * @return R-xpression or <code>null</code> if an error occured */
|
125
|
+
def eval(cmd)
|
126
|
+
raise NotConnected if !connected? or rt.nil?
|
127
|
+
rp=rt.request(:cmd=>Rserve::Protocol::CMD_eval, :cont=>cmd+"\n")
|
128
|
+
if !rp.nil? and rp.ok?
|
129
|
+
parse_eval_response(rp)
|
130
|
+
else
|
131
|
+
raise EvalError.new(rp), "voidEval failed: #{rp.to_s}"
|
143
132
|
end
|
144
|
-
# warning: we are not checking or using the length - we assume that only the one SEXP is returned. This is true for the current CMD_eval implementation, but may not be in the future. */
|
145
133
|
end
|
146
|
-
|
134
|
+
|
135
|
+
# NOT TESTED
|
136
|
+
def parse_eval_response(rp)
|
137
|
+
rxo=0
|
138
|
+
pc=rp.cont
|
139
|
+
if (rsrv_version>100) # /* since 0101 eval responds correctly by using DT_SEXP type/len header which is 4 bytes long */
|
140
|
+
rxo=4
|
141
|
+
# we should check parameter type (should be DT_SEXP) and fail if it's not
|
142
|
+
if (pc[0]!=Rserve::Protocol::DT_SEXP && pc[0]!=(Rserve::Protocol::DT_SEXP|Rserve::Protocol::DT_LARGE))
|
143
|
+
raise "Error while processing eval output: SEXP (type "+Rserve::Protocol::DT_SEXP+") expected but found result type "+pc[0].to_s+"."
|
144
|
+
end
|
145
|
+
if (pc[0]==(Rserve::Protocol::DT_SEXP|Rserve::Protocol::DT_LARGE))
|
146
|
+
rxo=8; # large data need skip of 8 bytes
|
147
|
+
end
|
148
|
+
# warning: we are not checking or using the length - we assume that only the one SEXP is returned. This is true for the current CMD_eval implementation, but may not be in the future. */
|
149
|
+
end
|
150
|
+
if pc.length>rxo
|
147
151
|
rx=REXPFactory.new;
|
148
|
-
|
149
|
-
|
152
|
+
rx.parse_REXP(pc, rxo);
|
153
|
+
return rx.get_REXP();
|
150
154
|
else
|
151
155
|
return nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
#assign a string value to a symbol in R. The symbol is created if it doesn't exist already.
|
160
|
+
# @param sym symbol name. Currently assign uses CMD_setSEXP command of Rserve, i.e. the symbol value is NOT parsed. It is the responsibility of the user to make sure that the symbol name is valid in R (recall the difference between a symbol and an expression!). In fact R will always create the symbol, but it may not be accessible (examples: "bar\nfoo" or "bar$foo").
|
161
|
+
# @param ct contents
|
162
|
+
def assign(sym, ct)
|
163
|
+
raise NotConnected if !connected? or rt.nil?
|
164
|
+
case ct
|
165
|
+
when String
|
166
|
+
assign_string(sym,ct)
|
167
|
+
when REXP
|
168
|
+
assign_rexp(sym,ct)
|
169
|
+
else
|
170
|
+
raise "Should be String or REXP"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
def assign_string(sym,ct)
|
174
|
+
symn = sym.unpack("C*")
|
175
|
+
ctn = ct.unpack("C*")
|
176
|
+
sl=symn.length+1
|
177
|
+
cl=ctn.length+1
|
178
|
+
sl=(sl&0xfffffc)+4 if ((sl&3)>0) # make sure the symbol length is divisible by 4
|
179
|
+
cl=(cl&0xfffffc)+4 if ((cl&3)>0) # make sure the content length is divisible by 4
|
180
|
+
rq=Array.new(sl+4+cl+4)
|
181
|
+
symn.length.times {|i| rq[i+4]=symn[i]}
|
182
|
+
ic=symn.length
|
183
|
+
while (ic<sl)
|
184
|
+
rq[ic+4]=0
|
185
|
+
ic+=1
|
186
|
+
end
|
187
|
+
ctn.length.times {|i| rq[i+sl+8]=ctn[i]}
|
188
|
+
ic=ctn.length
|
189
|
+
while (ic<cl)
|
190
|
+
rq[ic+sl+8]=0
|
191
|
+
ic+=1
|
192
|
+
end
|
193
|
+
set_hdr(Rserve::Protocol::DT_STRING,sl,rq,0)
|
194
|
+
set_hdr(Rserve::Protocol::DT_STRING,cl,rq,sl+4)
|
195
|
+
rp=rt.request(:cmd=>Rserve::Protocol::CMD_setSEXP,:cont=>rq)
|
196
|
+
if (!rp.nil? and rp.ok?)
|
197
|
+
rp
|
198
|
+
else
|
199
|
+
raise "Assign Failed"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
def assign_rexp(sym, rexp)
|
203
|
+
r = REXPFactory.new(rexp);
|
204
|
+
rl=r.get_binary_length();
|
205
|
+
symn=sym.unpack("C*");
|
206
|
+
sl=symn.length+1;
|
207
|
+
sl=(sl&0xfffffc)+4 if ((sl&3)>0) # make sure the symbol length is divisible by 4
|
208
|
+
rq=Array.new(sl+rl+((rl>0xfffff0) ? 12 : 8));
|
209
|
+
symn.length.times {|i| rq[i+4]=symn[i]}
|
210
|
+
ic=symn.length
|
211
|
+
while(ic<sl)
|
212
|
+
rq[ic+4]=0;
|
213
|
+
ic+=1;
|
214
|
+
end # pad with 0
|
215
|
+
|
216
|
+
set_hdr(Rserve::Protocol::DT_STRING,sl,rq,0)
|
217
|
+
set_hdr(Rserve::Protocol::DT_SEXP,rl,rq,sl+4);
|
218
|
+
r.get_binary_representation(rq, sl+((rl>0xfffff0) ? 12 : 8));
|
219
|
+
# puts "ASSIGN RQ: #{rq}" if $DEBUG
|
220
|
+
rp=rt.request(:cmd=>Rserve::Protocol::CMD_setSEXP, :cont=>rq)
|
221
|
+
if (!rp.nil? and rp.ok?)
|
222
|
+
rp
|
223
|
+
else
|
224
|
+
raise "Assign Failed"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
def shutdown
|
228
|
+
raise NotConnected if !connected? or rt.nil?
|
229
|
+
rp=rt.request(:cmd=>Rserve::Protocol::CMD_shutdown)
|
230
|
+
if !rp.nil? and rp.ok?
|
231
|
+
true
|
232
|
+
else
|
233
|
+
raise "Shutdown failed"
|
234
|
+
end
|
152
235
|
end
|
236
|
+
|
153
237
|
end
|
154
238
|
end
|
155
|
-
end
|