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;
        }
    }
}
Exemple #10
0
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;
		}