Module: Rserve::Protocol
- Included in:
- Connection, REXPFactory, Session, Talk
- Defined in:
- lib/rserve/protocol.rb,
lib/rserve/protocol/rexpfactory.rb
Overview
This module encapsulates methods and constants related to QAP1 protocol used by Rserv. Follows almost exactly the interface on RTalk class on Java version, except for use of undescores instead of CamelCase Implementation could differ if a cleaner/faster ruby version is available
Policy: No other class should know about the internal of protocol! See Rtalk class on Java version.
Defined Under Namespace
Classes: REXPFactory
Constant Summary collapse
- CMD_RESP =
Defines from Rsrv.h
0x010000
- RESP_OK =
all responses have this flag set
(CMD_RESP|0x0001)
- RESP_ERR =
command failed, check stats code attached string may describe the error
(CMD_RESP|0x0002)
- ERR_auth_failed =
auth.failed or auth.requested but no login came. in case of authentification failure due to name/pwd mismatch, server may send CMD_accessDenied instead
0x41
- ERR_conn_broken =
connection closed or broken packet killed it */
0x42
- ERR_inv_cmd =
unsupported/invalid command */
0x43
- ERR_inv_par =
some parameters are invalid */
0x44
- ERR_Rerror =
R-error occured, usually followed by connection shutdown */
0x45
- ERR_IOerror =
I/O error */
0x46
- ERR_notOpen =
attempt to perform fileRead/Write on closed file */
0x47
- ERR_accessDenied =
this answer is also valid on CMD_login; otherwise it’s sent if the server deosn;t allow the user to issue the specified command. (e.g. some server admins may block file I/O operations for some users)
0x48
- ERR_unsupportedCmd =
unsupported command */
0x49
- ERR_unknownCmd =
unknown command - the difference between unsupported and unknown is that unsupported commands are known to the server but for some reasons (e.g. platform dependent) it’s not supported. unknown commands are simply not recognized by the server at all. */
0x4a
- ERR_data_overflow =
incoming packet is too big. currently there is a limit as of the size of an incoming packet. */
0x4b
- ERR_object_too_big =
the requested object is too big to be transported in that way. If received after CMD_eval then the evaluation itself was successful. optional parameter is the size of the object
0x4c
- ERR_out_of_mem =
out of memory. the connection is usually closed after this error was sent
0x4d
- ERR_ctrl_closed =
control pipe to the master process is closed or broken
0x4e
- ERR_session_busy =
session is still busy */
0x50
- ERR_detach_failed =
unable to detach session (cannot determine peer IP or problems creating a listening socket for resume) */
0x51
- CMD_login =
“namenpwd” : - */
0x001
- CMD_voidEval =
string : - */
0x002
- CMD_eval =
string : encoded SEXP */
0x003
- CMD_shutdown =
- admin-pwd
-
: - */
0x004
- CMD_openFile =
/* file I/O routines. server may answe */
0x010
- CMD_createFile =
fn : - */
0x011
- CMD_closeFile =
fn : - */
0x012
- CMD_readFile =
-
: - */
-
0x013
- CMD_writeFile =
server is free to choose any value - usually it uses the size of its static buffer */
0x014
- CMD_removeFile =
data : - */
0x015
- CMD_setSEXP =
/* object manipulation */
0x020
- CMD_assignSEXP =
string(name), REXP : - */
0x021
- CMD_detachSession =
/* session management (since 0.4-0) */
0x030
- CMD_detachedVoidEval =
: session key */
0x031
- CMD_attachSession =
string : session key; doesn’t */
0x032
- CMD_ctrl =
control commands (since 0.6-0) - passed on to the master process */ Note: currently all control commands are asychronous, i.e. RESP_OK indicates that the command was enqueued in the master pipe, but there is no guarantee that it will be processed. Moreover non-forked connections (e.g. the default debug setup) don’t process any control commands until the current client connection is closed so the connection issuing the control command will never see its result.
0x40
- CMD_ctrlEval =
– not a command - just a constant – */
0x42
- CMD_ctrlSource =
string : - */
0x45
- CMD_ctrlShutdown =
string : - */
0x44
- CMD_setBufferSize =
/* ‘internal’ commands (since 0.1-9) */
0x081
- CMD_setEncoding =
- int sendBufSize
-
this commad allow clients to request bigger buffer sizes if large data is to be transported from Rserve to the client. (incoming buffer is resized automatically) */
0x082
- CMD_SPECIAL_MASK =
/* special commands - the payload of packages with this mask does not contain defined parameters */
0xf0
- CMD_serEval =
serialized eval - the packets are raw serialized data without data header */
0xf5
- CMD_serAssign =
serialized assign - serialized list with [[1]]=name, [[2]]=value */
0xf6
- CMD_serEEval =
serialized expression eval - like serEval with one additional evaluation round */
0xf7
- DT_INT =
data types for the transport protocol (QAP1)do NOT confuse with XT_.. values.
1
- DT_CHAR =
int */
2
- DT_DOUBLE =
char */
3
- DT_STRING =
double */
4
- DT_BYTESTREAM =
0 terminted string */
5
- DT_SEXP =
stream of bytes (unlike DT_STRING may contain 0) */
10
- DT_ARRAY =
encoded SEXP */
11
- DT_LARGE =
array of objects (i.e. first 4 bytes specify how many subsequent objects are part of the array; 0 is legitimate) */
64
- ERROR_DESCRIPTIONS =
new in 0102: if this flag is set then the length of the object is coded as 56-bit integer enlarging the header by 4 bytes */
{ ERR_auth_failed=>'auth.failed or auth.requested but no login came', ERR_conn_broken=>'connection closed or broken packet killed it', ERR_inv_cmd=>"unsupported/invalid command", ERR_inv_par=>"some parameters are invalid", ERR_Rerror=>"R-error", ERR_IOerror=>"I/O error", ERR_notOpen=>"attempt to perform fileRead/Write on closed file", ERR_accessDenied=>"Access denied", ERR_unsupportedCmd=>"unsupported command", ERR_unknownCmd=>"unknown command", ERR_data_overflow=>"data overflow", ERR_object_too_big=>"requested object is too big", ERR_out_of_mem=>"out of memory", ERR_ctrl_closed=>"control pipe to the master process is closed or broken", ERR_session_busy=>"session still busy", ERR_detach_failed=>"unable to detach seesion" }
- MAX_LONG_SIGNED =
I have to use to support different archs
2**31
- MAX_LONG_UNSIGNED =
2**32
Instance Method Summary collapse
- #doubleToRawLongBits(double) ⇒ Object
-
#get_int(buf, o) ⇒ Object
converts bit-wise stored int in Intel-endian form into ruby int.
-
#get_int_original(buf, o) ⇒ Object
:nodoc:.
-
#get_len(buf, o) ⇒ Object
converts bit-wise stored length from a header.
-
#get_long(buf, o) ⇒ Object
converts bit-wise Intel-endian format into long.
-
#get_long_original(buf, o) ⇒ Object
:nodoc:.
- #longBitsToDouble(bits) ⇒ Object
-
#longBitsToDouble_old(bits) ⇒ Object
Complete version of longBitsToDouble, as Java documentation established.
-
#new_hdr(ty, len) ⇒ Object
creates a new header according to the type and length of the parameter.
-
#set_hdr(ty, len, buf, o) ⇒ Object
writes cmd/resp/type byte + 3/7 bytes len into a byte buffer at specified offset.
-
#set_int(v, buf, o) ⇒ Object
writes bit-wise int to a byte buffer at specified position in Intel-endian form Internal: byte buffer will be the result of unpack(“CCCC”) an integer.
- #set_long(l, buf, o) ⇒ Object
Instance Method Details
#doubleToRawLongBits(double) ⇒ Object
223 224 225 |
# File 'lib/rserve/protocol.rb', line 223 def doubleToRawLongBits(double) [double].pack("d").unpack("Q")[0] end |
#get_int(buf, o) ⇒ Object
converts bit-wise stored int in Intel-endian form into ruby int
make sure that the buffer is big enough
172 173 174 |
# File 'lib/rserve/protocol.rb', line 172 def get_int(buf, o) buf[o,4].pack("C*").unpack("l")[0] end |
#get_int_original(buf, o) ⇒ Object
:nodoc:
175 176 177 178 |
# File 'lib/rserve/protocol.rb', line 175 def get_int_original(buf,o) # :nodoc: v=((buf[o]&255)|((buf[o+1]&255)<<8)|((buf[o+2]&255)<<16)|((buf[o+3]&255)<<24)) v >= MAX_LONG_SIGNED ? v-MAX_LONG_UNSIGNED : v end |
#get_len(buf, o) ⇒ Object
converts bit-wise stored length from a header. “long” format is supported up to 32-bit
184 185 186 187 188 189 190 191 192 193 |
# File 'lib/rserve/protocol.rb', line 184 def get_len(buf, o) # // "long" format; still - we support 32-bit only if ((buf[o]&64)>0) #p "buf:#{buf} --- o: #{o} -- [#{buf[o+4]}]" raise "Buffer without enough values" if buf[o+4].nil? (buf[o+1]&255)|((buf[o+2]&255)<<8)|((buf[o+3]&255)<<16)|((buf[o+4]&255)<<24) else (buf[o+1]&255)|((buf[o+2]&255)<<8)|((buf[o+3]&255)<<16) end end |
#get_long(buf, o) ⇒ Object
converts bit-wise Intel-endian format into long
199 200 201 |
# File 'lib/rserve/protocol.rb', line 199 def get_long(buf, o) buf[o,8].pack("CCCCCCCC").unpack("Q")[0] end |
#get_long_original(buf, o) ⇒ Object
:nodoc:
202 203 204 205 206 207 |
# File 'lib/rserve/protocol.rb', line 202 def get_long_original(buf,o) #:nodoc: low=(get_int(buf,o))&0xffffffff; hi=(get_int(buf,o+4))&0xffffffff; hi<<=32; hi|=low; hi end |
#longBitsToDouble(bits) ⇒ Object
209 210 211 |
# File 'lib/rserve/protocol.rb', line 209 def longBitsToDouble(bits) (bits==LONG_NA) ? Rserve::REXP::Double::NA : [bits].pack("Q").unpack("d")[0] end |
#longBitsToDouble_old(bits) ⇒ Object
Complete version of longBitsToDouble, as Java documentation established
214 215 216 217 218 219 220 221 |
# File 'lib/rserve/protocol.rb', line 214 def longBitsToDouble_old(bits) # :nodoc: s = ((bits >> 63) == 0) ? 1 : -1; e = ((bits >> 52) & 0x7ff) m = (e == 0) ? (bits & 0xfffffffffffff) << 1 : (bits & 0xfffffffffffff) | 0x10000000000000; s*m*2**(e-1075) end |
#new_hdr(ty, len) ⇒ Object
creates a new header according to the type and length of the parameter
159 160 161 162 163 |
# File 'lib/rserve/protocol.rb', line 159 def new_hdr(ty, len) hdr=Array.new( (len>0xfffff0)?8:4) set_hdr(ty,len,hdr,0); hdr end |
#set_hdr(ty, len, buf, o) ⇒ Object
writes cmd/resp/type byte + 3/7 bytes len into a byte buffer at specified offset.
143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/rserve/protocol.rb', line 143 def set_hdr(ty, len, buf, o) buf[o]=((ty&255)|((len>0xfffff0) ? DT_LARGE : 0)); o+=1; buf[o]=(len&255); o+=1; buf[o]=((len&0xff00)>>8); o+=1; buf[o]=((len&0xff0000)>>16); o+=1; if (len>0xfffff0) # for large data we need to set the next 4 bytes as well buf[o]=((len&0xff000000)>>24); o+=1; buf[o]=0; o+=1; # since len is int, we get 32-bits only buf[o]=0; o+=1; buf[o]=0; o+=1; end o end |
#set_int(v, buf, o) ⇒ Object
writes bit-wise int to a byte buffer at specified position in Intel-endian form Internal: byte buffer will be the result of unpack(“CCCC”) an integer.
130 131 132 133 134 135 |
# File 'lib/rserve/protocol.rb', line 130 def set_int(v, buf, o) buf[o]=(v&255);o+=1 buf[o]=((v&0xff00)>>8); o+=1 buf[o]=((v&0xff0000)>>16); o+=1 buf[o]=((v&0xff000000)>>24); end |
#set_long(l, buf, o) ⇒ Object
226 227 228 229 |
# File 'lib/rserve/protocol.rb', line 226 def set_long(l, buf, o) set_int((l&0xffffffff), buf, o) set_int((l>>32),buf,o+4) end |