[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