static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context)
{
    FormStreamFields* form = static_cast<FormStreamFields*>(context);

    switch (type) {
    case kCFStreamEventHasBytesAvailable:
        CFReadStreamSignalEvent(form->formStream, kCFStreamEventHasBytesAvailable, 0);
        break;
    case kCFStreamEventErrorOccurred: {
        CFStreamError readStreamError = CFReadStreamGetError(stream);
        CFReadStreamSignalEvent(form->formStream, kCFStreamEventErrorOccurred, &readStreamError);
        break;
    }
    case kCFStreamEventEndEncountered:
        openNextStream(form);
        if (!form->currentStream)
            CFReadStreamSignalEvent(form->formStream, kCFStreamEventEndEncountered, 0);
        break;
    case kCFStreamEventNone:
        LOG_ERROR("unexpected kCFStreamEventNone");
        break;
    case kCFStreamEventOpenCompleted:
        LOG_ERROR("unexpected kCFStreamEventOpenCompleted");
        break;
    case kCFStreamEventCanAcceptBytes:
        LOG_ERROR("unexpected kCFStreamEventCanAcceptBytes");
        break;
    }
}
示例#2
0
static Boolean readDataOpen(struct _CFStream *stream, CFStreamError *errorCode, Boolean *openComplete, void *info) {
    _CFReadDataStreamContext *dataStream = (_CFReadDataStreamContext *)info;
    if (dataStream->scheduled) {
        if (CFDataGetLength(dataStream->data) != 0) {
            CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventHasBytesAvailable, NULL);
        } else {
            CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventEndEncountered, NULL);
        }
    }
    errorCode->error = 0;
    *openComplete = TRUE;
    return TRUE;
}
示例#3
0
static void readDataSchedule(struct _CFStream *stream, CFRunLoopRef rl, CFStringRef rlMode, void *info) {
    _CFReadDataStreamContext *dataStream = (_CFReadDataStreamContext *)info;
    if (dataStream->scheduled == FALSE) {
        dataStream->scheduled = TRUE;
        if (CFReadStreamGetStatus((CFReadStreamRef)stream) != kCFStreamStatusOpen)
            return;
        if (CFDataGetBytePtr(dataStream->data) + CFDataGetLength(dataStream->data) > dataStream->loc) {
            CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventHasBytesAvailable, NULL);
        } else {
            CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventEndEncountered, NULL);
        }
    }
}
示例#4
0
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
}
示例#5
0
static CFIndex fileRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode, Boolean *atEOF, void *info) {
    _CFFileStreamContext *ctxt = (_CFFileStreamContext *)info;
    CFIndex result;
    result = fdRead(ctxt->fd, buffer, bufferLength, errorCode, atEOF);
#ifdef REAL_FILE_SCHEDULING
    if (__CFBitIsSet(ctxt->flags, SCHEDULE_AFTER_READ)) {
        __CFBitClear(ctxt->flags, SCHEDULE_AFTER_READ);
        if (!*atEOF && ctxt->rlInfo.cffd) {
            struct stat statbuf;
            int ret = fstat(ctxt->fd, &statbuf);
            if (0 <= ret && (S_IFREG == (statbuf.st_mode & S_IFMT))) {
                off_t offset = lseek(ctxt->fd, 0, SEEK_CUR);
                if (statbuf.st_size == offset) {
                    _CFFileDescriptorInduceFakeReadCallBack(ctxt->rlInfo.cffd);
                }
            }
        }
        if (ctxt->rlInfo.cffd) {
            CFFileDescriptorEnableCallBacks(ctxt->rlInfo.cffd, kCFFileDescriptorReadCallBack);
        }
    }
#else
    if (*atEOF)
        __CFBitSet(ctxt->flags, AT_EOF);
    if (ctxt->scheduled > 0 && !*atEOF) {
        CFReadStreamSignalEvent(stream, kCFStreamEventHasBytesAvailable, NULL);
    }
#endif
    return result;
}
示例#6
0
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;
}
示例#7
0
static void fileCallBack(CFFileDescriptorRef f, CFOptionFlags type, void *info) {
    struct _CFStream *stream = (struct _CFStream *)info;
    Boolean isReadStream = (CFGetTypeID(stream) == CFReadStreamGetTypeID());
    _CFFileStreamContext *fileStream = isReadStream ? CFReadStreamGetInfoPointer((CFReadStreamRef)stream) : CFWriteStreamGetInfoPointer((CFWriteStreamRef)stream);
    if (type == kCFFileDescriptorWriteCallBack) {
        __CFBitSet(fileStream->flags, SCHEDULE_AFTER_WRITE);
        CFWriteStreamSignalEvent((CFWriteStreamRef)stream, kCFStreamEventCanAcceptBytes, NULL);
    } else {
        __CFBitSet(fileStream->flags, SCHEDULE_AFTER_READ);
        CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventHasBytesAvailable, NULL);
    }
}
static Boolean formCanRead(CFReadStreamRef stream, void* context)
{
    FormStreamFields* form = static_cast<FormStreamFields*>(context);

    while (form->currentStream && CFReadStreamGetStatus(form->currentStream) == kCFStreamStatusAtEnd)
        openNextStream(form);

    if (!form->currentStream) {
        CFReadStreamSignalEvent(stream, kCFStreamEventEndEncountered, 0);
        return FALSE;
    }
    return CFReadStreamHasBytesAvailable(form->currentStream);
}
static const UInt8 *dataGetBuffer(CFReadStreamRef stream, CFIndex maxBytesToRead, CFIndex *numBytesRead, CFStreamError *error, Boolean *atEOF, void *info) {
    _CFReadDataStreamContext *dataCtxt = (_CFReadDataStreamContext *)info;
    const UInt8 *bytes = CFDataGetBytePtr(dataCtxt->data);
    if (dataCtxt->loc - bytes > maxBytesToRead) {
        *numBytesRead = maxBytesToRead;
        *atEOF = FALSE;
    } else {
        *numBytesRead = dataCtxt->loc - bytes;
        *atEOF = TRUE;
    }
    error->error = 0;
    bytes = dataCtxt->loc;
    dataCtxt->loc += *numBytesRead;
    if (dataCtxt->scheduled && !*atEOF) {
        CFReadStreamSignalEvent(stream, kCFStreamEventHasBytesAvailable, NULL);
    }
    return bytes;
}
示例#10
0
static CFIndex dataRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength, CFStreamError *error, Boolean *atEOF, void *info) {
    _CFReadDataStreamContext *dataCtxt = (_CFReadDataStreamContext *)info;
    const UInt8 *bytePtr = CFDataGetBytePtr(dataCtxt->data);
    CFIndex length = CFDataGetLength(dataCtxt->data);
    CFIndex bytesToCopy = bytePtr + length - dataCtxt->loc;
    if (bytesToCopy > bufferLength) {
        bytesToCopy = bufferLength;
    }
    if (bytesToCopy < 0) {
        bytesToCopy = 0;
    }
    if (bytesToCopy != 0) {
        memmove(buffer, dataCtxt->loc, bytesToCopy);
        dataCtxt->loc += bytesToCopy;
    }
    error->error = 0;
    *atEOF = (dataCtxt->loc < bytePtr + length) ? FALSE : TRUE;
    if (dataCtxt->scheduled && !*atEOF) {
        CFReadStreamSignalEvent(stream, kCFStreamEventHasBytesAvailable, NULL);
    }
    return bytesToCopy;
}