Connections are not yet exposed to R package writers and those embedding R into other software. This patch to R version 2.5.0 r39773:
http://biostat.mc.vanderbilt.edu/twiki/pub/Main/RApacheProject/Conn-patch-R-devel-r39795.patch
implements one, and the latest Cairo package here:
http://www.rforge.net/Cairo/files
implements it.
Here’s what I’ve tested so far:
library(Cairo) # from the above tarball x <- gzfile("plot.png.gz","w") Cairo(file=x) plot(cars) dev.off() flush(x) # need this for some reason close(x)
Also, this RApache handler works:
library('Cairo') rplot <- function(r) { apache.set_content_type(r,"image/png") Cairo(file=stdout()) plot(runif(100),rnorm(100),main="Random") dev.off() OK }
and this is a patched version of RApache:
http://biostat.mc.vanderbilt.edu/twiki/pub/Main/RApacheProject/rapache-with-conn-patch-r224.tgz
Requests have been made for this on the R devel mailing list and are documented here:
https://stat.ethz.ch/pipermail/r-devel/2006-October/039681.html
https://stat.ethz.ch/pipermail/r-devel/2006-October/039697.html
https://stat.ethz.ch/pipermail/r-devel/2006-October/039699.html
[ If you know of others please add to the above ]
Developers wanting to call functions from the API will include the R_ext/RConn.h header file that declares the Rconn struct and the public functions:
typedef struct Rconn *Rconnection; struct Rconn { char* class; char* description; char mode[5]; Rboolean text, isopen, incomplete, canread, canwrite, canseek, blocking, isGzcon; Rboolean (*open)(struct Rconn *); void (*close)(struct Rconn *); /* routine closing after auto open */ void (*destroy)(struct Rconn *); /* when closing connection */ int (*vfprintf)(struct Rconn *, const char *, va_list); int (*fgetc)(struct Rconn *); int (*fgetc_internal)(struct Rconn *); /* int (*ungetc)(int c, struct Rconn *); */ double (*seek)(struct Rconn *, double, int, int); void (*truncate)(struct Rconn *); int (*fflush)(struct Rconn *); size_t (*read)(void *, size_t, size_t, struct Rconn *); size_t (*write)(const void *, size_t, size_t, struct Rconn *); /* void (*onerror)(struct Rconn *); */ int nPushBack, posPushBack; /* number of lines, position on top line */ char **PushBack; int save, save2; /* unsigned char encoding[256];*/ char encname[101]; /* will be iconv_t, which is a pointer. NULL if not in use */ void *inconv, *outconv; /* The idea here is that no MBCS char will ever not fit */ char iconvbuff[25], oconvbuff[50], *next, init_out[25]; short navail, inavail; Rboolean EOF_signalled; void *private; }; int R_RegisterStdinConnection(SEXP scon); int R_RegisterStdoutConnection(SEXP scon); int R_RegisterStderrConnection(SEXP scon); SEXP R_NewConnection(char *class, char *description, char *mode, Rconnection *con); Rconnection R_GetConnection(Rconnection ucon, int idx); void R_CloseConnection(int idx); int R_VfprintfConnection(int idx, const char *format, va_list ap); int R_FgetcConnection(int idx); double R_SeekConnection(int idx, double where, int origin, int rw); void R_TruncateConnection(int idx); int R_FlushConnection(int idx); size_t R_ReadConnection(int idx, void *buf, size_t size, size_t n); size_t R_WriteConnection(int idx, const void *buf, size_t size, size_t n); size_t R_WriteRConnection(Rconnection con, void *buf, size_t n);
SEXP R_NewConnection(char *class, char *description, char *mode, Rconnection *con)
An SEXP which is an integer vector of length one with the class attribute set to class and connection. This can be returned back to R code.
Rconnection con; SEXP scon; scon = R_NewConnection("foopipe","pipe data to foo","w",&con); scon->text = FALSE; /*stuff binary data to foo*/ /* foopipe_vfprintf must be declared like struct rconn's vfprintf member */ scon->vfprintf = foopipe_vfprintf; /* same for foopipe_write */ scon->write = foopipe_write;
int R_RegisterStdoutConnection(SEXP scon); int R_RegisterStderrConnection(SEXP scon); int R_RegisterStdinConnection(SEXP scon);
Returns 0 on success and -1 on failure. (Is this standard?)
size_t R_WriteConnection(int idx, const void *buf, size_t size, size_t n)
This call is similar to the libc call fwrite, so buf must be size*n bytes long.
The number of items written.
if (R_WriteConnection(asInteger(scon),buf,1024,1) == 1){ /* Success */ } else { /* Write error occured */ }
int R_VfprintfConnection(int idx, const char *format, va_list ap)
The number of characters printed, not including the trailing NULL byte.
size_t R_ReadConnection(int idx, void *buf, size_t size, size_t n)
This call is similar to the libc call fread, so buf must be size*n bytes long.
The number of items written.
int R_FgetcConnection(int idx)
The character read as an unsigned char cast to an int? I’m getting this from the fgetc man page...
double R_SeekConnection(int idx, double where, int origin, int rw)
The position within the connection
void R_TruncateConnection(int idx)
None
int R_FlushConnection(int idx)
Upon successful completion 0 is returned, otherwise EOF.
void R_CloseConnection(int idx)
None