/core/externals/update-engine/externals/gdata-objectivec-client/Source/HTTPFetcher/GTMReadMonitorInputStream.m

http://macfuse.googlecode.com/ · Objective C · 189 lines · 125 code · 35 blank · 29 comment · 8 complexity · 85d497ac36f4581b50a34af49ca09f64 MD5 · raw file

  1. /* Copyright (c) 2011 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #import "GTMReadMonitorInputStream.h"
  16. @interface GTMReadMonitorInputStream ()
  17. - (void)invokeReadSelectorWithBuffer:(NSData *)data;
  18. @end
  19. @implementation GTMReadMonitorInputStream
  20. @synthesize readDelegate = readDelegate_;
  21. @synthesize readSelector = readSelector_;
  22. @synthesize runLoopModes = runLoopModes_;
  23. // We'll forward all unhandled messages to the NSInputStream class
  24. // or to the encapsulated input stream. This is needed
  25. // for all messages sent to NSInputStream which aren't
  26. // handled by our superclass; that includes various private run
  27. // loop calls.
  28. + (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
  29. return [NSInputStream methodSignatureForSelector:selector];
  30. }
  31. + (void)forwardInvocation:(NSInvocation*)invocation {
  32. [invocation invokeWithTarget:[NSInputStream class]];
  33. }
  34. - (BOOL)respondsToSelector:(SEL)selector {
  35. return [inputStream_ respondsToSelector:selector];
  36. }
  37. - (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
  38. return [inputStream_ methodSignatureForSelector:selector];
  39. }
  40. - (void)forwardInvocation:(NSInvocation*)invocation {
  41. [invocation invokeWithTarget:inputStream_];
  42. }
  43. #pragma mark -
  44. + (id)inputStreamWithStream:(NSInputStream *)input {
  45. return [[[self alloc] initWithStream:input] autorelease];
  46. }
  47. - (id)initWithStream:(NSInputStream *)input {
  48. self = [super init];
  49. if (self) {
  50. inputStream_ = [input retain];
  51. thread_ = [[NSThread currentThread] retain];
  52. }
  53. return self;
  54. }
  55. - (id)init {
  56. return [self initWithStream:nil];
  57. }
  58. - (void)dealloc {
  59. [inputStream_ release];
  60. [thread_ release];
  61. [runLoopModes_ release];
  62. [super dealloc];
  63. }
  64. #pragma mark -
  65. - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len {
  66. // Read from the encapsulated stream
  67. NSInteger numRead = [inputStream_ read:buffer maxLength:len];
  68. if (numRead > 0) {
  69. BOOL isOnOriginalThread = [thread_ isEqual:[NSThread currentThread]];
  70. if (readDelegate_ && readSelector_) {
  71. // call the read selector with the buffer and number of bytes actually
  72. // read into it
  73. SEL sel = @selector(invokeReadSelectorWithBuffer:);
  74. if (isOnOriginalThread) {
  75. // invoke immediately
  76. NSData *data = [NSData dataWithBytesNoCopy:buffer
  77. length:(NSUInteger)numRead
  78. freeWhenDone:NO];
  79. [self performSelector:sel withObject:data];
  80. } else {
  81. // copy the buffer into an NSData to be retained by the
  82. // performSelector, and invoke on the proper thread
  83. NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numRead];
  84. if (runLoopModes_) {
  85. [self performSelector:sel
  86. onThread:thread_
  87. withObject:data
  88. waitUntilDone:NO
  89. modes:runLoopModes_];
  90. } else {
  91. [self performSelector:sel
  92. onThread:thread_
  93. withObject:data
  94. waitUntilDone:NO];
  95. }
  96. }
  97. }
  98. }
  99. return numRead;
  100. }
  101. - (void)invokeReadSelectorWithBuffer:(NSData *)data {
  102. const void *buffer = [data bytes];
  103. NSUInteger length = [data length];
  104. NSMethodSignature *signature = [readDelegate_ methodSignatureForSelector:readSelector_];
  105. NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  106. [invocation setSelector:readSelector_];
  107. [invocation setTarget:readDelegate_];
  108. [invocation setArgument:&self atIndex:2];
  109. [invocation setArgument:&buffer atIndex:3];
  110. [invocation setArgument:&length atIndex:4];
  111. [invocation invoke];
  112. }
  113. - (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len {
  114. return [inputStream_ getBuffer:buffer length:len];
  115. }
  116. - (BOOL)hasBytesAvailable {
  117. return [inputStream_ hasBytesAvailable];
  118. }
  119. #pragma mark Standard messages
  120. // Pass expected messages to our encapsulated stream.
  121. //
  122. // We want our encapsulated NSInputStream to handle the standard messages;
  123. // we don't want the superclass to handle them.
  124. - (void)open {
  125. [inputStream_ open];
  126. }
  127. - (void)close {
  128. [inputStream_ close];
  129. }
  130. - (id)delegate {
  131. return [inputStream_ delegate];
  132. }
  133. - (void)setDelegate:(id)delegate {
  134. [inputStream_ setDelegate:delegate];
  135. }
  136. - (id)propertyForKey:(NSString *)key {
  137. return [inputStream_ propertyForKey:key];
  138. }
  139. - (BOOL)setProperty:(id)property forKey:(NSString *)key {
  140. return [inputStream_ setProperty:property forKey:key];
  141. }
  142. - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode {
  143. [inputStream_ scheduleInRunLoop:aRunLoop forMode:mode];
  144. }
  145. - (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode {
  146. [inputStream_ removeFromRunLoop:aRunLoop forMode:mode];
  147. }
  148. - (NSStreamStatus)streamStatus {
  149. return [inputStream_ streamStatus];
  150. }
  151. - (NSError *)streamError {
  152. return [inputStream_ streamError];
  153. }
  154. @end