// // HubSession.m // RemoteR // Class encapsulating a session to a remote R server // // Created by Simon Urbanek on 2/11/11. // Copyright 2011 Simon Urbanek. All rights reserved. // #import "HubSession.h" #import "MyDocument.h" static hub_res_t my_read_callback(hub_conn_t *hc, const void *data, int length) { HubSession *hs = (HubSession*) hc_user_ptr(hc); MyDocument *doc = hs ? [hs consoleDocument] : nil; if (!hs || !doc) return HCERR_OK; const char *c = (const char *)data, *cseg = c, *cend = c + length; while (c < cend) { if (*c == 1 || *c == 2 || *c == 3) { if (cseg < c) [doc writeConsoleBytes: cseg length: c - cseg mode: hs->inputMode]; hs->inputMode = *c; cseg = c + 1; } c++; } if (cseg < c) [doc writeConsoleBytes:cseg length:c - cseg mode:hs->inputMode]; return HCERR_OK; } static hub_res_t my_service(hub_service_t service, hub_conn_t *hc) { HubSession *hs = (HubSession*) hs_user_ptr(hc_session(hc)); if (!hs) return HCERR_OK; // FIXME: should really be an error... NSLog(@"my_service for %x", service); switch (service) { case 0x101: hs->c_in = hc; hc_set_user_ptr(hc, hs); break; case 0x102: hs->c_out = hc; hc_set_user_ptr(hc, hs); hc_set_read_callback(hc, my_read_callback); break; case 0x103: hs->c_err = hc; hc_set_user_ptr(hc, hs); hc_set_read_callback(hc, my_read_callback); break; default: { MyDocument *consoleDocument = [hs consoleDocument]; if (consoleDocument && [consoleDocument respondsToSelector:@selector(service:connection:)]) return [consoleDocument service: service connection: hc]; } } return HCERR_OK; } @implementation HubSession - (id) initWithInput: (int) inFD output: (int) outFD { self = [super init]; if (self != nil) { consoleDocument = nil; session = hs_create(inFD, outFD, HS_SERVER); hs_set_user_ptr(session, self); hs_provide_service(session, 0x101, my_service, self); hs_provide_service(session, 0x102, my_service, self); hs_provide_service(session, 0x103, my_service, self); } return self; } - (MyDocument*) consoleDocument { return consoleDocument; } - (void) setConsoleDocument: (MyDocument*) newDocument { if (consoleDocument) [consoleDocument release]; consoleDocument = newDocument; if (consoleDocument) [consoleDocument retain]; } @end