static void fileSchedule(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void *info) { _CFFileStreamContext *fileStream = (_CFFileStreamContext *)info; Boolean isReadStream = (CFGetTypeID(stream) == CFReadStreamGetTypeID()); CFStreamStatus status = isReadStream ? CFReadStreamGetStatus((CFReadStreamRef)stream) : CFWriteStreamGetStatus((CFWriteStreamRef)stream); if (fileStream->fd < 0 && status != kCFStreamStatusNotOpen) { // Stream's already closed or error-ed out return; } #ifdef REAL_FILE_SCHEDULING if (status == kCFStreamStatusNotOpen) { if (!fileStream->rlInfo.rlArray) { fileStream->rlInfo.rlArray = CFArrayCreateMutable(CFGetAllocator(stream), 0, &kCFTypeArrayCallBacks); } CFArrayAppendValue(fileStream->rlInfo.rlArray, runLoop); CFArrayAppendValue(fileStream->rlInfo.rlArray, runLoopMode); } else { CFRunLoopSourceRef rlSrc; if (!fileStream->rlInfo.cffd) { constructCFFD(fileStream, isReadStream, stream); } rlSrc = CFFileDescriptorCreateRunLoopSource(CFGetAllocator(stream), fileStream->rlInfo.cffd, 0); CFRunLoopAddSource(runLoop, rlSrc, runLoopMode); CFRelease(rlSrc); } #else fileStream->scheduled++; if (fileStream->scheduled == 1 && fileStream->fd > 0 && status == kCFStreamStatusOpen) { if (isReadStream) CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventHasBytesAvailable, NULL); else CFWriteStreamSignalEvent((CFWriteStreamRef)stream, kCFStreamEventCanAcceptBytes, NULL); } #endif }
static Boolean fileOpen(struct _CFStream *stream, CFStreamError *errorCode, Boolean *openComplete, void *info) { _CFFileStreamContext *ctxt = (_CFFileStreamContext *)info; Boolean forRead = (CFGetTypeID(stream) == CFReadStreamGetTypeID()); *openComplete = TRUE; if (ctxt->url) { if (constructFD(ctxt, errorCode, forRead, stream)) { #ifndef REAL_FILE_SCHEDULING if (ctxt->scheduled > 0) { if (forRead) CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventHasBytesAvailable, NULL); else CFWriteStreamSignalEvent((CFWriteStreamRef)stream, kCFStreamEventCanAcceptBytes, NULL); } #endif return TRUE; } else { return FALSE; } #ifdef REAL_FILE_SCHEDULING } else if (ctxt->rlInfo.rlArray != NULL) { constructCFFD(ctxt, forRead, stream); #endif } return TRUE; }
static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *error, Boolean forRead, struct _CFStream *stream) { int flags = forRead ? O_RDONLY : (O_CREAT | O_TRUNC | O_WRONLY); #if DEPLOYMENT_TARGET_WINDOWS wchar_t path[CFMaxPathSize]; flags |= (_O_BINARY|_O_NOINHERIT); if (_CFURLGetWideFileSystemRepresentation(fileStream->url, TRUE, path, CFMaxPathSize) == FALSE) #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI char path[CFMaxPathSize]; if (CFURLGetFileSystemRepresentation(fileStream->url, TRUE, (UInt8 *)path, CFMaxPathSize) == FALSE) #endif { error->error = ENOENT; error->domain = kCFStreamErrorDomainPOSIX; return FALSE; } if (__CFBitIsSet(fileStream->flags, APPEND)) { flags |= O_APPEND; flags &= ~O_TRUNC; } do { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI fileStream->fd = open((const char *)path, flags, 0666); #elif DEPLOYMENT_TARGET_WINDOWS fileStream->fd = _wopen(path, flags, 0666); #endif if (fileStream->fd < 0) break; if ((fileStream->offset != -1) && (lseek(fileStream->fd, fileStream->offset, SEEK_SET) == -1)) break; #ifdef REAL_FILE_SCHEDULING if (fileStream->rlInfo.rlArray != NULL) { constructCFFD(fileStream, forRead, stream); } #endif return TRUE; } while (1); __CFBitSet(fileStream->flags, USE_RUNLOOP_ARRAY); error->error = errno; error->domain = kCFStreamErrorDomainPOSIX; return FALSE; }
static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *error, Boolean forRead, struct _CFStream *stream) { int flags = forRead ? O_RDONLY : (O_CREAT | O_TRUNC | O_WRONLY); // WINOBJC: improve code reuse here by letting the underlying open implementation handle the narrow/wide conversions etc. char path[CFMaxPathSize]; #if DEPLOYMENT_TARGET_WINDOWS flags |= (_O_BINARY|_O_NOINHERIT); #endif if (CFURLGetFileSystemRepresentation(fileStream->url, TRUE, (UInt8 *)path, CFMaxPathSize) == FALSE) { error->error = ENOENT; error->domain = kCFStreamErrorDomainPOSIX; return FALSE; } if (__CFBitIsSet(fileStream->flags, APPEND)) { flags |= O_APPEND; flags &= ~O_TRUNC; } do { fileStream->fd = open((const char *)path, flags, 0666); if (fileStream->fd < 0) break; if ((fileStream->offset != -1) && (lseek(fileStream->fd, fileStream->offset, SEEK_SET) == -1)) break; #ifdef REAL_FILE_SCHEDULING if (fileStream->rlInfo.rlArray != NULL) { constructCFFD(fileStream, forRead, stream); } #endif return TRUE; } while (1); __CFBitSet(fileStream->flags, USE_RUNLOOP_ARRAY); error->error = errno; error->domain = kCFStreamErrorDomainPOSIX; return FALSE; }