jens@0: // jens@0: // BLIPConnection.m jens@0: // MYNetwork jens@0: // jens@0: // Created by Jens Alfke on 5/10/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import "BLIPConnection.h" jens@0: #import "BLIP_Internal.h" jens@0: #import "BLIPReader.h" jens@0: #import "BLIPWriter.h" jens@0: #import "BLIPDispatcher.h" jens@0: jens@0: #import "Logging.h" jens@0: #import "Test.h" jens@0: #import "ExceptionUtils.h" jens@0: jens@0: jens@0: NSString* const BLIPErrorDomain = @"BLIP"; jens@0: jens@0: NSError *BLIPMakeError( int errorCode, NSString *message, ... ) jens@0: { jens@0: va_list args; jens@0: va_start(args,message); jens@0: message = [[NSString alloc] initWithFormat: message arguments: args]; jens@0: va_end(args); jens@0: LogTo(BLIP,@"BLIPError #%i: %@",errorCode,message); jens@0: NSDictionary *userInfo = [NSDictionary dictionaryWithObject: message jens@0: forKey: NSLocalizedDescriptionKey]; jens@0: [message release]; jens@0: return [NSError errorWithDomain: BLIPErrorDomain code: errorCode userInfo: userInfo]; jens@0: } jens@0: jens@0: jens@0: jens@0: jens@0: @implementation BLIPConnection jens@0: jens@0: - (void) dealloc jens@0: { jens@0: [_dispatcher release]; jens@0: [super dealloc]; jens@0: } jens@0: jens@0: - (Class) readerClass {return [BLIPReader class];} jens@0: - (Class) writerClass {return [BLIPWriter class];} jens@0: - (id) delegate {return (id)_delegate;} jens@0: - (void) setDelegate: (id)delegate {_delegate = delegate;} jens@0: jens@0: - (BLIPDispatcher*) dispatcher jens@0: { jens@0: if( ! _dispatcher ) { jens@0: _dispatcher = [[BLIPDispatcher alloc] init]; jens@0: _dispatcher.parent = ((BLIPListener*)self.server).dispatcher; jens@0: } jens@0: return _dispatcher; jens@0: } jens@0: jens@0: jens@0: - (void) _dispatchRequest: (BLIPRequest*)request jens@0: { jens@0: LogTo(BLIP,@"Received all of %@",request.descriptionWithProperties); jens@0: @try{ jens@0: if( ! [self.dispatcher dispatchMessage: request] ) jens@0: [self tellDelegate: @selector(connection:receivedRequest:) withObject: request]; jens@0: if( ! request.noReply && ! request.repliedTo ) { jens@0: LogTo(BLIP,@"Returning default empty response to %@",request); jens@2: [request respondWithData: nil contentType: nil]; jens@0: } jens@0: }@catch( NSException *x ) { jens@0: MYReportException(x,@"Dispatching BLIP request"); jens@0: [request respondWithException: x]; jens@0: } jens@0: } jens@0: jens@0: - (void) _dispatchResponse: (BLIPResponse*)response jens@0: { jens@0: LogTo(BLIP,@"Received all of %@",response); jens@0: [self tellDelegate: @selector(connection:receivedResponse:) withObject: response]; jens@0: } jens@0: jens@0: jens@0: - (BLIPRequest*) requestWithBody: (NSData*)body jens@0: { jens@0: return [[[BLIPRequest alloc] _initWithConnection: self body: body properties: nil] autorelease]; jens@0: } jens@0: jens@0: - (BLIPRequest*) requestWithBody: (NSData*)body jens@0: properties: (NSDictionary*)properties jens@0: { jens@0: return [[[BLIPRequest alloc] _initWithConnection: self body: body properties: properties] autorelease]; jens@0: } jens@0: jens@0: - (BLIPResponse*) sendRequest: (BLIPRequest*)request jens@0: { jens@0: BLIPConnection *itsConnection = request.connection; jens@0: if( itsConnection==nil ) jens@0: request.connection = self; jens@0: else jens@0: Assert(itsConnection==self,@"%@ is already assigned to a different BLIPConnection",request); jens@0: return [request send]; jens@0: } jens@0: jens@0: jens@0: @end jens@0: jens@0: jens@0: jens@0: jens@0: @implementation BLIPListener jens@0: jens@0: - (id) initWithPort: (UInt16)port jens@0: { jens@0: self = [super initWithPort: port]; jens@0: if (self != nil) { jens@0: self.connectionClass = [BLIPConnection class]; jens@0: } jens@0: return self; jens@0: } jens@0: jens@0: - (void) dealloc jens@0: { jens@0: [_dispatcher release]; jens@0: [super dealloc]; jens@0: } jens@0: jens@0: - (BLIPDispatcher*) dispatcher jens@0: { jens@0: if( ! _dispatcher ) jens@0: _dispatcher = [[BLIPDispatcher alloc] init]; jens@0: return _dispatcher; jens@0: } jens@0: jens@0: @end jens@0: jens@0: jens@0: /* jens@0: Copyright (c) 2008, Jens Alfke . All rights reserved. jens@0: jens@0: Redistribution and use in source and binary forms, with or without modification, are permitted jens@0: provided that the following conditions are met: jens@0: jens@0: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@0: and the following disclaimer. jens@0: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions jens@0: and the following disclaimer in the documentation and/or other materials provided with the jens@0: distribution. jens@0: jens@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@0: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@0: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@0: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@0: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@0: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@0: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@0: */