+static const CFOptionFlags kNetworkEvents =
+ kCFStreamEventOpenCompleted |
+ kCFStreamEventHasBytesAvailable |
+ kCFStreamEventEndEncountered |
+ kCFStreamEventErrorOccurred |
+0;
+
+static void CFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType event, void *arg) {
+ switch (event) {
+ case kCFStreamEventOpenCompleted:
+ break;
+
+ case kCFStreamEventHasBytesAvailable:
+ case kCFStreamEventEndEncountered:
+ *reinterpret_cast<int *>(arg) = 1;
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ break;
+
+ case kCFStreamEventErrorOccurred:
+ *reinterpret_cast<int *>(arg) = -1;
+ CFRunLoopStop(CFRunLoopGetCurrent());
+ break;
+ }
+}
+
+/* http://lists.apple.com/archives/Macnetworkprog/2006/Apr/msg00014.html */
+int CFReadStreamOpen(CFReadStreamRef stream, double timeout) {
+ CFStreamClientContext context;
+ int value(0);
+
+ memset(&context, 0, sizeof(context));
+ context.info = &value;
+
+ if (CFReadStreamSetClient(stream, kNetworkEvents, CFReadStreamCallback, &context)) {
+ CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
+ if (CFReadStreamOpen(stream))
+ CFRunLoopRunInMode(kCFRunLoopDefaultMode, timeout, false);
+ else
+ value = -1;
+ CFReadStreamSetClient(stream, kCFStreamEventNone, NULL, NULL);
+ }
+
+ return value;
+}
+