rserve-client 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|