-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYInterappClient.m
128 lines (117 loc) · 3.6 KB
/
SSYInterappClient.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#import "SSYInterappClient.h"
NSString* const SSYInterappClientErrorDomain = @"SSYInterappClientErrorDomain" ;
@implementation SSYInterappClient
+ (BOOL)sendHeaderByte:(char)txHeaderByte
txPayload:(NSData*)txPayload
portName:(NSString*)portName
wait:(BOOL)wait
rxHeaderByte_p:(char*)rxHeaderByte_p
rxPayload_p:(NSData**)rxPayload_p
txTimeout:(NSTimeInterval)txTimeout
rxTimeout:(NSTimeInterval)rxTimeout
error_p:(NSError**)error_p {
BOOL ok = kCFMessagePortSuccess ;
SInt32 result ;
CFMessagePortRef remotePort = CFMessagePortCreateRemote(
NULL,
(CFStringRef)portName
) ;
if (!remotePort) {
ok = NO ;
result = SSYInterappClientErrorCantFindReceiver ;
goto end ;
}
NSMutableData* aggrTxData = [[NSMutableData alloc] init] ;
if (txHeaderByte) {
[aggrTxData appendBytes:(const void*)&txHeaderByte
length:1] ;
}
if (txHeaderByte) {
[aggrTxData appendData:txPayload] ;
}
NSData* aggrRxData = nil ;
CFStringRef replyMode = wait ? kCFRunLoopDefaultMode : NULL ;
result = CFMessagePortSendRequest(
remotePort,
0,
(CFDataRef)aggrTxData,
txTimeout,
rxTimeout,
replyMode,
(CFDataRef*)&aggrRxData
) ;
// As always, we are careful not to CFRelease(NULL) ;
CFRelease(remotePort) ;
[aggrTxData release] ;
ok = (result == kCFMessagePortSuccess) ;
if (ok) {
if (rxHeaderByte_p) {
if ([aggrRxData length] > 0) {
[aggrRxData getBytes:rxHeaderByte_p
range:NSMakeRange(0,1)] ;
}
else {
*rxHeaderByte_p = 0 ;
}
}
if (rxPayload_p) {
if ([aggrRxData length] > 1) {
*rxPayload_p = [aggrRxData subdataWithRange:NSMakeRange(1,[aggrRxData length] - 1)] ;
}
else {
*rxPayload_p = 0 ;
}
}
}
end:
if (!ok && error_p) {
NSString* errorDetail ;
switch (result) {
case kCFMessagePortSendTimeout:
errorDetail = @"Send Timeout" ;
break ;
case kCFMessagePortIsInvalid:
errorDetail = @"Port is Invalid" ;
break ;
case kCFMessagePortReceiveTimeout:
errorDetail = @"Receive Timeout" ;
break ;
case kCFMessagePortTransportError:
errorDetail = @"Transport Error" ;
break ;
case -5: // Mac OS X 10.6 SDK defines this as kCFMessagePortBecameInvalidError
errorDetail = @"Port Became Invalid" ;
break ;
case SSYInterappClientErrorCantFindReceiver:
errorDetail = [NSString stringWithFormat:
@"Server port (%@) not found",
portName] ;
break ;
default:
errorDetail = [NSString stringWithFormat:
@"Unknown Error Code: %ld",
(long)result] ;
break ;
}
NSString* errorDescription = [NSString stringWithFormat:
@"Interapp messaging error : %@",
errorDetail] ;
NSString* txHeaderString = txHeaderByte ? [[[NSString alloc] initWithBytes:&txHeaderByte
length:1
encoding:NSUTF8StringEncoding] autorelease] : @"No header byte" ;
NSNumber* txPayloadLength = [NSNumber numberWithInteger:[txPayload length]] ;
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
errorDescription, NSLocalizedDescriptionKey,
portName, @"Port Name",
txHeaderString, @"Tx Header Byte",
txPayloadLength, @"Tx Data Byte Count",
[NSNumber numberWithDouble:txTimeout], @"Tx Timeout (secs)",
[NSNumber numberWithDouble:rxTimeout], @"Rx Timeout (secs)",
nil] ;
*error_p = [NSError errorWithDomain:SSYInterappClientErrorDomain
code:result
userInfo:userInfo] ;
}
return ok ;
}
@end