From jeff.horner at vanderbilt.edu  Tue Oct 10 06:46:38 2006
From: jeff.horner at vanderbilt.edu (Jeffrey Horner)
Date: Mon, 09 Oct 2006 23:46:38 -0500
Subject: [Rd] Discussion starter for package level Connection API
In-Reply-To: <452AC1BE.90104@vanderbilt.edu>
References: <452AC1BE.90104@vanderbilt.edu>
Message-ID: <452B25AE.2070005@vanderbilt.edu>

Here's a function to create new connections. It returns and SEXP that 
can be returned to R code, but before that, the user can set up all the 
function pointer members via passing in the address of an Rconnection. 
Here's how you'd call it:

SEXP newcon;
Rconnection conptr;

newcon = R_NewConnection("newcon","newdesc","w",&conptr);

conptr->vfprintf = apachecon_vfprintf;
conptr->write = apachecon_write;
...
conptr->private = apachecon_init(); /* or whathaveyou */
return newcon;

And if you wanted to know the index, all you have to do is get it from 
asInteger(newcon). Here's the code for R_NewConnection;

SEXP R_NewConnection(char *class, char *description, char *mode, 
Rconnection *con)
{
     SEXP sclass, ans;
     Rconnection new = NULL;
     int ncon;

     /* Get index before we allocate memory */
     ncon = NextConnection();

     new = (Rconnection) malloc(sizeof(struct Rconn));
     if(!new) error(_("allocation of new connection failed"));
	new->class = (char *) malloc(strlen(class) + 1);
     if(!new->class) {
     	free(new);
     	error(_("allocation of terminal connection failed"));
     }
     strcpy(new->class, class);
     new->description = (char *) malloc(strlen(description) + 1);
     if(!new->description) {
     	free(new->class); free(new);
     	error(_("allocation of terminal connection failed"));
     }
     init_con(new, description, mode);
     new->isopen = TRUE;
     new->canread = (strcmp(mode, "r") == 0);
     new->canwrite = (strcmp(mode, "w") == 0);
     new->destroy = &null_close;
     new->private = NULL;

     /* Add to Connections, and also
      * allow users to assign function
      * pointer members
      */
     *con = Connections[ncon] = new;

     /* Create something to pass to R code */
     PROTECT(ans = allocVector(INTSXP, 1));
     INTEGER(ans)[0] = ncon;
     PROTECT(sclass = allocVector(STRSXP, 2));
     SET_STRING_ELT(sclass, 0, mkChar(class));
     SET_STRING_ELT(sclass, 1, mkChar("connection"));
     classgets(ans, sclass);
     UNPROTECT(2);

     return ans;
}


Jeff
-- 
http://biostat.mc.vanderbilt.edu/JeffreyHorner




[Rd] Discussion starter for package level Connection API
Jeffrey Horner