Many changes! Snapshots now working properly. Programmatic environment interface...
[RExecServer.git] / RObject.m
bloba04b2abac01bb6d683cc160254e36b17766673bd
1 #import "RObject.h"
2 #import "NSData+RSerialize.h"
4 #include <Rinternals.h>
5 #undef error
6 #undef length
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);
15         obj_ptr = aSexp;
16         preserved = shouldPreserve;
17         return self;
19 - (id)initWithSEXP:(void*)aSexp { return [self initWithSEXP:aSexp preserve:YES]; }
21 - (id)initWithData:(NSData*)data {
22         return [self initWithSEXP:[data unserialize]];
25 - (void)dealloc {
26         if(obj_ptr != NULL && YES == preserved) R_ReleaseObject((SEXP)obj_ptr);
27         [super dealloc];
31 - (NSData*)serialize { return [NSData dataWithSEXP:(SEXP)obj_ptr]; }
34 - (id)coerce {
35         return nil;
38 - (int)length { return Rf_length((SEXP)obj_ptr); }
40 - (NSArray*)dimensions {
41         NSMutableArray *arr = [[NSMutableArray alloc] init];
42         SEXP e,dims;
43         PROTECT(e = lang2(install("dim"),(SEXP)obj_ptr));
44         int  err,i;
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]]];
48         }
49         UNPROTECT(2);
50         return [arr autorelease];
53 - (BOOL)isMatrix {
54         SEXP e;
55         PROTECT(e = lang2(install("dim"),(SEXP)obj_ptr));
56         int  err;
57         BOOL isMatrix;
58         isMatrix = (R_NilValue == R_tryEval(e,R_GlobalEnv,&err)) ? NO : YES;
59         if(err) isMatrix = NO;
60         UNPROTECT(1);
61         return isMatrix;
63 - (NSArray*)classList {
64         NSMutableArray *arr = [[NSMutableArray alloc] init];
65         SEXP klass = getAttrib((SEXP)obj_ptr,R_ClassSymbol);
66         if(STRSXP == TYPEOF(klass)) {
67                 int i;
68                 for(i=0;i<Rf_length(klass);i++) [arr addObject:[NSString stringWithUTF8String:CHAR(STRING_ELT(klass,i))]];
69         } else {
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;
75                 }
76         }
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]; }
90 @end