Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: Reading from an existing connection in compiled code

Tags:

r

connection

api

I'd like to be able to read from an arbitrary R connection (in the sense of ?connections), which would be passed to an R function by the user and then down into some C code via .Call.

The R API, in file R_ext/Connections.h, specifies a function, R_ReadConnection, which takes a pointer to an Rconn struct as its first argument, and does what I want. The struct itself is also defined in that header, but I see no way of retrieving a struct of that type, aside from getConnection (the C function), which is not part of the API. As far as I can tell, the external pointer associated with the connection also does not point to the struct directly.

So, could anyone please tell me whether there is a supported way to convert a suitable SEXP to a pointer to the associated Rconn struct?

Thanks in advance.

like image 849
Jon Clayden Avatar asked Feb 18 '16 14:02

Jon Clayden


2 Answers

The R API function R_GetConnection() was added in R 3.3.0. It performs the conversion from SEXP to pointer to Rconn (a.k.a. Rconnection). Hence, the solution is now

#include <R_ext/Connections.h>

SEXP myfunction (SEXP conn_)
{
    Rconnection conn = R_GetConnection(conn_);
    // Do something with the connection
    
    return R_NilValue;
}

This was documented in NEWS:

R_GetConnection() which allows packages implementing connections to convert R connection objects to Rconnection handles. Code which previously used the low-level R-internal getConnection() entry point should switch.

like image 69
Jon Clayden Avatar answered Nov 15 '22 22:11

Jon Clayden


I don't think there is (this is an oversight, I think). The workaround is to declare an appropriate prototype and use it

Rconnection getConnection(int n);

SEXP connect_me(SEXP conn) {
    getConnection(INTEGER(conn)[0]);
    return R_NilValue;
}
like image 34
Martin Morgan Avatar answered Nov 15 '22 21:11

Martin Morgan