//export Cli func Cli(str_ C.SEXP) C.SEXP { if C.TYPEOF(str_) != C.STRSXP { fmt.Printf("not a STRXSP! instead: %d, argument to rmq() must be a string to be decoded to its integer constant value in the rmq pkg.\n", C.TYPEOF(str_)) return C.R_NilValue } name := C.R_CHAR(C.STRING_ELT(str_, 0)) msg := C.GoString(name) //fmt.Printf("rmq says: client sees '%s'.\n", msg) reply := client_main([]byte(msg)) VPrintf("rmq says: after client_main().\n") if len(reply) == 0 { return C.R_NilValue } if len(reply) > 0 { return decodeMsgpackToR(reply) } return C.R_NilValue }
func getAddr(addr_ C.SEXP) (*net.TCPAddr, error) { if C.TYPEOF(addr_) != C.STRSXP { return nil, fmt.Errorf("getAddr() error: addr is not a string STRXSP; instead it is type %d. addr argument must be a string of form 'ip:port'\n", C.TYPEOF(addr_)) } caddr := C.R_CHAR(C.STRING_ELT(addr_, 0)) addr := C.GoString(caddr) tcpAddr, err := net.ResolveTCPAddr("tcp", addr) if err != nil || tcpAddr == nil { return nil, fmt.Errorf("getAddr() error: address '%s' could not be parsed by net.ResolveTCPAddr(): error: '%s'", addr, err) } return tcpAddr, nil }
//export Srv func Srv(str_ C.SEXP) C.SEXP { if C.TYPEOF(str_) != C.STRSXP { fmt.Printf("not a STRXSP! instead: %d, argument to rmq() must be a string to be decoded to its integer constant value in the rmq pkg.\n", C.TYPEOF(str_)) return C.R_NilValue } name := C.R_CHAR(C.STRING_ELT(str_, 0)) gname := C.GoString(name) fmt.Printf("rmq says: Hello '%s'!\n", gname) //go StartServer() go server_main() fmt.Printf("\n after gorilla webserver on '%s' launched.\n", addr) return C.R_NilValue }
//export ReadTmFrame // // ReadTmFrame reads a TMFRAME file and returns the frames as // an R dataframe. // func ReadTmFrame(path_ C.SEXP) C.SEXP { // s must be a RAWSXP if C.TYPEOF(path_) != C.STRSXP { C.ReportErrorToR_NoReturn(C.CString("ReadTmFrame() error: path is not a string path to TMFRAME file.")) } cpath := C.R_CHAR(C.STRING_ELT(path_, 0)) path := C.GoString(cpath) if !FileExists(path) { C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("ReadTmFrame() error: bad path '%s'; does not exist", path))) } /// begin TMFRAME read f, err := os.Open(path) if err != nil { C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("ReadTmFrame() error, could not open path '%s': '%s'", path, err))) } i := int64(1) fr := tf.NewFrameReader(f, 1024*1024) var frame *tf.Frame //var raw []byte res := []*tf.Frame{} toploop: for ; err == nil; i++ { frame, _, err, _ = fr.NextFrame(nil) if err != nil { if err == io.EOF { break toploop } C.ReportErrorToR_NoReturn(C.CString(fmt.Sprintf("ReadTmFrame() error reading '%s', fr.NextFrame() at i=%v gave error: '%v'", path, i, err))) } res = append(res, frame) } // end for toploop if len(res) > 0 { return tmFramesToR(res) } return C.R_NilValue }
//export ListenAndServe func ListenAndServe(addr_ C.SEXP, handler_ C.SEXP, rho_ C.SEXP) C.SEXP { if C.TYPEOF(addr_) != C.STRSXP { fmt.Printf("addr is not a string (STRXSP; instead it is: %d)! addr argument to ListenAndServe() must be a string of form 'ip:port'\n", C.TYPEOF(addr_)) return C.R_NilValue } //msglen := 0 if 0 == int(C.isFunction(handler_)) { // 0 is false C.ReportErrorToR_NoReturn(C.CString("‘handler’ must be a function")) return C.R_NilValue } if rho_ != nil && rho_ != C.R_NilValue { if 0 == int(C.isEnvironment(rho_)) { // 0 is false C.ReportErrorToR_NoReturn(C.CString("‘rho’ should be an environment")) return C.R_NilValue } } caddr := C.R_CHAR(C.STRING_ELT(addr_, 0)) addr := C.GoString(caddr) fmt.Printf("ListenAndServe listening on address '%s'...\n", addr) webSockHandler := func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.Error(w, "Not found", 404) return } if r.Method != "GET" { http.Error(w, "Method not allowed, only GET allowed.", 405) return } c, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Print("websocket handler upgrade error:", err) return } defer c.Close() mt, message, err := c.ReadMessage() if err != nil { fmt.Println("read error: ", err) return } // make the call, and get a response msglen := len(message) rawmsg := C.allocVector(C.RAWSXP, C.R_xlen_t(msglen)) C.Rf_protect(rawmsg) C.memcpy(unsafe.Pointer(C.RAW(rawmsg)), unsafe.Pointer(&message[0]), C.size_t(msglen)) // put msg into env that handler_ is called with. C.defineVar(C.install(C.CString("msg")), rawmsg, rho_) R_serialize_fun = C.findVar(C.install(C.CString("serialize")), C.R_GlobalEnv) // todo: callbacks to R functions here not working. don't really need them if R always acts as a client instead. // evaluate C.PrintToR(C.CString("listenAndServe: stuffed msg into env rho_.\n")) //R_fcall := C.lang3(handler_, rawmsg, C.R_NilValue) R_fcall := C.lang3(R_serialize_fun, rawmsg, C.R_NilValue) C.Rf_protect(R_fcall) C.PrintToR(C.CString("listenAndServe: got msg, just prior to eval.\n")) evalres := C.eval(R_fcall, rho_) C.Rf_protect(evalres) C.PrintToR(C.CString("listenAndServe: after eval.\n")) /* var s, t C.SEXP s = C.allocList(3) t = s C.Rf_protect(t) C.SetTypeToLANGSXP(&s) //C.SETCAR(t, R_fcall) C.SETCAR(t, handler_) t = C.CDR(t) C.SETCAR(t, rawmsg) evalres := C.eval(s, rho_) C.Rf_protect(evalres) */ C.PrintToR(C.CString("nnListenAndServe: done with eval.\n")) if C.TYPEOF(evalres) != C.RAWSXP { fmt.Printf("rats! handler result was not RAWSXP raw bytes!\n") } else { //fmt.Printf("recv: %s\n", message) err = c.WriteMessage(mt, message) if err != nil { fmt.Println("write error: ", err) } } C.Rf_unprotect(3) } // end handler func http.HandleFunc("/", webSockHandler) err := http.ListenAndServe(addr, nil) if err != nil { fmt.Println("ListenAndServe: ", err) } return C.R_NilValue }