[R] S_alloc or Calloc for return value

Dan Kelley kelley.dan at gmail.com
Tue Jul 21 23:05:35 CEST 2009


Self-posting the solution, to help those who come across this thread with a
similar interest --

My solution, arrived at with the generous help of those who have replied to
my question, was to use .Call, as exemplified below.  My task was to find
indices in a "raw" buffer (input) that match a particular two-byte sequence
(b1 and b2).  (It's a task that is common in my research area.  The files
are large, so the use of C was important both to achive speed and to fit
within memory constraings.)  

<R code>
indices <- .Call("match2bytes", as.raw(input), as.raw(b1), as.raw(b2))
</R code>

<C code>
#include <R.h>
#include <Rdefines.h>
#include <Rinternals.h>
/* test R code:
   buf <- as.raw(c(0xa5, 0x11, 0xaa, 0xa5, 0x11, 0x00))
   dyn.load("bitwise.so")
   m <- .Call("match2bytes", buf, as.raw(0xa5), as.raw(0x11))
   print(m)
 */
SEXP match2bytes(SEXP buf, SEXP m1, SEXP m2)
{
  int i, j, n, n_match;
  double *resp;
  unsigned char *bufp, *m1p, *m2p;
  SEXP res;
  PROTECT(buf = AS_RAW(buf));
  PROTECT(m1 = AS_RAW(m1));
  PROTECT(m2 = AS_RAW(m2));
  bufp = RAW_POINTER(buf);
  m1p = RAW_POINTER(m1);
  m2p = RAW_POINTER(m2);
  n = LENGTH(buf);
  n_match = 0;
  for (i = 0; i < n - 1; i++) {
    if (bufp[i] == *m1p && bufp[i + 1] == *m2p) {
      n_match++;
      ++i;                      /* skip */
    }
  }
  PROTECT(res = NEW_NUMERIC(n_match));
  resp = NUMERIC_POINTER(res);
  j = 0;
  for (i = 0; i < n - 1; i++) {
    if (j <= n_match && bufp[i] == *m1p && bufp[i + 1] == *m2p) {
      resp[j++] = i + 1;        /* the 1 is to offset from C to R */
    }
  }
  UNPROTECT(4);
  return(res);
}
</C code>

-- 
View this message in context: http://www.nabble.com/S_alloc-or-Calloc-for-return-value-tp24579062p24595838.html
Sent from the R help mailing list archive at Nabble.com.




More information about the R-help mailing list