ASIInputStream.m 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //
  2. // ASIInputStream.m
  3. // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
  4. //
  5. // Created by Ben Copsey on 10/08/2009.
  6. // Copyright 2009 All-Seeing Interactive. All rights reserved.
  7. //
  8. #import "ASIInputStream.h"
  9. #import "ASIHTTPRequest.h"
  10. // Used to ensure only one request can read data at once
  11. static NSLock *readLock = nil;
  12. @implementation ASIInputStream
  13. + (void)initialize
  14. {
  15. if (self == [ASIInputStream class]) {
  16. readLock = [[NSLock alloc] init];
  17. }
  18. }
  19. + (id)inputStreamWithFileAtPath:(NSString *)path request:(ASIHTTPRequest *)theRequest
  20. {
  21. ASIInputStream *theStream = [[[self alloc] init] autorelease];
  22. [theStream setRequest:theRequest];
  23. [theStream setStream:[NSInputStream inputStreamWithFileAtPath:path]];
  24. return theStream;
  25. }
  26. + (id)inputStreamWithData:(NSData *)data request:(ASIHTTPRequest *)theRequest
  27. {
  28. ASIInputStream *theStream = [[[self alloc] init] autorelease];
  29. [theStream setRequest:theRequest];
  30. [theStream setStream:[NSInputStream inputStreamWithData:data]];
  31. return theStream;
  32. }
  33. - (void)dealloc
  34. {
  35. [stream release];
  36. [super dealloc];
  37. }
  38. // Called when CFNetwork wants to read more of our request body
  39. // When throttling is on, we ask ASIHTTPRequest for the maximum amount of data we can read
  40. - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len
  41. {
  42. [readLock lock];
  43. unsigned long toRead = len;
  44. if ([ASIHTTPRequest isBandwidthThrottled]) {
  45. toRead = [ASIHTTPRequest maxUploadReadLength];
  46. if (toRead > len) {
  47. toRead = len;
  48. } else if (toRead == 0) {
  49. toRead = 1;
  50. }
  51. [request performThrottling];
  52. }
  53. [readLock unlock];
  54. NSInteger rv = [stream read:buffer maxLength:toRead];
  55. if (rv > 0)
  56. [ASIHTTPRequest incrementBandwidthUsedInLastSecond:(NSUInteger)rv];
  57. return rv;
  58. }
  59. /*
  60. * Implement NSInputStream mandatory methods to make sure they are implemented
  61. * (necessary for MacRuby for example) and avoid the overhead of method
  62. * forwarding for these common methods.
  63. */
  64. - (void)open
  65. {
  66. [stream open];
  67. }
  68. - (void)close
  69. {
  70. [stream close];
  71. }
  72. - (id)delegate
  73. {
  74. return [stream delegate];
  75. }
  76. - (void)setDelegate:(id)delegate
  77. {
  78. [stream setDelegate:delegate];
  79. }
  80. - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
  81. {
  82. [stream scheduleInRunLoop:aRunLoop forMode:mode];
  83. }
  84. - (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
  85. {
  86. [stream removeFromRunLoop:aRunLoop forMode:mode];
  87. }
  88. - (id)propertyForKey:(NSString *)key
  89. {
  90. return [stream propertyForKey:key];
  91. }
  92. - (BOOL)setProperty:(id)property forKey:(NSString *)key
  93. {
  94. return [stream setProperty:property forKey:key];
  95. }
  96. - (NSStreamStatus)streamStatus
  97. {
  98. return [stream streamStatus];
  99. }
  100. - (NSError *)streamError
  101. {
  102. return [stream streamError];
  103. }
  104. // If we get asked to perform a method we don't have (probably internal ones),
  105. // we'll just forward the message to our stream
  106. - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
  107. {
  108. return [stream methodSignatureForSelector:aSelector];
  109. }
  110. - (void)forwardInvocation:(NSInvocation *)anInvocation
  111. {
  112. [anInvocation invokeWithTarget:stream];
  113. }
  114. @synthesize stream;
  115. @synthesize request;
  116. @end