Got it to build on iPhone. (Haven't tried running it yet.)
1.1 Binary file BLIP/BLIP.png has changed
2.1 --- a/BLIP/BLIPDispatcher.h Sun May 25 13:43:03 2008 -0700
2.2 +++ b/BLIP/BLIPDispatcher.h Thu May 29 16:40:36 2008 -0700
2.3 @@ -10,8 +10,9 @@
2.4 @class MYTarget, BLIPMessage;
2.5
2.6
2.7 -/** Routes BLIP messages to targets based on a series of rule predicates.
2.8 - Every BLIPConnection has a BLIPDispatcher, which is initially empty but you can add rules
2.9 +/** Routes BLIP messages to targets based on a series of rules.
2.10 +
2.11 + Every BLIPConnection has a BLIPDispatcher, which is initially empty, but you can add rules
2.12 to it.
2.13
2.14 Every BLIPListener also has a dispatcher, which is inherited as the parent by every
2.15 @@ -33,11 +34,13 @@
2.16 the parent, if there is one. */
2.17 @property (retain) BLIPDispatcher *parent;
2.18
2.19 +/** Convenience method that adds a rule that compares a property against a string. */
2.20 +- (void) addTarget: (MYTarget*)target forValueOfProperty: (NSString*)value forKey: (NSString*)key;
2.21 +
2.22 +#if ! TARGET_OS_IPHONE /* NSPredicate is not available on iPhone, unfortunately */
2.23 /** Adds a new rule, to call a given target method if a given predicate matches the message. */
2.24 - (void) addTarget: (MYTarget*)target forPredicate: (NSPredicate*)predicate;
2.25 -
2.26 -/** Convenience method that adds a rule that compares a property against a string. */
2.27 -- (void) addTarget: (MYTarget*)target forValueOfProperty: (NSString*)value forKey: (NSString*)key;
2.28 +#endif
2.29
2.30 /** Removes all rules with the given target method. */
2.31 - (void) removeTarget: (MYTarget*)target;
3.1 --- a/BLIP/BLIPDispatcher.m Sun May 25 13:43:03 2008 -0700
3.2 +++ b/BLIP/BLIPDispatcher.m Thu May 29 16:40:36 2008 -0700
3.3 @@ -39,11 +39,13 @@
3.4 @synthesize parent=_parent;
3.5
3.6
3.7 +#if ! TARGET_OS_IPHONE
3.8 - (void) addTarget: (MYTarget*)target forPredicate: (NSPredicate*)predicate
3.9 {
3.10 [_targets addObject: target];
3.11 [_predicates addObject: predicate];
3.12 }
3.13 +#endif
3.14
3.15
3.16 - (void) removeTarget: (MYTarget*)target
3.17 @@ -58,12 +60,29 @@
3.18
3.19 - (void) addTarget: (MYTarget*)target forValueOfProperty: (NSString*)value forKey: (NSString*)key
3.20 {
3.21 +#if TARGET_OS_IPHONE
3.22 + Assert(target);
3.23 + [_predicates addObject: $array(key,value)];
3.24 + [_targets addObject: target];
3.25 +#else
3.26 [self addTarget: target
3.27 forPredicate: [NSComparisonPredicate predicateWithLeftExpression: [NSExpression expressionForKeyPath: key]
3.28 rightExpression: [NSExpression expressionForConstantValue: value]
3.29 modifier: NSDirectPredicateModifier
3.30 type: NSEqualToPredicateOperatorType
3.31 options: 0]];
3.32 +#endif
3.33 +}
3.34 +
3.35 +
3.36 +static BOOL testPredicate( id predicate, NSDictionary *properties ) {
3.37 +#if TARGET_OS_IPHONE
3.38 + NSString *key = [predicate objectAtIndex: 0];
3.39 + NSString *value = [predicate objectAtIndex: 1];
3.40 + return $equal( [properties objectForKey: key], value );
3.41 +#else
3.42 + return [(NSPredicate*)predicate evaluateWithObject: properties];
3.43 +#endif
3.44 }
3.45
3.46
3.47 @@ -72,8 +91,8 @@
3.48 NSDictionary *properties = message.properties.allProperties;
3.49 NSUInteger n = _predicates.count;
3.50 for( NSUInteger i=0; i<n; i++ ) {
3.51 - NSPredicate *p = [_predicates objectAtIndex: i];
3.52 - if( [p evaluateWithObject: properties] ) {
3.53 + id p = [_predicates objectAtIndex: i];
3.54 + if( testPredicate(p, properties) ) {
3.55 MYTarget *target = [_targets objectAtIndex: i];
3.56 LogTo(BLIP,@"Dispatcher matched %@ -- calling %@",p,target);
3.57 [target invokeWithSender: message];
4.1 --- a/BLIP/BLIPMessage.m Sun May 25 13:43:03 2008 -0700
4.2 +++ b/BLIP/BLIPMessage.m Thu May 29 16:40:36 2008 -0700
4.3 @@ -247,10 +247,10 @@
4.4 }
4.5
4.6 // First write the frame header:
4.7 - BLIPFrameHeader header = { EndianU32_NtoB(kBLIPFrameHeaderMagicNumber),
4.8 - EndianU32_NtoB(_number),
4.9 - EndianU16_NtoB(flags),
4.10 - EndianU16_NtoB(sizeof(BLIPFrameHeader) + lengthToWrite) };
4.11 + BLIPFrameHeader header = { NSSwapHostIntToBig(kBLIPFrameHeaderMagicNumber),
4.12 + NSSwapHostIntToBig(_number),
4.13 + NSSwapHostShortToBig(flags),
4.14 + NSSwapHostShortToBig(sizeof(BLIPFrameHeader) + lengthToWrite) };
4.15
4.16 [writer writeData: [NSData dataWithBytes: &header length: sizeof(header)]];
4.17
5.1 --- a/BLIP/BLIPProperties.m Sun May 25 13:43:03 2008 -0700
5.2 +++ b/BLIP/BLIPProperties.m Thu May 29 16:40:36 2008 -0700
5.3 @@ -56,7 +56,7 @@
5.4
5.5 // Read the length:
5.6 const char *bytes = data.bytes;
5.7 - size_t length = EndianU16_BtoN( *(UInt16*)bytes ) + sizeof(UInt16);
5.8 + size_t length = NSSwapBigShortToHost( *(UInt16*)bytes ) + sizeof(UInt16);
5.9 if( length > available ) {
5.10 // Properties not complete yet.
5.11 *usedLength = 0;
5.12 @@ -307,7 +307,7 @@
5.13 NSUInteger length = data.length - sizeof(UInt16);
5.14 if( length > 0xFFFF )
5.15 return nil;
5.16 - *(UInt16*)[data mutableBytes] = EndianU16_NtoB((UInt16)length);
5.17 + *(UInt16*)[data mutableBytes] = NSSwapHostShortToBig((UInt16)length);
5.18 return data;
5.19 }
5.20
6.1 --- a/BLIP/BLIPReader.m Sun May 25 13:43:03 2008 -0700
6.2 +++ b/BLIP/BLIPReader.m Thu May 29 16:40:36 2008 -0700
6.3 @@ -63,10 +63,10 @@
6.4 - (NSString*) _validateHeader
6.5 {
6.6 // Convert header to native byte order:
6.7 - _curHeader.magic = EndianU32_BtoN(_curHeader.magic);
6.8 - _curHeader.number= EndianU32_BtoN(_curHeader.number);
6.9 - _curHeader.flags = EndianU16_BtoN(_curHeader.flags);
6.10 - _curHeader.size = EndianU16_BtoN(_curHeader.size);
6.11 + _curHeader.magic = NSSwapBigIntToHost(_curHeader.magic);
6.12 + _curHeader.number= NSSwapBigIntToHost(_curHeader.number);
6.13 + _curHeader.flags = NSSwapBigShortToHost(_curHeader.flags);
6.14 + _curHeader.size = NSSwapBigShortToHost(_curHeader.size);
6.15
6.16 if( _curHeader.magic != kBLIPFrameHeaderMagicNumber )
6.17 return $sprintf(@"Incorrect magic number (%08X not %08X)",
7.1 --- a/BLIP/BLIPTest.m Sun May 25 13:43:03 2008 -0700
7.2 +++ b/BLIP/BLIPTest.m Thu May 29 16:40:36 2008 -0700
7.3 @@ -233,7 +233,7 @@
7.4 Assert(listenerIdentity);
7.5 _listener.SSLProperties = $mdict({kTCPPropertySSLCertificates, $array((id)listenerIdentity)},
7.6 {kTCPPropertySSLAllowsAnyRoot,$true},
7.7 - {kTCPPropertySSLClientSideAuthentication, $object(kTryAuthenticate)});
7.8 + {kTCPPropertySSLClientSideAuthentication, $object(kTCPTryAuthenticate)});
7.9 }
7.10 Assert( [_listener open] );
7.11 Log(@"%@ is listening...",self);
8.1 --- a/TCP/TCPConnection.h Sun May 25 13:43:03 2008 -0700
8.2 +++ b/TCP/TCPConnection.h Thu May 29 16:40:36 2008 -0700
8.3 @@ -7,6 +7,7 @@
8.4 //
8.5
8.6 #import "TCPEndpoint.h"
8.7 +#import <Security/Security.h>
8.8 @class IPAddress;
8.9 @class TCPReader, TCPWriter, TCPListener;
8.10 @protocol TCPConnectionDelegate;
9.1 --- a/TCP/TCPConnection.m Sun May 25 13:43:03 2008 -0700
9.2 +++ b/TCP/TCPConnection.m Thu May 29 16:40:36 2008 -0700
9.3 @@ -14,6 +14,15 @@
9.4 #import "ExceptionUtils.h"
9.5
9.6
9.7 +#if TARGET_OS_IPHONE
9.8 +// SecureTransport.h is missing on iPhone, with its SSL constants:
9.9 +enum{
9.10 + errSSLClosedAbort = -9806, /* connection closed via error */
9.11 +};
9.12 +#endif
9.13 +
9.14 +
9.15 +
9.16 NSString* const TCPErrorDomain = @"TCP";
9.17
9.18
9.19 @@ -62,10 +71,20 @@
9.20 {
9.21 NSInputStream *input = nil;
9.22 NSOutputStream *output = nil;
9.23 +#if TARGET_OS_IPHONE
9.24 + // +getStreamsToHost: is missing for some stupid reason on iPhone. Grrrrrrrrrr.
9.25 + CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)address.hostname, address.port,
9.26 + (CFReadStreamRef*)&input, (CFWriteStreamRef*)&output);
9.27 + if( input )
9.28 + [(id)CFMakeCollectable(input) autorelease];
9.29 + if( output )
9.30 + [(id)CFMakeCollectable(output) autorelease];
9.31 +#else
9.32 [NSStream getStreamsToHost: [NSHost hostWithAddress: address.ipv4name]
9.33 port: address.port
9.34 inputStream: &input
9.35 outputStream: &output];
9.36 +#endif
9.37 return [self _initWithAddress: address inputStream: input outputStream: output];
9.38 //FIX: Support localPort!
9.39 }
10.1 --- a/TCP/TCPEndpoint.h Sun May 25 13:43:03 2008 -0700
10.2 +++ b/TCP/TCPEndpoint.h Thu May 29 16:40:36 2008 -0700
10.3 @@ -7,13 +7,23 @@
10.4 //
10.5
10.6 #import <Foundation/Foundation.h>
10.7 +#if TARGET_OS_IPHONE
10.8 +#include <CFNetwork/CFSocketStream.h>
10.9 +#else
10.10 #import <CoreServices/CoreServices.h>
10.11 +#endif
10.12
10.13
10.14 // SSL properties:
10.15 #define kTCPPropertySSLCertificates ((NSString*)kCFStreamSSLCertificates)
10.16 #define kTCPPropertySSLAllowsAnyRoot ((NSString*)kCFStreamSSLAllowsAnyRoot)
10.17 -extern NSString* const kTCPPropertySSLClientSideAuthentication; // value is SSLAuthenticate enum
10.18 +
10.19 +extern NSString* const kTCPPropertySSLClientSideAuthentication; // value is TCPAuthenticate enum
10.20 +typedef enum {
10.21 + kTCPNeverAuthenticate, /* skip client authentication */
10.22 + kTCPAlwaysAuthenticate, /* require it */
10.23 + kTCPTryAuthenticate /* try to authenticate, but not error if client has no cert */
10.24 +} TCPAuthenticate; // these MUST have same values as SSLAuthenticate enum in SecureTransport.h!
10.25
10.26
10.27 /** Abstract base class of TCPConnection and TCPListener.
11.1 --- a/TCP/TCPListener.m Sun May 25 13:43:03 2008 -0700
11.2 +++ b/TCP/TCPListener.m Thu May 29 16:40:36 2008 -0700
11.3 @@ -129,7 +129,7 @@
11.4 if( ! _ipv4socket ) {
11.5 if( error.code==EADDRINUSE && _pickAvailablePort && _port<0xFFFF ) {
11.6 LogTo(BLIPVerbose,@"%@: port busy, trying %hu...",self,_port+1);
11.7 - self.port++; // try the next port
11.8 + self.port += 1; // try the next port
11.9 } else {
11.10 if( outError ) *outError = error;
11.11 return [self _failedToOpen: error];
12.1 --- a/maindocs.h Sun May 25 13:43:03 2008 -0700
12.2 +++ b/maindocs.h Thu May 29 16:40:36 2008 -0700
12.3 @@ -11,7 +11,9 @@
12.4 /*! \mainpage MYNetwork: Mooseyard Networking Library, With BLIP Protocol Implementation
12.5
12.6 <center><b>By <a href="/Jens/">Jens Alfke</a></b></center>
12.7 -
12.8 +
12.9 + <img src="BLIP.png">
12.10 +
12.11 \section intro_sec Introduction
12.12
12.13 MYNetwork is a set of Objective-C networking classes for Cocoa applications on Mac OS X.
12.14 @@ -39,6 +41,19 @@
12.15
12.16 \section blipdesc What's BLIP?
12.17
12.18 + <table style="background-color: #fff; padding: 5px; float: right" cellspacing=0>
12.19 + <tr><td>
12.20 + <img src="http://groups.google.com/groups/img/3nb/groups_bar.gif"
12.21 + height=26 width=132 alt="Google Groups">
12.22 + </td></tr>
12.23 + <tr><td style="padding-left: 5px;font-size: 125%">
12.24 + <b>BLIP Protocol</b>
12.25 + </td></tr>
12.26 + <tr><td style="padding-left: 5px">
12.27 + <a href="http://groups.google.com/group/blip-protocol">Visit this group</a>
12.28 + </td></tr>
12.29 + </table>
12.30 +
12.31 BLIP is a message-oriented network protocol that lets the two peers on either end of a TCP socket send request and response messages to each other. It's a generic protocol, in that the requests and responses can contain any kind of data you like.
12.32
12.33 BLIP was inspired by <a
12.34 @@ -77,7 +92,7 @@
12.35
12.36 <li>The implementation supports SSL connections (with optional client-side certificates), and Bonjour service advertising.
12.37 </ul>
12.38 -
12.39 +
12.40 \section config Configuration
12.41
12.42 MYNetwork requires Mac OS X 10.5 or later, since it uses Objective-C 2 features like