Class: Rserve::Talk
Overview
Class which ‘talk’ to the server.
I separated the ‘abstract’ aspect of the protocol on Protocol module, for better testing
Constant Summary
Constants included from Protocol
Protocol::CMD_RESP, Protocol::CMD_SPECIAL_MASK, Protocol::CMD_assignSEXP, Protocol::CMD_attachSession, Protocol::CMD_closeFile, Protocol::CMD_createFile, Protocol::CMD_ctrl, Protocol::CMD_ctrlEval, Protocol::CMD_ctrlShutdown, Protocol::CMD_ctrlSource, Protocol::CMD_detachSession, Protocol::CMD_detachedVoidEval, Protocol::CMD_eval, Protocol::CMD_login, Protocol::CMD_openFile, Protocol::CMD_readFile, Protocol::CMD_removeFile, Protocol::CMD_serAssign, Protocol::CMD_serEEval, Protocol::CMD_serEval, Protocol::CMD_setBufferSize, Protocol::CMD_setEncoding, Protocol::CMD_setSEXP, Protocol::CMD_shutdown, Protocol::CMD_voidEval, Protocol::CMD_writeFile, Protocol::DT_ARRAY, Protocol::DT_BYTESTREAM, Protocol::DT_CHAR, Protocol::DT_DOUBLE, Protocol::DT_INT, Protocol::DT_LARGE, Protocol::DT_SEXP, Protocol::DT_STRING, Protocol::ERROR_DESCRIPTIONS, Protocol::ERR_IOerror, Protocol::ERR_Rerror, Protocol::ERR_accessDenied, Protocol::ERR_auth_failed, Protocol::ERR_conn_broken, Protocol::ERR_ctrl_closed, Protocol::ERR_data_overflow, Protocol::ERR_detach_failed, Protocol::ERR_inv_cmd, Protocol::ERR_inv_par, Protocol::ERR_notOpen, Protocol::ERR_object_too_big, Protocol::ERR_out_of_mem, Protocol::ERR_session_busy, Protocol::ERR_unknownCmd, Protocol::ERR_unsupportedCmd, Protocol::MAX_LONG_SIGNED, Protocol::MAX_LONG_UNSIGNED, Protocol::RESP_ERR, Protocol::RESP_OK
Instance Attribute Summary collapse
-
#io ⇒ Object
readonly
Returns the value of attribute io.
Instance Method Summary collapse
-
#initialize(io) ⇒ Talk
constructor
A new instance of Talk.
-
#request(params = Hash.new) ⇒ Object
sends a request with attached prefix and parameters.
- #request_int(par) ⇒ Object
- #request_string(s) ⇒ Object
Methods included from Protocol
#doubleToRawLongBits, #get_int, #get_int_original, #get_len, #get_long, #get_long_original, #longBitsToDouble, #longBitsToDouble_old, #new_hdr, #set_hdr, #set_int, #set_long
Constructor Details
#initialize(io) ⇒ Talk
Returns a new instance of Talk.
10 11 12 |
# File 'lib/rserve/talk.rb', line 10 def initialize(io) @io=io end |
Instance Attribute Details
#io ⇒ Object (readonly)
Returns the value of attribute io.
9 10 11 |
# File 'lib/rserve/talk.rb', line 9 def io @io end |
Instance Method Details
#request(params = Hash.new) ⇒ Object
sends a request with attached prefix and parameters. All parameters should be enter on Hash Both :prefix and :cont can be nil
. Effectively request(:cmd=>a,:prefix=>b,:cont=>nil)
and request(:cmd=>a,:prefix=>nil,:cont=>b)
are equivalent.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/rserve/talk.rb', line 22 def request(params=Hash.new) cmd = params.delete :cmd prefix = params.delete :prefix cont = params.delete :cont offset = params.delete :offset len = params.delete :len if cont.is_a? String cont=request_string(cont) elsif cont.is_a? Integer cont=request_int(cont) end raise ArgumentError, ":cont should be an Enumerable" if !cont.nil? and !cont.is_a? Enumerable if len.nil? len=(cont.nil?) ? 0 : cont.length end offset||=0 if (!cont.nil?) raise ":cont shouldn't contain anything but Fixnum" if cont.any? {|v| !v.is_a? Fixnum} if (offset>=cont.length) cont=nil;len=0 elsif (len>cont.length-offset) len=cont.length-offset end end offset=0 if offset<0 len=0 if len<0 contlen=(cont.nil?) ? 0 : len contlen+=prefix.length if (!prefix.nil? and prefix.length>0) hdr=Array.new(16) set_int(cmd,hdr,0) set_int(contlen,hdr,4); 8.upto(15) {|i| hdr[i]=0} if (cmd!=-1) io.write(hdr.pack("C*")) if (!prefix.nil? && prefix.length>0) io.write(prefix.pack("C*")) puts "SEND PREFIX #{prefix}" if $DEBUG end if (!cont.nil? and cont.length>0) puts "SEND CONTENT #{cont.slice(offset, len)} (#{offset},#{len})" if $DEBUG io.write(cont.slice(offset, len).pack("C*")) end end puts "Expecting 16 bytes..." if $DEBUG ih=io.recv(16).unpack("C*") return nil if (ih.length!=16) puts "Answer: #{ih.to_s}" if $DEBUG rep=get_int(ih,0); rl =get_int(ih,4); if $DEBUG puts "rep: #{rep} #{rep.class} #{rep & 0x00FFFFFF}" puts "rl: #{rl} #{rl.class}" end if (rl>0) ct=Array.new(); n=0; while (n<rl) do data=io.recv(rl-n).unpack("C*") ct+=data rd=data.length n+=rd; end return Packet.new(rep,ct); end return Packet.new(rep,nil); end |
#request_int(par) ⇒ Object
115 116 117 118 119 120 |
# File 'lib/rserve/talk.rb', line 115 def request_int(par) rq=Array.new(8) set_int(par,rq,4) set_hdr(DT_INT,4,rq,0) rq end |
#request_string(s) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/rserve/talk.rb', line 102 def request_string(s) b=s.unpack("C*") sl=b.length+1; sl=(sl&0xfffffc)+4 if ((sl&3)>0) # make sure the length is divisible by 4 rq=Array.new(sl+5) b.length.times {|i| rq[i+4]=b[i]} ((b.length)..sl).each {|i| rq[i+4]=0 } set_hdr(DT_STRING,sl,rq,0) rq end |