New file |
| | |
| | | // |
| | | // ASIInputStream.m |
| | | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest |
| | | // |
| | | // Created by Ben Copsey on 10/08/2009. |
| | | // Copyright 2009 All-Seeing Interactive. All rights reserved. |
| | | // |
| | | |
| | | #import "ASIInputStream.h" |
| | | #import "ASIHTTPRequest.h" |
| | | |
| | | // Used to ensure only one request can read data at once |
| | | static NSLock *readLock = nil; |
| | | |
| | | @implementation ASIInputStream |
| | | |
| | | + (void)initialize |
| | | { |
| | | if (self == [ASIInputStream class]) { |
| | | readLock = [[NSLock alloc] init]; |
| | | } |
| | | } |
| | | |
| | | + (id)inputStreamWithFileAtPath:(NSString *)path request:(ASIHTTPRequest *)theRequest |
| | | { |
| | | ASIInputStream *theStream = [[[self alloc] init] autorelease]; |
| | | [theStream setRequest:theRequest]; |
| | | [theStream setStream:[NSInputStream inputStreamWithFileAtPath:path]]; |
| | | return theStream; |
| | | } |
| | | |
| | | + (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)theRequest |
| | | { |
| | | ASIInputStream *theStream = [[[self alloc] init] autorelease]; |
| | | [theStream setRequest:theRequest]; |
| | | [theStream setStream:[NSInputStream inputStreamWithData:data]]; |
| | | return theStream; |
| | | } |
| | | |
| | | - (void)dealloc |
| | | { |
| | | [stream release]; |
| | | [super dealloc]; |
| | | } |
| | | |
| | | // Called when CFNetwork wants to read more of our request body |
| | | // When throttling is on, we ask ASIHTTPRequest for the maximum amount of data we can read |
| | | - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len |
| | | { |
| | | [readLock lock]; |
| | | unsigned long toRead = len; |
| | | if ([ASIHTTPRequest isBandwidthThrottled]) { |
| | | toRead = [ASIHTTPRequest maxUploadReadLength]; |
| | | if (toRead > len) { |
| | | toRead = len; |
| | | } else if (toRead == 0) { |
| | | toRead = 1; |
| | | } |
| | | [request performThrottling]; |
| | | } |
| | | [readLock unlock]; |
| | | NSInteger rv = [stream read:buffer maxLength:toRead]; |
| | | if (rv > 0) |
| | | [ASIHTTPRequest incrementBandwidthUsedInLastSecond:rv]; |
| | | return rv; |
| | | } |
| | | |
| | | /* |
| | | * Implement NSInputStream mandatory methods to make sure they are implemented |
| | | * (necessary for MacRuby for example) and avoid the overhead of method |
| | | * forwarding for these common methods. |
| | | */ |
| | | - (void)open |
| | | { |
| | | [stream open]; |
| | | } |
| | | |
| | | - (void)close |
| | | { |
| | | [stream close]; |
| | | } |
| | | |
| | | - (id)delegate |
| | | { |
| | | return [stream delegate]; |
| | | } |
| | | |
| | | - (void)setDelegate:(id)delegate |
| | | { |
| | | [stream setDelegate:delegate]; |
| | | } |
| | | |
| | | - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode |
| | | { |
| | | [stream scheduleInRunLoop:aRunLoop forMode:mode]; |
| | | } |
| | | |
| | | - (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode |
| | | { |
| | | [stream removeFromRunLoop:aRunLoop forMode:mode]; |
| | | } |
| | | |
| | | - (id)propertyForKey:(NSString *)key |
| | | { |
| | | return [stream propertyForKey:key]; |
| | | } |
| | | |
| | | - (BOOL)setProperty:(id)property forKey:(NSString *)key |
| | | { |
| | | return [stream setProperty:property forKey:key]; |
| | | } |
| | | |
| | | - (NSStreamStatus)streamStatus |
| | | { |
| | | return [stream streamStatus]; |
| | | } |
| | | |
| | | - (NSError *)streamError |
| | | { |
| | | return [stream streamError]; |
| | | } |
| | | |
| | | // If we get asked to perform a method we don't have (probably internal ones), |
| | | // we'll just forward the message to our stream |
| | | |
| | | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector |
| | | { |
| | | return [stream methodSignatureForSelector:aSelector]; |
| | | } |
| | | |
| | | - (void)forwardInvocation:(NSInvocation *)anInvocation |
| | | { |
| | | [anInvocation invokeWithTarget:stream]; |
| | | } |
| | | |
| | | @synthesize stream; |
| | | @synthesize request; |
| | | @end |