// // ConnectionCache.m // RCocoaBundle // // Created by Simon Urbanek on Sun Mar 07 2004. // Copyright (c) 2004 Simon Urbanek. All rights reserved. // #import "ConnectionCache.h" #import #import #import @implementation ConnectionCache - (id) initWithDescriptor: (int) fileDescriptor { fd = fileDescriptor; mutex = [[NSLock alloc] init]; ba = [[NSMutableArray alloc] initWithCapacity: 8]; [NSThread detachNewThreadSelector:@selector(readThread:) toTarget:self withObject:nil]; return self; } - (void) addBytes: (const char*) c length: (unsigned) len { [mutex lock]; [ba addObject: [NSData dataWithBytes:c length:len]]; [mutex unlock]; } - (void) addData: (NSData*) d { [mutex lock]; [ba addObject: d]; [mutex unlock]; } - (NSData*) next { NSData *d; [mutex lock]; if ([ba count]==0) { [mutex unlock]; return nil; } d=[ba objectAtIndex:0]; [ba removeObjectAtIndex:0]; [mutex unlock]; return d; } - (BOOL) hasData { BOOL really=NO; [mutex lock]; if ([ba count]>0) really=YES; [mutex unlock]; return really; } - (NSData*) nextWithLimit: (int) maxlen { NSData *d; [mutex lock]; if ([ba count]==0) { [mutex unlock]; return nil; } d=[ba objectAtIndex:0]; if ([d length]>maxlen) { NSData *head=[d subdataWithRange:NSMakeRange(0,maxlen)]; NSData *tail=[d subdataWithRange:NSMakeRange(maxlen,[d length]-maxlen)]; [ba replaceObjectAtIndex:0 withObject:tail]; [d autorelease]; [mutex unlock]; return head; } [ba removeObjectAtIndex:0]; [mutex unlock]; return d; } - (void) readThread: (id) argument { NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init]; char *buf=(char*) malloc(65536); int n; fd_set readfds; fcntl(fd, F_SETFL, O_NONBLOCK); while (1) { FD_ZERO(&readfds); FD_SET(fd,&readfds); select(fd+1, &readfds, 0, 0, 0); if (FD_ISSET(fd, &readfds)) { while ((n=read(fd,buf,65535))>0) { [self addBytes:buf length:n]; } } } free(buf); [pool release]; } @end