PageRenderTime 48ms CodeModel.GetById 13ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 16#import "GTMReadMonitorInputStream.h"
 17
 18@interface GTMReadMonitorInputStream ()
 19- (void)invokeReadSelectorWithBuffer:(NSData *)data;
 20@end
 21
 22@implementation GTMReadMonitorInputStream
 23
 24@synthesize readDelegate = readDelegate_;
 25@synthesize readSelector = readSelector_;
 26@synthesize runLoopModes = runLoopModes_;
 27
 28// We'll forward all unhandled messages to the NSInputStream class
 29// or to the encapsulated input stream.  This is needed
 30// for all messages sent to NSInputStream which aren't
 31// handled by our superclass; that includes various private run
 32// loop calls.
 33+ (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
 34  return [NSInputStream methodSignatureForSelector:selector];
 35}
 36
 37+ (void)forwardInvocation:(NSInvocation*)invocation {
 38  [invocation invokeWithTarget:[NSInputStream class]];
 39}
 40
 41- (BOOL)respondsToSelector:(SEL)selector {
 42  return [inputStream_ respondsToSelector:selector];
 43}
 44
 45- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
 46  return [inputStream_ methodSignatureForSelector:selector];
 47}
 48
 49- (void)forwardInvocation:(NSInvocation*)invocation {
 50  [invocation invokeWithTarget:inputStream_];
 51}
 52
 53#pragma mark -
 54
 55+ (id)inputStreamWithStream:(NSInputStream *)input {
 56  return [[[self alloc] initWithStream:input] autorelease];
 57}
 58
 59- (id)initWithStream:(NSInputStream *)input  {
 60  self = [super init];
 61  if (self) {
 62    inputStream_ = [input retain];
 63    thread_ = [[NSThread currentThread] retain];
 64  }
 65  return self;
 66}
 67
 68- (id)init {
 69  return [self initWithStream:nil];
 70}
 71
 72- (void)dealloc {
 73  [inputStream_ release];
 74  [thread_ release];
 75  [runLoopModes_ release];
 76  [super dealloc];
 77}
 78
 79#pragma mark -
 80
 81- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len {
 82  // Read from the encapsulated stream
 83  NSInteger numRead = [inputStream_ read:buffer maxLength:len];
 84  if (numRead > 0) {
 85
 86    BOOL isOnOriginalThread = [thread_ isEqual:[NSThread currentThread]];
 87
 88    if (readDelegate_ && readSelector_) {
 89      // call the read selector with the buffer and number of bytes actually
 90      // read into it
 91      SEL sel = @selector(invokeReadSelectorWithBuffer:);
 92
 93      if (isOnOriginalThread) {
 94        // invoke immediately
 95        NSData *data = [NSData dataWithBytesNoCopy:buffer
 96                                            length:(NSUInteger)numRead
 97                                      freeWhenDone:NO];
 98        [self performSelector:sel withObject:data];
 99      } else {
100        // copy the buffer into an NSData to be retained by the
101        // performSelector, and invoke on the proper thread
102        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numRead];
103        if (runLoopModes_) {
104          [self performSelector:sel
105                       onThread:thread_
106                     withObject:data
107                  waitUntilDone:NO
108                          modes:runLoopModes_];
109        } else {
110          [self performSelector:sel
111                       onThread:thread_
112                     withObject:data
113                  waitUntilDone:NO];
114        }
115      }
116    }
117  }
118
119  return numRead;
120}
121
122- (void)invokeReadSelectorWithBuffer:(NSData *)data {
123  const void *buffer = [data bytes];
124  NSUInteger length = [data length];
125
126  NSMethodSignature *signature = [readDelegate_ methodSignatureForSelector:readSelector_];
127  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
128  [invocation setSelector:readSelector_];
129  [invocation setTarget:readDelegate_];
130  [invocation setArgument:&self atIndex:2];
131  [invocation setArgument:&buffer atIndex:3];
132  [invocation setArgument:&length atIndex:4];
133  [invocation invoke];
134}
135
136- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)len {
137  return [inputStream_ getBuffer:buffer length:len];
138}
139
140- (BOOL)hasBytesAvailable {
141  return [inputStream_ hasBytesAvailable];
142}
143
144#pragma mark Standard messages
145
146// Pass expected messages to our encapsulated stream.
147//
148// We want our encapsulated NSInputStream to handle the standard messages;
149// we don't want the superclass to handle them.
150- (void)open {
151  [inputStream_ open];
152}
153
154- (void)close {
155  [inputStream_ close];
156}
157
158- (id)delegate {
159  return [inputStream_ delegate];
160}
161
162- (void)setDelegate:(id)delegate {
163  [inputStream_ setDelegate:delegate];
164}
165
166- (id)propertyForKey:(NSString *)key {
167  return [inputStream_ propertyForKey:key];
168}
169- (BOOL)setProperty:(id)property forKey:(NSString *)key {
170  return [inputStream_ setProperty:property forKey:key];
171}
172
173- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode {
174  [inputStream_ scheduleInRunLoop:aRunLoop forMode:mode];
175}
176
177- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode {
178  [inputStream_ removeFromRunLoop:aRunLoop forMode:mode];
179}
180
181- (NSStreamStatus)streamStatus {
182  return [inputStream_ streamStatus];
183}
184
185- (NSError *)streamError {
186  return [inputStream_ streamError];
187}
188
189@end