Skip to content

Instantly share code, notes, and snippets.

@lujiacn
Created March 14, 2015 13:25
Show Gist options
  • Save lujiacn/fc85f00505d8a0ed3f5b to your computer and use it in GitHub Desktop.
Save lujiacn/fc85f00505d8a0ed3f5b to your computer and use it in GitHub Desktop.
/*Rserve go client */
package rservcli
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"net"
"strings"
)
/*
return mkint32($cmd) . mkint32($n + 4) . mkint32(0) . mkint32(0) . chr(4) . mkint24($n) . $string;
*/
type Qhdr struct {
Cmd int32 /* command */
Len int32 /* length of the packet minus header (ergo -16) */
MsgId int32 /* message id (since 1.8) [WAS:data offset behind header (ergo usually 0)] */
Res int32 /* high 32-bit of the packet length (since 0103
and supported on 64-bit platforms only)
aka "lenhi", but the name was not changed to
maintain compatibility */
}
func NewQhdr(cmd int32, data string) *Qhdr {
head := new(Qhdr)
head.Cmd = cmd
head.Len = int32(len(data) + 4)
return head
}
//MkpStr
func MakeBytes(cmd int32, data string) []byte {
data = strings.Replace(data, "\r", "\n", -1)
buff := new(bytes.Buffer)
header := NewQhdr(cmd, data)
binary.Write(buff, binary.LittleEndian, header) //eval
binary.Write(buff, binary.LittleEndian, int8(4))
binary.Write(buff, binary.LittleEndian, int32(len(data)))
buff.Truncate(len(buff.Bytes()) - 1) // truncate 36bit int to 24 bit int -- 3 bytes
// data string
binary.Write(buff, binary.LittleEndian, []byte(data))
return buff.Bytes()
}
func RInit() (net.Conn, error) {
conn, err := net.Dial("tcp", "127.0.0.1:6311")
if err != nil {
fmt.Printf("Cannot connect to %v", err)
}
return conn, err
}
func REval(conn net.Conn, data string) (int, error) {
send := MakeBytes(0x002, data) //CMD_voidEval = 0x002
buff := new(bytes.Buffer)
binary.Write(buff, binary.LittleEndian, send)
// binary.Write(buff, binary.LittleEndian, int32(len(send)))
// binary.Write(buff, binary.LittleEndian, int32(0))
n, err := conn.Write(buff.Bytes())
if err != nil {
fmt.Printf("%v", err)
}
return n, err
}
func CheckResp(conn net.Conn) error {
read_buff := make([]byte, 32)
conn.Read(read_buff) // read protocol head
conn.Read(read_buff)
status := read_buff[0:3]
fmt.Print(string(status))
if status[0] == 1 && status[2] == 1 {
fmt.Print("ok")
} else {
err := errors.New("Something wrong with R script.")
return err
}
return nil
}
// func NewRespHdr(buff []byte) *RespHdr {
// head := new(RespHdr)
// head.XTType = buff[0]
// t_byte := make([]byte, 4)
// for i := 1; i < 4; i++ {
// t_byte[i-1] = buff[i]
// }
// fmt.Print(head.XTType)
// fmt.Print(t_byte)
// head.BodyLen = binary.LittleEndian.Uint32(t_byte)
// return head
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment