2 #import "NSData+RSerialize.h"
4 #include <Rinternals.h>
8 @implementation RObject
9 + (id)objectWithSEXP:(void*)aSexp preserve:(BOOL)shouldPreserve { return [[[self alloc] initWithSEXP:aSexp preserve:shouldPreserve] autorelease]; }
10 + (id)objectWithSEXP:(void*)aSexp { return [[[self alloc] initWithSEXP:aSexp] autorelease]; }
12 - (id)initWithSEXP:(void*)aSexp preserve:(BOOL)shouldPreserve {
13 if(nil == [super init]) return nil;
14 if(YES == shouldPreserve) R_PreserveObject((SEXP)aSexp);
16 preserved = shouldPreserve;
19 - (id)initWithSEXP:(void*)aSexp { return [self initWithSEXP:aSexp preserve:YES]; }
21 - (id)initWithData:(NSData*)data {
22 return [self initWithSEXP:[data unserialize]];
26 if(obj_ptr != NULL && YES == preserved) R_ReleaseObject((SEXP)obj_ptr);
31 - (NSData*)serialize { return [NSData dataWithSEXP:(SEXP)obj_ptr]; }
38 - (int)length { return Rf_length((SEXP)obj_ptr); }
40 - (NSArray*)dimensions {
41 NSMutableArray *arr = [[NSMutableArray alloc] init];
43 PROTECT(e = lang2(install("dim"),(SEXP)obj_ptr));
45 PROTECT(dims = R_tryEval(e,R_GlobalEnv,&err));
46 if(!err && R_NilValue != dims) {
47 for(i=0;i<Rf_length(dims);i++) [arr addObject:[NSNumber numberWithInt:INTEGER(dims)[i]]];
50 return [arr autorelease];
55 PROTECT(e = lang2(install("dim"),(SEXP)obj_ptr));
58 isMatrix = (R_NilValue == R_tryEval(e,R_GlobalEnv,&err)) ? NO : YES;
59 if(err) isMatrix = NO;
63 - (NSArray*)classList {
64 NSMutableArray *arr = [[NSMutableArray alloc] init];
65 SEXP klass = getAttrib((SEXP)obj_ptr,R_ClassSymbol);
66 if(STRSXP == TYPEOF(klass)) {
68 for(i=0;i<Rf_length(klass);i++) [arr addObject:[NSString stringWithUTF8String:CHAR(STRING_ELT(klass,i))]];
70 if(R_NilValue != getAttrib((SEXP)obj_ptr,R_DimSymbol)) [arr addObject:@"matrix"];
71 switch(TYPEOF(klass)) {
72 case INTSXP:[arr addObject:@"integer"];break;
73 case REALSXP:[arr addObject:@"numeric"];break;
74 case VECSXP:[arr addObject:@"list"];break;
77 return [arr autorelease];
80 - (NSDictionary*)describeWithName:(NSString*)aName {
81 NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
82 [self classList],@"Class",[NSNumber numberWithInt:[self length]],@"Length",nil];
83 if(nil != aName) [dict setObject:aName forKey:@"Name"];
84 if(YES == [self isMatrix]) [dict setObject:[self dimensions] forKey:@"Dimensions"];
85 return [dict autorelease];
88 - (NSDictionary*)describe { return [self describeWithName:nil]; }