#import "Stream.h"
#import "SynthesizeSingleton.h"
@implementation Stream
SYNTHESIZE_SINGLETON_FOR_CLASS(Stream);
-(void)startClient
{
_hasEstablished = NO;
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
NSString *server = ;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(CFStringRef)server,
1234,
&readStream,
&writeStream);
if(readStream && writeStream)
{
inStream = (NSInputStream *)readStream;
outStream = (NSOutputStream *)writeStream;
}
else
{
}
}
-(void)closeStreams{
[[PromptView sharedPromptView] dismissPromptView];
[inStream close];
[outStream close];
[inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inStream setDelegate:nil];
[outStream setDelegate:nil];
[inStream release];
[outStream release];
inStream = nil;
outStream = nil;
}
-(void)openStreams{
[inStream retain];
[outStream retain];
[inStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
[outStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
CFWriteStreamSetProperty((CFWriteStreamRef)outStream, kCFStreamPropertySSLSettings, [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kCFBooleanFalse,kCFStreamSSLValidatesCertificateChain,kCFBooleanFalse,kCFStreamSSLIsServer,nil]);
[inStream setDelegate:self];
[outStream setDelegate:self];
[inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inStream open];
[outStream open];
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if(_isFirstFourBytes)
{
uint8_t bufferLen[4];
if([inStream read:bufferLen maxLength:4] == 4)
{
remainingToRead = ((bufferLen[0]<<24)&0xff000000)+((bufferLen[1]<<16)&0xff0000)+((bufferLen[2]<<8)&0xff00)+(bufferLen[3] & 0xff);
_isFirstFourBytes = NO;
}
else
{
[self closeStreams];
}
}
else
{
int actuallyRead;
uint8_t buffer[32768];
if (!dataBuffer) {
dataBuffer = [[NSMutableData alloc] init];
}
actuallyRead = [inStream read:buffer maxLength:sizeof(buffer)];
if(actuallyRead == -1){
[self closeStreams];
}else if(actuallyRead == 0){
}else{
[dataBuffer appendBytes:buffer length:actuallyRead];
remainingToRead -= actuallyRead;
}
if(remainingToRead == 0)
{
_isFirstFourBytes = YES;
[self manageData:dataBuffer];
[dataBuffer release];
dataBuffer = nil;
}
}
break;
}
case NSStreamEventEndEncountered:
{
[self closeStreams];
break;
}
case NSStreamEventErrorOccurred:
{
if([[aStream streamError] code])
{
[self closeStreams];
break;
}
}
case NSStreamEventOpenCompleted:
{
_hasEstablished = YES;
break;
}
case NSStreamEventHasSpaceAvailable:
{
break;
}
case NSStreamEventNone:
default:
break;
}
}
-(BOOL)isServerAvailable{
NSString *addressString = ;
if (!addressString) {
return NO;
}
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [addressString UTF8String]);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags)
{
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
return (isReachable && !needsConnection) ? YES : NO;
}
-(void)requestData:(NSString *)requestString whoRequest:(id)currentObject condition:(int)numCondition
{
if(![self isServerAvailable])
{
}
else
{
if(inStream == nil || outStream == nil)
{
[[Stream sharedStream] startClient];
[[Stream sharedStream] openStreams];
_isFirstFourBytes = YES;
}
if(inStream != nil && outStream != nil)
{
_currentObject = currentObject;
_numCondition = numCondition;
if(_hasEstablished)
{
NSData *requestData = [requestString dataUsingEncoding:NSUTF8StringEncoding];
int dataLength = [requestData length];
uint8_t len[4];
for(int i = 0;i<4;i++)
{
len[i] = (Byte)(dataLength>>8*(3-i)&0xff);
}
[/i]
NSMutableData *dataToSend = [NSMutableData dataWithBytes:len length:4];
[dataToSend appendData:requestData];
int remainingToWrite = dataLength+ 4;
void * marker = (void *)[dataToSend bytes];
int actuallyWritten;
while ([outStream hasSpaceAvailable]) {
if (remainingToWrite > 0) {
actuallyWritten = 0;
if(remainingToWrite < 32768)
actuallyWritten = [outStream write:marker maxLength:remainingToWrite];
else
actuallyWritten = [outStream write:marker maxLength:32768];
if ((actuallyWritten == -1) || (actuallyWritten == 0))
{
[self closeStreams];
}
else
{
remainingToWrite -= actuallyWritten;
marker += actuallyWritten;
}
}
else
{
break;
}
}
}
else
{
}
}
}
}
-(void)manageData:(NSData *)receivedData{
[_currentObject getData:receivedData condition:_numCondition];
}
- (void)dealloc {
[super dealloc];
}
@end