forked from dankelley/oce
-
Notifications
You must be signed in to change notification settings - Fork 0
/
get_bit.c
41 lines (35 loc) · 982 Bytes
/
get_bit.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/* vim: set noexpandtab shiftwidth=2 softtabstop=2 tw=70: */
#include <R.h>
#include <Rdefines.h>
#include <Rinternals.h>
//#define DEBUG
/*
TEST
system("R CMD shlib get_bit.c")
dyn.load("get_bit.so")
buf<-0x0a
for(i in 7:0) cat(.Call("get_bit", buf, i))
OUTPUT (correct)
00001010
*/
SEXP get_bit(SEXP buf, SEXP bit) // bit=0 for rightmost bit, =7 for leftmost bit
{
static unsigned char mask[] = {1, 2, 4, 8, 16, 32, 64, 128};
PROTECT(buf = AS_RAW(buf));
PROTECT(bit = AS_INTEGER(bit));
int n = LENGTH(buf);
unsigned char *bufp = RAW_POINTER(buf);
int *bitp = INTEGER_POINTER(bit);
if (*bitp < 0)
error("cannot have bit number less than 0; got %d", *bitp);
if (*bitp > 7)
error("cannot have bit number greater than 7; got %d", *bitp);
SEXP res;
PROTECT(res = NEW_INTEGER(n));
int *resp = INTEGER_POINTER(res);
for (int i = 0; i < n; i++) {
resp[i] = (bufp[i] & mask[*bitp]) != 0;
}
UNPROTECT(3);
return(res);
}