/ NSOutputStream.m
NSOutputStream.m
1 // 2 // NSOutputStream.m 3 // CoreFoundation 4 // 5 // Copyright (c) 2014 Apportable. All rights reserved. 6 // 7 8 #import <Foundation/NSError.h> 9 #import <Foundation/NSRunLoop.h> 10 #import "NSStreamInternal.h" 11 #import "NSObjectInternal.h" 12 13 @implementation NSOutputStream 14 15 + (id)allocWithZone:(NSZone *)zone 16 { 17 if (self == [NSOutputStream class]) 18 { 19 return [__NSCFOutputStream allocWithZone:zone]; 20 } 21 else 22 { 23 return [super allocWithZone:zone]; 24 } 25 } 26 27 - (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)len 28 { 29 NSRequestConcreteImplementation(); 30 return 0; 31 } 32 33 - (BOOL)hasSpaceAvailable 34 { 35 NSRequestConcreteImplementation(); 36 return NO; 37 } 38 39 @end 40 41 @implementation NSOutputStream (NSOutputStreamExtensions) 42 43 + (id)outputStreamToMemory 44 { 45 return [[[self alloc] initToMemory] autorelease]; 46 } 47 48 + (id)outputStreamToBuffer:(uint8_t *)buffer capacity:(NSUInteger)capacity 49 { 50 return [[[self alloc] initToBuffer:buffer capacity:capacity] autorelease]; 51 } 52 53 + (id)outputStreamToFileAtPath:(NSString *)path append:(BOOL)shouldAppend 54 { 55 return [[[self alloc] initToFileAtPath:path append:shouldAppend] autorelease]; 56 } 57 58 + (id)outputStreamWithURL:(NSURL *)url append:(BOOL)shouldAppend 59 { 60 return [[[self alloc] initWithURL:url append:shouldAppend] autorelease]; 61 } 62 63 - (id)initToMemory 64 { 65 NSRequestConcreteImplementation(); 66 [self release]; 67 return nil; 68 } 69 70 - (id)initToBuffer:(uint8_t *)buffer capacity:(NSUInteger)capacity 71 { 72 NSRequestConcreteImplementation(); 73 [self release]; 74 return nil; 75 } 76 77 - (id)initToFileAtPath:(NSString *)path append:(BOOL)shouldAppend 78 { 79 NSRequestConcreteImplementation(); 80 [self release]; 81 return nil; 82 } 83 84 - (id)initWithURL:(NSURL *)url append:(BOOL)shouldAppend 85 { 86 NSRequestConcreteImplementation(); 87 [self release]; 88 return nil; 89 } 90 91 @end 92 93 @implementation __NSCFOutputStream 94 95 96 + (id)allocWithZone:(NSZone *)zone 97 { 98 static __NSCFOutputStream *placeholder = nil; 99 static dispatch_once_t once = 0L; 100 dispatch_once(&once, ^{ 101 placeholder = [super allocWithZone:zone]; 102 }); 103 return placeholder; 104 } 105 106 + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key 107 { 108 return NO; 109 } 110 111 - (void)_unscheduleFromCFRunLoop:(CFRunLoopRef)runLoop forMode:(CFStringRef)mode 112 { 113 CFWriteStreamUnscheduleFromRunLoop((CFWriteStreamRef)self, runLoop, mode); 114 } 115 116 - (void)_scheduleInCFRunLoop:(CFRunLoopRef)runLoop forMode:(CFStringRef)mode 117 { 118 CFWriteStreamUnscheduleFromRunLoop((CFWriteStreamRef)self, runLoop, mode); 119 } 120 121 - (BOOL)_setCFClientFlags:(CFOptionFlags)flags callback:(CFWriteStreamClientCallBack)callback context:(CFStreamClientContext *)context 122 { 123 return CFWriteStreamSetClient((CFWriteStreamRef)self, flags, callback, context); 124 } 125 126 - (BOOL)hasSpaceAvailable 127 { 128 return CFWriteStreamCanAcceptBytes((CFWriteStreamRef)self); 129 } 130 131 - (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)len 132 { 133 return CFWriteStreamWrite((CFWriteStreamRef)self, buffer, len); 134 } 135 136 - (NSError *)streamError 137 { 138 return [CFWriteStreamCopyError((CFWriteStreamRef)self) autorelease]; 139 } 140 141 - (NSStreamStatus)streamStatus 142 { 143 return (NSStreamStatus)CFWriteStreamGetStatus((CFWriteStreamRef)self); 144 } 145 146 - (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode 147 { 148 if (aRunLoop == nil) 149 { 150 return; 151 } 152 153 CFWriteStreamScheduleWithRunLoop((CFWriteStreamRef)self, [aRunLoop getCFRunLoop], (CFStringRef)mode); 154 } 155 156 - (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode 157 { 158 if (aRunLoop == nil) 159 { 160 return; 161 } 162 163 CFWriteStreamUnscheduleFromRunLoop((CFWriteStreamRef)self, [aRunLoop getCFRunLoop], (CFStringRef)mode); 164 } 165 166 - (id)propertyForKey:(NSString *)key 167 { 168 return [(id)CFWriteStreamCopyProperty((CFWriteStreamRef)self, (CFStringRef)key) autorelease]; 169 } 170 171 - (BOOL)setProperty:(id)property forKey:(NSString *)key 172 { 173 return CFWriteStreamSetProperty((CFWriteStreamRef)self, (CFStringRef)key, (CFTypeRef)property); 174 } 175 176 - (id <NSStreamDelegate>)delegate 177 { 178 return _CFWriteStreamGetClient((CFWriteStreamRef)self); 179 } 180 181 static void __NSCFOutputStreamCallback(CFWriteStreamRef stream, CFStreamEventType type, void *clientCallBackInfo) 182 { 183 id<NSStreamDelegate> delegate = [(NSStream *)stream delegate]; 184 [delegate stream:(NSStream *)stream handleEvent:(NSStreamEvent)type]; 185 } 186 187 - (void)setDelegate:(id <NSStreamDelegate>)delegate 188 { 189 CFStreamClientContext ctx = { 190 0, 191 delegate, 192 NULL, 193 NULL, 194 (CFStringRef (*)(void *))&_NSCFCopyDescription 195 }; 196 CFOptionFlags flags = kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered; 197 [self _setCFClientFlags:flags callback:&__NSCFOutputStreamCallback context:&ctx]; 198 } 199 200 - (void)close 201 { 202 CFWriteStreamClose((CFWriteStreamRef)self); 203 } 204 205 - (void)open 206 { 207 CFWriteStreamOpen((CFWriteStreamRef)self); 208 } 209 210 - (id)initWithURL:(NSURL *)url append:(BOOL)shouldAppend 211 { 212 CFWriteStreamRef stream = CFWriteStreamCreateWithFile(kCFAllocatorDefault, (CFURLRef)url); 213 if (stream != NULL && shouldAppend) 214 { 215 CFWriteStreamSetProperty(stream, kCFStreamPropertyAppendToFile, kCFBooleanTrue); 216 } 217 return (id)stream; 218 } 219 220 - (id)initToFileAtPath:(NSString *)path append:(BOOL)shouldAppend 221 { 222 NSURL *url = [[NSURL alloc] initFileURLWithPath:path]; 223 id stream = [self initWithURL:url append:shouldAppend]; 224 [url release]; 225 return stream; 226 } 227 228 - (id)initToBuffer:(uint8_t *)buffer capacity:(NSUInteger)capacity 229 { 230 return (id)CFWriteStreamCreateWithBuffer(kCFAllocatorDefault, buffer, capacity); 231 } 232 233 - (id)initToMemory 234 { 235 return (id)CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault); 236 } 237 238 - (NSUInteger)retainCount 239 { 240 return CFGetRetainCount((CFTypeRef)self); 241 } 242 243 - (BOOL)_isDeallocating 244 { 245 return _CFIsDeallocating((CFTypeRef)self); 246 } 247 248 - (BOOL)_tryRetain 249 { 250 return _CFTryRetain((CFTypeRef)self) != NULL; 251 } 252 253 - (oneway void)release 254 { 255 CFRelease((CFTypeRef)self); 256 } 257 258 - (id)retain 259 { 260 return (id)CFRetain((CFTypeRef)self); 261 } 262 263 - (NSUInteger)hash 264 { 265 return CFHash((CFTypeRef)self); 266 } 267 268 - (BOOL)isEqual:(id)other 269 { 270 if (other == nil) 271 { 272 return NO; 273 } 274 return CFEqual((CFTypeRef)self, (CFTypeRef)other); 275 } 276 277 - (CFTypeID)_cfTypeID 278 { 279 return CFWriteStreamGetTypeID(); 280 } 281 282 @end