static ssize_t mailstream_low_cfstream_read(mailstream_low * s, void * buf, size_t count) { #if HAVE_CFNETWORK struct mailstream_cfstream_data * cfstream_data; int r; cfstream_data = (struct mailstream_cfstream_data *) s->data; cfstream_data->readBuffer = buf; cfstream_data->readBufferSize = count; if (cfstream_data->cancelled) { return -1; } if (CFReadStreamGetStatus(cfstream_data->readStream) == kCFStreamStatusError) { return -1; } if (CFReadStreamHasBytesAvailable(cfstream_data->readStream)) { readDataFromStream(s); return cfstream_data->readResult; } r = wait_runloop(s, STATE_WAIT_READ); if (r != WAIT_RUNLOOP_EXIT_NO_ERROR) { return -1; } return cfstream_data->readResult; #else return -1; #endif }
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 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 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); } } }
SInt64 HTTPInputSource::Read(void *buffer, SInt64 byteCount) { if(!IsOpen()) return -1; CFStreamStatus status = CFReadStreamGetStatus(mReadStream); if(kCFStreamStatusAtEnd == status) return 0; else if(kCFStreamStatusNotOpen == status || kCFStreamStatusClosed == status || kCFStreamStatusError == status) return -1; CFIndex bytesRead = CFReadStreamRead(mReadStream, static_cast<UInt8 *>(buffer), byteCount); mOffset += bytesRead; return bytesRead; }
static void fileUnschedule(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void *info) { _CFFileStreamContext *fileStream = (_CFFileStreamContext *)info; #ifdef REAL_FILE_SCHEDULING Boolean isReadStream = (CFGetTypeID(stream) == CFReadStreamGetTypeID()); CFStreamStatus status = isReadStream ? CFReadStreamGetStatus((CFReadStreamRef)stream) : CFWriteStreamGetStatus((CFWriteStreamRef)stream); if (status == kCFStreamStatusNotOpen) { // Not opened yet if (fileStream->rlInfo.rlArray) { CFMutableArrayRef runloops = fileStream->rlInfo.rlArray; CFIndex i, c; for (i = 0, c = CFArrayGetCount(runloops); i+1 < c; i += 2) { if (CFEqual(CFArrayGetValueAtIndex(runloops, i), runLoop) && CFEqual(CFArrayGetValueAtIndex(runloops, i+1), runLoopMode)) { CFArrayRemoveValueAtIndex(runloops, i); CFArrayRemoveValueAtIndex(runloops, i); break; } } } } else if (fileStream->rlInfo.cffd) { if (__CFBitIsSet(fileStream->flags, USE_RUNLOOP_ARRAY)) { // we know that fileStream->rlInfo.rlArray is non-NULL because it is in a union with fileStream->rlInfo.cffd CFMutableArrayRef runloops = fileStream->rlInfo.rlArray; CFIndex i, c; for (i = 0, c = CFArrayGetCount(runloops); i+1 < c; i += 2) { if (CFEqual(CFArrayGetValueAtIndex(runloops, i), runLoop) && CFEqual(CFArrayGetValueAtIndex(runloops, i+1), runLoopMode)) { CFArrayRemoveValueAtIndex(runloops, i); CFArrayRemoveValueAtIndex(runloops, i); break; } } } else { CFRunLoopSourceRef rlSrc = CFFileDescriptorCreateRunLoopSource(CFGetAllocator(stream), fileStream->rlInfo.cffd, 0); CFRunLoopRemoveSource(runLoop, rlSrc, runLoopMode); CFRelease(rlSrc); } } #else if (fileStream->scheduled > 0) fileStream->scheduled--; #endif }
void HTTP_Stream::readCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { HTTP_Stream *THIS = static_cast<HTTP_Stream*>(clientCallBackInfo); switch (eventType) { case kCFStreamEventHasBytesAvailable: { if (!THIS->m_httpReadBuffer) { THIS->m_httpReadBuffer = new UInt8[STREAM_BUFSIZ]; } while (CFReadStreamHasBytesAvailable(stream)) { if (!THIS->m_scheduledInRunLoop) { /* * This is critical - though the stream has data available, * do not try to feed the audio queue with data, if it has * indicated that it doesn't want more data due to buffers * full. */ THIS->m_readPending = true; break; } CFIndex bytesRead = CFReadStreamRead(stream, THIS->m_httpReadBuffer, STREAM_BUFSIZ); if (CFReadStreamGetStatus(stream) == kCFStreamStatusError || bytesRead < 0) { if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(); } break; } if (bytesRead > 0) { THIS->parseHttpHeadersIfNeeded(THIS->m_httpReadBuffer, bytesRead); #ifdef INCLUDE_ID3TAG_SUPPORT if (THIS->m_id3Parser->wantData()) { THIS->m_id3Parser->feedData(THIS->m_httpReadBuffer, (UInt32)bytesRead); } #endif if (THIS->m_icyStream) { THIS->parseICYStream(THIS->m_httpReadBuffer, bytesRead); } else { if (THIS->m_delegate) { THIS->m_delegate->streamHasBytesAvailable(THIS->m_httpReadBuffer, (UInt32)bytesRead); } } } } break; } case kCFStreamEventEndEncountered: { if (THIS->m_delegate) { THIS->m_delegate->streamEndEncountered(); } break; } case kCFStreamEventErrorOccurred: { if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(); } break; } } }
nuiHTTPResponse* nuiHTTPRequest::SendRequest() { char* pUrl = mUrl.Export(); CFStringRef originalURLString = CFStringCreateWithCString(kCFAllocatorDefault, pUrl, kCFStringEncodingUTF8); CFStringRef preprocessedString = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, originalURLString, CFSTR(""), kCFStringEncodingUTF8); CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, preprocessedString, NULL, NULL, kCFStringEncodingUTF8); free(pUrl); CFURLRef url = CFURLCreateWithString(kCFAllocatorDefault, urlString, NULL); CFRelease(urlString); char* pMeth = mMethod.Export(); CFStringRef method = CFStringCreateWithCString(kCFAllocatorDefault, pMeth, kCFStringEncodingUTF8); free(pMeth); CFHTTPMessageRef req = CFHTTPMessageCreateRequest(kCFAllocatorDefault, method, url, kCFHTTPVersion1_1); CFStringRef userAgentField = CFSTR("User-Agent"); CFStringRef userAgentName = CFSTR("nuiHTTP/2.0"); CFHTTPMessageSetHeaderFieldValue(req, userAgentField, userAgentName); CFRelease(userAgentField); CFRelease(userAgentName); nuiHTTPHeaderMap::const_iterator end = mHeaders.end(); for (nuiHTTPHeaderMap::const_iterator it = mHeaders.begin(); it != end; ++it) { char* pName = it->first.Export(); char* pVal = it->second.Export(); CFStringRef fieldName = CFStringCreateWithCString(kCFAllocatorDefault, pName, kCFStringEncodingUTF8); CFStringRef fieldValue = CFStringCreateWithCString(kCFAllocatorDefault, pVal, kCFStringEncodingUTF8); CFHTTPMessageSetHeaderFieldValue(req, fieldName, fieldValue); CFRelease(fieldName); CFRelease(fieldValue); delete pName; delete pVal; } CFDataRef body = NULL; if (mBody.size()) { body = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8*)&mBody[0], mBody.size(), kCFAllocatorNull); CFHTTPMessageSetBody(req, body); } CFReadStreamRef readStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, req); CFReadStreamOpen(readStream); std::vector<char> buf; CFIndex pos = 0; CFIndex size = 0; bool cont = true; do { buf.resize(pos + 1024); size = CFReadStreamRead(readStream, (UInt8*)&buf[pos], 1024); if (size == -1) { return NULL; } else if (size == 0) { if (CFReadStreamGetStatus(readStream) == kCFStreamStatusAtEnd) cont = false; else nglThread::MsSleep(10); } pos += size; } while (cont); CFHTTPMessageRef responseHeader = (CFHTTPMessageRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertyHTTPResponseHeader); CFStringRef statusLine = CFHTTPMessageCopyResponseStatusLine(responseHeader); CFIndex strSize = CFStringGetLength(statusLine)+1; char* pStatus = new char[strSize]; CFStringGetCString(statusLine, pStatus, strSize, kCFStringEncodingUTF8); nglString status(pStatus); UInt32 statusCode = CFHTTPMessageGetResponseStatusCode(responseHeader); nuiHTTPResponse* pResponse = new nuiHTTPResponse(statusCode, status); pResponse->SetBody(&buf[0], pos); delete[] pStatus; CFDictionaryRef dict = CFHTTPMessageCopyAllHeaderFields(responseHeader); CFIndex valueCount = CFDictionaryGetCount(dict); const CFStringRef* pNames = new CFStringRef[valueCount]; const CFStringRef* pValues = new CFStringRef[valueCount]; CFDictionaryGetKeysAndValues(dict, (const void**)pNames, (const void**)pValues); for (CFIndex i = 0; i< valueCount; i++) { strSize = CFStringGetLength(pNames[i])+1; char* pName = new char[strSize]; CFStringGetCString(pNames[i], pName, strSize, kCFStringEncodingUTF8); strSize = CFStringGetLength(pValues[i])+1; char* pVal = new char[strSize]; CFStringGetCString(pValues[i], pVal, strSize, kCFStringEncodingUTF8); nglString name(pName); nglString val(pVal); pResponse->AddHeader(name, val); delete[] pName; delete[] pVal; } delete[] pNames; delete[] pValues; CFRelease(responseHeader); CFRelease(url); CFRelease(method); CFRelease(req); CFRelease(readStream); CFRelease(dict); CFRelease(statusLine); if (body) CFRelease(body); return pResponse; }
void HTTP_Stream::readCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) { HTTP_Stream *THIS = static_cast<HTTP_Stream*>(clientCallBackInfo); Stream_Configuration *config = Stream_Configuration::configuration(); switch (eventType) { case kCFStreamEventHasBytesAvailable: { if (!THIS->m_httpReadBuffer) { THIS->m_httpReadBuffer = new UInt8[config->httpConnectionBufferSize]; } while (CFReadStreamHasBytesAvailable(stream)) { if (!THIS->m_scheduledInRunLoop) { /* * This is critical - though the stream has data available, * do not try to feed the audio queue with data, if it has * indicated that it doesn't want more data due to buffers * full. */ THIS->m_readPending = true; break; } CFIndex bytesRead = CFReadStreamRead(stream, THIS->m_httpReadBuffer, config->httpConnectionBufferSize); if (CFReadStreamGetStatus(stream) == kCFStreamStatusError || bytesRead < 0) { #if defined (HS_DEBUG) CFErrorRef streamError = CFReadStreamCopyError(stream); if (streamError) { CFStringRef errorDesc = CFErrorCopyDescription(streamError); if (errorDesc) { HS_TRACE_CFSTRING(errorDesc); CFRelease(errorDesc); } CFRelease(streamError); } #endif /* HS_DEBUG */ if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(); } break; } if (bytesRead > 0) { HS_TRACE("Read %li bytes\n", bytesRead); THIS->parseHttpHeadersIfNeeded(THIS->m_httpReadBuffer, bytesRead); #ifdef INCLUDE_ID3TAG_SUPPORT if (!THIS->m_icyStream && THIS->m_id3Parser->wantData()) { THIS->m_id3Parser->feedData(THIS->m_httpReadBuffer, (UInt32)bytesRead); } #endif if (THIS->m_icyStream) { HS_TRACE("Parsing ICY stream\n"); THIS->parseICYStream(THIS->m_httpReadBuffer, bytesRead); } else { if (THIS->m_delegate) { HS_TRACE("Not an ICY stream; calling the delegate back\n"); THIS->m_delegate->streamHasBytesAvailable(THIS->m_httpReadBuffer, (UInt32)bytesRead); } } } } break; } case kCFStreamEventEndEncountered: { if (THIS->m_delegate) { THIS->m_delegate->streamEndEncountered(); } break; } case kCFStreamEventErrorOccurred: { if (THIS->m_delegate) { THIS->m_delegate->streamErrorOccurred(); } break; } } }
void *ConvertWAVCFURL(CFURLRef theURL, size_t *sndSize, int *loopStart, int *loopEnd, short *sampleSize, unsigned int *rate, bool *stereo) { PCMWavePtr WAVERsrc = NULL; long fSize = 0; CFReadStreamRef fRef = CFReadStreamCreateWithFile(kCFAllocatorDefault, theURL); CFReadStreamOpen(fRef); CFStreamStatus theStat = CFReadStreamGetStatus(fRef); while (theStat != kCFStreamStatusOpen && theStat != kCFStreamStatusError) { theStat = CFReadStreamGetStatus(fRef); } if (theStat == kCFStreamStatusError) { CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } *stereo = false; if (fRef != NULL) { fSize = URLGetFileSize(theURL); if (!(WAVERsrc = (PCMWavePtr)malloc(fSize))) { CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } if (CFReadStreamRead(fRef, (UInt8*)WAVERsrc, fSize) != fSize) { free(WAVERsrc); CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } if (memcmp(WAVERsrc->ckid, "RIFF", 4) == 0) { WAVERsrc->cksize = longswap(WAVERsrc->cksize); if (memcmp(WAVERsrc->fccType, "WAVE", 4) == 0) { WAVERsrc->dwDataOffset = longswap(WAVERsrc->dwDataOffset); if (memcmp(WAVERsrc->fmtType, "fmt ", 4) == 0) { WAVERsrc->wFormatTag = shrtswap(WAVERsrc->wFormatTag); WAVERsrc->nCannels = shrtswap(WAVERsrc->nCannels); WAVERsrc->nSamplesPerSec = longswap(WAVERsrc->nSamplesPerSec); WAVERsrc->nSamplesPerSec = CFSwapInt32BigToHost(WAVERsrc->nSamplesPerSec) << 16; //FIXME: is this right for LE machines? WAVERsrc->nAvgBytesPerSec = longswap(WAVERsrc->nAvgBytesPerSec); WAVERsrc->nBlockAlign = shrtswap(WAVERsrc->nBlockAlign); WAVERsrc->wBitsPerSample = shrtswap(WAVERsrc->wBitsPerSample); WAVERsrc->dataSize = longswap(WAVERsrc->dataSize); *loopStart = 0; *loopEnd = 0; *sampleSize = WAVERsrc->wBitsPerSample; *rate = WAVERsrc->nSamplesPerSec; if (WAVERsrc->nCannels == 2) *stereo = true; else *stereo = false; if (WAVERsrc->wFormatTag != 1) { free(WAVERsrc); CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } } else { free(WAVERsrc); CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } } else { free(WAVERsrc); CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } } else { free(WAVERsrc); CFReadStreamClose(fRef); CFRelease(fRef); return NULL; } CFReadStreamClose(fRef); CFRelease(fRef); } { #if __BIG_ENDIAN__ unsigned short *tt; #endif *sndSize = WAVERsrc->dataSize; memmove(WAVERsrc, WAVERsrc->theData, *sndSize); WAVERsrc = realloc(WAVERsrc, *sndSize); switch (*sampleSize) { case 8: MADConvertInstrument((Byte*)WAVERsrc, *sndSize); break; case 16: #if __BIG_ENDIAN__ tt = (unsigned short*)WAVERsrc; dispatch_apply((*sndSize) / 2, dispatch_get_global_queue(0, 0), ^(size_t i) { tt[i] = shrtswap(tt[i]); }); #endif break; }