]>
Commit | Line | Data |
---|---|---|
d8925383 | 1 | /* |
d8b101a4 | 2 | * Copyright (c) 2014 Apple Inc. All rights reserved. |
d8925383 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
d7384798 | 5 | * |
d8925383 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
d7384798 | 12 | * |
d8925383 A |
13 | * The Original Code and all software distributed under the License are |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
d7384798 | 20 | * |
d8925383 A |
21 | * @APPLE_LICENSE_HEADER_END@ |
22 | */ | |
f64f9b69 | 23 | |
d8925383 | 24 | /* CFStream.h |
d7384798 | 25 | Copyright (c) 2000-2014, Apple Inc. All rights reserved. |
d8925383 A |
26 | */ |
27 | ||
28 | #if !defined(__COREFOUNDATION_CFSTREAM__) | |
29 | #define __COREFOUNDATION_CFSTREAM__ 1 | |
30 | ||
31 | #include <CoreFoundation/CFBase.h> | |
32 | #include <CoreFoundation/CFString.h> | |
33 | #include <CoreFoundation/CFDictionary.h> | |
34 | #include <CoreFoundation/CFURL.h> | |
35 | #include <CoreFoundation/CFRunLoop.h> | |
36 | #include <CoreFoundation/CFSocket.h> | |
bd5b749c | 37 | #include <CoreFoundation/CFError.h> |
a48904a4 | 38 | #include <dispatch/dispatch.h> |
d8925383 | 39 | |
856091c5 | 40 | CF_IMPLICIT_BRIDGING_ENABLED |
bd5b749c | 41 | CF_EXTERN_C_BEGIN |
d8925383 | 42 | |
856091c5 | 43 | typedef CF_ENUM(CFIndex, CFStreamStatus) { |
d8925383 A |
44 | kCFStreamStatusNotOpen = 0, |
45 | kCFStreamStatusOpening, /* open is in-progress */ | |
46 | kCFStreamStatusOpen, | |
47 | kCFStreamStatusReading, | |
48 | kCFStreamStatusWriting, | |
49 | kCFStreamStatusAtEnd, /* no further bytes can be read/written */ | |
50 | kCFStreamStatusClosed, | |
51 | kCFStreamStatusError | |
bd5b749c | 52 | }; |
d8925383 | 53 | |
856091c5 | 54 | typedef CF_OPTIONS(CFOptionFlags, CFStreamEventType) { |
d8925383 A |
55 | kCFStreamEventNone = 0, |
56 | kCFStreamEventOpenCompleted = 1, | |
57 | kCFStreamEventHasBytesAvailable = 2, | |
58 | kCFStreamEventCanAcceptBytes = 4, | |
59 | kCFStreamEventErrorOccurred = 8, | |
60 | kCFStreamEventEndEncountered = 16 | |
bd5b749c | 61 | }; |
d8925383 A |
62 | |
63 | typedef struct { | |
64 | CFIndex version; | |
65 | void *info; | |
66 | void *(*retain)(void *info); | |
67 | void (*release)(void *info); | |
68 | CFStringRef (*copyDescription)(void *info); | |
69 | } CFStreamClientContext; | |
70 | ||
d7384798 A |
71 | typedef struct CF_BRIDGED_MUTABLE_TYPE(NSInputStream) __CFReadStream * CFReadStreamRef; |
72 | typedef struct CF_BRIDGED_MUTABLE_TYPE(NSOutputStream) __CFWriteStream * CFWriteStreamRef; | |
d8925383 A |
73 | |
74 | typedef void (*CFReadStreamClientCallBack)(CFReadStreamRef stream, CFStreamEventType type, void *clientCallBackInfo); | |
75 | typedef void (*CFWriteStreamClientCallBack)(CFWriteStreamRef stream, CFStreamEventType type, void *clientCallBackInfo); | |
76 | ||
77 | CF_EXPORT | |
78 | CFTypeID CFReadStreamGetTypeID(void); | |
79 | CF_EXPORT | |
80 | CFTypeID CFWriteStreamGetTypeID(void); | |
81 | ||
82 | /* Memory streams */ | |
83 | ||
84 | /* Value will be a CFData containing all bytes thusfar written; used to recover the data written to a memory write stream. */ | |
85 | CF_EXPORT | |
86 | const CFStringRef kCFStreamPropertyDataWritten; | |
87 | ||
88 | /* Pass kCFAllocatorNull for bytesDeallocator to prevent CFReadStream from deallocating bytes; otherwise, CFReadStream will deallocate bytes when the stream is destroyed */ | |
89 | CF_EXPORT | |
90 | CFReadStreamRef CFReadStreamCreateWithBytesNoCopy(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex length, CFAllocatorRef bytesDeallocator); | |
91 | ||
92 | /* The stream writes into the buffer given; when bufferCapacity is exhausted, the stream is exhausted (status becomes kCFStreamStatusAtEnd) */ | |
93 | CF_EXPORT | |
94 | CFWriteStreamRef CFWriteStreamCreateWithBuffer(CFAllocatorRef alloc, UInt8 *buffer, CFIndex bufferCapacity); | |
95 | ||
96 | /* New buffers are allocated from bufferAllocator as bytes are written to the stream. At any point, you can recover the bytes thusfar written by asking for the property kCFStreamPropertyDataWritten, above */ | |
97 | CF_EXPORT | |
98 | CFWriteStreamRef CFWriteStreamCreateWithAllocatedBuffers(CFAllocatorRef alloc, CFAllocatorRef bufferAllocator); | |
99 | ||
100 | /* File streams */ | |
101 | CF_EXPORT | |
102 | CFReadStreamRef CFReadStreamCreateWithFile(CFAllocatorRef alloc, CFURLRef fileURL); | |
103 | CF_EXPORT | |
104 | CFWriteStreamRef CFWriteStreamCreateWithFile(CFAllocatorRef alloc, CFURLRef fileURL); | |
856091c5 | 105 | CF_IMPLICIT_BRIDGING_DISABLED |
bd5b749c A |
106 | CF_EXPORT |
107 | void CFStreamCreateBoundPair(CFAllocatorRef alloc, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream, CFIndex transferBufferSize); | |
856091c5 | 108 | CF_IMPLICIT_BRIDGING_ENABLED |
d8925383 | 109 | |
d8925383 A |
110 | /* Property for file write streams; value should be a CFBoolean. Set to TRUE to append to a file, rather than to replace its contents */ |
111 | CF_EXPORT | |
112 | const CFStringRef kCFStreamPropertyAppendToFile; | |
d8925383 | 113 | |
8ca704e1 A |
114 | CF_EXPORT |
115 | const CFStringRef kCFStreamPropertyFileCurrentOffset; // Value is a CFNumber | |
d8925383 | 116 | |
d8925383 A |
117 | |
118 | /* Socket stream properties */ | |
119 | ||
120 | /* Value will be a CFData containing the native handle */ | |
121 | CF_EXPORT | |
122 | const CFStringRef kCFStreamPropertySocketNativeHandle; | |
123 | ||
124 | /* Value will be a CFString, or NULL if unknown */ | |
125 | CF_EXPORT | |
126 | const CFStringRef kCFStreamPropertySocketRemoteHostName; | |
127 | ||
128 | /* Value will be a CFNumber, or NULL if unknown */ | |
129 | CF_EXPORT | |
130 | const CFStringRef kCFStreamPropertySocketRemotePortNumber; | |
131 | ||
856091c5 | 132 | CF_IMPLICIT_BRIDGING_DISABLED |
d8925383 A |
133 | /* Socket streams; the returned streams are paired such that they use the same socket; pass NULL if you want only the read stream or the write stream */ |
134 | CF_EXPORT | |
135 | void CFStreamCreatePairWithSocket(CFAllocatorRef alloc, CFSocketNativeHandle sock, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream); | |
136 | CF_EXPORT | |
137 | void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream); | |
d8925383 A |
138 | CF_EXPORT |
139 | void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc, const CFSocketSignature *signature, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream); | |
856091c5 | 140 | CF_IMPLICIT_BRIDGING_ENABLED |
d8925383 A |
141 | |
142 | ||
143 | /* Returns the current state of the stream */ | |
144 | CF_EXPORT | |
145 | CFStreamStatus CFReadStreamGetStatus(CFReadStreamRef stream); | |
146 | CF_EXPORT | |
147 | CFStreamStatus CFWriteStreamGetStatus(CFWriteStreamRef stream); | |
148 | ||
bd5b749c | 149 | /* Returns NULL if no error has occurred; otherwise returns the error. */ |
d8925383 | 150 | CF_EXPORT |
8ca704e1 | 151 | CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream) CF_AVAILABLE(10_5, 2_0); |
d8925383 | 152 | CF_EXPORT |
8ca704e1 | 153 | CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream) CF_AVAILABLE(10_5, 2_0); |
d8925383 A |
154 | |
155 | /* Returns success/failure. Opening a stream causes it to reserve all the system | |
156 | resources it requires. If the stream can open non-blocking, this will always | |
157 | return TRUE; listen to the run loop source to find out when the open completes | |
158 | and whether it was successful, or poll using CFRead/WriteStreamGetStatus(), waiting | |
159 | for a status of kCFStreamStatusOpen or kCFStreamStatusError. */ | |
160 | CF_EXPORT | |
161 | Boolean CFReadStreamOpen(CFReadStreamRef stream); | |
162 | CF_EXPORT | |
163 | Boolean CFWriteStreamOpen(CFWriteStreamRef stream); | |
164 | ||
165 | /* Terminates the flow of bytes; releases any system resources required by the | |
166 | stream. The stream may not fail to close. You may call CFStreamClose() to | |
167 | effectively abort a stream. */ | |
168 | CF_EXPORT | |
169 | void CFReadStreamClose(CFReadStreamRef stream); | |
170 | CF_EXPORT | |
171 | void CFWriteStreamClose(CFWriteStreamRef stream); | |
172 | ||
173 | /* Whether there is data currently available for reading; returns TRUE if it's | |
174 | impossible to tell without trying */ | |
175 | CF_EXPORT | |
176 | Boolean CFReadStreamHasBytesAvailable(CFReadStreamRef stream); | |
177 | ||
178 | /* Returns the number of bytes read, or -1 if an error occurs preventing any | |
179 | bytes from being read, or 0 if the stream's end was encountered. | |
180 | It is an error to try and read from a stream that hasn't been opened first. | |
181 | This call will block until at least one byte is available; it will NOT block | |
182 | until the entire buffer can be filled. To avoid blocking, either poll using | |
183 | CFReadStreamHasBytesAvailable() or use the run loop and listen for the | |
184 | kCFStreamCanRead event for notification of data available. */ | |
185 | CF_EXPORT | |
186 | CFIndex CFReadStreamRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength); | |
187 | ||
188 | /* Returns a pointer to an internal buffer if possible (setting *numBytesRead | |
a48904a4 A |
189 | to the length of the returned buffer), otherwise returns NULL; guaranteed |
190 | to return in O(1). Bytes returned in the buffer are considered read from | |
d8925383 A |
191 | the stream; if maxBytesToRead is greater than 0, not more than maxBytesToRead |
192 | will be returned. If maxBytesToRead is less than or equal to zero, as many bytes | |
a48904a4 A |
193 | as are readily available will be returned. The returned buffer is good only |
194 | until the next stream operation called on the stream. Caller should neither | |
d8925383 A |
195 | change the contents of the returned buffer nor attempt to deallocate the buffer; |
196 | it is still owned by the stream. */ | |
197 | CF_EXPORT | |
198 | const UInt8 *CFReadStreamGetBuffer(CFReadStreamRef stream, CFIndex maxBytesToRead, CFIndex *numBytesRead); | |
199 | ||
200 | /* Whether the stream can currently be written to without blocking; | |
201 | returns TRUE if it's impossible to tell without trying */ | |
202 | CF_EXPORT | |
203 | Boolean CFWriteStreamCanAcceptBytes(CFWriteStreamRef stream); | |
204 | ||
205 | /* Returns the number of bytes successfully written, -1 if an error has | |
206 | occurred, or 0 if the stream has been filled to capacity (for fixed-length | |
207 | streams). If the stream is not full, this call will block until at least | |
208 | one byte is written. To avoid blocking, either poll via CFWriteStreamCanAcceptBytes | |
209 | or use the run loop and listen for the kCFStreamCanWrite event. */ | |
210 | CF_EXPORT | |
211 | CFIndex CFWriteStreamWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex bufferLength); | |
212 | ||
213 | /* Particular streams can name properties and assign meanings to them; you | |
214 | access these properties through the following calls. A property is any interesting | |
215 | information about the stream other than the data being transmitted itself. | |
216 | Examples include the headers from an HTTP transmission, or the expected | |
217 | number of bytes, or permission information, etc. Properties that can be set | |
218 | configure the behavior of the stream, and may only be settable at particular times | |
219 | (like before the stream has been opened). See the documentation for particular | |
220 | properties to determine their get- and set-ability. */ | |
221 | CF_EXPORT | |
222 | CFTypeRef CFReadStreamCopyProperty(CFReadStreamRef stream, CFStringRef propertyName); | |
223 | CF_EXPORT | |
224 | CFTypeRef CFWriteStreamCopyProperty(CFWriteStreamRef stream, CFStringRef propertyName); | |
225 | ||
d8925383 A |
226 | /* Returns TRUE if the stream recognizes and accepts the given property-value pair; |
227 | FALSE otherwise. */ | |
228 | CF_EXPORT | |
229 | Boolean CFReadStreamSetProperty(CFReadStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue); | |
230 | CF_EXPORT | |
231 | Boolean CFWriteStreamSetProperty(CFWriteStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue); | |
d8925383 A |
232 | |
233 | /* Asynchronous processing - If you wish to neither poll nor block, you may register | |
234 | a client to hear about interesting events that occur on a stream. Only one client | |
235 | per stream is allowed; registering a new client replaces the previous one. | |
a48904a4 A |
236 | |
237 | Once you have set a client, the stream must be scheduled to provide the context in | |
238 | which the client will be called. Streams may be scheduled on a single dispatch queue | |
239 | or on one or more run loops. If scheduled on a run loop, it is the caller's responsibility | |
240 | to ensure that at least one of the scheduled run loops is being run. | |
d8925383 | 241 | |
bd5b749c A |
242 | NOTE: Unlike other CoreFoundation APIs, pasing a NULL clientContext here will remove |
243 | the client. If you do not care about the client context (i.e. your only concern | |
244 | is that your callback be called), you should pass in a valid context where every | |
245 | entry is 0 or NULL. | |
246 | ||
d8925383 A |
247 | */ |
248 | ||
249 | CF_EXPORT | |
250 | Boolean CFReadStreamSetClient(CFReadStreamRef stream, CFOptionFlags streamEvents, CFReadStreamClientCallBack clientCB, CFStreamClientContext *clientContext); | |
251 | CF_EXPORT | |
252 | Boolean CFWriteStreamSetClient(CFWriteStreamRef stream, CFOptionFlags streamEvents, CFWriteStreamClientCallBack clientCB, CFStreamClientContext *clientContext); | |
253 | ||
254 | CF_EXPORT | |
255 | void CFReadStreamScheduleWithRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode); | |
256 | CF_EXPORT | |
257 | void CFWriteStreamScheduleWithRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode); | |
258 | ||
259 | CF_EXPORT | |
260 | void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode); | |
261 | CF_EXPORT | |
262 | void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode); | |
263 | ||
a48904a4 A |
264 | /* |
265 | * Specify the dispatch queue upon which the client callbacks will be invoked. | |
266 | * Passing NULL for the queue will prevent future callbacks from being invoked. | |
267 | * Specifying a dispatch queue using this API will unschedule the stream from | |
268 | * any run loops it had previously been scheduled upon - similarly, scheduling | |
269 | * with a runloop will disassociate the stream from any existing dispatch queue. | |
270 | */ | |
271 | CF_EXPORT | |
272 | void CFReadStreamSetDispatchQueue(CFReadStreamRef stream, dispatch_queue_t q) CF_AVAILABLE(10_9, 7_0); | |
273 | ||
274 | CF_EXPORT | |
275 | void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q) CF_AVAILABLE(10_9, 7_0); | |
276 | ||
277 | /* | |
278 | * Returns the previously set dispatch queue with an incremented retain count. | |
279 | * Note that the stream's queue may have been set to NULL if the stream was | |
280 | * scheduled on a runloop subsequent to it having had a dispatch queue set. | |
281 | */ | |
282 | CF_EXPORT | |
283 | dispatch_queue_t CFReadStreamCopyDispatchQueue(CFReadStreamRef stream) CF_AVAILABLE(10_9, 7_0); | |
284 | ||
285 | CF_EXPORT | |
286 | dispatch_queue_t CFWriteStreamCopyDispatchQueue(CFWriteStreamRef stream) CF_AVAILABLE(10_9, 7_0); | |
bd5b749c A |
287 | |
288 | /* The following API is deprecated starting in 10.5; please use CFRead/WriteStreamCopyError(), above, instead */ | |
856091c5 A |
289 | typedef CF_ENUM(CFIndex, CFStreamErrorDomain) { |
290 | kCFStreamErrorDomainCustom = -1L, /* custom to the kind of stream in question */ | |
bd5b749c A |
291 | kCFStreamErrorDomainPOSIX = 1, /* POSIX errno; interpret using <sys/errno.h> */ |
292 | kCFStreamErrorDomainMacOSStatus /* OSStatus type from Carbon APIs; interpret using <MacTypes.h> */ | |
293 | }; | |
bd5b749c A |
294 | |
295 | typedef struct { | |
296 | CFIndex domain; | |
297 | SInt32 error; | |
298 | } CFStreamError; | |
299 | CF_EXPORT | |
300 | CFStreamError CFReadStreamGetError(CFReadStreamRef stream); | |
301 | CF_EXPORT | |
302 | CFStreamError CFWriteStreamGetError(CFWriteStreamRef stream); | |
303 | ||
304 | ||
305 | CF_EXTERN_C_END | |
856091c5 | 306 | CF_IMPLICIT_BRIDGING_DISABLED |
d8925383 A |
307 | |
308 | #endif /* ! __COREFOUNDATION_CFSTREAM__ */ |