#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