diff options
Diffstat (limited to 'objective-c/src')
56 files changed, 13021 insertions, 0 deletions
diff --git a/objective-c/src/Glacier2/.gitignore b/objective-c/src/Glacier2/.gitignore new file mode 100644 index 00000000000..ece727d3b20 --- /dev/null +++ b/objective-c/src/Glacier2/.gitignore @@ -0,0 +1,18 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +Metrics.m +PermissionsVerifierF.m +PermissionsVerifier.m +Router.m +RouterF.m +Session.m +SSLInfo.m +Metrics.h +PermissionsVerifierF.h +PermissionsVerifier.h +Router.h +RouterF.h +Session.h +SSLInfo.h diff --git a/objective-c/src/Glacier2/Makefile b/objective-c/src/Glacier2/Makefile new file mode 100644 index 00000000000..dd942e510f2 --- /dev/null +++ b/objective-c/src/Glacier2/Makefile @@ -0,0 +1,50 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +LIBFILENAME = $(call mklibfilename,Glacier2ObjC,$(VERSION)) +SONAME = $(call mksoname,Glacier2ObjC,$(SOVERSION)) +LIBNAME = $(call mklibname,Glacier2ObjC) + +TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) + +SLICE_OBJS = Metrics.o \ + PermissionsVerifierF.o \ + PermissionsVerifier.o \ + Router.o \ + RouterF.o \ + Session.o \ + SSLInfo.o + +OBJS = $(SLICE_OBJS) + +HDIR = $(headerdir)/objc/Glacier2 +SDIR = $(slicedir)/Glacier2 + +include $(top_srcdir)/config/Make.rules + +SLICE2OBJCFLAGS := --ice --include-dir objc/Glacier2 --dll-export GLACIER2_API $(SLICE2OBJCFLAGS) + +$(libdir)/$(LIBFILENAME): $(OBJS) $(HDIR)/PermissionsVerifierF.h $(HDIR)/RouterF.h + @mkdir -p $(dir $@) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(OBJS),$(LIBS)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + @mkdir -p $(libdir) + rm -f $@ + ln -s $(SONAME) $@ + +install:: all + $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/objective-c/src/Ice/.gitignore b/objective-c/src/Ice/.gitignore new file mode 100644 index 00000000000..7f8d62bd8d6 --- /dev/null +++ b/objective-c/src/Ice/.gitignore @@ -0,0 +1,76 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +BuiltinSequences.m +Communicator.m +CommunicatorF.m +Connection.m +ConnectionF.m +Current.m +Endpoint.m +EndpointF.m +EndpointTypes.m +FacetMap.m +Identity.m +InstrumentationF.m +ImplicitContext.m +ImplicitContextF.m +Locator.m +LocatorF.m +LocalException.m +Logger.m +LoggerF.m +Metrics.m +ObjectAdapter.m +ObjectAdapterF.m +ObjectFactoryF.m +PluginF.m +Process.m +ProcessF.m +Properties.m +PropertiesF.m +PropertiesAdmin.m +RemoteLogger.m +Router.m +RouterF.m +ServantLocator.m +ServantLocatorF.m +SliceChecksumDict.m +Version.m +BuiltinSequences.h +Communicator.h +CommunicatorF.h +Connection.h +ConnectionF.h +Current.h +Endpoint.h +EndpointF.h +EndpointTypes.h +FacetMap.h +Identity.h +InstrumentationF.h +ImplicitContext.h +ImplicitContextF.h +Locator.h +LocatorF.h +LocalException.h +Logger.h +LoggerF.h +Metrics.h +ObjectAdapter.h +ObjectAdapterF.h +ObjectFactoryF.h +PluginF.h +Process.h +ProcessF.h +Properties.h +PropertiesF.h +PropertiesAdmin.h +RemoteLogger.h +Router.h +RouterF.h +ServantLocator.h +ServantLocatorF.h +SliceChecksumDict.h +Version.h diff --git a/objective-c/src/Ice/BatchRequestInterceptor.mm b/objective-c/src/Ice/BatchRequestInterceptor.mm new file mode 100644 index 00000000000..43a72ad5f07 --- /dev/null +++ b/objective-c/src/Ice/BatchRequestInterceptor.mm @@ -0,0 +1,105 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <BatchRequestInterceptorI.h> +#import <Util.h> +#import <ProxyI.h> + +#include <Block.h> + +@interface ICEBatchRequest : NSObject<ICEBatchRequest> +{ + const Ice::BatchRequest* cxxRequest_; +} +-(void) reset:(const Ice::BatchRequest*)call; +@end + + +namespace +{ + +class BatchRequestInterceptorI : public Ice::BatchRequestInterceptor +{ +public: + +// We must explicitely retain/release so that the garbage +// collector does not trash the dispatcher. +BatchRequestInterceptorI(void(^interceptor)(id<ICEBatchRequest>, int, int)) : + _interceptor(Block_copy(interceptor)), _request([[ICEBatchRequest alloc] init]) +{ +} + +virtual ~BatchRequestInterceptorI() +{ + Block_release(_interceptor); + [_request release]; +} + +virtual void +enqueue(const Ice::BatchRequest& request, int count, int size) +{ + NSException* ex = nil; + @autoreleasepool + { + @try + { + [_request reset:&request]; + _interceptor(_request, count, size); + } + @catch(id e) + { + ex = [e retain]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } +} + +private: + +void(^_interceptor)(id<ICEBatchRequest>, int, int); +ICEBatchRequest* _request; + +}; +typedef IceUtil::Handle<BatchRequestInterceptorI> BatchRequestInterceptorIPtr; + +} + +@implementation ICEBatchRequestInterceptor ++(Ice::BatchRequestInterceptor*) +batchRequestInterceptorWithBatchRequestInterceptor:(void(^)(id<ICEBatchRequest>, int, int))interceptor +{ + return new BatchRequestInterceptorI(interceptor); +} +@end + +@implementation ICEBatchRequest +-(void) reset:(const Ice::BatchRequest*)request +{ + cxxRequest_ = request; +} +-(void) enqueue +{ + cppCall(^ { cxxRequest_->enqueue(); }); +} +-(int) getSize +{ + return cxxRequest_->getSize(); +} +-(NSString*) getOperation +{ + return [toNSString(cxxRequest_->getOperation()) autorelease]; +} +-(id<ICEObjectPrx>) getProxy +{ + return [ICEObjectPrx objectPrxWithObjectPrx__:cxxRequest_->getProxy()]; +} +@end diff --git a/objective-c/src/Ice/BatchRequestInterceptorI.h b/objective-c/src/Ice/BatchRequestInterceptorI.h new file mode 100644 index 00000000000..9ebcc87600e --- /dev/null +++ b/objective-c/src/Ice/BatchRequestInterceptorI.h @@ -0,0 +1,17 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Initialize.h> + +#include <Ice/BatchRequestInterceptor.h> + +@interface ICEBatchRequestInterceptor : NSObject ++(Ice::BatchRequestInterceptor*) +batchRequestInterceptorWithBatchRequestInterceptor:(void(^)(id<ICEBatchRequest>, int, int))arg; +@end diff --git a/objective-c/src/Ice/CommunicatorI.h b/objective-c/src/Ice/CommunicatorI.h new file mode 100644 index 00000000000..e900d52601b --- /dev/null +++ b/objective-c/src/Ice/CommunicatorI.h @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Communicator.h> + +#import <objc/Ice/LocalObject.h> + +#import <Foundation/NSSet.h> + +#include <Ice/Communicator.h> + +@class ICEObjectAdapter; + +@interface ICECommunicator : ICELocalObject<ICECommunicator> +{ + NSMutableDictionary* objectFactories_; + NSDictionary* prefixTable_; + NSMutableDictionary* adminFacets_; +} +-(void)setup:(NSDictionary*)prefixTable; +-(Ice::Communicator*)communicator; +-(NSDictionary*)getPrefixTable; +@end diff --git a/objective-c/src/Ice/CommunicatorI.mm b/objective-c/src/Ice/CommunicatorI.mm new file mode 100644 index 00000000000..6b19bbc862a --- /dev/null +++ b/objective-c/src/Ice/CommunicatorI.mm @@ -0,0 +1,702 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <CommunicatorI.h> +#import <PropertiesI.h> +#import <ProxyI.h> +#import <IdentityI.h> +#import <LoggerI.h> +#import <ObjectAdapterI.h> +#import <Util.h> +#import <StreamI.h> +#import <SlicedDataI.h> +#import <ImplicitContextI.h> +#import <ProxyI.h> +#import <LocalObjectI.h> +#import <ObjectI.h> + +#include <Ice/Router.h> +#include <Ice/Locator.h> +#include <Ice/ObjectFactory.h> + +#import <objc/Ice/Router.h> +#import <objc/Ice/Locator.h> +#import <objc/Ice/ObjectFactory.h> + +#import <objc/runtime.h> + +#define COMMUNICATOR dynamic_cast<Ice::Communicator*>(static_cast<IceUtil::Shared*>(cxxObject_)) + +namespace IceObjC +{ + +class UnknownSlicedObjectFactoryI : public Ice::ObjectFactory +{ +public: + + virtual Ice::ObjectPtr + create(const std::string&) + { + ICEUnknownSlicedObject* obj = [[ICEUnknownSlicedObject alloc] init]; + Ice::ObjectPtr o = [ICEInputStream createObjectReader:obj]; + [obj release]; + return o; + } + + virtual void + destroy() + { + } +}; + +class ObjectFactoryI : public Ice::ObjectFactory +{ +public: + + // We must explicitely CFRetain/CFRelease so that the garbage + // collector does not trash the dictionaries. + ObjectFactoryI(NSDictionary* factories, NSDictionary* prefixTable) : + _factories(factories), _prefixTable(prefixTable) + { + CFRetain(_factories); + CFRetain(_prefixTable); + } + + ~ObjectFactoryI() + { + CFRelease(_factories); + CFRelease(_prefixTable); + } + + virtual Ice::ObjectPtr + create(const std::string& type) + { + NSString* sliceId = [[NSString alloc] initWithUTF8String:type.c_str()]; + @try + { + id<ICEObjectFactory> factory = nil; + @synchronized(_factories) + { + factory = [_factories objectForKey:sliceId]; + if(factory == nil) + { + factory = [_factories objectForKey:@""]; + } + } + + ICEObject* obj = nil; + if(factory != nil) + { + obj = [factory create:sliceId]; + } + + if(obj == nil) + { + std::string tId = toObjCSliceId(type, _prefixTable); + Class c = objc_lookUpClass(tId.c_str()); + if(c == nil) + { + return 0; // No object factory. + } + if([c isSubclassOfClass:[ICEObject class]]) + { + obj = (ICEObject*)[[c alloc] init]; + } + } + + Ice::ObjectPtr o; + if(obj != nil) + { + o = [ICEInputStream createObjectReader:obj]; + [obj release]; + } + return o; + } + @catch(id ex) + { + rethrowCxxException(ex); + } + @finally + { + [sliceId release]; + } + return nil; // Keep the compiler happy. + } + + virtual void + destroy() + { + for(NSString* k in _factories) + { + [[_factories objectForKey:k] destroy]; + } + } + +private: + + NSDictionary* _factories; + NSDictionary* _prefixTable; +}; + +} + +@interface ICEInternalPrefixTable(ICEInternal) ++(NSDictionary*) newPrefixTable; +@end + +@implementation ICEInternalPrefixTable(ICEInternal) ++(NSDictionary*) newPrefixTable +{ + NSMutableDictionary* prefixTable = [[NSMutableDictionary alloc] init]; + ICEInternalPrefixTable* table = [[ICEInternalPrefixTable alloc] init]; + unsigned int count; + Method* methods = class_copyMethodList([ICEInternalPrefixTable class], &count); + for(unsigned int i = 0; i < count; ++i) + { + SEL selector = method_getName(methods[i]); + const char* methodName = sel_getName(selector); + if(strncmp(methodName, "addPrefixes_C", 13) == 0) + { + [table performSelector:selector withObject:prefixTable]; + } + } + free(methods); + [table release]; + return prefixTable; +} +@end + +@implementation ICECommunicator +-(void)setup:(NSDictionary*)prefixTable +{ + objectFactories_ = [[NSMutableDictionary alloc] init]; + if(prefixTable) + { + prefixTable_ = [prefixTable retain]; + } + else + { + prefixTable_ = [ICEInternalPrefixTable newPrefixTable]; + } + adminFacets_ = [[NSMutableDictionary alloc] init]; + COMMUNICATOR->addObjectFactory(new IceObjC::UnknownSlicedObjectFactoryI, "::Ice::Object"); + COMMUNICATOR->addObjectFactory(new IceObjC::ObjectFactoryI(objectFactories_, prefixTable_), ""); +} +-(void) dealloc +{ + [prefixTable_ release]; + [objectFactories_ release]; + [adminFacets_ release]; + [super dealloc]; +} +-(Ice::Communicator*) communicator +{ + return COMMUNICATOR; +} +-(NSDictionary*) getPrefixTable +{ + return prefixTable_; +} + +// +// Methods from @protocol ICECommunicator +// + +-(void) destroy +{ + NSException* nsex = nil; + try + { + COMMUNICATOR->destroy(); + @synchronized(adminFacets_) + { + [adminFacets_ removeAllObjects]; + } + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) shutdown +{ + NSException* nsex = nil; + try + { + COMMUNICATOR->shutdown(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) waitForShutdown +{ + NSException* nsex = nil; + try + { + COMMUNICATOR->waitForShutdown(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(BOOL) isShutdown +{ + NSException* nsex = nil; + try + { + return COMMUNICATOR->isShutdown(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return NO; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) stringToProxy:(NSString*)str +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->stringToProxy(fromNSString(str))]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableString*)proxyToString:(id<ICEObjectPrx>)obj +{ + NSException* nsex = nil; + try + { + return [toNSMutableString(COMMUNICATOR->proxyToString([(ICEObjectPrx*)obj objectPrx__])) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>)propertyToProxy:(NSString*)property +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->propertyToProxy(fromNSString(property))]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableDictionary*)proxyToProperty:(id<ICEObjectPrx>)prx property:(NSString*)property +{ + NSException* nsex = nil; + try + { + return [toNSDictionary(COMMUNICATOR->proxyToProperty([(ICEObjectPrx*)prx objectPrx__], + fromNSString(property))) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEIdentity*) stringToIdentity:(NSString*)str +{ + NSException* nsex = nil; + try + { + return [ICEIdentity identityWithIdentity:COMMUNICATOR->stringToIdentity(fromNSString(str))]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableString*) identityToString:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return [toNSMutableString(COMMUNICATOR->identityToString([ident identity])) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectAdapter>) createObjectAdapter:(NSString*)name; +{ + NSException* nsex = nil; + try + { + ICEObjectAdapter* adapter = [ICEObjectAdapter localObjectWithCxxObject: + COMMUNICATOR->createObjectAdapter( + fromNSString(name)).get()]; + return adapter; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectAdapter>) createObjectAdapterWithEndpoints:(NSString*)name endpoints:(NSString*)endpoints; +{ + NSException* nsex = nil; + try + { + ICEObjectAdapter* adapter = [ICEObjectAdapter localObjectWithCxxObject: + COMMUNICATOR->createObjectAdapterWithEndpoints( + fromNSString(name), fromNSString(endpoints)).get()]; + return adapter; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectAdapter>) createObjectAdapterWithRouter:(NSString*)name router:(id<ICERouterPrx>)rtr +{ + NSException* nsex = nil; + try + { + Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)rtr objectPrx__])); + ICEObjectAdapter* adapter = [ICEObjectAdapter localObjectWithCxxObject: + COMMUNICATOR->createObjectAdapterWithRouter( + fromNSString(name), router).get()]; + return adapter; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) addObjectFactory:(id<ICEObjectFactory>)factory sliceId:(NSString*)sliceId +{ + @synchronized(objectFactories_) + { + [objectFactories_ setObject:factory forKey:sliceId]; + } +} +-(id<ICEObjectFactory>) findObjectFactory:(NSString*)sliceId +{ + @synchronized(objectFactories_) + { + return [objectFactories_ objectForKey:sliceId]; + } + return nil; // Keep the compiler happy. +} + +-(id<ICEImplicitContext>) getImplicitContext +{ + return [ICEImplicitContext implicitContextWithImplicitContext:COMMUNICATOR->getImplicitContext().get()]; +} + +-(id<ICEProperties>) getProperties +{ + NSException* nsex = nil; + try + { + return [ICEProperties localObjectWithCxxObject:COMMUNICATOR->getProperties().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICELogger>) getLogger +{ + NSException* nsex = nil; + try + { + return [ICELoggerWrapper loggerWithLogger:COMMUNICATOR->getLogger().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEINSTRUMENTATIONCommunicatorObserver>) getObserver +{ + return nil; +} + +-(id<ICERouterPrx>) getDefaultRouter +{ + NSException* nsex = nil; + try + { + return (id<ICERouterPrx>)[ICERouterPrx objectPrxWithObjectPrx__:COMMUNICATOR->getDefaultRouter()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) setDefaultRouter:(id<ICERouterPrx>)rtr +{ + NSException* nsex = nil; + try + { + COMMUNICATOR->setDefaultRouter(Ice::RouterPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)rtr objectPrx__]))); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(id<ICELocatorPrx>) getDefaultLocator +{ + NSException* nsex = nil; + try + { + return (id<ICELocatorPrx>)[ICELocatorPrx objectPrxWithObjectPrx__:COMMUNICATOR->getDefaultLocator()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) setDefaultLocator:(id<ICELocatorPrx>)loc +{ + NSException* nsex = nil; + try + { + COMMUNICATOR->setDefaultLocator(Ice::LocatorPrx::uncheckedCast( + Ice::ObjectPrx([(ICEObjectPrx*)loc objectPrx__]))); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(id<ICEPluginManager>) getPluginManager +{ + @throw [ICEFeatureNotSupportedException featureNotSupportedException:__FILE__ line:__LINE__]; +} +-(void) flushBatchRequests +{ + NSException* nsex = nil; + try + { + COMMUNICATOR->flushBatchRequests(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(id<ICEAsyncResult>) begin_flushBatchRequests +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) + { + result = COMMUNICATOR->begin_flushBatchRequests(); + }); +} +-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception +{ + return [self begin_flushBatchRequests:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = COMMUNICATOR->begin_flushBatchRequests(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + COMMUNICATOR->end_flushBatchRequests(result); + }, + exception, sent); +} +-(void) end_flushBatchRequests:(id<ICEAsyncResult>)result +{ + endCppCall(^(const Ice::AsyncResultPtr& r) + { + COMMUNICATOR->end_flushBatchRequests(r); + }, result); +} +-(id<ICEObjectPrx>) createAdmin:(id<ICEObjectAdapter>)adapter adminId:(ICEIdentity*)adminId +{ + NSException* nsex; + try + { + Ice::ObjectAdapterPtr adminAdapter = [(ICEObjectAdapter*)adapter adapter]; + return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->createAdmin(adminAdapter, [adminId identity])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(id<ICEObjectPrx>) getAdmin +{ + NSException* nsex; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:COMMUNICATOR->getAdmin()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(void) addAdminFacet:(ICEObject*)servant facet:(NSString*)facet +{ + NSException* nsex; + try + { + COMMUNICATOR->addAdminFacet([servant object__], fromNSString(facet)); + @synchronized(adminFacets_) + { + [adminFacets_ setObject:servant forKey:facet]; + } + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(ICEObject*) removeAdminFacet:(NSString*)facet +{ + NSException* nsex; + try + { + @synchronized(adminFacets_) + { + [adminFacets_ removeObjectForKey:facet]; + } + return toObjC(COMMUNICATOR->removeAdminFacet(fromNSString(facet))); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(ICEObject*) findAdminFacet:(NSString*)facet +{ + NSException* nsex; + try + { + @synchronized(adminFacets_) + { + ICEObject* obj = [adminFacets_ objectForKey:facet]; + if(obj != nil) + { + return obj; + } + obj = toObjC(COMMUNICATOR->findAdminFacet(fromNSString(facet))); + if(obj != nil) + { + [adminFacets_ setObject:obj forKey:facet]; + } + return obj; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(ICEMutableFacetMap*) findAllAdminFacets +{ + NSException* nsex; + try + { + ICEMutableFacetMap* facetMap = toNSDictionary(COMMUNICATOR->findAllAdminFacets()); + @synchronized(adminFacets_) + { + [adminFacets_ addEntriesFromDictionary:facetMap]; + } + return facetMap; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +@end diff --git a/objective-c/src/Ice/ConnectionI.h b/objective-c/src/Ice/ConnectionI.h new file mode 100644 index 00000000000..4ac8abc445a --- /dev/null +++ b/objective-c/src/Ice/ConnectionI.h @@ -0,0 +1,42 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Connection.h> + +#import <objc/Ice/LocalObject.h> + +#include <Ice/Connection.h> +//#include <IceSSL/ConnectionInfo.h> + +@interface ICEConnectionInfo (ICEInternal) +-(id) initWithConnectionInfo:(Ice::ConnectionInfo*)connectionInfo; +@end + +@interface ICEIPConnectionInfo (ICEInternal) +-(id) initWithIPConnectionInfo:(Ice::IPConnectionInfo*)ipConnectionInfo; +@end + +@interface ICETCPConnectionInfo (ICEInternal) +-(id) initWithTCPConnectionInfo:(Ice::TCPConnectionInfo*)tcpConnectionInfo; +@end + +@interface ICEUDPConnectionInfo (ICEInternal) +-(id) initWithUDPConnectionInfo:(Ice::UDPConnectionInfo*)udpConnectionInfo; +@end + +@interface ICEWSConnectionInfo (ICEInternal) +-(id) initWithWSConnectionInfo:(Ice::WSConnectionInfo*)wsConnectionInfo; +@end + +// @interface ICESSLConnectionInfo (ICEInternal) +// -(id) initWithSSLConnectionInfo:(IceSSL::ConnectionInfo*)sslConnectionInfo; +// @end + +@interface ICEConnection : ICELocalObject<ICEConnection> +@end diff --git a/objective-c/src/Ice/ConnectionI.mm b/objective-c/src/Ice/ConnectionI.mm new file mode 100644 index 00000000000..21b4ce742f8 --- /dev/null +++ b/objective-c/src/Ice/ConnectionI.mm @@ -0,0 +1,408 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <ConnectionI.h> +#import <EndpointI.h> +#import <IdentityI.h> +#import <ObjectAdapterI.h> +#import <ProxyI.h> +#import <Util.h> +#import <LocalObjectI.h> + +#import <objc/Ice/LocalException.h> + +#import <objc/runtime.h> + +@implementation ICEConnectionInfo (ICEInternal) + +-(id) initWithConnectionInfo:(Ice::ConnectionInfo*)connectionInfo; +{ + self = [super initWithCxxObject:connectionInfo]; + if(self != nil) + { + self->incoming = connectionInfo->incoming; + self->adapterName = [[NSString alloc] initWithUTF8String:connectionInfo->adapterName.c_str()]; + self->connectionId = [[NSString alloc] initWithUTF8String:connectionInfo->connectionId.c_str()]; + self->rcvSize = connectionInfo->rcvSize; + self->sndSize = connectionInfo->sndSize; + } + return self; +} + +@end + +@implementation ICEIPConnectionInfo (ICEInternal) + +-(id) initWithIPConnectionInfo:(Ice::IPConnectionInfo*)ipConnectionInfo +{ + self = [super initWithConnectionInfo:ipConnectionInfo]; + if(self) + { + self->localAddress = [[NSString alloc] initWithUTF8String:ipConnectionInfo->localAddress.c_str()]; + self->localPort = ipConnectionInfo->localPort; + self->remoteAddress = [[NSString alloc] initWithUTF8String:ipConnectionInfo->remoteAddress.c_str()]; + self->remotePort = ipConnectionInfo->remotePort; + } + return self; +} + +@end + +@implementation ICETCPConnectionInfo (ICEInternal) +-(id) initWithTCPConnectionInfo:(Ice::TCPConnectionInfo*)tcpConnectionInfo +{ + self = [super initWithIPConnectionInfo:tcpConnectionInfo]; + return self; +} +@end + +@implementation ICEUDPConnectionInfo (ICEInternal) + +-(id) initWithUDPConnectionInfo:(Ice::UDPConnectionInfo*)udpConnectionInfo +{ + self = [super initWithIPConnectionInfo:udpConnectionInfo]; + if(self) + { + self->mcastAddress = [[NSString alloc] initWithUTF8String:udpConnectionInfo->mcastAddress.c_str()]; + self->mcastPort = udpConnectionInfo->mcastPort; + } + return self; +} + +@end + +@implementation ICEWSConnectionInfo (ICEInternal) +-(id) initWithWSConnectionInfo:(Ice::WSConnectionInfo*)wsConnectionInfo +{ + self = [super initWithIPConnectionInfo:wsConnectionInfo]; + if(self) + { + self->headers = toNSDictionary(wsConnectionInfo->headers); + } + return self; +} +@end + +namespace +{ + +class ConnectionCallbackI : public Ice::ConnectionCallback +{ +public: + + ConnectionCallbackI(id<ICEConnection> connection, id<ICEConnectionCallback> callback) : + _connection(connection), _callback(callback) + { + [_connection retain]; + [_callback retain]; + } + + ~ConnectionCallbackI() + { + [_connection release]; + [_callback release]; + } + + void + heartbeat(const Ice::ConnectionPtr& connection) + { + NSException* ex = nil; + @autoreleasepool + { + @try + { + [_callback heartbeat:_connection]; + } + @catch(id e) + { + ex = [e retain]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } + } + + void + closed(const Ice::ConnectionPtr& connection) + { + NSException* ex = nil; + @autoreleasepool + { + @try + { + [_callback closed:_connection]; + } + @catch(id e) + { + ex = [e retain]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } + } + +private: + + id<ICEConnection> _connection; + id<ICEConnectionCallback> _callback; +}; + +} + +#define CONNECTION dynamic_cast<Ice::Connection*>(static_cast<IceUtil::Shared*>(cxxObject_)) + +@implementation ICEConnection +-(void) close:(BOOL)force +{ + NSException* nsex = nil; + try + { + CONNECTION->close(force); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(id<ICEObjectPrx>) createProxy:(ICEIdentity*)identity +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:CONNECTION->createProxy([identity identity])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) setAdapter:(id<ICEObjectAdapter>)adapter +{ + NSException* nsex = nil; + try + { + CONNECTION->setAdapter([(ICEObjectAdapter*)adapter adapter]); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(id<ICEObjectAdapter>) getAdapter +{ + NSException* nsex = nil; + try + { + return [ICEObjectAdapter localObjectWithCxxObject:CONNECTION->getAdapter().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) flushBatchRequests +{ + NSException* nsex = nil; + try + { + CONNECTION->flushBatchRequests(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(id<ICEAsyncResult>) begin_flushBatchRequests +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) + { + result = CONNECTION->begin_flushBatchRequests(); + }); +} +-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception +{ + return [self begin_flushBatchRequests:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = CONNECTION->begin_flushBatchRequests(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + CONNECTION->end_flushBatchRequests(result); + }, + exception, sent); +} +-(void) end_flushBatchRequests:(id<ICEAsyncResult>)result +{ + endCppCall(^(const Ice::AsyncResultPtr& r) + { + CONNECTION->end_flushBatchRequests(r); + }, result); +} +-(void) setCallback:(id<ICEConnectionCallback>)callback +{ + CONNECTION->setCallback(new ConnectionCallbackI(self, callback)); +} +-(void) setACM:(id)timeout close:(id)close heartbeat:(id)heartbeat +{ + IceUtil::Optional<int> to; + ICEInt intValue; + if([ICEOptionalGetter getInt:timeout value:&intValue]) + { + to = intValue; + } + IceUtil::Optional<Ice::ACMClose> c; + if([ICEOptionalGetter getInt:close value:&intValue]) + { + c = (Ice::ACMClose)intValue; + } + IceUtil::Optional<Ice::ACMHeartbeat> hb; + if([ICEOptionalGetter getInt:heartbeat value:&intValue]) + { + hb = (Ice::ACMHeartbeat)intValue; + } + + CONNECTION->setACM(to, c, hb); +} +-(ICEACM*) getACM +{ + Ice::ACM acm = CONNECTION->getACM(); + return [ICEACM acm:acm.timeout close:(ICEACMClose)acm.close heartbeat:(ICEACMHeartbeat)acm.heartbeat]; +} +-(NSMutableString*) type +{ + return [toNSMutableString(CONNECTION->type()) autorelease]; +} +-(ICEInt) timeout +{ + return CONNECTION->timeout(); +} +-(NSMutableString*) toString +{ + return [toNSMutableString(CONNECTION->toString()) autorelease]; +} +-(NSString*) description +{ + return [toNSString(CONNECTION->toString()) autorelease]; +} + +-(ICEConnectionInfo*) getInfo +{ + NSException* nsex = nil; + try + { + Ice::ConnectionInfoPtr info = CONNECTION->getInfo(); + if(!info) + { + return nil; + } + + Ice::UDPConnectionInfoPtr udpInfo = Ice::UDPConnectionInfoPtr::dynamicCast(info); + if(udpInfo) + { + return [[[ICEUDPConnectionInfo alloc] initWithUDPConnectionInfo:udpInfo.get()] autorelease]; + } + + Ice::TCPConnectionInfoPtr tcpInfo = Ice::TCPConnectionInfoPtr::dynamicCast(info); + if(tcpInfo) + { + return [[[ICETCPConnectionInfo alloc] initWithTCPConnectionInfo:tcpInfo.get()] autorelease]; + } + + Ice::WSConnectionInfoPtr wsInfo = Ice::WSConnectionInfoPtr::dynamicCast(info); + if(wsInfo) + { + return [[[ICEWSConnectionInfo alloc] initWithWSConnectionInfo:wsInfo.get()] autorelease]; + } + + std::ostringstream os; + os << "connectionInfoWithType_" << CONNECTION->type() << ":"; + SEL selector = sel_registerName(os.str().c_str()); + if([ICEConnectionInfo respondsToSelector:selector]) + { + IceUtil::Shared* shared = info.get(); + return [ICEConnectionInfo performSelector:selector withObject:[NSValue valueWithPointer:shared]]; + } + + Ice::IPConnectionInfoPtr ipInfo = Ice::IPConnectionInfoPtr::dynamicCast(info); + if(ipInfo) + { + return [[[ICEIPConnectionInfo alloc] initWithIPConnectionInfo:ipInfo.get()] autorelease]; + } + + return [[[ICEConnectionInfo alloc] initWithConnectionInfo:info.get()] autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; +} + +-(void) setBufferSize:(int)rcvSize sndSize:(int)sndSize +{ + NSException* nsex = nil; + try + { + CONNECTION->setBufferSize(rcvSize, sndSize); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(ICEEndpoint*) getEndpoint +{ + NSException* nsex = nil; + try + { + return [ICEEndpoint localObjectWithCxxObject:CONNECTION->getEndpoint().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; +} +@end diff --git a/objective-c/src/Ice/CurrentI.h b/objective-c/src/Ice/CurrentI.h new file mode 100644 index 00000000000..3c9fdf7dafe --- /dev/null +++ b/objective-c/src/Ice/CurrentI.h @@ -0,0 +1,16 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Current.h> + +#include <Ice/Current.h> + +@interface ICECurrent (IceInternal) +-(ICECurrent*) initWithCurrent:(const Ice::Current&)arg; +@end diff --git a/objective-c/src/Ice/CurrentI.mm b/objective-c/src/Ice/CurrentI.mm new file mode 100644 index 00000000000..c84a8f4f5c1 --- /dev/null +++ b/objective-c/src/Ice/CurrentI.mm @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <CurrentI.h> +#import <VersionI.h> +#import <ObjectAdapterI.h> +#import <ConnectionI.h> +#import <IdentityI.h> +#import <Util.h> +#import <LocalObjectI.h> + +@implementation ICECurrent (ICEInternal) + +-(ICECurrent*) initWithCurrent:(const Ice::Current&)current +{ + self = [super init]; + if(!self) + { + return nil; + } + + // + // TODO: Optimize: the servant blobject should cache an ICECurrent object to + // avoid re-creating the wrappers for each dispatched invocation. + // + adapter = [ICEObjectAdapter localObjectWithCxxObjectNoAutoRelease:current.adapter.get()]; + con = [ICEConnection localObjectWithCxxObjectNoAutoRelease:current.con.get()]; + id_ = [[ICEIdentity alloc] initWithIdentity:current.id]; + facet = [[NSString alloc] initWithUTF8String:current.facet.c_str()]; + operation = [[NSString alloc] initWithUTF8String:current.operation.c_str()]; + mode = (ICEOperationMode)current.mode; + ctx = toNSDictionary(current.ctx); + requestId = current.requestId; + encoding = [[ICEEncodingVersion encodingVersionWithEncodingVersion:current.encoding] retain]; + return self; +} +@end + diff --git a/objective-c/src/Ice/DispatchInterceptor.m b/objective-c/src/Ice/DispatchInterceptor.m new file mode 100644 index 00000000000..f8c6c5a150d --- /dev/null +++ b/objective-c/src/Ice/DispatchInterceptor.m @@ -0,0 +1,60 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/DispatchInterceptor.h> + +#import <Request.h> + +#import <Foundation/NSThread.h> +#import <Foundation/NSInvocation.h> + +@implementation ICEDispatchInterceptor +-(BOOL) dispatch__:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + ICERequest* request = [ICERequest request:current is:is os:os]; + id<ICEDispatchInterceptor> dispatchInterceptor = (id<ICEDispatchInterceptor>)self; + return [dispatchInterceptor dispatch:request]; +} +@end + +@implementation ICEMainThreadDispatch + +-(id)init:(ICEObject*)s +{ + servant = [s retain]; + return self; +} + ++(id)mainThreadDispatch:(ICEObject*)s +{ + return [[[self alloc] init:s] autorelease]; +} + +-(BOOL) dispatch:(id<ICERequest>)request +{ + SEL selector = @selector(ice_dispatch:); + NSMethodSignature* sig = [[servant class] instanceMethodSignatureForSelector:selector]; + NSInvocation* inv = [NSInvocation invocationWithMethodSignature:sig]; + [inv setTarget:servant]; + [inv setSelector:selector]; + [inv setArgument:&request atIndex:2]; + + [inv performSelectorOnMainThread:@selector(invokeWithTarget:) withObject:servant waitUntilDone:YES]; + + BOOL status; + [inv getReturnValue:&status]; + return status; +} + +-(void)dealloc +{ + [servant release]; + [super dealloc]; +} +@end diff --git a/objective-c/src/Ice/Dispatcher.mm b/objective-c/src/Ice/Dispatcher.mm new file mode 100644 index 00000000000..a3a53fa9ac2 --- /dev/null +++ b/objective-c/src/Ice/Dispatcher.mm @@ -0,0 +1,101 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <DispatcherI.h> +#import <Util.h> +#import <ConnectionI.h> +#import <LocalObjectI.h> + +#include <Block.h> + +namespace +{ + +class DispatcherI : public Ice::Dispatcher +{ +public: + +// We must explicitely retain/release so that the garbage +// collector does not trash the dispatcher. +DispatcherI(void(^dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>)) : _dispatcher(Block_copy(dispatcher)) +{ +} + +virtual ~DispatcherI() +{ + Block_release(_dispatcher); +} + +virtual void +dispatch(const Ice::DispatcherCallPtr& call, const Ice::ConnectionPtr& connection) +{ + NSException* ex = nil; + @autoreleasepool + { + id<ICEConnection> con = [ICEConnection localObjectWithCxxObject:connection.get()]; + id<ICEDispatcherCall> c = [[ICEDispatcherCall alloc] initWithCall:call.get()]; + @try + { + _dispatcher(c, con); + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [c release]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } +} + +private: + +void(^_dispatcher)(id<ICEDispatcherCall>, id<ICEConnection>); + +}; +typedef IceUtil::Handle<DispatcherI> DispatcherIPtr; + +} + +@implementation ICEDispatcher ++(Ice::Dispatcher*) dispatcherWithDispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))dispatcher +{ + return new DispatcherI(dispatcher); +} +@end + +@implementation ICEDispatcherCall +-(id) initWithCall:(Ice::DispatcherCall*)call +{ + self = [super init]; + if(!self) + { + return nil; + } + + cxxCall_ = call; + cxxCall_->__incRef(); + return self; +} +-(void) dealloc +{ + cxxCall_->__decRef(); + cxxCall_ = 0; + [super dealloc]; +} +-(void) run +{ + cppCall(^ { cxxCall_->run(); }); +} +@end diff --git a/objective-c/src/Ice/DispatcherI.h b/objective-c/src/Ice/DispatcherI.h new file mode 100644 index 00000000000..9ad5554add8 --- /dev/null +++ b/objective-c/src/Ice/DispatcherI.h @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Initialize.h> +#import <objc/Ice/Connection.h> + +#import <objc/Ice/LocalObject.h> + +#include <Ice/Dispatcher.h> + +@interface ICEDispatcher : NSObject ++(Ice::Dispatcher*)dispatcherWithDispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))arg; +@end + +@interface ICEDispatcherCall : NSObject<ICEDispatcherCall> +{ + Ice::DispatcherCall* cxxCall_; +} +-(id) initWithCall:(Ice::DispatcherCall*)call; +@end + diff --git a/objective-c/src/Ice/EndpointI.h b/objective-c/src/Ice/EndpointI.h new file mode 100644 index 00000000000..bba7cfd1bdf --- /dev/null +++ b/objective-c/src/Ice/EndpointI.h @@ -0,0 +1,43 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in +// the ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Endpoint.h> + +#import <objc/Ice/LocalObject.h> + +#include <Ice/Endpoint.h> + +@interface ICEEndpoint : ICELocalObject<ICEEndpoint> +-(Ice::Endpoint*) endpoint; +@end + +@interface ICEEndpointInfo (ICEInternal) +-(id) initWithEndpointInfo:(Ice::EndpointInfo*)endpointInfo; +@end + +@interface ICEIPEndpointInfo (ICEInternal) +-(id) initWithIPEndpointInfo:(Ice::IPEndpointInfo*)ipEndpointInfo; +@end + +@interface ICETCPEndpointInfo (ICEInternal) +-(id) initWithTCPEndpointInfo:(Ice::TCPEndpointInfo*)tcpEndpointInfo; +@end + +@interface ICEUDPEndpointInfo (ICEInternal) +-(id) initWithUDPEndpointInfo:(Ice::UDPEndpointInfo*)udpEndpointInfo; +@end + +@interface ICEWSEndpointInfo (ICEInternal) +-(id) initWithWSEndpointInfo:(Ice::WSEndpointInfo*)wsEndpointInfo; +@end + +@interface ICEOpaqueEndpointInfo (ICEInternal) +-(id) initWithOpaqueEndpointInfo:(Ice::OpaqueEndpointInfo*)opaqueEndpointInfo; +@end + diff --git a/objective-c/src/Ice/EndpointI.mm b/objective-c/src/Ice/EndpointI.mm new file mode 100644 index 00000000000..ea308e35f98 --- /dev/null +++ b/objective-c/src/Ice/EndpointI.mm @@ -0,0 +1,196 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in +// the ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <EndpointI.h> +#import <Util.h> +#import <VersionI.h> +#import <LocalObjectI.h> + +#import <objc/Ice/BuiltinSequences.h> + +#import <Ice/Endpoint.h> + +#include <objc/runtime.h> + +#define ENDPOINT dynamic_cast<Ice::Endpoint*>(static_cast<IceUtil::Shared*>(cxxObject_)) +#define ENDPOINTINFO dynamic_cast<Ice::EndpointInfo*>(static_cast<IceUtil::Shared*>(cxxObject_)) + +@implementation ICEEndpoint + +-(Ice::Endpoint*) endpoint +{ + return ENDPOINT; +} + +-(ICEEndpointInfo*) getInfo +{ + NSException* nsex = nil; + try + { + Ice::EndpointInfoPtr info = ENDPOINT->getInfo(); + if(!info) + { + return nil; + } + + Ice::UDPEndpointInfoPtr udpInfo = Ice::UDPEndpointInfoPtr::dynamicCast(info); + if(udpInfo) + { + return [[[ICEUDPEndpointInfo alloc] initWithUDPEndpointInfo:udpInfo.get()] autorelease]; + } + + Ice::TCPEndpointInfoPtr tcpInfo = Ice::TCPEndpointInfoPtr::dynamicCast(info); + if(tcpInfo) + { + return [[[ICETCPEndpointInfo alloc] initWithTCPEndpointInfo:tcpInfo.get()] autorelease]; + } + + Ice::WSEndpointInfoPtr wsInfo = Ice::WSEndpointInfoPtr::dynamicCast(info); + if(wsInfo) + { + return [[[ICEWSEndpointInfo alloc] initWithWSEndpointInfo:wsInfo.get()] autorelease]; + } + + Ice::OpaqueEndpointInfoPtr opaqueInfo = Ice::OpaqueEndpointInfoPtr::dynamicCast(info); + if(opaqueInfo) + { + return [[[ICEOpaqueEndpointInfo alloc] initWithOpaqueEndpointInfo:opaqueInfo.get()] autorelease]; + } + + std::ostringstream os; + os << "endpointInfoWithType_" << info->type() << ":"; + SEL selector = sel_registerName(os.str().c_str()); + if([ICEEndpointInfo respondsToSelector:selector]) + { + IceUtil::Shared* shared = info.get(); + return [ICEEndpointInfo performSelector:selector withObject:[NSValue valueWithPointer:shared]]; + } + + Ice::IPEndpointInfoPtr ipInfo = Ice::IPEndpointInfoPtr::dynamicCast(info); + if(ipInfo) + { + return [[[ICEIPEndpointInfo alloc] initWithIPEndpointInfo:ipInfo.get()] autorelease]; + } + + return [[[ICEEndpointInfo alloc] initWithEndpointInfo:info.get()] autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; +} + +-(NSMutableString*) toString +{ + return [toNSMutableString(ENDPOINT->toString()) autorelease]; +} + +@end + +@implementation ICEEndpointInfo(ICEInternal) + +-(id) initWithEndpointInfo:(Ice::EndpointInfo*)endpointInfo; +{ + self = [super initWithCxxObject:endpointInfo]; + if(self) + { + self->timeout = endpointInfo->timeout; + self->compress = endpointInfo->compress; + } + return self; +} + +-(ICEShort) type +{ + return ENDPOINTINFO->type(); +} + +-(BOOL) datagram; +{ + return ENDPOINTINFO->datagram(); +} + +-(BOOL) secure; +{ + return ENDPOINTINFO->secure(); +} +@end + +@implementation ICEIPEndpointInfo(ICEInternal) + +-(id) initWithIPEndpointInfo:(Ice::IPEndpointInfo*)ipEndpointInfo; +{ + self = [super initWithEndpointInfo:ipEndpointInfo]; + if(self) + { + self->host = [[NSString alloc] initWithUTF8String:ipEndpointInfo->host.c_str()]; + self->port = ipEndpointInfo->port; + self->sourceAddress = [[NSString alloc] initWithUTF8String:ipEndpointInfo->sourceAddress.c_str()]; + } + return self; +} + +@end + +@implementation ICETCPEndpointInfo(ICEInternal) +-(id) initWithTCPEndpointInfo:(Ice::TCPEndpointInfo*)tcpEndpointInfo +{ + self = [super initWithIPEndpointInfo:tcpEndpointInfo]; + return self; +} +@end + +@implementation ICEUDPEndpointInfo(ICEInternal) + +-(id) initWithUDPEndpointInfo:(Ice::UDPEndpointInfo*)udpEndpointInfo +{ + self = [super initWithIPEndpointInfo:udpEndpointInfo]; + if(self) + { + self->mcastInterface = [[NSString alloc] initWithUTF8String:udpEndpointInfo->mcastInterface.c_str()]; + self->mcastTtl = udpEndpointInfo->mcastTtl; + } + return self; +} + +@end + +@implementation ICEWSEndpointInfo(ICEInternal) + +-(id) initWithWSEndpointInfo:(Ice::WSEndpointInfo*)wsEndpointInfo +{ + self = [super initWithIPEndpointInfo:wsEndpointInfo]; + if(self) + { + self->resource = [[NSString alloc] initWithUTF8String:wsEndpointInfo->resource.c_str()]; + } + return self; +} + +@end + +@implementation ICEOpaqueEndpointInfo(ICEInternal) + +-(id) initWithOpaqueEndpointInfo:(Ice::OpaqueEndpointInfo*)opaqueEndpointInfo +{ + self = [super init]; + if(self) + { + self->rawEncoding = [[ICEEncodingVersion alloc] initWithEncodingVersion:opaqueEndpointInfo->rawEncoding]; + self->rawBytes = toNSData(opaqueEndpointInfo->rawBytes); + } + return self; +} + +@end diff --git a/objective-c/src/Ice/Exception.mm b/objective-c/src/Ice/Exception.mm new file mode 100644 index 00000000000..97f265c407d --- /dev/null +++ b/objective-c/src/Ice/Exception.mm @@ -0,0 +1,977 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <ExceptionI.h> +#import <IdentityI.h> +#import <Util.h> +#import <VersionI.h> + +#import <objc/Ice/LocalException.h> + +#include <Ice/LocalException.h> + +#import <Foundation/NSKeyedArchiver.h> + +@implementation ICEException +-(id)init +{ + return [super initWithName:[self ice_name] reason:nil userInfo:nil]; +} + +-(id)initWithReason:(NSString*)reason +{ + return [super initWithName:[self ice_name] reason:reason userInfo:nil]; +} + +-(NSString*)ice_name +{ + NSAssert(false, @"ice_name not overriden"); + return nil; +} + +-(id) initWithCoder:(NSCoder*)decoder +{ + [NSException raise:NSInvalidArchiveOperationException format:@"ICEExceptions do not support NSCoding"]; + return nil; +} + +-(void) encodeWithCoder:(NSCoder*)coder +{ + [NSException raise:NSInvalidArchiveOperationException format:@"ICEExceptions do not support NSCoding"]; +} + +-(id) copyWithZone:(NSZone *)zone +{ + NSAssert(false, @"copyWithZone: must be overriden"); + return nil; +} + +-(void) dealloc +{ + [super dealloc]; +} +@end + +static NSString* +localExceptionToString(const Ice::LocalException& ex) +{ + std::ostringstream os; + os << ex; + std::string str = os.str(); + // Remove the lengthy path part of the C++ filename. + std::string::size_type pos = str.find(".cpp"); + if(pos != std::string::npos) + { + pos = str.rfind('/', pos); + if(pos != std::string::npos) + { + str = str.substr(pos + 1); + } + } + return [NSString stringWithUTF8String:str.c_str()]; +} + +@implementation ICELocalException +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithReason:localExceptionToString(ex)]; + if(!self) + { + return nil; + } + file = ex.ice_file(); + line = ex.ice_line(); + return self; +} + +-(void)rethrowCxx +{ + NSAssert(false, @"rethrowCxx must be overriden"); +} + ++(id)localExceptionWithLocalException:(const Ice::LocalException&)ex +{ + return [[[self alloc] initWithLocalException:ex] autorelease]; +} + +-(NSString*) file +{ + return [toNSString(file) autorelease]; +} + +@synthesize line; + +-(id)init:(const char*)f line:(int)l reason_:(NSString*)r +{ + return [self init:f line:l reason:r]; +} + +-(id)init:(const char*)f line:(int)l +{ + self = [super init]; + if(!self) + { + return nil; + } + file = f; + line = l; + return self; +} + +-(id)init:(const char*)f line:(int)l reason:(NSString*)r +{ + self = [super initWithReason:r]; + if(!self) + { + return nil; + } + file = f; + line = l; + return self; +} + ++(id)localException:(const char*)file line:(int)line +{ + return [[[self alloc] init:file line:line] autorelease]; +} + +-(NSString*)description +{ + try + { + [self rethrowCxx]; + return @""; // Keep the compiler happy. + } + catch(const Ice::LocalException& ex) + { + return localExceptionToString(ex); + } +} + +-(id) copyWithZone:(NSZone *)zone +{ + return [[[self class] allocWithZone:zone] init:file line:line]; +} + +-(void) dealloc +{ + [super dealloc]; +} +@end + +@implementation ICEUserException +-(BOOL)usesClasses__ +{ + return NO; +} + +-(void)write__:(id<ICEOutputStream>)os +{ + [os startException:nil]; + [self writeImpl__:os]; + [os endException]; +} + +-(void) writeImpl__:(id<ICEOutputStream>)os +{ + NSAssert(NO, @"writeImpl__ requires override"); +} + +-(void)read__:(id<ICEInputStream>)is +{ + [is startException]; + [self readImpl__:is]; + [is endException:NO]; +} + +-(void) readImpl__:(id<ICEInputStream>)is +{ + NSAssert(NO, @"readImpl__ requires override"); +} + +-(id) copyWithZone:(NSZone *)zone +{ + return [[[self class] allocWithZone:zone] init]; +} + +-(void) dealloc +{ + [super dealloc]; +} +@end + +@implementation ICEInitializationException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::InitializationException*>(&ex), @"invalid local exception type"); + const Ice::InitializationException& localEx = dynamic_cast<const Ice::InitializationException&>(ex); + reason_ = toNSString(localEx.reason); + return self; +} +-(void) rethrowCxx +{ + throw Ice::InitializationException(file, line, fromNSString(reason_)); +} +@end + +@implementation ICEPluginInitializationException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::PluginInitializationException*>(&ex), @"invalid local exception type"); + const Ice::PluginInitializationException& localEx = dynamic_cast<const Ice::PluginInitializationException&>(ex); + reason_ = toNSString(localEx.reason); + return self; +} +-(void) rethrowCxx +{ + throw Ice::PluginInitializationException(file, line, fromNSString(reason_)); +} +@end + +@implementation ICECollocationOptimizationException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::CollocationOptimizationException(file, line); +} +@end + +@implementation ICEAlreadyRegisteredException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::AlreadyRegisteredException*>(&ex), @"invalid local exception type"); + const Ice::AlreadyRegisteredException& localEx = dynamic_cast<const Ice::AlreadyRegisteredException&>(ex); + kindOfObject = toNSString(localEx.kindOfObject); + id_ = toNSString(localEx.id); + return self; +} +-(void) rethrowCxx +{ + throw Ice::AlreadyRegisteredException(file, line, fromNSString(kindOfObject), fromNSString(id_)); +} +@end + +@implementation ICENotRegisteredException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::NotRegisteredException*>(&ex), @"invalid local exception type"); + const Ice::NotRegisteredException& localEx = dynamic_cast<const Ice::NotRegisteredException&>(ex); + kindOfObject = toNSString(localEx.kindOfObject); + id_ = toNSString(localEx.id); + return self; +} +-(void) rethrowCxx +{ + throw Ice::NotRegisteredException(file, line, fromNSString(kindOfObject), fromNSString(id_)); +} +@end + +@implementation ICETwowayOnlyException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::TwowayOnlyException*>(&ex), @"invalid local exception type"); + const Ice::TwowayOnlyException& localEx = dynamic_cast<const Ice::TwowayOnlyException&>(ex); + operation = toNSString(localEx.operation); + return self; +} +-(void) rethrowCxx +{ + throw Ice::TwowayOnlyException(file, line, fromNSString(operation)); +} +@end + +@implementation ICEUnknownException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::UnknownException*>(&ex), @"invalid local exception type"); + const Ice::UnknownException& localEx = dynamic_cast<const Ice::UnknownException&>(ex); + unknown = toNSString(localEx.unknown); + return self; +} +-(void) rethrowCxx +{ + throw Ice::UnknownException(file, line, fromNSString(unknown)); +} +@end + +@implementation ICEUnknownLocalException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::UnknownLocalException(file, line, fromNSString([self unknown])); +} +@end + +@implementation ICEUnknownUserException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::UnknownUserException(file, line, fromNSString([self unknown])); +} +@end + +@implementation ICEVersionMismatchException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::VersionMismatchException(file, line); +} +@end + +@implementation ICECommunicatorDestroyedException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::CommunicatorDestroyedException(file, line); +} +@end + +@implementation ICEObjectAdapterDeactivatedException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::ObjectAdapterDeactivatedException*>(&ex), @"invalid local exception type"); + const Ice::ObjectAdapterDeactivatedException& localEx = dynamic_cast<const Ice::ObjectAdapterDeactivatedException&>(ex); + name_ = toNSString(localEx.name); + return self; +} +-(void) rethrowCxx +{ + throw Ice::ObjectAdapterDeactivatedException(file, line, fromNSString(name_)); +} +@end + +@implementation ICEObjectAdapterIdInUseException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::ObjectAdapterIdInUseException*>(&ex), @"invalid local exception type"); + const Ice::ObjectAdapterIdInUseException& localEx = dynamic_cast<const Ice::ObjectAdapterIdInUseException&>(ex); + id_ = toNSString(localEx.id); + return self; +} +@end + +@implementation ICENoEndpointException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::NoEndpointException*>(&ex), @"invalid local exception type"); + const Ice::NoEndpointException& localEx = dynamic_cast<const Ice::NoEndpointException&>(ex); + proxy = toNSString(localEx.proxy); + return self; +} +-(void) rethrowCxx +{ + throw Ice::NoEndpointException(file, line, fromNSString(proxy)); +} +@end + +@implementation ICEEndpointParseException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::EndpointParseException*>(&ex), @"invalid local exception type"); + const Ice::EndpointParseException& localEx = dynamic_cast<const Ice::EndpointParseException&>(ex); + str = toNSString(localEx.str); + return self; +} +-(void) rethrowCxx +{ + throw Ice::EndpointParseException(file, line, fromNSString(str)); +} +@end + +@implementation ICEEndpointSelectionTypeParseException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::EndpointSelectionTypeParseException*>(&ex), @"invalid local exception type"); + const Ice::EndpointSelectionTypeParseException& localEx = dynamic_cast<const Ice::EndpointSelectionTypeParseException&>(ex); + str = toNSString(localEx.str); + return self; +} +-(void) rethrowCxx +{ + throw Ice::EndpointSelectionTypeParseException(file, line, fromNSString(str)); +} +@end + +@implementation ICEIdentityParseException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::IdentityParseException*>(&ex), @"invalid local exception type"); + const Ice::IdentityParseException& localEx = dynamic_cast<const Ice::IdentityParseException&>(ex); + str = toNSString(localEx.str); + return self; +} +@end + +@implementation ICEProxyParseException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::ProxyParseException*>(&ex), @"invalid local exception type"); + const Ice::ProxyParseException& localEx = dynamic_cast<const Ice::ProxyParseException&>(ex); + str = toNSString(localEx.str); + return self; +} +-(void) rethrowCxx +{ + throw Ice::ProxyParseException(file, line, fromNSString(str)); +} +@end + +@implementation ICEIllegalIdentityException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::IllegalIdentityException*>(&ex), @"invalid local exception type"); + const Ice::IllegalIdentityException& localEx = dynamic_cast<const Ice::IllegalIdentityException&>(ex); + id_ = [[ICEIdentity alloc] initWithIdentity:localEx.id]; + return self; +} +-(void) rethrowCxx +{ + Ice::Identity ident = { fromNSString(id_.name), fromNSString(id_.category) }; + throw Ice::IllegalIdentityException(file, line, ident); +} +@end + +@implementation ICERequestFailedException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::RequestFailedException*>(&ex), @"invalid local exception type"); + const Ice::RequestFailedException& localEx = dynamic_cast<const Ice::RequestFailedException&>(ex); + id_ = [[ICEIdentity alloc] initWithIdentity:localEx.id]; + facet = toNSString(localEx.facet); + operation = toNSString(localEx.operation); + return self; +} +-(void) rethrowCxx +{ + Ice::Identity ident = { fromNSString(id_.name), fromNSString(id_.category) }; + throw Ice::RequestFailedException(file, line, ident, fromNSString(facet), fromNSString(operation)); +} +@end + +@implementation ICEObjectNotExistException (ICEInternal) +-(void) rethrowCxx +{ + Ice::Identity ident = { fromNSString([self id_].name), fromNSString([self id_].category) }; + throw Ice::ObjectNotExistException(file, line, ident, fromNSString([self facet]), fromNSString([self operation])); +} +@end + +@implementation ICEFacetNotExistException (ICEInternal) +-(void) rethrowCxx +{ + Ice::Identity ident = { fromNSString([self id_].name), fromNSString([self id_].category) }; + throw Ice::FacetNotExistException(file, line, ident, fromNSString([self facet]), fromNSString([self operation])); +} +@end + +@implementation ICEOperationNotExistException (ICEInternal) +-(void) rethrowCxx +{ + Ice::Identity ident = { fromNSString([self id_].name), fromNSString([self id_].category) }; + throw Ice::OperationNotExistException(file, line, ident, fromNSString([self facet]), fromNSString([self operation])); +} +@end + +@implementation ICESyscallException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::SyscallException*>(&ex), @"invalid local exception type"); + const Ice::SyscallException& localEx = dynamic_cast<const Ice::SyscallException&>(ex); + error = localEx.error; + return self; +} +-(void) rethrowCxx +{ + throw Ice::SyscallException(file, line, error); +} +@end + +@implementation ICESocketException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::SocketException(file, line, [self error]); +} +@end + +@implementation ICEConnectFailedException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ConnectFailedException(file, line, [self error]); +} +@end + +@implementation ICEConnectionRefusedException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ConnectionRefusedException(file, line, [self error]); +} +@end + +@implementation ICEConnectionLostException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ConnectionLostException(file, line, [self error]); +} +@end + +@implementation ICEFileException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::FileException*>(&ex), @"invalid local exception type"); + const Ice::FileException& localEx = dynamic_cast<const Ice::FileException&>(ex); + path = toNSString(localEx.path); + return self; +} +-(void) rethrowCxx +{ + throw Ice::FileException(file, line, [self error], fromNSString(path)); +} +@end + +@implementation ICEDNSException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::DNSException*>(&ex), @"invalid local exception type"); + const Ice::DNSException& localEx = dynamic_cast<const Ice::DNSException&>(ex); + error = localEx.error; + host = toNSString(localEx.host); + return self; +} +-(void) rethrowCxx +{ + throw Ice::DNSException(file, line, [self error], fromNSString(host)); +} +@end + +@implementation ICETimeoutException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::TimeoutException(file, line); +} +@end + +@implementation ICEConnectTimeoutException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ConnectTimeoutException(file, line); +} +@end + +@implementation ICECloseTimeoutException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::CloseTimeoutException(file, line); +} +@end + +@implementation ICEConnectionTimeoutException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ConnectionTimeoutException(file, line); +} +@end + +@implementation ICEInvocationTimeoutException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::InvocationTimeoutException(file, line); +} +@end + +@implementation ICEInvocationCanceledException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::InvocationCanceledException(file, line); +} +@end + +@implementation ICEProtocolException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::ProtocolException*>(&ex), @"invalid local exception type"); + const Ice::ProtocolException& localEx = dynamic_cast<const Ice::ProtocolException&>(ex); + reason_ = toNSString(localEx.reason); + return self; +} +-(void) rethrowCxx +{ + throw Ice::ProtocolException(file, line, fromNSString(reason_)); +} +@end + +@implementation ICEUnknownMessageException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::UnknownMessageException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEConnectionNotValidatedException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ConnectionNotValidatedException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEUnknownRequestIdException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::UnknownRequestIdException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEUnknownReplyStatusException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::UnknownReplyStatusException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICECloseConnectionException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::CloseConnectionException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEForcedCloseConnectionException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ForcedCloseConnectionException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEIllegalMessageSizeException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::IllegalMessageSizeException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICECompressionException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::CompressionException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEDatagramLimitException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::DatagramLimitException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEMarshalException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::MarshalException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEProxyUnmarshalException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ProxyUnmarshalException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEUnmarshalOutOfBoundsException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::UnmarshalOutOfBoundsException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEMemoryLimitException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::MemoryLimitException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEStringConversionException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::StringConversionException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEEncapsulationException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::EncapsulationException(file, line, fromNSString([self reason_])); +} +@end + +@implementation ICEBadMagicException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::BadMagicException*>(&ex), @"invalid local exception type"); + const Ice::BadMagicException& localEx = dynamic_cast<const Ice::BadMagicException&>(ex); + badMagic = toNSData(localEx.badMagic); + return self; +} +-(void) rethrowCxx +{ + Ice::ByteSeq s; + throw Ice::BadMagicException(file, line, fromNSString([self reason_]), fromNSData(badMagic, s)); +} +@end + +@implementation ICEUnsupportedProtocolException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::UnsupportedProtocolException*>(&ex), @"invalid local exception type"); + const Ice::UnsupportedProtocolException& localEx = dynamic_cast<const Ice::UnsupportedProtocolException&>(ex); + bad = [[ICEProtocolVersion protocolVersionWithProtocolVersion:localEx.bad] retain]; + supported = [[ICEProtocolVersion protocolVersionWithProtocolVersion:localEx.supported] retain]; + return self; +} +-(void) rethrowCxx +{ + Ice::ProtocolVersion badVersion = [bad protocolVersion]; + Ice::ProtocolVersion supportedVersion = [supported protocolVersion]; + throw Ice::UnsupportedProtocolException(file, line, fromNSString([self reason_]), badVersion, supportedVersion); +} +@end + +@implementation ICEUnsupportedEncodingException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::UnsupportedEncodingException*>(&ex), @"invalid local exception type"); + const Ice::UnsupportedEncodingException& localEx = dynamic_cast<const Ice::UnsupportedEncodingException&>(ex); + bad = [[ICEEncodingVersion encodingVersionWithEncodingVersion:localEx.bad] retain]; + supported = [[ICEEncodingVersion encodingVersionWithEncodingVersion:localEx.supported] retain]; + return self; +} +-(void) rethrowCxx +{ + Ice::EncodingVersion badVersion = [bad encodingVersion]; + Ice::EncodingVersion supportedVersion = [supported encodingVersion]; + throw Ice::UnsupportedEncodingException(file, line, fromNSString([self reason_]), badVersion, supportedVersion); +} +@end + +@implementation ICENoObjectFactoryException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::NoObjectFactoryException*>(&ex), @"invalid local exception type"); + const Ice::NoObjectFactoryException& localEx = dynamic_cast<const Ice::NoObjectFactoryException&>(ex); + type = toNSString(localEx.type); + return self; +} +-(void) rethrowCxx +{ + throw Ice::NoObjectFactoryException(file, line, fromNSString([self reason_]), fromNSString(type)); +} +@end + +@implementation ICEUnexpectedObjectException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::UnexpectedObjectException*>(&ex), @"invalid local exception type"); + const Ice::UnexpectedObjectException& localEx = dynamic_cast<const Ice::UnexpectedObjectException&>(ex); + type = toNSString(localEx.type); + expectedType = toNSString(localEx.expectedType); + return self; +} +-(void) rethrowCxx +{ + throw Ice::UnexpectedObjectException(file, line, fromNSString([self reason_]), fromNSString(type), fromNSString(expectedType)); +} +@end + +@implementation ICEFeatureNotSupportedException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::FeatureNotSupportedException*>(&ex), @"invalid local exception type"); + const Ice::FeatureNotSupportedException& localEx = dynamic_cast<const Ice::FeatureNotSupportedException&>(ex); + unsupportedFeature = toNSString(localEx.unsupportedFeature); + return self; +} +-(void) rethrowCxx +{ + throw Ice::FeatureNotSupportedException(file, line, fromNSString(unsupportedFeature)); +} +@end + +@implementation ICESecurityException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::SecurityException*>(&ex), @"invalid local exception type"); + const Ice::SecurityException& localEx = dynamic_cast<const Ice::SecurityException&>(ex); + reason_ = toNSString(localEx.reason); + return self; +} +-(void) rethrowCxx +{ + throw Ice::SecurityException(file, line, fromNSString(reason_)); +} +@end + +@implementation ICEFixedProxyException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::FixedProxyException(file, line); +} +@end + +@implementation ICEResponseSentException (ICEInternal) +-(void) rethrowCxx +{ + throw Ice::ResponseSentException(file, line); +} +@end + +#ifdef ICE_USE_CFSTREAM +@implementation ICECFNetworkException (ICEInternal) +-(id)initWithLocalException:(const Ice::LocalException&)ex +{ + self = [super initWithLocalException:ex]; + if(!self) + { + return nil; + } + NSAssert(dynamic_cast<const Ice::CFNetworkException*>(&ex), @"invalid local exception type"); + const Ice::CFNetworkException& localEx = dynamic_cast<const Ice::CFNetworkException&>(ex); + domain = toNSString(localEx.domain); + return self; +} +-(void) rethrowCxx +{ + throw Ice::CFNetworkException(file, line, fromNSString(domain)); +} +@end +#endif diff --git a/objective-c/src/Ice/ExceptionI.h b/objective-c/src/Ice/ExceptionI.h new file mode 100644 index 00000000000..fb28fb979ca --- /dev/null +++ b/objective-c/src/Ice/ExceptionI.h @@ -0,0 +1,18 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Exception.h> + +#include <Ice/Exception.h> + +@interface ICELocalException () +-(id) initWithLocalException:(const Ice::LocalException&)ex; +-(void) rethrowCxx; ++(id) localExceptionWithLocalException:(const Ice::LocalException&)ex; +@end diff --git a/objective-c/src/Ice/IdentityI.h b/objective-c/src/Ice/IdentityI.h new file mode 100644 index 00000000000..c69ac138fb1 --- /dev/null +++ b/objective-c/src/Ice/IdentityI.h @@ -0,0 +1,18 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Identity.h> + +#include <Ice/Identity.h> + +@interface ICEIdentity (ICEInternal) +-(ICEIdentity*)initWithIdentity:(const Ice::Identity&)arg; +-(Ice::Identity)identity; ++(ICEIdentity*)identityWithIdentity:(const Ice::Identity&)arg; +@end diff --git a/objective-c/src/Ice/IdentityI.mm b/objective-c/src/Ice/IdentityI.mm new file mode 100644 index 00000000000..917deb91514 --- /dev/null +++ b/objective-c/src/Ice/IdentityI.mm @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <IdentityI.h> +#import <Util.h> + +@implementation ICEIdentity (ICEInternal) + +-(ICEIdentity*) initWithIdentity:(const Ice::Identity&)arg +{ + self = [super init]; + if(!self) + { + return nil; + } + category = [[NSString alloc] initWithUTF8String:arg.category.c_str()]; + name = [[NSString alloc] initWithUTF8String:arg.name.c_str()]; + return self; +} + +-(Ice::Identity) identity +{ + Ice::Identity ident; + ident.category = fromNSString(category); + ident.name = fromNSString(name); + return ident; +} + ++(ICEIdentity*) identityWithIdentity:(const Ice::Identity&)arg +{ + return [[[ICEIdentity alloc] initWithIdentity:arg] autorelease]; +} + +@end diff --git a/objective-c/src/Ice/ImplicitContextI.h b/objective-c/src/Ice/ImplicitContextI.h new file mode 100644 index 00000000000..4c4782c377f --- /dev/null +++ b/objective-c/src/Ice/ImplicitContextI.h @@ -0,0 +1,22 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/ImplicitContext.h> + +#include <Ice/ImplicitContext.h> + +@interface ICEImplicitContext : NSObject<ICEImplicitContext> +{ +@private + + Ice::ImplicitContext* implicitContext__; +} +-(id) init:(Ice::ImplicitContext*)implicitContext; ++(id) implicitContextWithImplicitContext:(Ice::ImplicitContext*)implicitContext; +@end diff --git a/objective-c/src/Ice/ImplicitContextI.mm b/objective-c/src/Ice/ImplicitContextI.mm new file mode 100644 index 00000000000..b564bdc78f6 --- /dev/null +++ b/objective-c/src/Ice/ImplicitContextI.mm @@ -0,0 +1,83 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <ImplicitContextI.h> +#import <Util.h> + +@implementation ICEImplicitContext + +-(id) init:(Ice::ImplicitContext*)implicitContext +{ + self = [super init]; + if(self) + { + self->implicitContext__ = implicitContext; + self->implicitContext__->__incRef(); + } + return self; +} + ++(id) implicitContextWithImplicitContext:(Ice::ImplicitContext*)implicitContext +{ + if(!implicitContext) + { + return nil; + } + else + { + return [[[ICEImplicitContext alloc] init:implicitContext] autorelease]; + } +} + +-(void) dealloc +{ + self->implicitContext__->__decRef(); + [super dealloc]; +} + +-(ICEContext*) getContext +{ + return [toNSDictionary(implicitContext__->getContext()) autorelease]; +} + +-(void) setContext:(ICEContext*)context +{ + Ice::Context ctx; + fromNSDictionary(context, ctx); + implicitContext__->setContext(ctx); +} + +-(BOOL) containsKey:(NSString*)key +{ + return implicitContext__->containsKey(fromNSString(key)); +} + +-(NSMutableString*) get:(NSString*)key +{ + if(implicitContext__->containsKey(fromNSString(key))) + { + return [toNSMutableString(implicitContext__->get(fromNSString(key))) autorelease]; + } + else + { + return nil; + } +} + +-(NSMutableString*) put:(NSString*)key value:(NSString*)value +{ + return [toNSMutableString(implicitContext__->put(fromNSString(key), fromNSString(value))) autorelease]; +} + +-(NSMutableString*) remove:(NSString*)key +{ + return [toNSMutableString(implicitContext__->remove(fromNSString(key))) autorelease]; +} + +@end diff --git a/objective-c/src/Ice/Initialize.mm b/objective-c/src/Ice/Initialize.mm new file mode 100644 index 00000000000..f4bd535d367 --- /dev/null +++ b/objective-c/src/Ice/Initialize.mm @@ -0,0 +1,630 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <InitializeI.h> +#import <PropertiesI.h> +#import <CommunicatorI.h> +#import <StreamI.h> +#import <LoggerI.h> +#import <DispatcherI.h> +#import <BatchRequestInterceptorI.h> +#import <Util.h> +#import <VersionI.h> +#import <LocalObjectI.h> + +#import <objc/Ice/LocalException.h> + +#include <Ice/Initialize.h> +#include <IceUtil/UUID.h> +#include <IceUtil/MutexPtrLock.h> + +#include <Availability.h> + +#import <Foundation/NSAutoreleasePool.h> +#import <Foundation/NSThread.h> + +#ifdef ICE_NO_KQUEUE +# define ICE_USE_CFSTREAM 1 +#endif + +namespace +{ +typedef std::map<int, std::string> CompactIdMap; + +IceUtil::Mutex* _compactIdMapMutex = 0; +CompactIdMap* _compactIdMap = 0; + +class CompactIdResolverI : public Ice::CompactIdResolver +{ +public: + + virtual ::std::string + resolve(::Ice::Int value) const + { + assert(_compactIdMapMutex); + assert(_compactIdMap); + + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_compactIdMapMutex); + CompactIdMap::iterator p = _compactIdMap->find(value); + if(p != _compactIdMap->end()) + { + return p->second; + } + return ::std::string(); + } +}; + +// +// We don't use the constructor to initialize the compactIdMap as +// static initializtion takes place after +load is called. +// +class Init +{ +public: + + ~Init() + { + if(_compactIdMap) + { + delete _compactIdMap; + _compactIdMap = 0; + } + + if(_compactIdMapMutex) + { + delete _compactIdMapMutex; + _compactIdMapMutex = 0; + } + } +}; +Init init; + +} + +@implementation CompactIdMapHelper ++(void) initialize +{ + assert(!_compactIdMapMutex); + assert(!_compactIdMap); + _compactIdMapMutex = new ::IceUtil::Mutex; + _compactIdMap = new CompactIdMap; +} + ++(void) registerClass:(NSString*)type value:(ICEInt)value +{ + assert(_compactIdMapMutex); + assert(_compactIdMap); + + IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(_compactIdMapMutex); + CompactIdMap::iterator p = _compactIdMap->find(value); + if(p != _compactIdMap->end()) + { + _compactIdMap->erase(p); + } + _compactIdMap->insert(CompactIdMap::value_type(value, fromNSString(type))); +} +@end + +namespace IceObjC +{ + +class ThreadNotification : public Ice::ThreadNotification, public IceUtil::Mutex +{ +public: + + ThreadNotification() + { + } + + virtual void start() + { + Lock sync(*this); + _pools.insert(std::make_pair(IceUtil::ThreadControl().id(), [[NSAutoreleasePool alloc] init])); + } + + virtual void stop() + { + Lock sync(*this); + std::map<IceUtil::ThreadControl::ID, NSAutoreleasePool*>::iterator p = + _pools.find(IceUtil::ThreadControl().id()); + [p->second drain]; + _pools.erase(p); + } + +private: + + std::map<IceUtil::ThreadControl::ID, NSAutoreleasePool*> _pools; +}; + +}; + +@implementation ICEInitializationData (ICEInternal) +-(Ice::InitializationData)initializationData +{ + Ice::InitializationData data; + data.properties = [(ICEProperties*)properties properties]; + data.logger = [ICELogger loggerWithLogger:logger]; + if(batchRequestInterceptor) + { + data.batchRequestInterceptor = [ICEBatchRequestInterceptor + batchRequestInterceptorWithBatchRequestInterceptor:batchRequestInterceptor]; + } + if(dispatcher) + { + data.dispatcher = [ICEDispatcher dispatcherWithDispatcher:dispatcher]; + } + data.compactIdResolver = new CompactIdResolverI; + return data; +} +@end + +@implementation ICEInitializationData + +@synthesize properties; +@synthesize logger; +@synthesize dispatcher; +@synthesize batchRequestInterceptor; +@synthesize prefixTable__; + +-(id) init:(id<ICEProperties>)props logger:(id<ICELogger>)log dispatcher:(void(^)(id<ICEDispatcherCall>, + id<ICEConnection>))d; +{ + self = [super init]; + if(!self) + { + return nil; + } + properties = [props retain]; + logger = [log retain]; + dispatcher = [d copy]; + return self; +} + ++(id) initializationData; +{ + ICEInitializationData *s = [[ICEInitializationData alloc] init]; + [s autorelease]; + return s; +} + ++(id) initializationData:(id<ICEProperties>)p logger:(id<ICELogger>)l + dispatcher:(void(^)(id<ICEDispatcherCall>, id<ICEConnection>))d; +{ + return [[((ICEInitializationData *)[ICEInitializationData alloc]) init:p logger:l dispatcher:d] autorelease]; +} + +-(id) copyWithZone:(NSZone *)zone +{ + ICEInitializationData *copy = [ICEInitializationData allocWithZone:zone]; + copy->properties = [properties retain]; + copy->logger = [logger retain]; + copy->dispatcher = [dispatcher copy]; + copy->prefixTable__ = [prefixTable__ retain]; + return copy; +} + +-(NSUInteger) hash; +{ + NSUInteger h = 0; + h = (h << 5 ^ [properties hash]); + h = (h << 5 ^ [logger hash]); + h = (h << 5 ^ [prefixTable__ hash]); + return h; +} + +-(BOOL) isEqual:(id)anObject; +{ + if(self == anObject) + { + return YES; + } + if(!anObject || ![anObject isKindOfClass:[self class]]) + { + return NO; + } + ICEInitializationData * obj =(ICEInitializationData *)anObject; + if(!properties) + { + if(obj->properties) + { + return NO; + } + } + else + { + if(![properties isEqual:obj->properties]) + { + return NO; + } + } + if(!logger) + { + if(obj->logger) + { + return NO; + } + } + else + { + if(![logger isEqual:obj->logger]) + { + return NO; + } + } + if(!dispatcher) + { + if(obj->dispatcher) + { + return NO; + } + } + else + { + if(dispatcher == obj->dispatcher) + { + return NO; + } + } + if(!prefixTable__) + { + if(obj->prefixTable__) + { + return NO; + } + } + else + { + if(![prefixTable__ isEqual:obj->prefixTable__]) + { + return NO; + } + } + return YES; +} + +-(void) dealloc; +{ + [properties release]; + [logger release]; + [dispatcher release]; + [prefixTable__ release]; + [super dealloc]; +} +@end + +@implementation ICEUtil ++(id<ICEProperties>) createProperties +{ + return [self createProperties:nil argv:nil]; +} + ++(id<ICEProperties>) createProperties:(int*)argc argv:(char*[])argv +{ + NSException* nsex = nil; + try + { + Ice::PropertiesPtr properties; + if(argc != nil && argv != nil) + { + properties = Ice::createProperties(*argc, argv); + } + else + { + properties = Ice::createProperties(); + } + return [ICEProperties localObjectWithCxxObject:properties.get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICECommunicator>) createCommunicator +{ + return [self createCommunicator:nil argv:nil initData:nil]; +} + ++(id<ICECommunicator>) createCommunicator:(ICEInitializationData*)initData +{ + return [self createCommunicator:nil argv:nil initData:initData]; +} + ++(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv +{ + return [self createCommunicator:argc argv:argv initData:nil]; +} + ++(id<ICECommunicator>) createCommunicator:(int*)argc argv:(char*[])argv initData:(ICEInitializationData*)initData +{ + if(![NSThread isMultiThreaded]) // Ensure sure Cocoa is multithreaded. + { + NSThread* thread = [[NSThread alloc] init]; + [thread start]; + [thread release]; + } + + id<ICEProperties> properties = [initData properties]; + if(properties != nil && ![properties isKindOfClass:[ICEProperties class]]) + { + @throw [ICEInitializationException initializationException:__FILE__ line:__LINE__ + reason:@"properties were not created with createProperties"]; + } + + NSException* nsex = nil; + try + { + Ice::InitializationData data; + if(initData != nil) + { + data = [initData initializationData]; + } + data.threadHook = new IceObjC::ThreadNotification(); + if(!data.properties) + { + data.properties = Ice::createProperties(); + } + + if(argc != nil && argv != nil) + { + data.properties = createProperties(*argc, argv, data.properties); + } + + Ice::CommunicatorPtr communicator; + if(argc != nil && argv != nil) + { + communicator = Ice::initialize(*argc, argv, data); + } + else + { + communicator = Ice::initialize(data); + } + + ICECommunicator* c = [ICECommunicator localObjectWithCxxObject:communicator.get()]; + [c setup:initData.prefixTable__]; + return c; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICEInputStream>) createInputStream:(id<ICECommunicator>)communicator data:(NSData*)data +{ + NSException* nsex = nil; + try + { + Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator]; + Ice::Byte* start = (Ice::Byte*)[data bytes]; + Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length]; + Ice::InputStreamPtr is = Ice::createInputStream(com, std::make_pair(start, end)); + if(is) + { + return [ICEInputStream localObjectWithCxxObject:is.get()]; + } + else + { + return nil; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICEInputStream>) createInputStream:(id<ICECommunicator>)c data:(NSData*)data encoding:(ICEEncodingVersion*)e +{ + NSException* nsex = nil; + try + { + Ice::CommunicatorPtr com = [(ICECommunicator*)c communicator]; + Ice::Byte* start = (Ice::Byte*)[data bytes]; + Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length]; + Ice::InputStreamPtr is = Ice::createInputStream(com, std::make_pair(start, end), [e encodingVersion]); + if(is) + { + return [ICEInputStream localObjectWithCxxObject:is.get()]; + } + else + { + return nil; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICEInputStream>) wrapInputStream:(id<ICECommunicator>)communicator data:(NSData*)data +{ + NSException* nsex = nil; + try + { + Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator]; + Ice::Byte* start = (Ice::Byte*)[data bytes]; + Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length]; + Ice::InputStreamPtr is = Ice::wrapInputStream(com, std::make_pair(start, end)); + if(is) + { + return [ICEInputStream localObjectWithCxxObject:is.get()]; + } + else + { + return nil; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICEInputStream>) wrapInputStream:(id<ICECommunicator>)c data:(NSData*)data encoding:(ICEEncodingVersion*)e +{ + NSException* nsex = nil; + try + { + Ice::CommunicatorPtr com = [(ICECommunicator*)c communicator]; + Ice::Byte* start = (Ice::Byte*)[data bytes]; + Ice::Byte* end = (Ice::Byte*)[data bytes] + [data length]; + Ice::InputStreamPtr is = Ice::wrapInputStream(com, std::make_pair(start, end), [e encodingVersion]); + if(is) + { + return [ICEInputStream localObjectWithCxxObject:is.get()]; + } + else + { + return nil; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICEOutputStream>) createOutputStream:(id<ICECommunicator>)communicator +{ + NSException* nsex = nil; + try + { + Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator]; + Ice::OutputStreamPtr os = Ice::createOutputStream(com); + if(os) + { + return [ICEOutputStream localObjectWithCxxObject:os.get()]; + } + else + { + return nil; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(id<ICEOutputStream>) createOutputStream:(id<ICECommunicator>)communicator encoding:(ICEEncodingVersion*)encoding +{ + NSException* nsex = nil; + try + { + Ice::CommunicatorPtr com = [(ICECommunicator*)communicator communicator]; + Ice::OutputStreamPtr os = Ice::createOutputStream(com, [encoding encodingVersion]); + if(os) + { + return [ICEOutputStream localObjectWithCxxObject:os.get()]; + } + else + { + return nil; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + ++(NSString*) generateUUID +{ + return [NSString stringWithUTF8String:IceUtil::generateUUID().c_str()]; +} + ++(NSArray*)argsToStringSeq:(int)argc argv:(char*[])argv +{ + NSMutableArray* ns = [NSMutableArray array]; + int i; + for(i = 0; i < argc; ++i) + { + [ns addObject:[NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]]; + } + return [[ns copy] autorelease]; +} + ++(void)stringSeqToArgs:(NSArray*)args argc:(int*)argc argv:(char*[])argv; +{ + // + // Shift all elements in argv which are present in args to the + // beginning of argv. We record the original value of argc so + // that we can know later if we've shifted the array. + // + const int argcOrig = *argc; + int i = 0; + while(i < *argc) + { + BOOL found = NO; + for(NSString* s in args) + { + if([s compare:[NSString stringWithCString:argv[i] encoding:NSUTF8StringEncoding]] == 0) + { + found = YES; + break; + } + } + if(!found) + { + int j; + for(j = i; j < *argc - 1; j++) + { + argv[j] = argv[j + 1]; + } + --(*argc); + } + else + { + ++i; + } + } + + // + // Make sure that argv[*argc] == 0, the ISO C++ standard requires this. + // We can only do this if we've shifted the array, otherwise argv[*argc] + // may point to an invalid address. + // + if(argv && argcOrig != *argc) + { + argv[*argc] = 0; + } +} +@end + +@implementation ICEEncodingVersion(StringConv) ++(ICEEncodingVersion*) encodingVersionWithString:(NSString*)str +{ + return [ICEEncodingVersion encodingVersionWithEncodingVersion:Ice::stringToEncodingVersion(fromNSString(str))]; +} +@end + +@implementation ICEProtocolVersion(StringConv) ++(ICEProtocolVersion*) protocolVersionWithString:(NSString*)str +{ + return [ICEProtocolVersion protocolVersionWithProtocolVersion:Ice::stringToProtocolVersion(fromNSString(str))]; +} +@end diff --git a/objective-c/src/Ice/InitializeI.h b/objective-c/src/Ice/InitializeI.h new file mode 100644 index 00000000000..9fcbc87cbed --- /dev/null +++ b/objective-c/src/Ice/InitializeI.h @@ -0,0 +1,16 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Initialize.h> + +#include <Ice/Initialize.h> + +@interface ICEInitializationData (ICEInternal) +-(Ice::InitializationData)initializationData; +@end diff --git a/objective-c/src/Ice/LocalObject.mm b/objective-c/src/Ice/LocalObject.mm new file mode 100644 index 00000000000..e7651c85d33 --- /dev/null +++ b/objective-c/src/Ice/LocalObject.mm @@ -0,0 +1,143 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <LocalObjectI.h> + +#include <map> + +#include <IceUtil/Shared.h> +#include <Foundation/Foundation.h> + +#define CXXOBJECT ((IceUtil::Shared*)cxxObject_) + +namespace +{ + +std::map<IceUtil::Shared*, ICELocalObject*> cachedObjects; + +} + +@implementation ICELocalObject + +-(id) init +{ + self = [super init]; + if(!self) + { + return nil; + } + cxxObject_ = 0; + return self; +} +-(id) initWithCxxObject:(IceUtil::Shared*)arg +{ + self = [super init]; + if(!self) + { + return nil; + } + cxxObject_ = arg; + CXXOBJECT->__incRef(); + + // + // No synchronization because initWithCxxObject is always called with the wrapper class object locked + // + assert(cachedObjects.find(CXXOBJECT) == cachedObjects.end()); + cachedObjects.insert(std::make_pair(CXXOBJECT, self)); + return self; +} + +-(IceUtil::Shared*) cxxObject +{ + return CXXOBJECT; +} + +-(void) dealloc +{ + if(cxxObject_) + { + // + // No synchronization because dealloc is always called with the wrapper class object locked + // + cachedObjects.erase(CXXOBJECT); + CXXOBJECT->__decRef(); + cxxObject_ = 0; + } + + [super dealloc]; +} + ++(id) getLocalObjectWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg +{ + // + // Note: the returned object is NOT retained. It must be held + // some other way by the calling thread. + // + + if(arg == 0) + { + return nil; + } + + @synchronized([ICELocalObject class]) + { + std::map<IceUtil::Shared*, ICELocalObject*>::const_iterator p = cachedObjects.find(arg); + if(p != cachedObjects.end()) + { + return p->second; + } + } + return nil; +} + ++(id) localObjectWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg +{ + if(arg == 0) + { + return nil; + } + + @synchronized([ICELocalObject class]) + { + std::map<IceUtil::Shared*, ICELocalObject*>::const_iterator p = cachedObjects.find(arg); + if(p != cachedObjects.end()) + { + return [p->second retain]; + } + else + { + return [[self alloc] initWithCxxObject:arg]; + } + } + return nil; // Keep the compiler happy. +} + ++(id) localObjectWithCxxObject:(IceUtil::Shared*)arg +{ + return [[self localObjectWithCxxObjectNoAutoRelease:arg] autorelease]; +} + + +-(id) retain +{ + NSIncrementExtraRefCount(self); + return self; +} + +-(oneway void) release +{ + @synchronized([ICELocalObject class]) + { + if(NSDecrementExtraRefCountWasZero(self)) + { + [self dealloc]; + } + } +} +@end diff --git a/objective-c/src/Ice/LocalObjectI.h b/objective-c/src/Ice/LocalObjectI.h new file mode 100644 index 00000000000..1020ecd3077 --- /dev/null +++ b/objective-c/src/Ice/LocalObjectI.h @@ -0,0 +1,30 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/LocalObject.h> + +namespace IceUtil +{ +class Shared; +} + +@interface ICELocalObject () +-(id) initWithCxxObject:(IceUtil::Shared*)arg; + +// +// Note: the returned object is NOT retained. It must be held +// some other way by the calling thread. +// ++(id) getLocalObjectWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg; + ++(id) localObjectWithCxxObjectNoAutoRelease:(IceUtil::Shared*)arg; ++(id) localObjectWithCxxObject:(IceUtil::Shared*)arg; + +-(IceUtil::Shared*) cxxObject; +@end diff --git a/objective-c/src/Ice/LoggerI.h b/objective-c/src/Ice/LoggerI.h new file mode 100644 index 00000000000..cf8cd98d224 --- /dev/null +++ b/objective-c/src/Ice/LoggerI.h @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Logger.h> + +#import <objc/Ice/LocalObject.h> + +#include <Ice/Logger.h> + +@interface ICELogger : ICELocalObject<ICELogger> +{ + NSString* prefix_; + NSString* formattedPrefix_; +} ++(Ice::Logger*)loggerWithLogger:(id<ICELogger>)arg; +@end + +@interface ICELoggerWrapper : ICELocalObject<ICELogger> +{ + Ice::Logger* logger_; +} ++(id)loggerWithLogger:(Ice::Logger*)arg; +@end diff --git a/objective-c/src/Ice/LoggerI.mm b/objective-c/src/Ice/LoggerI.mm new file mode 100644 index 00000000000..96f0006ae73 --- /dev/null +++ b/objective-c/src/Ice/LoggerI.mm @@ -0,0 +1,316 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <LoggerI.h> +#import <Util.h> +#import <LocalObjectI.h> + +#import <Foundation/NSDate.h> + +namespace +{ + +class LoggerWrapperI : public Ice::Logger +{ +public: + +// We must explicitely CFRetain/CFRelease so that the garbage +// collector does not trash the logger. +LoggerWrapperI(id<ICELogger> logger) : _logger(logger) +{ + CFRetain(_logger); +} + +virtual ~LoggerWrapperI() +{ + CFRelease(_logger); +} + +virtual void +print(const std::string& msg) +{ + NSException* ex = nil; + @autoreleasepool + { + NSString* s = toNSString(msg); + @try + { + [_logger print:s]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [s release]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } +} + +virtual void +trace(const std::string& category, const std::string& msg) +{ + NSException* ex = nil; + @autoreleasepool + { + NSString* s1 = toNSString(category); + NSString* s2 = toNSString(msg); + @try + { + [_logger trace:s1 message:s2]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [s1 release]; + [s2 release]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } +} + +virtual void +warning(const std::string& msg) +{ + NSException* ex = nil; + @autoreleasepool + { + NSString* s = toNSString(msg); + @try + { + [_logger warning:s]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [s release]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } +} + +virtual void +error(const std::string& msg) +{ + NSException* ex = nil; + @autoreleasepool + { + NSString* s = toNSString(msg); + @try + { + [_logger error:s]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [s release]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } +} + +virtual Ice::LoggerPtr +cloneWithPrefix(const std::string& prefix) +{ + NSString* s = toNSString(prefix); + @try + { + return [ICELogger loggerWithLogger:[_logger cloneWithPrefix:s]]; + } + @finally + { + [s release]; + } +} + +virtual std::string +getPrefix() +{ + return fromNSString([_logger getPrefix]); +} + +id<ICELogger> +getLogger() +{ + return _logger; +} + +private: + +id<ICELogger> _logger; + +}; +typedef IceUtil::Handle<LoggerWrapperI> LoggerWrapperIPtr; + +} + +@implementation ICELoggerWrapper ++(id) loggerWithLogger:(Ice::Logger*)cxxObject +{ + LoggerWrapperI* impl = dynamic_cast<LoggerWrapperI*>(cxxObject); + if(impl) + { + return [[impl->getLogger() retain] autorelease]; + } + else + { + ICELoggerWrapper* wrapper = [self localObjectWithCxxObject:static_cast<IceUtil::Shared*>(cxxObject)]; + wrapper->logger_ = cxxObject; + return wrapper; + } +} +-(void) print:(NSString*)message +{ + logger_->print(fromNSString(message)); +} +-(void) trace:(NSString*)category message:(NSString*)message +{ + logger_->trace(fromNSString(category), fromNSString(message)); +} +-(void) warning:(NSString*)message +{ + logger_->warning(fromNSString(message)); +} +-(void) error:(NSString*)message +{ + logger_->error(fromNSString(message)); +} +-(NSMutableString*) getPrefix +{ + return toNSMutableString(logger_->getPrefix()); +} +-(id<ICELogger>) cloneWithPrefix:(NSString*)prefix +{ + Ice::LoggerPtr logger = logger_->cloneWithPrefix(fromNSString(prefix)); + if(logger.get() != logger_) + { + return [ICELoggerWrapper loggerWithLogger:logger.get()]; + } + return self; +} +@end + +@implementation ICELogger ++(Ice::Logger*) loggerWithLogger:(id<ICELogger>)logger +{ + if(logger == 0) + { + id<ICELogger> l = [[self alloc] init]; + Ice::Logger* impl = new LoggerWrapperI(l); + [l release]; + return impl; + } + else + { + return new LoggerWrapperI(logger); + } +} +-(id) init +{ + self = [super init]; + if(!self) + { + return nil; + } + self->prefix_ = @""; + self->formattedPrefix_ = @""; + return self; +} +-(id) initWithPrefix:(NSString*)prefix +{ + self = [super init]; + if(!self) + { + return nil; + } + self->prefix_ = prefix == nil ? @"" : [prefix retain]; + if(self->prefix_.length > 0) + { + self->formattedPrefix_ = [[NSString alloc] initWithFormat:@"%@ :", prefix]; + } + else + { + self->formattedPrefix_ = @""; + } + return self; +} +-(void) dealloc +{ + [self->prefix_ release]; + [self->formattedPrefix_ release]; + [super dealloc]; +} + +// +// @protocol Logger methods. +// + +-(void) print:(NSString*)message +{ + NSLog(@"%@", message); +} + +-(void) trace:(NSString*)cat message:(NSString*)msg +{ + NSMutableString* s = [[NSMutableString alloc] initWithFormat:@"%@[%@: %@]", self->formattedPrefix_, cat, msg]; +#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR + [s replaceOccurrencesOfString:@"\n" withString:@" " options:0 range:NSMakeRange(0, s.length)]; +#endif + [self print:s]; + [s release]; +} + +-(void) warning:(NSString*)message +{ + NSString* s = [[NSString alloc] initWithFormat:@"%@warning: %@", self->formattedPrefix_, message]; + [self print:s]; + [s release]; +} + +-(void) error:(NSString*)message +{ + NSString* s = [[NSString alloc] initWithFormat:@"%@error: %@", self->formattedPrefix_, message]; + [self print:s]; + [s release]; +} + +-(NSMutableString*) getPrefix +{ + return [[self->prefix_ mutableCopy] autorelease]; +} + +-(id<ICELogger>) cloneWithPrefix:(NSString*)prefix +{ + return [[[ICELogger alloc] initWithPrefix:prefix] autorelease]; +} + +@end diff --git a/objective-c/src/Ice/Makefile b/objective-c/src/Ice/Makefile new file mode 100644 index 00000000000..5e61fb797a5 --- /dev/null +++ b/objective-c/src/Ice/Makefile @@ -0,0 +1,109 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +LIBFILENAME = $(call mklibfilename,IceObjC$(libsuffix),$(VERSION)) +SONAME = $(call mksoname,IceObjC$(libsuffix),$(SOVERSION)) +LIBNAME = $(call mklibname,IceObjC$(libsuffix)) + +TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) + +SLICE_OBJS = BuiltinSequences.o \ + Communicator.o \ + CommunicatorF.o \ + Connection.o \ + ConnectionF.o \ + Current.o \ + Endpoint.o \ + EndpointF.o \ + EndpointTypes.o \ + FacetMap.o \ + Identity.o \ + InstrumentationF.o \ + ImplicitContext.o \ + ImplicitContextF.o \ + Locator.o \ + LocatorF.o \ + LocalException.o \ + Logger.o \ + LoggerF.o \ + Metrics.o \ + ObjectAdapter.o \ + ObjectAdapterF.o \ + ObjectFactoryF.o \ + PluginF.o \ + Process.o \ + ProcessF.o \ + Properties.o \ + PropertiesF.o \ + PropertiesAdmin.o \ + RemoteLogger.o \ + Router.o \ + RouterF.o \ + ServantLocator.o \ + ServantLocatorF.o \ + SliceChecksumDict.o \ + Version.o + +OBJC_OBJS = DispatchInterceptor.o \ + Request.o \ + $(SLICE_OBJS) + +OBJCXX_OBJS = BatchRequestInterceptor.o \ + CommunicatorI.o \ + ConnectionI.o \ + CurrentI.o \ + EndpointI.o \ + Exception.o \ + Dispatcher.o \ + IdentityI.o \ + ImplicitContextI.o \ + Initialize.o \ + LocalObject.o \ + LoggerI.o \ + Object.o \ + ObjectAdapterI.o \ + PropertiesI.o \ + Proxy.o \ + Stream.o \ + SlicedData.o \ + Util.o \ + VersionI.o + +OBJS := $(OBJC_OBJS) $(OBJCXX_OBJS) + +HDIR = $(includedir)/objc/Ice +SDIR = $(slicedir)/Ice + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I$(ice_cpp_dir)/include -DICE_API_EXPORTS $(CPPFLAGS) +SLICE2OBJCFLAGS := --ice --include-dir objc/Ice --dll-export ICE_API $(SLICE2OBJCFLAGS) +LINKWITH := $(BASELIBS) + +$(libdir)/$(LIBFILENAME): $(OBJS) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + rm -f $@ + ln -s $(SONAME) $@ + +# Prevent generation of these files from .ice files + +$(HDIR)/ObjectFactory.h ObjectFactory.m: + @echo + +install:: all + $(call installlib,$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/objective-c/src/Ice/Object.mm b/objective-c/src/Ice/Object.mm new file mode 100644 index 00000000000..3f571a7b084 --- /dev/null +++ b/objective-c/src/Ice/Object.mm @@ -0,0 +1,739 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <ObjectI.h> +#import <StreamI.h> +#import <CurrentI.h> +#import <Util.h> +#import <Request.h> +#import <LocalObjectI.h> + +#import <objc/Ice/LocalException.h> + +#include <Ice/Object.h> +#include <Ice/IncomingAsync.h> +#include <Ice/Initialize.h> +#include <Ice/ObjectAdapter.h> +#include <Ice/NativePropertiesAdmin.h> + +namespace +{ + +std::map<Ice::Object*, ICEObjectWrapper*> cachedObjects; + +NSString* +operationModeToString(ICEOperationMode mode) +{ + switch(mode) + { + case ICENormal: + return @"::Ice::Normal"; + + case ICENonmutating: + return @"::Ice::Nonmutating"; + + case ICEIdempotent: + return @"::Ice::Idempotent"; + + default: + return [NSString stringWithFormat:@"unknown value(%d)", mode]; + } +} + +class ObjectI : public IceObjC::ObjectWrapper, public Ice::BlobjectArrayAsync +{ +public: + + ObjectI(ICEServant*); + + virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, + const std::pair<const Ice::Byte*, const Ice::Byte*>&, + const Ice::Current&); + + virtual ICEObject* getObject() + { + return _object; + } + + // We must explicitely CFRetain/CFRelease so that the garbage + // collector does not trash the _object. + virtual void __incRef() + { + CFRetain(_object); + } + + virtual void __decRef() + { + CFRelease(_object); + } + +private: + + ICEServant* _object; +}; + +class BlobjectI : public IceObjC::ObjectWrapper, public Ice::BlobjectArrayAsync +{ +public: + + BlobjectI(ICEBlobject*); + + virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, + const std::pair<const Ice::Byte*, const Ice::Byte*>&, + const Ice::Current&); + + virtual ICEObject* getObject() + { + return _blobject; + } + + // We must explicitely CFRetain/CFRelease so that the garbage + // collector does not trash the _blobject. + virtual void __incRef() + { + CFRetain(_blobject); + } + + virtual void __decRef() + { + CFRelease(_blobject); + } + +private: + + ICEBlobject* _blobject; + id _target; +}; + +ObjectI::ObjectI(ICEServant* object) : _object(object) +{ +} + +void +ObjectI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb, + const std::pair<const Ice::Byte*, const Ice::Byte*>& inParams, + const Ice::Current& current) +{ + ICEInputStream* is = nil; + ICEOutputStream* os = nil; + { + Ice::InputStreamPtr s = Ice::createInputStream(current.adapter->getCommunicator(), inParams); + is = [ICEInputStream localObjectWithCxxObjectNoAutoRelease:s.get()]; + } + { + Ice::OutputStreamPtr s = Ice::createOutputStream(current.adapter->getCommunicator()); + os = [ICEOutputStream localObjectWithCxxObjectNoAutoRelease:s.get()]; + } + + NSException* exception = nil; + BOOL ok = YES; // Keep the compiler happy + @autoreleasepool + { + ICECurrent* c = [[ICECurrent alloc] initWithCurrent:current]; + @try + { + ok = [_object dispatch__:c is:is os:os]; + } + @catch(id ex) + { + exception = [ex retain]; + } + @finally + { + [c release]; + [is release]; + } + } + + if(exception != nil) + { + [os release]; + rethrowCxxException(exception, true); // True = release the exception. + } + + std::vector<Ice::Byte> outParams; + [os os]->finished(outParams); + [os release]; + + cb->ice_response(ok, std::make_pair(&outParams[0], &outParams[0] + outParams.size())); +} + +BlobjectI::BlobjectI(ICEBlobject* blobject) : _blobject(blobject), _target([blobject target__]) +{ +} + +void +BlobjectI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb, + const std::pair<const Ice::Byte*, const Ice::Byte*>& inEncaps, + const Ice::Current& current) +{ + NSException* exception = nil; + BOOL ok = YES; // Keep the compiler happy. + NSMutableData* outE = nil; + + @autoreleasepool + { + ICECurrent* c = [[ICECurrent alloc] initWithCurrent:current]; + NSData* inE = [NSData dataWithBytesNoCopy:const_cast<Ice::Byte*>(inEncaps.first) + length:(inEncaps.second - inEncaps.first) + freeWhenDone:NO]; + @try + { + ok = [_target ice_invoke:inE outEncaps:&outE current:c]; + [outE retain]; + } + @catch(id ex) + { + exception = [ex retain]; + } + @finally + { + [c release]; + } + } + + if(exception != nil) + { + rethrowCxxException(exception, true); // True = release the exception. + } + + cb->ice_response(ok, std::make_pair((ICEByte*)[outE bytes], (ICEByte*)[outE bytes] + [outE length])); + [outE release]; +} + +} + +int +ICEInternalLookupString(NSString* const array[], size_t count, NSString* __unsafe_unretained str) +{ + size_t low = 0; + size_t high = count - 1; + while(low <= high) + { + size_t mid = (low + high) / 2; + switch([array[mid] compare:str]) + { + case NSOrderedDescending: + if(mid == 0) + { + return -1; + } + high = mid - 1; + break; + case NSOrderedAscending: + low = mid + 1; + break; + case NSOrderedSame: + return mid; + default: + return -1; // Can't be reached + } + } + return -1; +} + +void +ICEInternalCheckModeAndSelector(id target, ICEOperationMode expected, SEL sel, ICECurrent* current) +{ + ICEOperationMode received = current.mode; + if(expected != received) + { + if(expected == ICEIdempotent && received == ICENonmutating) + { + // + // Fine: typically an old client still using the deprecated nonmutating keyword + // + + // + // Note that expected == Nonmutating and received == Idempotent is not ok: + // the server may still use the deprecated nonmutating keyword to detect updates + // and the client should not break this (deprecated) feature. + // + } + else + { + ICEMarshalException* ex = [ICEMarshalException marshalException:__FILE__ line:__LINE__]; + [ex setReason_:[NSString stringWithFormat:@"unexpected operation mode. expected = %@ received=%@", + operationModeToString(expected), operationModeToString(received)]]; + @throw ex; + } + } + + if(![target respondsToSelector:sel]) + { + @throw [ICEOperationNotExistException operationNotExistException:__FILE__ + line:__LINE__ + id:current.id_ + facet:current.facet + operation:current.operation]; + } +} + +@implementation ICEObject (ICEInternal) +-(Ice::Object*) object__ +{ + NSAssert(NO, @"object__ requires override"); + return 0; +} +@end + +@implementation ICEObject +static NSString* ICEObject_ids__[1] = +{ + @"::Ice::Object" +}; + +-(id)init +{ + self = [super init]; + if(!self) + { + return nil; + } + return self; +} + +-(void) dealloc +{ + [super dealloc]; +} +-(BOOL) ice_isA:(NSString*)typeId +{ + return [self ice_isA:typeId current:nil]; +} +-(void) ice_ping +{ + [self ice_ping:nil]; +} +-(NSString*) ice_id +{ + return [self ice_id:nil]; +} +-(NSArray*) ice_ids +{ + return [self ice_ids:nil]; +} +-(void) ice_preMarshal +{ +} +-(void) ice_postUnmarshal +{ +} +-(BOOL) ice_isA:(NSString*)typeId current:(ICECurrent*)current +{ + NSAssert(NO, @"ice_isA requires override"); + return nil; +} +-(void) ice_ping:(ICECurrent*)current +{ + NSAssert(NO, @"ice_ping requires override"); +} +-(NSString*) ice_id:(ICECurrent*)current +{ + NSAssert(NO, @"ice_id requires override"); + return nil; +} +-(NSArray*) ice_ids:(ICECurrent*)current +{ + NSAssert(NO, @"ice_ids requires override"); + return nil; +} +-(BOOL) ice_dispatch:(id<ICERequest>)request; +{ + NSAssert(NO, @"ice_dispatch requires override"); + return NO; +} ++(NSString*) ice_staticId +{ + int count, index; + NSString*const* staticIds = [self staticIds__:&count idIndex:&index]; + return staticIds[index]; +} ++(NSString*const*) staticIds__:(int*)count idIndex:(int*)idx +{ + *count = sizeof(ICEObject_ids__) / sizeof(NSString*); + *idx = 0; + return ICEObject_ids__; +} +-(void) write__:(id<ICEOutputStream>)os +{ + NSAssert(NO, @"write__ requires override"); +} +-(void) read__:(id<ICEInputStream>)is +{ + NSAssert(NO, @"read__ requires override"); +} +-(id) copyWithZone:(NSZone*)zone +{ + return [[[self class] allocWithZone:zone] init]; +} +@end + +@implementation ICEServant +static NSString* ICEObject_all__[4] = +{ + @"ice_id", + @"ice_ids", + @"ice_isA", + @"ice_ping" +}; + +-(id)init +{ + self = [super init]; + if(!self) + { + return nil; + } + object__ = 0; + delegate__ = 0; + return self; +} + +-(id)initWithDelegate:(id)delegate +{ + self = [super init]; + if(!self) + { + return nil; + } + object__ = 0; + delegate__ = [delegate retain]; + return self; +} + +-(void) dealloc +{ + if(object__) + { + delete static_cast<IceObjC::ObjectWrapper*>(object__); + object__ = 0; + } + [delegate__ release]; + [super dealloc]; +} + ++(id)objectWithDelegate:(id)delegate +{ + return [[[self alloc] initWithDelegate:delegate] autorelease]; +} + +-(BOOL) ice_isA:(NSString*)typeId current:(ICECurrent*)current +{ + int count, index; + NSString*const* staticIds = [[self class] staticIds__:&count idIndex:&index]; + return ICEInternalLookupString(staticIds, count, typeId) >= 0; +} + +-(void) ice_ping:(ICECurrent*)current +{ + // Nothing to do. +} + +-(NSString*) ice_id:(ICECurrent*)current +{ + return [[self class] ice_staticId]; +} + +-(NSArray*) ice_ids:(ICECurrent*)current +{ + int count, index; + NSString*const* staticIds = [[self class] staticIds__:&count idIndex:&index]; + return [NSArray arrayWithObjects:staticIds count:count]; +} + +-(BOOL) ice_dispatch:(id<ICERequest>)request +{ + @try + { + ICERequest* requestI = (ICERequest*)request; + return [requestI callDispatch:self]; + } + @catch(ICELocalException*) + { + @throw; + } + return FALSE; +} + ++(BOOL) ice_isA___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + ICEEncodingVersion* encoding = [is startEncapsulation]; + NSString* id__ = [is readString]; + [is endEncapsulation]; + [os startEncapsulation:encoding format:ICEDefaultFormat]; + BOOL ret__ = [servant ice_isA:id__ current:current]; + [os writeBool:ret__]; + [os endEncapsulation]; + return YES; +} + ++(BOOL) ice_ping___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + ICEEncodingVersion* encoding = [is startEncapsulation]; + [is endEncapsulation]; + [os startEncapsulation:encoding format:ICEDefaultFormat]; + [servant ice_ping:current]; + [os endEncapsulation]; + return YES; +} + ++(BOOL) ice_id___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + ICEEncodingVersion* encoding = [is startEncapsulation]; + [is endEncapsulation]; + [os startEncapsulation:encoding format:ICEDefaultFormat]; + NSString* ret__ = [servant ice_id:current]; + [os writeString:ret__]; + [os endEncapsulation]; + return YES; +} + ++(BOOL) ice_ids___:(id)servant current:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + ICEEncodingVersion* encoding = [is startEncapsulation]; + [is endEncapsulation]; + [os startEncapsulation:encoding format:ICEDefaultFormat]; + NSArray* ret__ = [servant ice_ids:current]; + [os writeStringSeq:ret__]; + [os endEncapsulation]; + return YES; +} + +-(BOOL) dispatch__:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + switch(ICEInternalLookupString(ICEObject_all__, sizeof(ICEObject_all__) / sizeof(NSString*), current.operation)) + { + case 0: + return [ICEServant ice_id___:self current:current is:is os:os]; + case 1: + return [ICEServant ice_ids___:self current:current is:is os:os]; + case 2: + return [ICEServant ice_isA___:self current:current is:is os:os]; + case 3: + return [ICEServant ice_ping___:self current:current is:is os:os]; + default: + @throw [ICEOperationNotExistException requestFailedException:__FILE__ + line:__LINE__ + id:current.id_ + facet:current.facet + operation:current.operation]; + } +} + +-(void) write__:(id<ICEOutputStream>)os +{ + [os startObject:nil]; + [self writeImpl__:os]; + [os endObject]; +} + +-(void) read__:(id<ICEInputStream>)is +{ + [is startObject]; + [self readImpl__:is]; + [is endObject:NO]; +} + +-(void) writeImpl__:(id<ICEOutputStream>)os +{ + NSAssert(NO, @"writeImpl__ requires override"); +} + +-(void) readImpl__:(id<ICEInputStream>)is +{ + NSAssert(NO, @"readImpl__ requires override"); +} + +-(id)target__ +{ + return (delegate__ == 0) ? self : delegate__; +} + +-(Ice::Object*) object__ +{ + @synchronized([self class]) + { + if(object__ == 0) + { + // + // NOTE: IceObjC::ObjectI implements it own reference counting and there's no need + // to call __incRef/__decRef here. The C++ object and Objective-C object are sharing + // the same reference count (the one of the Objective-C object). This is necessary + // to properly release both objects when there's either no more C++ handle/ObjC + // reference to the object (without this, servants added to the object adapter + // couldn't be retained or released easily). + // + object__ = static_cast<IceObjC::ObjectWrapper*>(new ObjectI(self)); + } + } + return static_cast<IceObjC::ObjectWrapper*>(object__); +} +@end + +@implementation ICEBlobject +-(Ice::Object*) object__ +{ + @synchronized([self class]) + { + if(object__ == 0) + { + // + // NOTE: IceObjC::ObjectI implements it own reference counting and there's no need + // to call __incRef/__decRef here. The C++ object and Objective-C object are sharing + // the same reference count (the one of the Objective-C object). This is necessary + // to properly release both objects when there's either no more C++ handle/ObjC + // reference to the object (without this, servants added to the object adapter + // couldn't be retained or released easily). + // + object__ = static_cast<IceObjC::ObjectWrapper*>(new BlobjectI(self)); + } + } + return static_cast<IceObjC::ObjectWrapper*>(object__); +} +@end + +@implementation ICEObjectWrapper +-(id) initWithCxxObject:(Ice::Object*)arg +{ + self = [super init]; + if(!self) + { + return nil; + } + + object__ = arg; + object__->__incRef(); + assert(cachedObjects.find(object__) == cachedObjects.end()); + cachedObjects.insert(std::make_pair(object__, self)); + return self; +} +-(void) dealloc +{ + cachedObjects.erase(object__); + object__->__decRef(); + [super dealloc]; +} ++(id) objectWrapperWithCxxObject:(Ice::Object*)arg +{ + @synchronized([ICEObjectWrapper class]) + { + std::map<Ice::Object*, ICEObjectWrapper*>::const_iterator p = cachedObjects.find(arg); + if(p != cachedObjects.end()) + { + return [p->second retain]; + } + else + { + return [[(ICEObjectWrapper*)[self alloc] initWithCxxObject:arg] autorelease]; + } + } +} +-(id) retain +{ + NSIncrementExtraRefCount(self); + return self; +} +-(oneway void) release +{ + @synchronized([ICEObjectWrapper class]) + { + if(NSDecrementExtraRefCountWasZero(self)) + { + [self dealloc]; + } + } +} +-(BOOL) ice_isA:(NSString*)typeId current:(ICECurrent*)current +{ + NSException* nsex = nil; + try + { + return object__->ice_isA(fromNSString(typeId), Ice::Current()); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(void) ice_ping:(ICECurrent*)current +{ + NSException* nsex = nil; + try + { + return object__->ice_ping(Ice::Current()); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(NSString*) ice_id:(ICECurrent*)current +{ + NSException* nsex = nil; + try + { + return toNSString(object__->ice_id(Ice::Current())); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(NSArray*) ice_ids:(ICECurrent*)current +{ + NSException* nsex = nil; + try + { + return toNSArray(object__->ice_ids(Ice::Current())); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(BOOL) ice_dispatch:(id<ICERequest>)request +{ + @throw [ICEFeatureNotSupportedException featureNotSupportedException:__FILE__ line:__LINE__]; +} +-(void) write__:(id<ICEOutputStream>)os +{ + NSException* nsex = nil; + try + { + object__->__write([(ICEOutputStream*)os os]); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(void) read__:(id<ICEInputStream>)is +{ + NSException* nsex = nil; + try + { + object__->__read([(ICEInputStream*)is is]); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(Ice::Object*) object__ +{ + return object__; +} +@end diff --git a/objective-c/src/Ice/ObjectAdapterI.h b/objective-c/src/Ice/ObjectAdapterI.h new file mode 100644 index 00000000000..8d859c4be7a --- /dev/null +++ b/objective-c/src/Ice/ObjectAdapterI.h @@ -0,0 +1,21 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/ObjectAdapter.h> + +#import <objc/Ice/LocalObject.h> + +#include <Ice/ObjectAdapter.h> + +@class ICECommunicator; + +@interface ICEObjectAdapter : ICELocalObject<ICEObjectAdapter> +-(Ice::ObjectAdapter*) adapter; +@end + diff --git a/objective-c/src/Ice/ObjectAdapterI.mm b/objective-c/src/Ice/ObjectAdapterI.mm new file mode 100644 index 00000000000..41b30a55e4e --- /dev/null +++ b/objective-c/src/Ice/ObjectAdapterI.mm @@ -0,0 +1,834 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <ObjectAdapterI.h> +#import <CommunicatorI.h> +#import <ProxyI.h> +#import <IdentityI.h> +#import <ObjectI.h> +#import <Util.h> +#import <LocalObjectI.h> +#import <CurrentI.h> +#import <StreamI.h> + +#import <objc/Ice/LocalException.h> +#import <objc/Ice/Locator.h> +#import <objc/Ice/ServantLocator.h> + +#include <Ice/Locator.h> +#include <Ice/ServantLocator.h> +#include <Ice/Stream.h> + +namespace +{ +class DefaultServantLocator : public Ice::ServantLocator +{ +public: + + DefaultServantLocator(const Ice::ObjectPtr& s) : + _servant(s) + { + } + + virtual Ice::ObjectPtr + locate(const Ice::Current&, Ice::LocalObjectPtr&) + { + return _servant; + } + + virtual void + finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr&) + { + } + + virtual void + deactivate(const std::string&) + { + } + + const Ice::ObjectPtr& + servant() const + { + return _servant; + } + +private: + Ice::ObjectPtr _servant; +}; +typedef IceUtil::Handle<DefaultServantLocator> DefaultServantLocatorPtr; + +class Cookie : public Ice::LocalObject +{ +public: + + Cookie(id cookie) : _cookie(cookie) + { + [_cookie retain]; + } + + ~Cookie() + { + [_cookie release]; + } + + id cookie() + { + return _cookie; + } +private: + + id _cookie; +}; +typedef IceUtil::Handle<Cookie> CookiePtr; + +class ExceptionWriter : public Ice::UserExceptionWriter +{ +public: + + ExceptionWriter(const Ice::CommunicatorPtr& communicator, ICEUserException* ex) : + Ice::UserExceptionWriter(communicator), _ex(ex) + { + } + + ~ExceptionWriter() throw() + { + [_ex release]; + } + + void + write(const Ice::OutputStreamPtr& s) const + { + ICEOutputStream* os = [ICEOutputStream localObjectWithCxxObjectNoAutoRelease:s.get()]; + [_ex write__:os]; + [os release]; + } + + bool + usesClasses() const + { + return [_ex usesClasses__]; + } + + std::string + ice_name() const + { + return [[_ex ice_name] UTF8String]; + } + + Ice::UserException* + ice_clone() const + { + return new ExceptionWriter(*this); + } + + void + ice_throw() const + { + throw *this; + } + +private: + + ICEUserException* _ex; +}; + +class ServantLocatorWrapper : public Ice::ServantLocator +{ +public: + + ServantLocatorWrapper(id<ICEServantLocator> locator) : + _locator(locator) + { + [_locator retain]; + } + + ~ServantLocatorWrapper() + { + [_locator release]; + } + + virtual Ice::ObjectPtr + locate(const Ice::Current& current, Ice::LocalObjectPtr& cookie) + { + NSException* ex = nil; + @autoreleasepool + { + ICECurrent* cu = [[ICECurrent alloc] initWithCurrent:current]; + id co = nil; + @try + { + ICEObject* servant = [_locator locate:cu cookie:&co]; + if(co != nil) + { + cookie = new Cookie(co); + } + return [servant object__]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [cu release]; + } + } + if(ex != nil) + { + if([ex isKindOfClass:[ICEUserException class]]) + { + throw ExceptionWriter(current.adapter->getCommunicator(), (ICEUserException*)ex); + } + rethrowCxxException(ex, true); // True = release the exception. + } + } + + virtual void + finished(const Ice::Current& current, const Ice::ObjectPtr& servant, const Ice::LocalObjectPtr& cookie) + { + NSException* ex = nil; + @autoreleasepool + { + ICECurrent* cu = [[ICECurrent alloc] initWithCurrent:current]; + id co = cookie ? CookiePtr::dynamicCast(cookie)->cookie() : nil; + @try + { + [_locator finished:cu servant:toObjC(servant) cookie:co]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [cu release]; + } + } + if(ex != nil) + { + if([ex isKindOfClass:[ICEUserException class]]) + { + throw ExceptionWriter(current.adapter->getCommunicator(), (ICEUserException*)ex); + } + rethrowCxxException(ex, true); // True = release the exception. + } + } + + virtual void + deactivate(const std::string& category) + { + NSException* ex = nil; + @autoreleasepool + { + NSString* cat = toNSString(category); + @try + { + [_locator deactivate:cat]; + } + @catch(id e) + { + ex = [e retain]; + } + @finally + { + [cat release]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } + } + + id<ICEServantLocator> + locator() const + { + return _locator; + } + +private: + + id<ICEServantLocator> _locator; +}; +typedef IceUtil::Handle<ServantLocatorWrapper> ServantLocatorWrapperPtr; + +} + +#define OBJECTADAPTER dynamic_cast<Ice::ObjectAdapter*>(static_cast<IceUtil::Shared*>(cxxObject_)) + +@implementation ICEObjectAdapter +-(Ice::ObjectAdapter*) adapter +{ + return OBJECTADAPTER; +} +// +// @protocol ICEObjectAdapter methods. +// + +-(id<ICECommunicator>) getCommunicator +{ + NSException* nsex = nil; + try + { + return [ICECommunicator localObjectWithCxxObject:OBJECTADAPTER->getCommunicator().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableString*) getName +{ + NSException* nsex = nil; + try + { + return [toNSMutableString(OBJECTADAPTER->getName()) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) activate +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->activate(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) hold +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->hold(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) waitForHold +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->waitForHold(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) deactivate +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->deactivate(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) waitForDeactivate +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->waitForDeactivate(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(BOOL) isDeactivated +{ + NSException* nsex = nil; + try + { + return OBJECTADAPTER->isDeactivated(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return NO; // Keep the compiler happy. +} + +-(void) destroy +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->destroy(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(id<ICEObjectPrx>) add:(ICEObject*)servant identity:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->add([servant object__], [ident identity])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) addFacet:(ICEObject*)servant identity:(ICEIdentity*)ident facet:(NSString*)facet +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->addFacet([servant object__], [ident identity], + fromNSString(facet))]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) addWithUUID:(ICEObject*)servant +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->addWithUUID([servant object__])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) addFacetWithUUID:(ICEObject*)servant facet:(NSString*)facet +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->addFacetWithUUID([servant object__], + fromNSString(facet))]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) addDefaultServant:(ICEObject*)servant category:(NSString*)category +{ + NSException* nsex = nil; + try + { + Ice::ServantLocatorPtr servantLocator = new DefaultServantLocator([servant object__]); + OBJECTADAPTER->addServantLocator(servantLocator, fromNSString(category)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(ICEObject*) remove:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return toObjC(OBJECTADAPTER->remove([ident identity])); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(ICEObject*) removeFacet:(ICEIdentity*)ident facet:(NSString*)facet +{ + NSException* nsex = nil; + try + { + return toObjC(OBJECTADAPTER->removeFacet([ident identity], fromNSString(facet))); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEMutableFacetMap*) removeAllFacets:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return toNSDictionary(OBJECTADAPTER->removeAllFacets([ident identity])); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEObject*) removeDefaultServant:(NSString*)category +{ + NSException* nsex = nil; + try + { + Ice::ServantLocatorPtr locator = OBJECTADAPTER->removeServantLocator(fromNSString(category)); + if(!locator) + { + return nil; + } + DefaultServantLocatorPtr defaultServantLocator = DefaultServantLocatorPtr::dynamicCast(locator); + if(!defaultServantLocator) + { + return nil; + } + return toObjC(defaultServantLocator->servant()); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEObject*) find:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return toObjC(OBJECTADAPTER->find([ident identity])); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEObject*) findFacet:(ICEIdentity*)ident facet:(NSString*)facet +{ + NSException* nsex = nil; + try + { + return toObjC(OBJECTADAPTER->findFacet([ident identity], fromNSString(facet))); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableDictionary*) findAllFacets:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return toNSDictionary(OBJECTADAPTER->findAllFacets([ident identity])); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEObject*) findByProxy:(id<ICEObjectPrx>)proxy +{ + NSException* nsex = nil; + try + { + return toObjC(OBJECTADAPTER->findByProxy([(ICEObjectPrx*)proxy objectPrx__])); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) addServantLocator:(id<ICEServantLocator>)locator category:(NSString*)category +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->addServantLocator(new ServantLocatorWrapper(locator), fromNSString(category)); + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(id<ICEServantLocator>) removeServantLocator:(NSString*)category +{ + NSException* nsex = nil; + try + { + Ice::ServantLocatorPtr locator = OBJECTADAPTER->removeServantLocator(fromNSString(category)); + return ServantLocatorWrapperPtr::dynamicCast(locator)->locator(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(id<ICEServantLocator>) findServantLocator:(NSString*)category +{ + NSException* nsex = nil; + try + { + Ice::ServantLocatorPtr locator = OBJECTADAPTER->removeServantLocator(fromNSString(category)); + return locator ? ServantLocatorWrapperPtr::dynamicCast(locator)->locator() : nil; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +-(ICEObject*) findDefaultServant:(NSString*)category +{ + NSException* nsex = nil; + try + { + Ice::ServantLocatorPtr servantLocator = OBJECTADAPTER->findServantLocator(fromNSString(category)); + if(servantLocator == 0) + { + return nil; + } + DefaultServantLocatorPtr defaultServantLocator = DefaultServantLocatorPtr::dynamicCast(servantLocator); + if(defaultServantLocator == 0) + { + return nil; // should never happen! + } + else + { + return toObjC(defaultServantLocator->servant()); + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) createProxy:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->createProxy([ident identity])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) createDirectProxy:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->createDirectProxy([ident identity])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) createIndirectProxy:(ICEIdentity*)ident +{ + NSException* nsex = nil; + try + { + return [ICEObjectPrx objectPrxWithObjectPrx__:OBJECTADAPTER->createIndirectProxy([ident identity])]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) setLocator:(id<ICELocatorPrx>)loc +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->setLocator(Ice::LocatorPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)loc objectPrx__]))); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(id<ICELocatorPrx>) getLocator +{ + NSException* nsex = nil; + try + { + return (id<ICELocatorPrx>)[ICELocatorPrx objectPrxWithObjectPrx__:OBJECTADAPTER->getLocator()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Keep the compiler happy. +} + +-(void) refreshPublishedEndpoints +{ + NSException* nsex = nil; + try + { + OBJECTADAPTER->refreshPublishedEndpoints(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(ICEEndpointSeq*) getEndpoints +{ + NSException* nsex = nil; + try + { + return [toNSArray(OBJECTADAPTER->getEndpoints()) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; +} + +-(ICEEndpointSeq*) getPublishedEndpoints +{ + NSException* nsex = nil; + try + { + return [toNSArray(OBJECTADAPTER->getPublishedEndpoints()) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; +} + +@end diff --git a/objective-c/src/Ice/ObjectI.h b/objective-c/src/Ice/ObjectI.h new file mode 100644 index 00000000000..87e9d01bd7a --- /dev/null +++ b/objective-c/src/Ice/ObjectI.h @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Object.h> + +#include <Ice/Object.h> + +// +// Forward declarations. +// +@class ICECurrent; +@class ICEInputStream; +@class ICEOutputStream; + +namespace IceObjC +{ + +class ObjectWrapper : virtual public Ice::Object +{ +public: + + virtual ~ObjectWrapper() { } + virtual ICEObject* getObject() = 0; +}; +typedef IceUtil::Handle<ObjectWrapper> ObjectWrapperPtr; + +}; + +@interface ICEObject (ICEInternal) +-(Ice::Object*) object__; +@end + +@interface ICEObjectWrapper : ICEObject +{ + Ice::Object* object__; +} ++(id) objectWrapperWithCxxObject:(Ice::Object*)arg; +@end diff --git a/objective-c/src/Ice/PropertiesI.h b/objective-c/src/Ice/PropertiesI.h new file mode 100644 index 00000000000..c7d54756cbc --- /dev/null +++ b/objective-c/src/Ice/PropertiesI.h @@ -0,0 +1,32 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Properties.h> + +#import <objc/Ice/LocalObject.h> +#import <objc/Ice/NativePropertiesAdmin.h> + +#import <ObjectI.h> + +#include <Ice/Properties.h> +#include <Ice/NativePropertiesAdmin.h> + +@interface ICEProperties : ICELocalObject<ICEProperties> +{ + Ice::Properties* properties_; +} +-(Ice::Properties*)properties; +@end + +@interface ICENativePropertiesAdmin : ICEObjectWrapper<ICENativePropertiesAdmin> +{ + IceUtil::Mutex mutex_; + std::vector<Ice::PropertiesAdminUpdateCallbackPtr> callbacks_; +} +@end diff --git a/objective-c/src/Ice/PropertiesI.mm b/objective-c/src/Ice/PropertiesI.mm new file mode 100644 index 00000000000..176521af234 --- /dev/null +++ b/objective-c/src/Ice/PropertiesI.mm @@ -0,0 +1,309 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <PropertiesI.h> +#import <Util.h> +#import <LocalObjectI.h> + +#include <Ice/NativePropertiesAdmin.h> + +@implementation ICEProperties +-(id) initWithCxxObject:(IceUtil::Shared*)cxxObject +{ + self = [super initWithCxxObject:cxxObject]; + if(!self) + { + return nil; + } + properties_ = dynamic_cast<Ice::Properties*>(cxxObject); + return self; +} +-(Ice::Properties*) properties +{ + return (Ice::Properties*)properties_; +} + +// @protocol ICEProperties methods. + +-(NSMutableString*) getProperty:(NSString*)key +{ + NSException* nsex = nil; + try + { + return [toNSMutableString(properties_->getProperty(fromNSString(key))) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(NSMutableString*) getPropertyWithDefault:(NSString*)key value:(NSString*)value +{ + NSException* nsex = nil; + try + { + return [toNSMutableString(properties_->getPropertyWithDefault(fromNSString(key), + fromNSString(value))) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(int) getPropertyAsInt:(NSString*)key +{ + NSException* nsex = nil; + try + { + return properties_->getPropertyAsInt(fromNSString(key)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} +-(int) getPropertyAsIntWithDefault:(NSString*)key value:(int)value +{ + NSException* nsex = nil; + try + { + return properties_->getPropertyAsIntWithDefault(fromNSString(key), value); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} +-(ICEMutableStringSeq*) getPropertyAsList:(NSString*)key +{ + NSException* nsex = nil; + try + { + return [toNSArray(properties_->getPropertyAsList(fromNSString(key))) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(ICEMutableStringSeq*) getPropertyAsListWithDefault:(NSString*)key value:(NSArray*)value +{ + NSException* nsex = nil; + try + { + std::vector<std::string> s; + fromNSArray(value, s); + return [toNSArray(properties_->getPropertyAsListWithDefault(fromNSString(key), s)) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(ICEMutablePropertyDict*) getPropertiesForPrefix:(NSString*)prefix +{ + NSException* nsex = nil; + try + { + return [toNSDictionary(properties_->getPropertiesForPrefix(fromNSString(prefix))) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) setProperty:(NSString*)key value:(NSString*)value +{ + NSException* nsex = nil; + try + { + properties_->setProperty(fromNSString(key), fromNSString(value)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(ICEMutableStringSeq*) getCommandLineOptions +{ + NSException* nsex = nil; + try + { + return [toNSArray(properties_->getCommandLineOptions()) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(ICEMutableStringSeq*) parseCommandLineOptions:(NSString*)prefix options:(NSArray*)options +{ + NSException* nsex = nil; + try + { + std::vector<std::string> o; + fromNSArray(options, o); + return [toNSArray(properties_->parseCommandLineOptions(fromNSString(prefix), o)) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(ICEMutableStringSeq*) parseIceCommandLineOptions:(NSArray*)options +{ + NSException* nsex = nil; + try + { + std::vector<std::string> o; + fromNSArray(options, o); + return [toNSArray(properties_->parseIceCommandLineOptions(o)) autorelease]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) load:(NSString*)file +{ + NSException* nsex = nil; + try + { + properties_->load(fromNSString(file)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(id<ICEProperties>) clone +{ + NSException* nsex = nil; + try + { + return [ICEProperties localObjectWithCxxObject:properties_->clone().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +@end + +namespace +{ + +class UpdateCallbackI : public Ice::PropertiesAdminUpdateCallback +{ +public: + + UpdateCallbackI(id<ICEPropertiesAdminUpdateCallback> callback) : _callback(callback) + { + [_callback retain]; + } + + ~UpdateCallbackI() + { + [_callback release]; + } + + void + updated(const Ice::PropertyDict& properties) + { + NSException* ex = nil; + @autoreleasepool + { + @try + { + [_callback updated:[toNSDictionary(properties) autorelease]]; + } + @catch(id e) + { + ex = [e retain]; + } + } + if(ex != nil) + { + rethrowCxxException(ex, true); // True = release the exception. + } + } + + id<ICEPropertiesAdminUpdateCallback> + callback() + { + return _callback; + } + +private: + + id<ICEPropertiesAdminUpdateCallback> _callback; +}; +typedef IceUtil::Handle<UpdateCallbackI> UpdateCallbackIPtr; + +} + +@implementation ICEPropertiesAdminUpdateCallback +@end + +#define NATIVEPROPERTIESADMIN dynamic_cast<Ice::NativePropertiesAdmin*>(object__) + +@implementation ICENativePropertiesAdmin +-(void) addUpdateCallback:(id<ICEPropertiesAdminUpdateCallback>)cb +{ + IceUtil::Mutex::Lock sync(mutex_); + callbacks_.push_back(new UpdateCallbackI(cb)); + assert(Ice::NativePropertiesAdminPtr::dynamicCast(object__)); + NATIVEPROPERTIESADMIN->addUpdateCallback(callbacks_.back()); +} + +-(void) removeUpdateCallback:(id<ICEPropertiesAdminUpdateCallback>)cb +{ + IceUtil::Mutex::Lock sync(mutex_); + for(std::vector<Ice::PropertiesAdminUpdateCallbackPtr>::iterator p = callbacks_.begin(); p != callbacks_.end(); ++p) + { + if(UpdateCallbackIPtr::dynamicCast(*p)->callback() == cb) + { + NATIVEPROPERTIESADMIN->removeUpdateCallback(*p); + callbacks_.erase(p); + return; + } + } +} +@end diff --git a/objective-c/src/Ice/Proxy.mm b/objective-c/src/Ice/Proxy.mm new file mode 100644 index 00000000000..04f076b9f02 --- /dev/null +++ b/objective-c/src/Ice/Proxy.mm @@ -0,0 +1,1760 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <ProxyI.h> +#import <Util.h> +#import <StreamI.h> +#import <VersionI.h> +#import <CommunicatorI.h> +#import <IdentityI.h> +#import <ConnectionI.h> +#import <LocalObjectI.h> + +#import <objc/Ice/Object.h> +#import <objc/Ice/LocalException.h> +#import <objc/Ice/Router.h> +#import <objc/Ice/Locator.h> + +#include <Ice/Initialize.h> +#include <Ice/Proxy.h> +#include <Ice/LocalException.h> +#include <Ice/Router.h> +#include <Ice/Locator.h> + +#import <objc/runtime.h> +#import <objc/message.h> + +#import <Foundation/NSThread.h> +#import <Foundation/NSInvocation.h> + +#include <Block.h> + +#define OBJECTPRX ((IceProxy::Ice::Object*)objectPrx__) +#define ASYNCRESULT ((Ice::AsyncResult*)asyncResult__) + +namespace +{ + +class BeginInvokeAsyncCallback : public IceUtil::Shared +{ +public: + +BeginInvokeAsyncCallback(void (^completed)(id<ICEInputStream>, BOOL), + void (^exception)(ICEException*), + void (^sent)(BOOL), + BOOL returnsData) : + _completed(Block_copy(completed)), + _exception(Block_copy(exception)), + _sent(Block_copy(sent)), + _returnsData(returnsData) +{ +} + +virtual ~BeginInvokeAsyncCallback() +{ + Block_release(_completed); + Block_release(_exception); + Block_release(_sent); +} + +void completed(const Ice::AsyncResultPtr& result) +{ + BOOL ok = YES; // Keep the compiler happy. + id<ICEInputStream> is = nil; + NSException* nsex = nil; + Ice::ObjectPrx proxy = result->getProxy(); + try + { + std::vector<Ice::Byte> outParams; + ok = proxy->end_ice_invoke(outParams, result); + if(_returnsData) + { + Ice::InputStreamPtr s = Ice::createInputStream(proxy->ice_getCommunicator(), outParams); + is = [ICEInputStream localObjectWithCxxObjectNoAutoRelease:s.get()]; + } + else if(!outParams.empty()) + { + if(ok) + { + if(outParams.size() != 6) + { + throw Ice::EncapsulationException(__FILE__, __LINE__); + } + } + else + { + Ice::InputStreamPtr s = Ice::createInputStream(proxy->ice_getCommunicator(), outParams); + try + { + s->startEncapsulation(); + s->throwException(); + } + catch(const Ice::UserException& ex) + { + s->endEncapsulation(); + throw Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_name()); + } + } + } + } + catch(const std::exception& ex) + { + if(is != nil) + { + [is release]; + is = nil; + } + nsex = toObjCException(ex); + } + + NSException* exception = nil; + @autoreleasepool + { + @try + { + if(nsex != nil) + { + @try + { + @throw nsex; + } + @catch(ICEException* ex) + { + if(_exception) + { + _exception(ex); + } + return; + } + } + + _completed(is, ok); + } + @catch(id e) + { + exception = [e retain]; + } + @finally + { + [is release]; + } + } + + if(exception != nil) + { + rethrowCxxException(exception, true); // True = release the exception. + } +} + +void sent(const Ice::AsyncResultPtr& result) +{ + if(!_sent) + { + return; + } + + NSException* exception = nil; + @autoreleasepool + { + @try + { + _sent(result->sentSynchronously()); + } + @catch(id e) + { + exception = [e retain]; + } + } + + if(exception != nil) + { + rethrowCxxException(exception, true); // True = release the exception. + } +} + +private: + +void (^_completed)(id<ICEInputStream>, BOOL); +void (^_exception)(ICEException*); +void (^_sent)(BOOL); +BOOL _returnsData; + +}; + +}; + +@implementation ICEAsyncResult +-(ICEAsyncResult*) initWithAsyncResult__:(const Ice::AsyncResultPtr&)arg + operation:(NSString*)op + proxy:(id<ICEObjectPrx>)p; +{ + self = [super init]; + if(!self) + { + return nil; + } + + asyncResult__ = arg.get(); + ASYNCRESULT->__incRef(); + operation_ = [op retain]; + proxy_ = [p retain]; + return self; +} + +-(Ice::AsyncResult*) asyncResult__ +{ + return ASYNCRESULT; +} + +-(void) dealloc +{ + ASYNCRESULT->__decRef(); + asyncResult__ = 0; + [operation_ release]; + [proxy_ release]; + [super dealloc]; +} + ++(ICEAsyncResult*) asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg +{ + return [self asyncResultWithAsyncResult__:arg operation:nil proxy:nil]; +} ++(ICEAsyncResult*) asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg + operation:(NSString*)op + proxy:(id<ICEObjectPrx>)p +{ + if(!arg) + { + return nil; + } + else + { + return [[[self alloc] initWithAsyncResult__:arg operation:op proxy:p] autorelease]; + } +} +-(NSString*) operation +{ + return operation_; +} + +-(void) cancel +{ + ASYNCRESULT->cancel(); +} + +-(id<ICECommunicator>) getCommunicator +{ + return [ICECommunicator localObjectWithCxxObject:ASYNCRESULT->getCommunicator().get()]; +} + +-(id<ICEConnection>) getConnection +{ + return [ICEConnection localObjectWithCxxObject:ASYNCRESULT->getConnection().get()]; +} + +-(id<ICEObjectPrx>) getProxy +{ + return [[proxy_ retain] autorelease]; +} + +-(BOOL) isCompleted +{ + return ASYNCRESULT->isCompleted(); +} + +-(void) waitForCompleted +{ + ASYNCRESULT->waitForCompleted(); +} + +-(BOOL) isSent +{ + return ASYNCRESULT->isSent(); +} + +-(void) waitForSent +{ + ASYNCRESULT->waitForSent(); +} + +-(BOOL) sentSynchronously +{ + return ASYNCRESULT->sentSynchronously(); +} + +-(void) throwLocalException +{ + NSException* nsex; + try + { + ASYNCRESULT->throwLocalException(); + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +-(NSString*) getOperation +{ + if(operation_ != nil) + { + return [[operation_ retain] autorelease]; + } + else + { + return [toNSString(ASYNCRESULT->getOperation()) autorelease]; + } +} +@end + +@implementation ICEObjectPrx + +-(ICEObjectPrx*) initWithObjectPrx__:(const Ice::ObjectPrx&)arg +{ + self = [super init]; + if(!self) + { + return nil; + } + communicator__ = [ICECommunicator localObjectWithCxxObjectNoAutoRelease:arg->ice_getCommunicator().get()]; + objectPrx__ = arg.get(); + OBJECTPRX->__incRef(); + return self; +} + +-(IceProxy::Ice::Object*) objectPrx__ +{ + return (IceProxy::Ice::Object*)objectPrx__; +} + +-(void) dealloc +{ + OBJECTPRX->__decRef(); + objectPrx__ = 0; + [communicator__ release]; + [super dealloc]; +} + ++(ICEObjectPrx*) objectPrxWithObjectPrx__:(const Ice::ObjectPrx&)arg +{ + if(!arg) + { + return nil; + } + else + { + return [[[self alloc] initWithObjectPrx__:arg] autorelease]; + } +} + ++(id) uncheckedCast:(id<ICEObjectPrx>)proxy +{ + if(proxy != nil) + { + if([(ICEObjectPrx*)proxy isKindOfClass:self]) + { + return [[proxy retain] autorelease]; + } + else + { + return [[[self alloc] initWithObjectPrx__:[(ICEObjectPrx*)proxy objectPrx__]] autorelease]; + } + } + return nil; +} ++(id) uncheckedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet +{ + return [self uncheckedCast:[proxy ice_facet:facet]]; +} ++(id) checkedCast:(id<ICEObjectPrx>)proxy +{ + if(proxy != nil) + { + if([(ICEObjectPrx*)proxy isKindOfClass:self]) + { + return [[proxy retain] autorelease]; + } + else if([(ICEObjectPrx*)proxy conformsToProtocol:[self protocol__]] || + [proxy ice_isA:[self ice_staticId]]) + { + return [[[self alloc] initWithObjectPrx__:[(ICEObjectPrx*)proxy objectPrx__]] autorelease]; + } + } + return nil; +} ++(id) checkedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet +{ + @try + { + return [self checkedCast:[proxy ice_facet:facet]]; + } + @catch(ICEFacetNotExistException* ex) + { + return nil; + } +} ++(id) checkedCast:(id<ICEObjectPrx>)proxy context:(ICEContext*)context +{ + if(proxy != nil) + { + if([(ICEObjectPrx*)proxy isKindOfClass:self]) + { + return [[proxy retain] autorelease]; + } + else if([(ICEObjectPrx*)proxy conformsToProtocol:[self protocol__]] || + [proxy ice_isA:[self ice_staticId] context:context]) + { + return [[[self alloc] initWithObjectPrx__:[(ICEObjectPrx*)proxy objectPrx__]] autorelease]; + } + } + return nil; +} ++(id) checkedCast:(id<ICEObjectPrx>)proxy facet:(NSString*)facet context:(ICEContext*)context +{ + @try + { + return [self checkedCast:[proxy ice_facet:facet] context:context]; + } + @catch(ICEFacetNotExistException* ex) + { + return nil; + } +} ++(NSString*) ice_staticId +{ + return @"::Ice::Object"; +} + ++(Protocol*) protocol__ +{ + return objc_getProtocol(class_getName([self class])); +} + +-(id<ICEOutputStream>) createOutputStream__ +{ + NSException* nsex = nil; + try + { + Ice::OutputStreamPtr os = Ice::createOutputStream(OBJECTPRX->ice_getCommunicator()); + return [ICEOutputStream localObjectWithCxxObjectNoAutoRelease:os.get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) checkAsyncTwowayOnly__:(NSString*)operation +{ + // + // No mutex lock necessary, there is nothing mutable in this + // operation. + // + + if(![self ice_isTwoway]) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:[NSString stringWithFormat:@"`%@' can only be called with a twoway proxy", operation] + userInfo:nil]; + } +} + +-(void) invoke__:(NSString*)operation + mode:(ICEOperationMode)mode + format:(ICEFormatType)format + marshal:(ICEMarshalCB)marshal + unmarshal:(ICEUnmarshalCB)unmarshal + context:(ICEContext*)context +{ + if(unmarshal && !OBJECTPRX->ice_isTwoway()) + { + @throw [ICETwowayOnlyException twowayOnlyException:__FILE__ line:__LINE__ operation:operation]; + } + + ICEOutputStream<ICEOutputStream>* os = nil; + if(marshal) + { + os = [self createOutputStream__]; + try + { + [os os]->startEncapsulation(IceInternal::getCompatibleEncoding(OBJECTPRX->ice_getEncodingVersion()), + (Ice::FormatType)format); + } + catch(const std::exception& ex) + { + [os release]; + @throw toObjCException(ex); + } + + @try + { + marshal(os); + } + @catch(id ex) + { + [os release]; + @throw ex; + } + } + + BOOL ok = YES; // Keep the compiler happy. + ICEInputStream<ICEInputStream>* is = nil; + NSException* nsex = nil; + try + { + std::vector<Ice::Byte> inParams; + if(os) + { + [os os]->endEncapsulation(); + [os os]->finished(inParams); + [os release]; + os = nil; + } + + std::vector<Ice::Byte> outParams; + if(context != nil) + { + Ice::Context ctx; + fromNSDictionary(context, ctx); + ok = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, outParams, ctx); + } + else + { + ok = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, outParams); + } + + if(unmarshal) + { + Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams); + is = [ICEInputStream localObjectWithCxxObjectNoAutoRelease:s.get()]; + } + else if(!outParams.empty()) + { + if(ok) + { + if(outParams.size() != 6) + { + throw Ice::EncapsulationException(__FILE__, __LINE__); + } + } + else + { + Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams); + try + { + s->startEncapsulation(); + s->throwException(); + } + catch(const Ice::UserException& ex) + { + s->endEncapsulation(); + throw Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_name()); + } + } + } + } + catch(const std::exception& ex) + { + if(os != nil) + { + [os release]; + os = nil; + } + if(is != nil) + { + [is release]; + is = nil; + } + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + + NSAssert(os == nil, @"output stream not cleared"); + if(is) + { + @try + { + unmarshal(is, ok); + } + @finally + { + [is release]; + } + } +} + +-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation + mode:(ICEOperationMode)mode + format:(ICEFormatType)format + marshal:(void(^)(id<ICEOutputStream>))marshal + returnsData:(BOOL)returnsData + context:(ICEContext*)context +{ + if(returnsData) + { + [self checkAsyncTwowayOnly__:operation]; + } + + ICEOutputStream<ICEOutputStream>* os = nil; + if(marshal) + { + os = [self createOutputStream__]; + try + { + [os os]->startEncapsulation(IceInternal::getCompatibleEncoding(OBJECTPRX->ice_getEncodingVersion()), + (Ice::FormatType)format); + } + catch(const std::exception& ex) + { + [os release]; + @throw toObjCException(ex); + } + + @try + { + marshal(os); + } + @catch(id ex) + { + [os release]; + @throw ex; + } + } + + NSException* nsex = nil; + try + { + std::vector<Ice::Byte> inParams; + if(os) + { + [os os]->endEncapsulation(); + [os os]->finished(inParams); + [os release]; + os = nil; + } + + Ice::AsyncResultPtr r; + if(context != nil) + { + Ice::Context ctx; + fromNSDictionary(context, ctx); + r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, ctx); + } + else + { + r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams); + } + return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:operation proxy:self]; + } + catch(const std::exception& ex) + { + if(os != nil) + { + [os release]; + os = nil; + } + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Keep the compiler happy. +} + +-(id<ICEAsyncResult>) begin_invoke__:(NSString*)operation + mode:(ICEOperationMode)mode + format:(ICEFormatType)format + marshal:(void(^)(id<ICEOutputStream>))marshal + returnsData:(BOOL)returnsData + completed:(void(^)(id<ICEInputStream>, BOOL))completed + response:(BOOL)response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent + context:(ICEContext*)context +{ + if(returnsData) + { + [self checkAsyncTwowayOnly__:operation]; + if(!response) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:@"Response callback is nil" + userInfo:nil]; + } + } + + if(!exception) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:@"Exception callback is nil" + userInfo:nil]; + } + + ICEOutputStream<ICEOutputStream>* os = nil; + if(marshal) + { + os = [self createOutputStream__]; + try + { + [os os]->startEncapsulation(IceInternal::getCompatibleEncoding(OBJECTPRX->ice_getEncodingVersion()), + (Ice::FormatType)format); + } + catch(const std::exception& ex) + { + [os release]; + @throw toObjCException(ex); + } + + @try + { + marshal(os); + } + @catch(id ex) + { + [os release]; + @throw ex; + } + } + + NSException* nsex = nil; + try + { + std::vector<Ice::Byte> inParams; + if(os) + { + [os os]->endEncapsulation(); + [os os]->finished(inParams); + [os release]; + os = nil; + } + + Ice::CallbackPtr cb = Ice::newCallback(new BeginInvokeAsyncCallback(completed, exception, sent, returnsData), + &BeginInvokeAsyncCallback::completed, + &BeginInvokeAsyncCallback::sent); + Ice::AsyncResultPtr r; + if(context != nil) + { + Ice::Context ctx; + fromNSDictionary(context, ctx); + r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, ctx, cb); + } + else + { + r = OBJECTPRX->begin_ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inParams, cb); + } + return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:operation proxy:self]; + } + catch(const std::exception& ex) + { + if(os != nil) + { + [os release]; + os = nil; + } + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Keep the compiler happy. +} +-(id<ICEAsyncResult>) begin_invoke__:(NSString*)op + mode:(ICEOperationMode)mode + format:(ICEFormatType)format + marshal:(void(^)(id<ICEOutputStream>))marshal + response:(void(^)())response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent + context:(ICEContext*)ctx +{ + void(^completed)(id<ICEInputStream>, BOOL) = ^(id<ICEInputStream>, BOOL) { + if(response) + { + response(); + } + }; + return [self begin_invoke__:op + mode:mode + format:format + marshal:marshal + returnsData:NO + completed:completed + response:TRUE + exception:exception + sent:sent + context:ctx]; +} + +-(id<ICEAsyncResult>) begin_invoke__:(NSString*)op + mode:(ICEOperationMode)mode + format:(ICEFormatType)format + marshal:(void(^)(id<ICEOutputStream>))marshal + completed:(void(^)(id<ICEInputStream>, BOOL))completed + response:(BOOL)response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent + context:(ICEContext*)ctx +{ + return [self begin_invoke__:op + mode:mode + format:format + marshal:marshal + returnsData:TRUE + completed:completed + response:response + exception:exception + sent:sent context:ctx]; +} + +-(void)end_invoke__:(NSString*)operation unmarshal:(ICEUnmarshalCB)unmarshal result:(id<ICEAsyncResult>)r +{ + ICEAsyncResult* result = (ICEAsyncResult*)r; + if(operation != [result operation]) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:[NSString stringWithFormat:@"Incorrect operation for end_%@ method: %@", + operation, [result operation]] + userInfo:nil]; + } + if(result == nil) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException + reason:@"ICEAsyncResult is nil" + userInfo:nil]; + } + + BOOL ok = YES; // Keep the compiler happy. + NSException* nsex = nil; + ICEInputStream* is = nil; + try + { + std::vector<Ice::Byte> outParams; + ok = OBJECTPRX->end_ice_invoke(outParams, [result asyncResult__]); + + if(unmarshal) + { + Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams); + is = [ICEInputStream localObjectWithCxxObjectNoAutoRelease:s.get()]; + } + else if(!outParams.empty()) + { + if(ok) + { + if(outParams.size() != 6) + { + throw Ice::EncapsulationException(__FILE__, __LINE__); + } + } + else + { + Ice::InputStreamPtr s = Ice::createInputStream(OBJECTPRX->ice_getCommunicator(), outParams); + try + { + s->startEncapsulation(); + s->throwException(); + } + catch(const Ice::UserException& ex) + { + s->endEncapsulation(); + throw Ice::UnknownUserException(__FILE__, __LINE__, ex.ice_name()); + } + } + } + } + catch(const std::exception& ex) + { + if(is != nil) + { + [is release]; + is = nil; + } + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + + if(is != nil) + { + @try + { + unmarshal(is, ok); + } + @finally + { + [is release]; + } + } +} + +-(id) copyWithZone:(NSZone *)zone +{ + return [self retain]; +} + +-(NSUInteger) hash +{ + return (NSUInteger)OBJECTPRX->__hash(); +} +-(NSString*) description +{ + return [toNSString(OBJECTPRX->ice_toString()) autorelease]; +} +-(BOOL) isEqual:(id)o_ +{ + if(self == o_) + { + return YES; + } + if(!o_ || ![o_ isKindOfClass:[ICEObjectPrx class]]) + { + return NO; + } + return *OBJECTPRX == *[o_ objectPrx__]; +} + +-(NSComparisonResult) compareIdentity:(id<ICEObjectPrx>)aProxy +{ + IceProxy::Ice::Object* lhs = OBJECTPRX; + IceProxy::Ice::Object* rhs = [(ICEObjectPrx*)aProxy objectPrx__]; + if(Ice::proxyIdentityEqual(lhs, rhs)) + { + return NSOrderedSame; + } + else if(Ice::proxyIdentityLess(lhs, rhs)) + { + return NSOrderedAscending; + } + else + { + return NSOrderedDescending; + } +} + +-(NSComparisonResult) compareIdentityAndFacet:(id<ICEObjectPrx>)aProxy +{ + IceProxy::Ice::Object* lhs = OBJECTPRX; + IceProxy::Ice::Object* rhs = [(ICEObjectPrx*)aProxy objectPrx__]; + if(Ice::proxyIdentityAndFacetEqual(lhs, rhs)) + { + return NSOrderedSame; + } + else if(Ice::proxyIdentityAndFacetLess(lhs, rhs)) + { + return NSOrderedAscending; + } + else + { + return NSOrderedDescending; + } +} + +-(id<ICECommunicator>) ice_getCommunicator +{ + return [[communicator__ retain] autorelease]; +} + +-(NSMutableString*) ice_toString +{ + return [toNSMutableString(OBJECTPRX->ice_toString()) autorelease]; +} + +-(BOOL) ice_isA:(NSString*)typeId +{ + __block BOOL ret__; + cppCall(^ { ret__ = OBJECTPRX->ice_isA(fromNSString(typeId)); }); + return ret__; +} +-(BOOL) ice_isA:(NSString*)typeId context:(ICEContext*)context +{ + __block BOOL ret__; + cppCall(^(const Ice::Context& ctx) { ret__ = OBJECTPRX->ice_isA(fromNSString(typeId), ctx); }, context); + return ret__; +} +-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) + { + result = OBJECTPRX->begin_ice_isA(fromNSString(typeId)); + }, self); +} +-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId context:(ICEContext*)context +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx) + { + result = OBJECTPRX->begin_ice_isA(fromNSString(typeId), ctx); + }, context, self); +} +-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId + response:(void(^)(BOOL))response + exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_isA:typeId response:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId + context:(ICEContext*)context + response:(void(^)(BOOL))response + exception:(void(^)(ICEException*))exception + +{ + return [self begin_ice_isA:typeId context:context response:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId + response:(void(^)(BOOL))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_isA(fromNSString(typeId), cb); + }, + ^(const Ice::AsyncResultPtr& result) { + BOOL ret__ = OBJECTPRX->end_ice_isA(result); + if(response) + { + response(ret__); + } + }, + exception, sent, self); + +} +-(id<ICEAsyncResult>) begin_ice_isA:(NSString*)typeId + context:(ICEContext*)context + response:(void(^)(BOOL))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_isA(fromNSString(typeId), ctx, cb); + }, + context, + ^(const Ice::AsyncResultPtr& result) { + BOOL ret__ = OBJECTPRX->end_ice_isA(result); + if(response) + { + response(ret__); + } + }, + exception, sent, self); +} +-(BOOL) end_ice_isA:(id<ICEAsyncResult>)result +{ + __block BOOL ret__; + endCppCall(^(const Ice::AsyncResultPtr& r) { ret__ = OBJECTPRX->end_ice_isA(r); }, result); + return ret__; +} + +-(void) ice_ping +{ + cppCall(^ { OBJECTPRX->ice_ping(); }); +} +-(void) ice_ping:(ICEContext*)context +{ + cppCall(^(const Ice::Context& ctx) { OBJECTPRX->ice_ping(ctx); }, context); +} +-(id<ICEAsyncResult>) begin_ice_ping +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) { result = OBJECTPRX->begin_ice_ping(); }, self); +} +-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx) + { + result = OBJECTPRX->begin_ice_ping(ctx); + }, context, self); +} + +-(id<ICEAsyncResult>) begin_ice_ping:(void(^)())response exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_ping:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context + response:(void(^)())response + exception:(void(^)(ICEException*))exception + +{ + return [self begin_ice_ping:context response:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_ping:(void(^)())response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_ping(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + OBJECTPRX->end_ice_ping(result); + if(response) + { + response(); + } + }, + exception, sent, self); +} + +-(id<ICEAsyncResult>) begin_ice_ping:(ICEContext*)context + response:(void(^)())response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_ping(ctx, cb); + }, + context, + ^(const Ice::AsyncResultPtr& result) { + OBJECTPRX->end_ice_ping(result); + if(response) + { + response(); + } + }, + exception, sent, self); +} +-(void) end_ice_ping:(id<ICEAsyncResult>)result +{ + endCppCall(^(const Ice::AsyncResultPtr& r) { OBJECTPRX->end_ice_ping(r); }, result); +} + +-(NSMutableArray*) ice_ids +{ + __block NSMutableArray* ret__; + cppCall(^ { ret__ = [toNSArray(OBJECTPRX->ice_ids()) autorelease]; }); + return ret__; +} +-(NSMutableArray*) ice_ids:(ICEContext*)context +{ + __block NSMutableArray* ret__; + cppCall(^(const Ice::Context& ctx) { ret__ = [toNSArray(OBJECTPRX->ice_ids(ctx)) autorelease]; }, context); + return ret__; +} +-(id<ICEAsyncResult>) begin_ice_ids +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) { result = OBJECTPRX->begin_ice_ids(); } , self); +} + +-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx) + { + result = OBJECTPRX->begin_ice_ids(ctx); + }, context, self); +} +-(id<ICEAsyncResult>) begin_ice_ids:(void(^)(NSArray*))response exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_ids:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context + response:(void(^)(NSArray*))response + exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_ids:context response:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_ids:(void(^)(NSArray*))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_ids(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + NSMutableArray* ret__ = [toNSArray(OBJECTPRX->end_ice_ids(result)) autorelease]; + if(response) + { + response(ret__); + } + }, + exception, sent, self); +} +-(id<ICEAsyncResult>) begin_ice_ids:(ICEContext*)context + response:(void(^)(NSArray*))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_ids(ctx, cb); + }, + context, + ^(const Ice::AsyncResultPtr& result) { + NSMutableArray* ret__ = [toNSArray(OBJECTPRX->end_ice_ids(result)) autorelease]; + if(response) + { + response(ret__); + } + }, + exception, sent, self); +} +-(NSMutableArray*) end_ice_ids:(id<ICEAsyncResult>)result +{ + __block NSMutableArray* ret__; + endCppCall(^(const Ice::AsyncResultPtr& r) { ret__ = [toNSArray(OBJECTPRX->end_ice_ids(r)) autorelease]; }, result); + return ret__; +} + +-(NSMutableString*) ice_id +{ + __block NSMutableString* ret__; + cppCall(^ { ret__ = [toNSMutableString(OBJECTPRX->ice_id()) autorelease]; }); + return ret__; +} +-(NSMutableString*) ice_id:(ICEContext*)context +{ + __block NSMutableString* ret__; + cppCall(^(const Ice::Context& ctx) { ret__ = [toNSMutableString(OBJECTPRX->ice_id(ctx)) autorelease]; }, context); + return ret__; +} +-(id<ICEAsyncResult>) begin_ice_id +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) { result = OBJECTPRX->begin_ice_id(); } , self); +} +-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx) + { + result = OBJECTPRX->begin_ice_id(ctx); + }, context, self); +} +-(id<ICEAsyncResult>) begin_ice_id:(void(^)(NSString*))response exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_id:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context + response:(void(^)(NSString*))response + exception:(void(^)(ICEException*))exception + +{ + return [self begin_ice_id:context response:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_id:(void(^)(NSString*))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_id(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + NSString* ret__ = [toNSString(OBJECTPRX->end_ice_id(result)) autorelease]; + if(response) + { + response(ret__); + } + }, + exception, sent, self); +} +-(id<ICEAsyncResult>) begin_ice_id:(ICEContext*)context + response:(void(^)(NSString*))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_id(ctx, cb); + }, + context, + ^(const Ice::AsyncResultPtr& result) { + NSString* ret__ = [toNSString(OBJECTPRX->end_ice_id(result)) autorelease]; + if(response) + { + response(ret__); + } + }, + exception, sent, self); +} +-(NSMutableString*) end_ice_id:(id<ICEAsyncResult>)result +{ + __block NSMutableString* ret__; + endCppCall(^(const Ice::AsyncResultPtr& r) { ret__ = [toNSMutableString(OBJECTPRX->end_ice_id(r)) autorelease]; }, + result); + return ret__; +} + +-(BOOL) ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + outEncaps:(NSMutableData**)outEncaps +{ + __block BOOL ret__; + cppCall(^ { + std::pair<const Ice::Byte*, const Ice::Byte*> inP((ICEByte*)[inEncaps bytes], + (ICEByte*)[inEncaps bytes] + [inEncaps length]); + std::vector<Ice::Byte> outP; + ret__ = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inP, outP); + *outEncaps = [NSMutableData dataWithBytes:&outP[0] length:outP.size()]; + }); + return ret__; +} + +-(BOOL) ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + outEncaps:(NSMutableData**)outEncaps + context:(ICEContext*)context +{ + __block BOOL ret__; + cppCall(^(const Ice::Context& ctx) { + std::pair<const Ice::Byte*, const Ice::Byte*> inP((ICEByte*)[inEncaps bytes], + (ICEByte*)[inEncaps bytes] + [inEncaps length]); + std::vector<Ice::Byte> outP; + ret__ = OBJECTPRX->ice_invoke(fromNSString(operation), (Ice::OperationMode)mode, inP, outP, ctx); + *outEncaps = [NSMutableData dataWithBytes:&outP[0] length:outP.size()]; + }, context); + return ret__; +} +-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation mode:(ICEOperationMode)mode inEncaps:(NSData*)inEncaps +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) + { + std::pair<const Ice::Byte*, const Ice::Byte*> + inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]); + result = OBJECTPRX->begin_ice_invoke(fromNSString(operation), + (Ice::OperationMode)mode, + inP); + }, self); +} +-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + context:(ICEContext*)context +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx) + { + std::pair<const Ice::Byte*, const Ice::Byte*> + inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]); + result = OBJECTPRX->begin_ice_invoke(fromNSString(operation), + (Ice::OperationMode)mode, + inP, + ctx); + }, context, self); +} +-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + response:(void(^)(BOOL, NSMutableData*))response + exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_invoke:operation mode:mode inEncaps:inEncaps response:response exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + context:(ICEContext*)context + response:(void(^)(BOOL, NSMutableData*))response + exception:(void(^)(ICEException*))exception +{ + return [self begin_ice_invoke:operation mode:mode inEncaps:inEncaps context:context response:response + exception:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + response:(void(^)(BOOL, NSMutableData*))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + std::pair<const Ice::Byte*, const Ice::Byte*> + inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]); + result = OBJECTPRX->begin_ice_invoke(fromNSString(operation), + (Ice::OperationMode)mode, + inP, + cb); + }, + ^(const Ice::AsyncResultPtr& result) { + std::pair<const ::Ice::Byte*, const ::Ice::Byte*> outP; + BOOL ret__ = OBJECTPRX->___end_ice_invoke(outP, result); + NSMutableData* outEncaps = + [NSMutableData dataWithBytes:outP.first length:(outP.second - outP.first)]; + if(response) + { + response(ret__, outEncaps); + } + }, + exception, sent, self); +} +-(id<ICEAsyncResult>) begin_ice_invoke:(NSString*)operation + mode:(ICEOperationMode)mode + inEncaps:(NSData*)inEncaps + context:(ICEContext*)context + response:(void(^)(BOOL, NSMutableData*))response + exception:(void(^)(ICEException*))exception + sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::Context& ctx, const Ice::CallbackPtr& cb) + { + std::pair<const Ice::Byte*, const Ice::Byte*> + inP((ICEByte*)[inEncaps bytes], (ICEByte*)[inEncaps bytes] + [inEncaps length]); + result = OBJECTPRX->begin_ice_invoke(fromNSString(operation), + (Ice::OperationMode)mode, + inP, + ctx, + cb); + }, + context, + ^(const Ice::AsyncResultPtr& result) { + std::pair<const ::Ice::Byte*, const ::Ice::Byte*> outP; + BOOL ret__ = OBJECTPRX->___end_ice_invoke(outP, result); + NSMutableData* outEncaps = + [NSMutableData dataWithBytes:outP.first length:(outP.second - outP.first)]; + if(response) + { + response(ret__, outEncaps); + } + }, + exception, sent, self); +} +-(BOOL) end_ice_invoke:(NSMutableData**)outEncaps result:(id<ICEAsyncResult>)result + +{ + __block BOOL ret__; + endCppCall(^(const Ice::AsyncResultPtr& r) + { + std::vector<Ice::Byte> outP; + ret__ = OBJECTPRX->end_ice_invoke(outP, r); + *outEncaps = [NSMutableData dataWithBytes:&outP[0] length:outP.size()]; + }, result); + return ret__; +} + +-(ICEIdentity*) ice_getIdentity +{ + return [ICEIdentity identityWithIdentity:OBJECTPRX->ice_getIdentity()]; +} +-(id) ice_identity:(ICEIdentity*)identity +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_identity([identity identity])]; +} +-(ICEMutableContext*) ice_getContext +{ + return [toNSDictionary(OBJECTPRX->ice_getContext()) autorelease]; +} +-(id) ice_context:(ICEContext*)context +{ + Ice::Context ctx; + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_context(fromNSDictionary(context, ctx))]; +} +-(NSMutableString*) ice_getFacet +{ + return [toNSMutableString(OBJECTPRX->ice_getFacet()) autorelease]; +} +-(id) ice_facet:(NSString*)facet +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_facet(fromNSString(facet))]; +} +-(NSMutableString*) ice_getAdapterId +{ + return [toNSMutableString(OBJECTPRX->ice_getAdapterId()) autorelease]; +} + +-(ICEMutableEndpointSeq*) ice_getEndpoints +{ + return [toNSArray(OBJECTPRX->ice_getEndpoints()) autorelease]; +} + +-(id) ice_endpoints:(ICEEndpointSeq*)endpoints +{ + Ice::EndpointSeq cxxEndpoints; + fromNSArray(endpoints, cxxEndpoints); + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_endpoints(cxxEndpoints)]; +} + +-(id) ice_adapterId:(NSString*)adapterId +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_adapterId(fromNSString(adapterId))]; +} + +-(ICEInt) ice_getLocatorCacheTimeout +{ + return OBJECTPRX->ice_getLocatorCacheTimeout(); +} +-(id) ice_locatorCacheTimeout:(ICEInt)timeout +{ + NSException* nsex; + try + { + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_locatorCacheTimeout(timeout)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(BOOL) ice_isConnectionCached +{ + return OBJECTPRX->ice_isConnectionCached(); +} +-(id) ice_connectionCached:(BOOL)cached +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_connectionCached(cached)]; +} +-(ICEEndpointSelectionType) ice_getEndpointSelection +{ + return (ICEEndpointSelectionType)OBJECTPRX->ice_getEndpointSelection(); +} +-(id) ice_endpointSelection:(ICEEndpointSelectionType)type +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_endpointSelection((Ice::EndpointSelectionType)type)]; +} +-(BOOL) ice_isSecure +{ + return OBJECTPRX->ice_isSecure(); +} +-(id) ice_secure:(BOOL)secure +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_secure(secure)]; +} + +-(ICEEncodingVersion*) ice_getEncodingVersion +{ + return [ICEEncodingVersion encodingVersionWithEncodingVersion:OBJECTPRX->ice_getEncodingVersion()]; +} + +-(id) ice_encodingVersion:(ICEEncodingVersion*)encoding; +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_encodingVersion([encoding encodingVersion])]; +} + +-(BOOL) ice_isPreferSecure +{ + return OBJECTPRX->ice_isPreferSecure(); +} +-(id) ice_preferSecure:(BOOL)preferSecure +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_preferSecure(preferSecure)]; +} +-(id<ICERouterPrx>) ice_getRouter +{ + return (id<ICERouterPrx>)[ICERouterPrx objectPrxWithObjectPrx__:OBJECTPRX->ice_getRouter()]; +} +-(id) ice_router:(id<ICERouterPrx>)router +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_router( + Ice::RouterPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)router objectPrx__])))]; +} +-(id<ICELocatorPrx>) ice_getLocator +{ + return (id<ICELocatorPrx>)[ICELocatorPrx objectPrxWithObjectPrx__:OBJECTPRX->ice_getLocator()]; +} +-(id) ice_locator:(id<ICELocatorPrx>)locator +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_locator( + Ice::LocatorPrx::uncheckedCast(Ice::ObjectPrx([(ICEObjectPrx*)locator objectPrx__])))]; +} +-(BOOL) ice_isCollocationOptimized +{ + return OBJECTPRX->ice_isCollocationOptimized(); +} +-(id) ice_collocationOptimized:(BOOL)collocOptimized +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_collocationOptimized(collocOptimized)]; +} +-(ICEInt) ice_getInvocationTimeout +{ + return OBJECTPRX->ice_getInvocationTimeout(); +} +-(id) ice_invocationTimeout:(ICEInt)timeout +{ + NSException* nsex; + try + { + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_invocationTimeout(timeout)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(id) ice_twoway +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_twoway()]; +} +-(BOOL) ice_isTwoway +{ + return OBJECTPRX->ice_isTwoway(); +} +-(id) ice_oneway +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_oneway()]; +} +-(BOOL) ice_isOneway +{ + return OBJECTPRX->ice_isOneway(); +} +-(id) ice_batchOneway +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_batchOneway()]; +} +-(BOOL) ice_isBatchOneway +{ + return OBJECTPRX->ice_isBatchOneway(); +} +-(id) ice_datagram +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_datagram()]; +} +-(BOOL) ice_isDatagram +{ + return OBJECTPRX->ice_isDatagram(); +} +-(id) ice_batchDatagram +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_batchDatagram()]; +} +-(BOOL) ice_isBatchDatagram +{ + return OBJECTPRX->ice_isBatchDatagram(); +} +-(id) ice_compress:(BOOL)compress +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_compress(compress)]; +} +-(id) ice_timeout:(int)timeout +{ + NSException* nsex; + try + { + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_timeout(timeout)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} +-(id) ice_connectionId:(NSString*)connectionId +{ + return [[self class] objectPrxWithObjectPrx__:OBJECTPRX->ice_connectionId(fromNSString(connectionId))]; +} +-(id<ICEConnection>) ice_getConnection +{ + NSException* nsex = nil; + try + { + return [ICEConnection localObjectWithCxxObject:OBJECTPRX->ice_getConnection().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(id<ICEAsyncResult>) begin_ice_getConnection +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) + { + result = OBJECTPRX->begin_ice_getConnection(); + }, self); +} +-(id<ICEAsyncResult>) begin_ice_getConnection:(void(^)(id<ICEConnection>))response + exception:(void(^)(ICEException*))exception +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_getConnection(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + id<ICEConnection> ret__ = + [ICEConnection localObjectWithCxxObject:OBJECTPRX->end_ice_getConnection(result).get()]; + if(response) + { + response(ret__); + } + }, + exception, nil, self); +} +-(id<ICEConnection>) end_ice_getConnection:(id<ICEAsyncResult>)result +{ + __block id<ICEConnection> ret__; + endCppCall(^(const Ice::AsyncResultPtr& r) + { + ret__ = [ICEConnection localObjectWithCxxObject:OBJECTPRX->end_ice_getConnection(r).get()]; + }, result); + return ret__; +} + +-(id<ICEConnection>) ice_getCachedConnection +{ + NSException* nsex = nil; + try + { + return [ICEConnection localObjectWithCxxObject:OBJECTPRX->ice_getCachedConnection().get()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) ice_flushBatchRequests +{ + NSException* nsex = nil; + try + { + OBJECTPRX->ice_flushBatchRequests(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(id<ICEAsyncResult>) begin_ice_flushBatchRequests +{ + return beginCppCall(^(Ice::AsyncResultPtr& result) + { + result = OBJECTPRX->begin_ice_flushBatchRequests(); + }, self); +} +-(id<ICEAsyncResult>) begin_ice_flushBatchRequests:(void(^)(ICEException*))exception +{ + return [self begin_ice_flushBatchRequests:exception sent:nil]; +} +-(id<ICEAsyncResult>) begin_ice_flushBatchRequests:(void(^)(ICEException*))exception sent:(void(^)(BOOL))sent +{ + return beginCppCall(^(Ice::AsyncResultPtr& result, const Ice::CallbackPtr& cb) + { + result = OBJECTPRX->begin_ice_flushBatchRequests(cb); + }, + ^(const Ice::AsyncResultPtr& result) { + OBJECTPRX->end_ice_flushBatchRequests(result); + }, + exception, sent, self); +} +-(void) end_ice_flushBatchRequests:(id<ICEAsyncResult>)result +{ + endCppCall(^(const Ice::AsyncResultPtr& r) + { + OBJECTPRX->end_ice_flushBatchRequests(r); + }, result); +} +@end diff --git a/objective-c/src/Ice/ProxyI.h b/objective-c/src/Ice/ProxyI.h new file mode 100644 index 00000000000..934ed6de73c --- /dev/null +++ b/objective-c/src/Ice/ProxyI.h @@ -0,0 +1,32 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Proxy.h> + +#include <Ice/Proxy.h> + +@interface ICEAsyncResult : NSObject<ICEAsyncResult> +{ +@private + void* asyncResult__; + NSString* operation_; + id<ICEObjectPrx> proxy_; +} +-(ICEAsyncResult*)initWithAsyncResult__:(const Ice::AsyncResultPtr&)arg operation:(NSString*)op proxy:(id<ICEObjectPrx>)p; +-(Ice::AsyncResult*) asyncResult__; ++(ICEAsyncResult*)asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg; ++(ICEAsyncResult*)asyncResultWithAsyncResult__:(const Ice::AsyncResultPtr&)arg operation:(NSString*)op proxy:(id<ICEObjectPrx>)p; +-(NSString*)operation; +@end + +@interface ICEObjectPrx () +-(ICEObjectPrx*)initWithObjectPrx__:(const Ice::ObjectPrx&)arg; +-(IceProxy::Ice::Object*) objectPrx__; ++(ICEObjectPrx*)objectPrxWithObjectPrx__:(const Ice::ObjectPrx&)arg; +@end diff --git a/objective-c/src/Ice/Request.h b/objective-c/src/Ice/Request.h new file mode 100644 index 00000000000..0f07ca48331 --- /dev/null +++ b/objective-c/src/Ice/Request.h @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Object.h> + +@interface ICERequest : NSObject<ICERequest> +{ + @private + ICECurrent* current; + id<ICEInputStream> is; + id<ICEOutputStream> os; + BOOL needReset; +} ++(id) request:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os; +-(id) init:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os; +-(BOOL) callDispatch:(ICEServant*)servant; +@end diff --git a/objective-c/src/Ice/Request.m b/objective-c/src/Ice/Request.m new file mode 100644 index 00000000000..8d60870e177 --- /dev/null +++ b/objective-c/src/Ice/Request.m @@ -0,0 +1,59 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <Request.h> + +@implementation ICERequest +-(ICECurrent*) getCurrent +{ + return current; +} + ++(id) request:(ICECurrent*)current is:(id<ICEInputStream>)is os:(id<ICEOutputStream>)os +{ + ICERequest* result = [((ICERequest*)[ICERequest alloc]) init:current is:is os:os]; + [result autorelease]; + return result; +} + +-(id) init:(ICECurrent*)current_ is:(id<ICEInputStream>)is_ os:(id<ICEOutputStream>)os_ +{ + if(![super init]) + { + return nil; + } + current = [current_ retain]; + is = [is_ retain]; + os = [os_ retain]; + needReset = NO; + return self; +} + +-(BOOL) callDispatch:(ICEServant*)servant +{ + if(needReset == NO) + { + needReset = YES; + } + else + { + [is rewind]; + [os reset:NO]; + } + return [servant dispatch__:current is:is os:os]; +} + +-(void) dealloc +{ + [current release]; + [is release]; + [os release]; + [super dealloc]; +} +@end diff --git a/objective-c/src/Ice/SlicedData.mm b/objective-c/src/Ice/SlicedData.mm new file mode 100644 index 00000000000..91bb70a7da6 --- /dev/null +++ b/objective-c/src/Ice/SlicedData.mm @@ -0,0 +1,89 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in +// the ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <SlicedDataI.h> +#import <Util.h> + +#import <Ice/SlicedData.h> + +@implementation ICESlicedData + +-(id) initWithSlicedData:(Ice::SlicedData*)slicedData +{ + self = [super init]; + if(!self) + { + return nil; + } + self->slicedData__ = slicedData; + self->slicedData__->__incRef(); + return self; +} + +-(void) dealloc +{ + self->slicedData__->__decRef(); + [super dealloc]; +} + +-(Ice::SlicedData*) slicedData +{ + return slicedData__; +} + +@end + +@implementation ICEUnknownSlicedObject + +-(id) init +{ + self = [super init]; + if(!self) + { + return nil; + } + self->unknownTypeId_ = nil; + self->slicedData_ = nil; + return self; +} + +-(void) dealloc +{ + [slicedData_ release]; + [unknownTypeId_ release]; + [super dealloc]; +} + +-(NSString*) getUnknownTypeId +{ + return [[unknownTypeId_ retain] autorelease]; +} + +-(ICESlicedData*) getSlicedData +{ + return [[slicedData_ retain] autorelease]; +} + +-(void) write__:(id<ICEOutputStream>)os +{ + [os startObject:slicedData_]; + [os endObject]; +} + +-(void) read__:(id<ICEInputStream>)is +{ + [is startObject]; + slicedData_ = [is endObject:YES]; + + // Initialize unknown type ID to type ID of first slice. + Ice::SlicedData* slicedData = [((ICESlicedData*)slicedData_) slicedData]; + assert(!slicedData->slices.empty()); + unknownTypeId_ = toNSString(slicedData->slices[0]->typeId); +} +@end diff --git a/objective-c/src/Ice/SlicedDataI.h b/objective-c/src/Ice/SlicedDataI.h new file mode 100644 index 00000000000..933c589ad2d --- /dev/null +++ b/objective-c/src/Ice/SlicedDataI.h @@ -0,0 +1,21 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in +// the ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/SlicedData.h> + +#include <Ice/SlicedData.h> + +@interface ICESlicedData : NSObject<ICESlicedData> +{ +@private + Ice::SlicedData* slicedData__; +} +-(id) initWithSlicedData:(Ice::SlicedData*)slicedData; +-(Ice::SlicedData*) slicedData; +@end diff --git a/objective-c/src/Ice/Stream.mm b/objective-c/src/Ice/Stream.mm new file mode 100644 index 00000000000..2890833320c --- /dev/null +++ b/objective-c/src/Ice/Stream.mm @@ -0,0 +1,3450 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <StreamI.h> +#import <CommunicatorI.h> +#import <ProxyI.h> +#import <Util.h> +#import <ObjectI.h> +#import <SlicedDataI.h> +#import <VersionI.h> +#import <LocalObjectI.h> + +#import <objc/Ice/LocalException.h> + +#include <Ice/Stream.h> +#include <Ice/SlicedData.h> + +#import <objc/runtime.h> + +ICE_API id ICENone = nil; + +namespace IceObjC +{ + +class ObjectWriter : public Ice::ObjectWriter +{ +public: + + ObjectWriter(ICEObject* obj, ICEOutputStream* stream) : _obj(obj), _stream(stream) + { + } + + virtual void + write(const Ice::OutputStreamPtr& stream) const + { + @try + { + [_obj write__:_stream]; + } + @catch(id ex) + { + rethrowCxxException(ex); + } + } + + virtual void ice_preMarshal() + { + [_obj ice_preMarshal]; + } + +private: + + ICEObject* _obj; + ICEOutputStream* _stream; +}; + +class ObjectReader : public Ice::ObjectReader +{ +public: + + // We must explicitely CFRetain/CFRelease so that the garbage + // collector does not trash the _obj. + ObjectReader(ICEObject* obj) : _obj(obj) + { + CFRetain(_obj); + } + + virtual ~ObjectReader() + { + CFRelease(_obj); + } + + virtual void + read(const Ice::InputStreamPtr& stream) + { + @try + { + // + // TODO: explain why calling getLocalObjectWithCxxObjectNoAutoRelease is safe here + // + ICEInputStream* is = [ICEInputStream getLocalObjectWithCxxObjectNoAutoRelease:stream.get()]; + assert(is != 0); + [_obj read__:is]; + } + @catch(id ex) + { + rethrowCxxException(ex); + } + } + + ICEObject* + getObject() + { + return _obj; + } + + virtual void ice_postUnmarshal() + { + [_obj ice_postUnmarshal]; + } + +private: + + ICEObject* _obj; +}; +typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr; + +class ReadObjectBase : public Ice::ReadObjectCallback +{ +public: + + ReadObjectBase(Class expectedType) : _expectedType(expectedType) + { + } + + void checkType(ICEObject*); + +private: + + Class _expectedType; +}; + +void +ReadObjectBase::checkType(ICEObject* o) +{ + if(o != nil && ![o isKindOfClass:_expectedType]) + { + NSString* actualType = [o ice_id]; + NSString* expectedType = [_expectedType ice_staticId]; + NSString* reason = [NSString stringWithFormat:@"expected element of type `%@' but received `%@'", + expectedType, actualType]; + + @throw [ICEUnexpectedObjectException unexpectedObjectException:__FILE__ + line:__LINE__ + reason:reason + type:actualType + expectedType:expectedType]; + } +} + +class ReadObject : public ReadObjectBase +{ +public: + + ReadObject(ICEObject** addr, Class expectedType, bool autorelease) : + ReadObjectBase(expectedType), _addr(addr), _autorelease(autorelease) + { + } + + virtual void + invoke(const Ice::ObjectPtr& obj) + { + @try + { + if(obj) + { + ICEObject* o = ObjectReaderPtr::dynamicCast(obj)->getObject(); + checkType(o); + *_addr = [o retain]; + if(_autorelease) + { + [*_addr autorelease]; + } + } + else + { + *_addr = nil; + } + } + @catch(id ex) + { + rethrowCxxException(ex); + } + } + +private: + + ICEObject** _addr; + bool _autorelease; +}; + +class ReadObjectAtIndex : public ReadObjectBase +{ +public: + + ReadObjectAtIndex(NSMutableArray* array, ICEInt index, Class expectedType) : + ReadObjectBase(expectedType), _array(array), _index(index) + { + } + + virtual void + invoke(const Ice::ObjectPtr& obj) + { + @try + { + if(obj) + { + ICEObject* o = ObjectReaderPtr::dynamicCast(obj)->getObject(); + checkType(o); + [_array replaceObjectAtIndex:_index withObject:o]; + } + } + @catch(id ex) + { + rethrowCxxException(ex); + } + } + +private: + + NSMutableArray* _array; + ICEInt _index; +}; + +class ReadObjectForKey : public ReadObjectBase +{ +public: + + // We must explicitely CFRetain/CFRelease so that the garbage + // collector does not trash the _key. + ReadObjectForKey(NSMutableDictionary* dict, id key, Class expectedType) : + ReadObjectBase(expectedType), _dict(dict), _key(key) + { + CFRetain(_key); + } + + virtual ~ReadObjectForKey() + { + CFRelease(_key); + } + + virtual void + invoke(const Ice::ObjectPtr& obj) + { + @try + { + if(obj) + { + ICEObject* o = ObjectReaderPtr::dynamicCast(obj)->getObject(); + checkType(o); + [_dict setObject:o forKey:_key]; + } + else + { + [_dict setObject:[NSNull null] forKey:_key]; + } + } + @catch(id ex) + { + rethrowCxxException(ex); + } + } + +private: + + NSMutableDictionary* _dict; + id _key; +}; + +class ExceptionWriter : public Ice::UserExceptionWriter +{ +public: + + ExceptionWriter(const Ice::CommunicatorPtr& communicator, ICEOutputStream* stream, ICEUserException* ex) : + Ice::UserExceptionWriter(communicator), + _stream(stream), + _ex(ex) + { + + } + + virtual bool + usesClasses() const + { + return [_ex usesClasses__]; + } + + virtual std::string + ice_name() const + { + return [[_ex ice_name] UTF8String]; + } + + virtual Ice::UserException* + ice_clone() const + { + return new ExceptionWriter(*this); + } + + virtual void + ice_throw() const + { + throw *this; + } + + virtual void + write(const Ice::OutputStreamPtr& stream) const + { + [_ex write__:_stream]; + } + +private: + + ICEOutputStream* _stream; + ICEUserException* _ex; +}; + +class ExceptionReader : public Ice::UserExceptionReader +{ +public: + + ExceptionReader(const Ice::CommunicatorPtr& communicator, ICEInputStream* stream, ICEUserException* ex) : + Ice::UserExceptionReader(communicator), + _stream(stream), + _ex(ex) + { + } + + void + read(const Ice::InputStreamPtr& stream) const + { + [_ex read__:_stream]; + } + + virtual std::string + ice_name() const + { + return [[_ex ice_name] UTF8String]; + } + + virtual bool + usesClasses() const + { + return [_ex usesClasses__]; + } + + virtual Ice::UserException* + ice_clone() const + { + assert(false); + return 0; + } + + virtual void + ice_throw() const + { + throw *this; + } + + ICEUserException* getException() const + { + return _ex; + } + +private: + + ICEInputStream* _stream; + ICEUserException* _ex; +}; + +class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory +{ +public: + + UserExceptionReaderFactoryI(const Ice::CommunicatorPtr& communicator, ICEInputStream* is) : + _communicator(communicator), + _is(is) + { + } + + virtual void createAndThrow(const std::string& typeId) const + { + ICEUserException* ex = nil; + std::string objcId = toObjCSliceId(typeId, + [[ICECommunicator localObjectWithCxxObject:_communicator.get()] getPrefixTable]); + Class c = objc_lookUpClass(objcId.c_str()); + if(c != nil) + { + ex = [[c alloc] init]; + throw ExceptionReader(_communicator, _is, ex); + } + } + +private: + + Ice::CommunicatorPtr _communicator; + ICEInputStream* _is; +}; + +} + +@implementation ICEInternalPrefixTable +@end + +@interface ICEInternalNone : NSObject +@end + +@implementation ICEInternalNone ++(void)load +{ + ICENone = [[ICEInternalNone alloc] init]; +} +-(id) copyWithZone:(NSZone *)zone +{ + return self; +} +-(id) retain +{ + return self; +} +-(NSUInteger) retainCount +{ + return NSUIntegerMax; +} +-(oneway void) release +{ +} +-(id) autorelease +{ + return self; +} +@end + +@implementation ICEInputStream +-(id) initWithCxxObject:(IceUtil::Shared*)cxxObject +{ + self = [super initWithCxxObject:cxxObject]; + if(!self) + { + return nil; + } + is_ = dynamic_cast<Ice::InputStream*>(cxxObject); + return self; +} + ++(Ice::Object*)createObjectReader:(ICEObject*)obj +{ + return new IceObjC::ObjectReader(obj); +} + +-(Ice::InputStream*) is +{ + return is_; +} + +// @protocol ICEInputStream methods + +-(id<ICECommunicator>) communicator +{ + return [ICECommunicator localObjectWithCxxObject:is_->communicator().get()]; +} + +-(void) sliceObjects:(BOOL)b +{ + NSException* nsex = nil; + try + { + is_->sliceObjects(b); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(BOOL)readBool +{ + NSException* nsex = nil; + try + { + bool value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return NO; // Keep the compiler happy. +} + +-(NSMutableData*) readBoolSeq +{ + return [[self newBoolSeq] autorelease]; +} + +-(NSMutableData*) newBoolSeq +{ + NSException* nsex = nil; + try + { + std::pair<const bool*, const bool*> seq; + IceUtil::ScopedArray<bool> result; + is_->read(seq, result); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(BOOL)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEByte) readByte +{ + NSException* nsex = nil; + try + { + Ice::Byte value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} + +-(NSMutableData*) readByteSeq +{ + return [[self newByteSeq] autorelease]; +} + +-(NSMutableData*) newByteSeq +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Byte*, const Ice::Byte*> seq; + is_->read(seq); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +-(NSData*) readByteSeqNoCopy +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Byte*, const Ice::Byte*> seq; + is_->read(seq); + return [NSData dataWithBytesNoCopy:const_cast<Ice::Byte*>(seq.first) + length:(seq.second - seq.first) freeWhenDone:NO]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEShort) readShort +{ + NSException* nsex = nil; + try + { + Ice::Short value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} + +-(NSMutableData*) readShortSeq +{ + return [[self newShortSeq] autorelease]; +} + +-(NSMutableData*) newShortSeq +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Short*, const Ice::Short*> seq; + IceUtil::ScopedArray<Ice::Short> result; + is_->read(seq, result); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEShort)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEInt) readInt +{ + NSException* nsex = nil; + try + { + Ice::Int value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} + +-(NSMutableData*) readIntSeq +{ + return [[self newIntSeq] autorelease]; +} + +-(NSMutableData*) newIntSeq +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Int*, const Ice::Int*> seq; + IceUtil::ScopedArray<Ice::Int> result; + is_->read(seq, result); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEInt)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICELong) readLong +{ + NSException* nsex = nil; + try + { + Ice::Long value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} + +-(NSMutableData*) readLongSeq +{ + return [[self newLongSeq] autorelease]; +} + +-(NSMutableData*) newLongSeq +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Long*, const Ice::Long*> seq; + IceUtil::ScopedArray<Ice::Long> result; + is_->read(seq, result); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICELong)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEFloat) readFloat +{ + NSException* nsex = nil; + try + { + Ice::Float value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0.f; // Keep the compiler happy. +} + +-(NSMutableData*) readFloatSeq +{ + return [[self newFloatSeq] autorelease]; +} + +-(NSMutableData*) newFloatSeq +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Float*, const Ice::Float*> seq; + IceUtil::ScopedArray<Ice::Float> result; + is_->read(seq, result); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEFloat)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEDouble) readDouble +{ + NSException* nsex = nil; + try + { + Ice::Double value; + is_->read(value); + return value; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0.0; // Keep the compiler happy. +} + +-(NSMutableData*) readDoubleSeq +{ + return [[self newDoubleSeq] autorelease]; +} + +-(NSMutableData*) newDoubleSeq +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Double*, const Ice::Double*> seq; + IceUtil::ScopedArray<Ice::Double> result; + is_->read(seq, result); + return [[NSMutableData alloc] initWithBytes:seq.first length:(seq.second - seq.first) * sizeof(ICEDouble)]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableString*)readString +{ + return [[self newString] autorelease]; +} + +-(NSMutableString*)newString +{ + NSException* nsex = nil; + try + { + std::string value; + is_->read(value); + return toNSMutableString(value); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSMutableArray*) readStringSeq +{ + return [[self newStringSeq] autorelease]; +} + +-(NSMutableArray*) newStringSeq +{ + NSException* nsex = nil; + try + { + Ice::StringSeq value; + is_->read(value); + return toNSArray(value); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(ICEInt) readEnumerator:(ICEInt)min max:(ICEInt)max +{ + NSException* nsex = nil; + ICEInt val = 0; // Keep the compiler happy. + try + { + if(is_->getEncoding() == Ice::Encoding_1_0) + { + if(max <= 0x7f) + { + val = [self readByte]; + } + else if(max <= 0x7fff) + { + val = [self readShort]; + } + else + { + val = [self readInt]; + } + } + else + { + val = [self readSize]; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + if(val > max || val < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"enumerator out of range"]; + } + return val; +} + +// +// Size of an enum. Slice enum underling type is specified as ICEInt so +// all Slice enums have the same size as an ICEInt. +// +#define ENUM_SIZE sizeof(ICEInt) + +-(NSMutableData*) readEnumSeq:(ICEInt)min max:(ICEInt)max +{ + return [[self newEnumSeq:(ICEInt)min max:(ICEInt)max] autorelease]; +} + +-(NSMutableData*) newEnumSeq:(ICEInt)min max:(ICEInt)max +{ + int minWireSize; + if(max <= 0x7f) + { + minWireSize = 1; + } + else if(max <= 0x7fff) + { + minWireSize = 2; + } + else + { + minWireSize = 4; + } + + NSException* nsex = nil; + NSMutableData* ret = 0; + try + { + int count = is_->readAndCheckSeqSize(minWireSize); + if((ret = [[NSMutableData alloc] initWithLength:(count * ENUM_SIZE)]) == 0) + { + return ret; + } + + ICEInt *v = (ICEInt *)[ret bytes]; + if(max <= 0x7f) + { + while(count-- > 0) + { + *v = [self readByte]; + if(*v > max || *v < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ + reason:@"enumerator out of range"]; + } + ++v; + } + } + else if(max <= 0x7fff) + { + while(count-- > 0) + { + *v = [self readShort]; + if(*v > max || *v < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ + reason:@"enumerator out of range"]; + } + ++v; + } + } + else + { + while(count-- > 0) + { + *v = [self readInt]; + if(*v > max || *v < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ + reason:@"enumerator out of range"]; + } + ++v; + } + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return ret; +} + +-(ICEInt) readSize +{ + NSException* nsex = nil; + try + { + return is_->readSize(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} + +-(ICEInt) readAndCheckSeqSize:(ICEInt)minSize +{ + NSException* nsex = nil; + try + { + return is_->readAndCheckSeqSize(minSize); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return 0; // Keep the compiler happy. +} + +-(id<ICEObjectPrx>) readProxy:(Class)type +{ + return [[self newProxy:type] autorelease]; +} + +-(id<ICEObjectPrx>) newProxy:(Class)type +{ + NSException* nsex = nil; + try + { + Ice::ObjectPrx p = is_->readProxy(); + if(!p) + { + return nil; + } + else + { + return [[type alloc] initWithObjectPrx__:p]; + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} +-(void) readObject:(ICEObject**)object +{ + [self readObject:object expectedType:[ICEObject class]]; +} +-(void) readObject:(ICEObject**)object expectedType:(Class)type +{ + NSException* nsex = nil; + try + { + is_->readObject(new IceObjC::ReadObject(object, type, true)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} +-(void) newObject:(ICEObject*ICE_STRONG_QUALIFIER*)object +{ + [self newObject:object expectedType:[ICEObject class]]; +} +-(void) newObject:(ICEObject*ICE_STRONG_QUALIFIER*)object expectedType:(Class)type +{ + NSException* nsex = nil; + try + { + is_->readObject(new IceObjC::ReadObject(object, type, false)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(NSMutableArray*) readObjectSeq:(Class)type +{ + return [[self newObjectSeq:(Class)type] autorelease]; +} + +-(NSMutableArray*) newObjectSeq:(Class)type +{ + ICEInt sz = [self readAndCheckSeqSize:1]; + NSMutableArray* arr = [[NSMutableArray alloc] initWithCapacity:sz]; + NSException* nsex = nil; + try + { + int i; + id null = [NSNull null]; + for(i = 0; i < sz; i++) + { + [arr addObject:null]; + is_->readObject(new IceObjC::ReadObjectAtIndex(arr, i, type)); + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + [arr release]; + @throw nsex; + } + return arr; +} + +-(NSMutableDictionary*) readObjectDict:(Class)keyHelper expectedType:(Class)type +{ + return [[self newObjectDict:(Class)keyHelper expectedType:(Class)type] autorelease]; +} + +-(NSMutableDictionary*) newObjectDict:(Class)keyHelper expectedType:(Class)type +{ + ICEInt sz = [self readAndCheckSeqSize:[keyHelper minWireSize] + 1]; + NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:sz]; + id key = nil; + for(int i = 0; i < sz; ++i) + { + @try + { + key = [keyHelper readRetained:self]; + } + @catch(id ex) + { + [dictionary release]; + @throw ex; + } + + NSException* nsex = nil; + try + { + is_->readObject(new IceObjC::ReadObjectForKey(dictionary, key, type)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + [key release]; + [dictionary release]; + @throw nsex; + } + [key release]; + } + return dictionary; +} + +-(NSMutableArray*) readSequence:(Class)helper +{ + return [[self newSequence:(Class)helper] autorelease]; +} + +-(NSMutableArray*) newSequence:(Class)helper +{ + ICEInt sz = [self readAndCheckSeqSize:[helper minWireSize]]; + NSMutableArray* arr = [[NSMutableArray alloc] initWithCapacity:sz]; + id obj = nil; + @try + { + while(sz-- > 0) + { + obj = [helper readRetained:self]; + if(obj == nil) + { + [arr addObject:[NSNull null]]; + } + else + { + [arr addObject:obj]; + [obj release]; + } + } + } + @catch(id ex) + { + [arr release]; + [obj release]; + @throw ex; + } + return arr; +} + +-(NSMutableDictionary*) readDictionary:(ICEKeyValueTypeHelper)helper +{ + return [[self newDictionary:(ICEKeyValueTypeHelper)helper] autorelease]; +} + +-(NSMutableDictionary*) newDictionary:(ICEKeyValueTypeHelper)helper +{ + ICEInt sz = [self readAndCheckSeqSize:[helper.key minWireSize] + [helper.value minWireSize]]; + NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:sz]; + id key = nil; + id value = nil; + @try + { + while(sz-- > 0) + { + key = [helper.key readRetained:self]; + value = [helper.value readRetained:self]; + if(value == nil) + { + [dictionary setObject:[NSNull null] forKey:key]; + } + else + { + [dictionary setObject:value forKey:key]; + [value release]; + } + [key release]; + } + } + @catch(id ex) + { + [dictionary release]; + [key release]; + [value release]; + @throw ex; + } + return dictionary; +} + +-(BOOL) readOptional:(ICEInt)tag format:(ICEOptionalFormat)format +{ + NSException* nsex = nil; + try + { + return is_->readOptional(tag, static_cast<Ice::OptionalFormat>(format)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return NO; // Keep the compiler happy. +} + +-(void) throwException +{ + ICEUserException* ex = nil; + NSException* nsex = nil; + try + { + Ice::UserExceptionReaderFactoryPtr factory = + new IceObjC::UserExceptionReaderFactoryI(is_->communicator().get(), self); + is_->throwException(factory); + } + catch(const IceObjC::ExceptionReader& reader) + { + ex = reader.getException(); + @throw [ex autorelease]; // NOTE: exceptions are always auto-released, no need for the caller to do it. + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + @throw nsex; + } +} + +-(void) startObject +{ + NSException* nsex = nil; + try + { + is_->startObject(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(id<ICESlicedData>) endObject:(BOOL)preserve +{ + NSException* nsex = nil; + try + { + Ice::SlicedDataPtr slicedData = is_->endObject(preserve); + return slicedData ? [[ICESlicedData alloc] initWithSlicedData:slicedData.get()] : nil; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Make compiler happy +} + +-(void) startException +{ + NSException* nsex = nil; + try + { + is_->startException(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(id<ICESlicedData>) endException:(BOOL)preserve +{ + NSException* nsex = nil; + try + { + Ice::SlicedDataPtr slicedData = is_->endException(preserve); + return slicedData ? [[ICESlicedData alloc] initWithSlicedData:slicedData.get()] : nil; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Make compiler happy +} + +-(void) startSlice +{ + NSException* nsex = nil; + try + { + is_->startSlice(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) endSlice +{ + NSException* nsex = nil; + try + { + is_->endSlice(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) skipSlice +{ + NSException* nsex = nil; + try + { + is_->skipSlice(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(ICEEncodingVersion*) startEncapsulation +{ + NSException* nsex = nil; + try + { + return [ICEEncodingVersion encodingVersionWithEncodingVersion:is_->startEncapsulation()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Keep the compiler happy. +} + +-(void) endEncapsulation +{ + NSException* nsex = nil; + try + { + is_->endEncapsulation(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(ICEEncodingVersion*) skipEncapsulation +{ + NSException* nsex = nil; + try + { + return [ICEEncodingVersion encodingVersionWithEncodingVersion:is_->skipEncapsulation()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return nil; // Keep the compiler happy. +} + +-(ICEEncodingVersion*) getEncoding +{ + return [ICEEncodingVersion encodingVersionWithEncodingVersion:is_->getEncoding()]; +} + +-(void) readPendingObjects +{ + NSException* nsex = nil; + try + { + is_->readPendingObjects(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) rewind +{ + NSException* nsex = nil; + try + { + is_->rewind(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) skip:(ICEInt)sz +{ + NSException* nsex = nil; + try + { + is_->skip(sz); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) skipSize +{ + NSException* nsex = nil; + try + { + is_->skipSize(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +@end + +@implementation ICEOutputStream +-(id) initWithCxxObject:(IceUtil::Shared*)cxxObject +{ + self = [super initWithCxxObject:cxxObject]; + if(!self) + { + return nil; + } + os_ = dynamic_cast<Ice::OutputStream*>(cxxObject); + objectWriters_ = 0; + return self; +} + +-(Ice::OutputStream*) os +{ + return os_; +} + +-(void) dealloc +{ + if(objectWriters_) + { + delete objectWriters_; + } + [super dealloc]; +} + +// @protocol ICEOutputStream methods + +-(id<ICECommunicator>) communicator +{ + return [ICECommunicator localObjectWithCxxObject:os_->communicator().get()]; +} + +-(void)writeBool:(BOOL)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<bool>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeBoolSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((bool*)[v bytes], (bool*)[v bytes] + [v length] / sizeof(BOOL)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeByte:(ICEByte)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<Ice::Byte>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeByteSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((ICEByte*)[v bytes], (ICEByte*)[v bytes] + [v length]); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeShort:(ICEShort)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<Ice::Short>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeShortSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((ICEShort*)[v bytes], (ICEShort*)[v bytes] + [v length] / sizeof(ICEShort)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeInt:(ICEInt)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<Ice::Int>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeIntSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((ICEInt*)[v bytes], (ICEInt*)[v bytes] + [v length] / sizeof(ICEInt)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeLong:(ICELong)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<Ice::Long>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeLongSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((ICELong*)[v bytes], (ICELong*)[v bytes] + [v length] / sizeof(ICELong)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeFloat:(ICEFloat)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<Ice::Float>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeFloatSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((ICEFloat*)[v bytes], (ICEFloat*)[v bytes] + [v length] / sizeof(ICEFloat)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeDouble:(ICEDouble)v +{ + NSException* nsex = nil; + try + { + os_->write(static_cast<Ice::Double>(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeDoubleSeq:(NSData*)v +{ + NSException* nsex = nil; + try + { + v == nil ? os_->writeSize(0) + : os_->write((ICEDouble*)[v bytes], + (ICEDouble*)[v bytes] + [v length] / sizeof(ICEDouble)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeString:(NSString*)v +{ + NSException* nsex = nil; + try + { + os_->write(fromNSString(v)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeStringSeq:(NSArray*)v +{ + NSException* nsex = nil; + try + { + std::vector<std::string> s; + os_->write(fromNSArray(v, s)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void)writeSequence:(NSArray*)arr helper:(Class)helper +{ + if(arr == nil) + { + [self writeSize:0]; + return; + } + + [self writeSize:[arr count]]; + for(id i in arr) + { + [helper write:(i == [NSNull null] ? nil : i) stream:self]; + } +} + +-(void) writeDictionary:(NSDictionary*)dictionary helper:(ICEKeyValueTypeHelper)helper +{ + if(dictionary == nil) + { + [self writeSize:0]; + return; + } + + [self writeSize:[dictionary count]]; + NSEnumerator* e = [dictionary keyEnumerator]; + id key; + while((key = [e nextObject])) + { + if(key == [NSNull null]) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [helper.key write:key stream:self]; + NSObject *obj = [dictionary objectForKey:key]; + [helper.value write:(obj == [NSNull null] ? nil : obj) stream:self]; + } +} + +-(BOOL) writeOptional:(ICEInt)tag format:(ICEOptionalFormat)format +{ + NSException* nsex = nil; + try + { + return os_->writeOptional(tag, static_cast<Ice::OptionalFormat>(format)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } + return NO; // Keep the compiler happy. +} + +-(void) writeEnumerator:(ICEInt)v min:(int)min max:(int)max +{ + if(v > max || v < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"enumerator out of range"]; + } + NSException* nsex = nil; + try + { + if(os_->getEncoding() == Ice::Encoding_1_0) + { + if(max <= 0x7f) + { + os_->write(static_cast<Ice::Byte>(v)); + } + else if(max <= 0x7fff) + { + os_->write(static_cast<Ice::Short>(v)); + } + else + { + os_->write(static_cast<Ice::Int>(v)); + } + } + else + { + os_->writeSize(static_cast<Ice::Int>(v)); + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +// +// The C standard does not fix the size of an enum. The compiler is free +// to choose an enum size that depends on the number of enumerators, and +// the choice may vary depending on the processor. This means that we don't +// know what the size of an enum is until run time, so the marshaling +// has to be generic and copy with enums that could be 8, 16, or 32 bits wide. +// +-(void) writeEnumSeq:(NSData*)v min:(ICEInt)min max:(ICEInt)max +{ + NSException* nsex = nil; + try + { + int count = v == nil ? 0 : [v length] / ENUM_SIZE; + [self writeSize:count]; + if(count == 0) + { + return; + } + + const ICEInt* p = (const ICEInt*)[v bytes]; + if(max <= 0x7f) + { + while(count-- > 0) + { + if(*p > max || *p < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ + reason:@"enumerator out of range"]; + } + [self writeByte:*p++]; + } + } + else if(max <= 0x7fff) + { + while(count-- > 0) + { + if(*p > max || *p < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ + reason:@"enumerator out of range"]; + } + [self writeShort:*p++]; + } + } + else + { + while(count-- > 0) + { + if(*p > max || *p < min) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ + reason:@"enumerator out of range"]; + } + [self writeInt:*p++]; + } + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeSize:(ICEInt)v +{ + NSException* nsex = nil; + try + { + os_->writeSize(v); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + + +-(void) writeProxy:(id<ICEObjectPrx>)v +{ + NSException* nsex = nil; + try + { + os_->writeProxy([(ICEObjectPrx*)v objectPrx__]); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeObject:(ICEObject*)v +{ + NSException* nsex = nil; + try + { + if(v == nil) + { + os_->writeObject(0); + } + else + { + os_->writeObject([self addObject:v]); + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) writeObjectSeq:(NSArray*)arr +{ + if(arr == nil) + { + [self writeSize:0]; + return; + } + + [self writeSize:[arr count]]; + for(id i in arr) + { + [self writeObject:(i == [NSNull null] ? nil : i)]; + } +} + +-(void) writeObjectDict:(NSDictionary*)dictionary helper:(Class)helper +{ + if(dictionary == nil) + { + [self writeSize:0]; + return; + } + + [self writeSize:[dictionary count]]; + NSEnumerator* e = [dictionary keyEnumerator]; + id key; + while((key = [e nextObject])) + { + if(key == [NSNull null]) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [helper write:key stream:self]; + id obj = [dictionary objectForKey:key]; + [self writeObject:(obj == [NSNull null] ? nil : obj)]; + } +} + +-(void) writeException:(ICEUserException*)ex +{ + IceObjC::ExceptionWriter writer(os_->communicator().get(), self, ex); + os_->writeException(writer); +} + +-(void) startObject:(id<ICESlicedData>)slicedData +{ + NSException* nsex = nil; + try + { + if(slicedData != nil) + { + os_->startObject([self writeSlicedData:slicedData]); + } + else + { + os_->startObject(0); + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) endObject +{ + NSException* nsex = nil; + try + { + os_->endObject(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) startException:(id<ICESlicedData>)slicedData +{ + NSException* nsex = nil; + try + { + if(slicedData != nil) + { + os_->startException([self writeSlicedData:slicedData]); + } + else + { + os_->startException(0); + } + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) endException +{ + NSException* nsex = nil; + try + { + os_->endException(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) startSlice:(NSString*)typeId compactId:(ICEInt)compactId lastSlice:(BOOL)lastSlice +{ + NSException* nsex = nil; + try + { + os_->startSlice([typeId UTF8String], compactId, static_cast<bool>(lastSlice)); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) endSlice +{ + NSException* nsex = nil; + try + { + os_->endSlice(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) startEncapsulation +{ + NSException* nsex = nil; + try + { + os_->startEncapsulation(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) startEncapsulation:(ICEEncodingVersion*)encoding format:(ICEFormatType)format +{ + NSException* nsex = nil; + try + { + os_->startEncapsulation([encoding encodingVersion], (Ice::FormatType)format); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(void) endEncapsulation +{ + NSException* nsex = nil; + try + { + os_->endEncapsulation(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(ICEEncodingVersion*) getEncoding +{ + return [ICEEncodingVersion encodingVersionWithEncodingVersion:os_->getEncoding()]; +} + +-(void) writePendingObjects +{ + NSException* nsex = nil; + try + { + os_->writePendingObjects(); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(NSMutableData*) finished +{ + NSException* nsex = nil; + try + { + std::vector<Ice::Byte> buf; + os_->finished(buf); + return [NSMutableData dataWithBytes:&buf[0] length:buf.size()]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(NSData*) finishedNoCopy +{ + NSException* nsex = nil; + try + { + std::pair<const Ice::Byte*, const Ice::Byte*> b = os_->finished(); + return [NSData dataWithBytesNoCopy:const_cast<Ice::Byte*>(b.first) length:(b.second - b.first) freeWhenDone:NO]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; + return nil; // Keep the compiler happy. +} + +-(void) reset:(BOOL)clearBuffer +{ + NSException* nsex = nil; + try + { + os_->reset(clearBuffer); + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + if(nsex != nil) + { + @throw nsex; + } +} + +-(Ice::Object*) addObject:(ICEObject*)object +{ + // + // Ice::ObjectWriter is a subclass of Ice::Object that wraps an Objective-C object for marshaling. + // It is possible that this Objective-C object has already been marshaled, therefore we first must + // check the object map to see if this object is present. If so, we use the existing ObjectWriter, + // otherwise we create a new one. + // + if(!objectWriters_) + { + objectWriters_ = new std::map<ICEObject*, Ice::ObjectPtr>(); + } + std::map<ICEObject*, Ice::ObjectPtr>::const_iterator p = objectWriters_->find(object); + if(p != objectWriters_->end()) + { + return p->second.get(); + } + else + { + Ice::ObjectWriterPtr writer = new IceObjC::ObjectWriter(object, self); + objectWriters_->insert(std::make_pair(object, writer)); + return writer.get(); + } +} + +-(Ice::SlicedData*) writeSlicedData:(id<ICESlicedData>)sd +{ + NSAssert([sd isKindOfClass:[ICESlicedData class]], @"invalid sliced data object"); + Ice::SlicedData* origSlicedData = [((ICESlicedData*)sd) slicedData]; + Ice::SliceInfoSeq slices; + for(Ice::SliceInfoSeq::const_iterator p = origSlicedData->slices.begin(); p != origSlicedData->slices.end(); ++p) + { + Ice::SliceInfoPtr info = new Ice::SliceInfo; + info->typeId = (*p)->typeId; + info->compactId = (*p)->compactId; + info->bytes = (*p)->bytes; + info->hasOptionalMembers = (*p)->hasOptionalMembers; + info->isLastSlice = (*p)->isLastSlice; + + for(std::vector<Ice::ObjectPtr>::const_iterator q = (*p)->objects.begin(); q != (*p)->objects.end(); ++q) + { + if(*q) + { + assert(IceObjC::ObjectReaderPtr::dynamicCast(*q)); + info->objects.push_back([self addObject:IceObjC::ObjectReaderPtr::dynamicCast(*q)->getObject()]); + } + else + { + info->objects.push_back(0); + } + } + slices.push_back(info); + } + return new Ice::SlicedData(slices); +} + +@end + +@implementation ICEStreamHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + NSAssert(NO, @"requires override"); + return nil; +} ++(id) read:(id<ICEInputStream>)stream +{ + return [[self readRetained:stream] autorelease]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + NSAssert(NO, @"requires override"); +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + NSAssert(NO, @"requires override"); + return nil; +} ++(id) readOpt:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + return [[self readOptRetained:stream tag:tag] autorelease]; + return nil; +} ++(void) writeOpt:(id)obj stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + NSAssert(NO, @"requires override"); +} ++(ICEInt) minWireSize +{ + NSAssert(NO, @"requires override"); + return 0; +} +@end + +@implementation ICEBoolHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithBool:[stream readBool]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeBool:[obj boolValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF1]) + { + return [[NSNumber alloc] initWithBool:[stream readBool]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + BOOL value; + if([ICEOptionalGetter getBool:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF1]) + { + [stream writeBool:value]; + } +} ++(ICEInt) minWireSize +{ + return 1; +} +@end + +@implementation ICEByteHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithUnsignedChar:[stream readByte]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeByte:[obj unsignedCharValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF1]) + { + return [[NSNumber alloc] initWithUnsignedChar:[stream readByte]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEByte value; + if([ICEOptionalGetter getByte:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF1]) + { + [stream writeByte:value]; + } +} ++(ICEInt) minWireSize +{ + return 1; +} +@end + +@implementation ICEShortHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithShort:[stream readShort]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeShort:[obj shortValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF2]) + { + return [[NSNumber alloc] initWithShort:[stream readShort]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEShort value; + if([ICEOptionalGetter getShort:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF2]) + { + [stream writeShort:value]; + } +} ++(ICEInt) minWireSize +{ + return 2; +} +@end + +@implementation ICEIntHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithInt:[stream readInt]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeInt:[obj intValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF4]) + { + return [[NSNumber alloc] initWithInt:[stream readInt]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEInt value; + if([ICEOptionalGetter getInt:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF4]) + { + [stream writeInt:value]; + } +} ++(ICEInt) minWireSize +{ + return 4; +} +@end + +@implementation ICELongHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithLong:[stream readLong]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeLong:[obj longValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF8]) + { + return [[NSNumber alloc] initWithLong:[stream readLong]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICELong value; + if([ICEOptionalGetter getLong:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF8]) + { + [stream writeLong:value]; + } +} ++(ICEInt) minWireSize +{ + return 8; +} +@end + +@implementation ICEFloatHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithFloat:[stream readFloat]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeFloat:[obj floatValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF4]) + { + return [[NSNumber alloc] initWithFloat:[stream readFloat]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEFloat value; + if([ICEOptionalGetter getFloat:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF4]) + { + [stream writeFloat:value]; + } +} ++(ICEInt) minWireSize +{ + return 4; +} +@end + +@implementation ICEDoubleHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithDouble:[stream readDouble]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeDouble:[obj doubleValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatF8]) + { + return [[NSNumber alloc] initWithDouble:[stream readDouble]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEDouble value; + if([ICEOptionalGetter getDouble:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatF8]) + { + [stream writeDouble:value]; + } +} ++(ICEInt) minWireSize +{ + return 8; +} +@end + +@implementation ICEStringHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newString]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == [NSNull null]) + { + obj = nil; + } + [stream writeString:obj]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatVSize]) + { + return [stream newString]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + NSString* value; + if([ICEOptionalGetter get:v value:&value type:[NSString class]] && + [stream writeOptional:tag format:ICEOptionalFormatVSize]) + { + [stream writeString:v]; + } +} ++(ICEInt) minWireSize +{ + return 1; +} +@end + +@implementation ICEEnumHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [[NSNumber alloc] initWithInt:[stream readEnumerator:[self getMinValue] max:[self getMaxValue]]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + @throw [ICEMarshalException marshalException:__FILE__ line:__LINE__ reason:@"illegal NSNull value"]; + } + [stream writeEnumerator:[obj intValue] min:[self getMinValue] max:[self getMaxValue]]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatSize]) + { + return [[NSNumber alloc] initWithInt:[stream readEnumerator:[self getMinValue] max:[self getMaxValue]]]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEInt value; + if([ICEOptionalGetter getInt:v value:&value] && [stream writeOptional:tag format:ICEOptionalFormatSize]) + { + [stream writeEnumerator:value min:[self getMinValue] max:[self getMaxValue]]; + } +} ++(ICEInt) getMinValue +{ + NSAssert(NO, @"ICEEnumHelper getMinValue requires override"); + return 0; +} ++(ICEInt) getMaxValue +{ + NSAssert(NO, @"ICEEnumHelper getMaxValue requires override"); + return 0; +} ++(ICEInt) minWireSize +{ + return 1; +} +@end + +@implementation ICEObjectHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + // + // This will only work with the 1.1 encoding. With the 1.0 encoding + // objects are read when readPendingObjects is called. + // + ICEObject* obj; + [stream newObject:&obj]; + return (id)obj; +} ++(void)readRetained:(ICEObject**)v stream:(id<ICEInputStream>)stream +{ + [stream newObject:v]; +} ++(void)read:(ICEObject**)v stream:(id<ICEInputStream>)stream +{ + [stream readObject:v]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeObject:obj]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatClass]) + { + return [self readRetained:stream]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEObject* value; + if([ICEOptionalGetter get:v value:&value type:[ICEObject class]] && + [stream writeOptional:tag format:ICEOptionalFormatClass]) + { + [self write:value stream:stream]; + } +} ++(void)readOptRetained:(id *)v stream:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatClass]) + { + [self readRetained:(ICEObject**)v stream:stream]; + } + else + { + *v = ICENone; + } +} ++(void)readOpt:(id *)v stream:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatClass]) + { + [self read:(ICEObject**)v stream:stream]; + } + else + { + *v = ICENone; + } +} ++(ICEInt) minWireSize +{ + return 1; +} +@end + +@implementation ICEProxyHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newProxy:[ICEObjectPrx class]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeProxy:obj]; +} ++(id)readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatFSize]) + { + return [ICEVarLengthOptionalHelper readRetained:stream helper:self]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + ICEObjectPrx* value; + if([ICEOptionalGetter get:v value:&value type:[ICEObjectPrx class]] && + [stream writeOptional:tag format:ICEOptionalFormatFSize]) + { + [ICEVarLengthOptionalHelper write:v stream:stream helper:self]; + } +} ++(ICEInt) minWireSize +{ + return 2; +} +@end + +@implementation ICEStructHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [self readRetained:stream value:nil]; +} ++(id) readRetained:(id<ICEInputStream>)stream value:(id)p +{ + if(p == nil) + { + p = [[self getType] new]; + } + else + { + [p retain]; + } + + @try + { + [p read__:stream]; + } + @catch(NSException *ex) + { + [p release]; + @throw ex; + } + return p; +} ++(id) read:(id<ICEInputStream>)stream value:(id)p +{ + return [[self readRetained:stream value:p] autorelease]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + if(obj == nil) + { + obj = [[self getType] new]; + @try + { + [obj write__:stream]; + } + @finally + { + [obj release]; + } + } + else + { + [obj write__:stream]; + } +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + Class helper = [self getOptionalHelper]; + if([stream readOptional:tag format:[helper optionalFormat]]) + { + return [helper readRetained:stream helper:self]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)s tag:(ICEInt)tag +{ + Class helper = [self getOptionalHelper]; + NSObject* a; + if([ICEOptionalGetter get:v value:&a type:[self getType]] && [s writeOptional:tag format:[helper optionalFormat]]) + { + [helper write:a stream:s helper:self]; + } +} ++(Class) getType +{ + NSAssert(NO, @"getType requires override"); + return nil; +} ++(Class) getOptionalHelper +{ + NSAssert(NO, @"getOptionalHelper requires override"); + return nil; +} ++(ICEInt) minWireSize +{ + NSAssert(NO, @"minWireSize requires override"); + return 0; +} +@end + +@implementation ICEArraySequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newSequence:[self getElementHelper]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeSequence:obj helper:[self getElementHelper]]; +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + Class helper = [self getOptionalHelper]; + if([stream readOptional:tag format:[helper optionalFormat]]) + { + return [helper readRetained:stream helper:self]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)s tag:(ICEInt)tag +{ + Class helper = [self getOptionalHelper]; + NSArray* a; + if([ICEOptionalGetter get:v value:&a type:[NSArray class]] && [s writeOptional:tag format:[helper optionalFormat]]) + { + [helper write:a stream:s helper:self]; + } +} ++(Class) getElementHelper +{ + NSAssert(NO, @"getElementHelper requires override"); + return nil; +} ++(Class) getOptionalHelper +{ + NSAssert(NO, @"getOptionalHelper requires override"); + return nil; +} ++(ICEInt) minWireSize +{ + return 1; +} ++(ICEInt) count:(id)obj +{ + return [obj count]; +} +@end + +@implementation ICEDataSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + NSAssert(NO, @"readRetained requires override"); + return nil; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + NSAssert(NO, @"write requires override"); +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatVSize]) + { + return [ICEFixedSequenceOptionalHelper readRetained:stream helper:self]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + NSData* a; + if([ICEOptionalGetter get:v value:&a type:[NSData class]] && + [stream writeOptional:tag format:ICEOptionalFormatVSize]) + { + [ICEFixedSequenceOptionalHelper write:a stream:stream helper:self]; + } +} ++(ICEInt) minWireSize +{ + return 1; +} ++(ICEInt) count:(id)obj +{ + return [obj length] / [[self getElementHelper] minWireSize]; +} ++(Class) getElementHelper +{ + return [ICEShortHelper class]; +} +@end + +@implementation ICEBoolSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newBoolSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeBoolSeq:obj]; +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatVSize]) + { + return [stream newBoolSeq]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + NSData* a; + if([ICEOptionalGetter get:v value:&a type:[NSData class]] && + [stream writeOptional:tag format:ICEOptionalFormatVSize]) + { + [stream writeBoolSeq:a]; + } +} ++(Class) getElementHelper +{ + return [ICEBoolHelper class]; +} +@end + +@implementation ICEByteSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newByteSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeByteSeq:obj]; +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + if([stream readOptional:tag format:ICEOptionalFormatVSize]) + { + return [stream newByteSeq]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)stream tag:(ICEInt)tag +{ + NSData* a; + if([ICEOptionalGetter get:v value:&a type:[NSData class]] && + [stream writeOptional:tag format:ICEOptionalFormatVSize]) + { + [stream writeByteSeq:a]; + } +} ++(Class) getElementHelper +{ + return [ICEIntHelper class]; +} +@end + +@implementation ICEShortSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newShortSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeShortSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICEShortHelper class]; +} +@end + +@implementation ICEIntSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newIntSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeIntSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICEIntHelper class]; +} +@end + +@implementation ICELongSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newLongSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeLongSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICELongHelper class]; +} +@end + +@implementation ICEFloatSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newFloatSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeFloatSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICEFloatHelper class]; +} +@end + +@implementation ICEDoubleSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newDoubleSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeDoubleSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICEDoubleHelper class]; +} +@end + +@implementation ICEEnumSequenceHelper ++(ICEInt) count:(id)obj +{ + return [obj length] / ENUM_SIZE; +} ++(Class) getElementHelper +{ + return [ICEEnumHelper class]; +} +@end + +@implementation ICEStringSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newStringSeq]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeStringSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICEStringHelper class]; +} ++(Class) getOptionalHelper +{ + return [ICEVarLengthOptionalHelper class]; +} +@end + +@implementation ICEObjectSequenceHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newObjectSeq:[ICEObject class]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeObjectSeq:obj]; +} ++(Class) getElementHelper +{ + return [ICEObjectHelper class]; +} ++(Class) getOptionalHelper +{ + return [ICEVarLengthOptionalHelper class]; +} +@end + +@implementation ICEProxySequenceHelper ++(Class) getElementHelper +{ + return [ICEProxyHelper class]; +} ++(Class) getOptionalHelper +{ + return [ICEVarLengthOptionalHelper class]; +} +@end + +@implementation ICEDictionaryHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + return [stream newDictionary:[self getKeyValueHelper]]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + [stream writeDictionary:obj helper:[self getKeyValueHelper]]; +} ++(id) readOptRetained:(id<ICEInputStream>)stream tag:(ICEInt)tag +{ + Class helper = [self getOptionalHelper]; + if([stream readOptional:tag format:[helper optionalFormat]]) + { + return [helper readRetained:stream helper:self]; + } + return ICENone; +} ++(void) writeOpt:(id)v stream:(id<ICEOutputStream>)s tag:(ICEInt)tag +{ + Class helper = [self getOptionalHelper]; + NSDictionary* a; + if([ICEOptionalGetter get:v value:&a type:[NSDictionary class]] && + [s writeOptional:tag format:[helper optionalFormat]]) + { + [helper write:a stream:s helper:self]; + } +} ++(Class) getOptionalHelper +{ + NSAssert(NO, @"getOptionalHelper requires override"); + return nil; +} ++(ICEKeyValueTypeHelper) getKeyValueHelper +{ + NSAssert(NO, @"ICEDictionaryHelper getKeyValueHelper requires override"); + ICEKeyValueTypeHelper dummy; + return dummy; // Keep compiler quiet +} ++(ICEInt) minWireSize +{ + return 1; +} ++(ICEInt) count:(id)obj +{ + return [obj count]; +} +@end + +@implementation ICEObjectDictionaryHelper ++(id) readRetained:(id<ICEInputStream>)stream +{ + NSAssert(NO, @"ICEObjectDictionaryHelper readRetained requires override"); + return nil; +} + ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream +{ + NSAssert(NO, @"ICEObjectDictionaryHelper write requires override"); +} +@end + +@implementation ICEVarLengthOptionalHelper ++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper +{ + [stream skip:4]; + return [helper readRetained:stream]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper +{ + Ice::OutputStream* os = [(ICEOutputStream*)stream os]; + os->write(static_cast<Ice::Int>(0)); + Ice::OutputStream::size_type p = os->pos(); + [helper write:obj stream:stream]; + os->rewrite(static_cast<Ice::Int>(os->pos() - p), p - 4); +} ++(ICEOptionalFormat) optionalFormat +{ + return ICEOptionalFormatFSize; +} +@end + +@implementation ICEFixedLengthOptionalHelper ++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper +{ + [stream skipSize]; + return [helper readRetained:stream]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper +{ + [stream writeSize:[helper minWireSize]]; + [helper write:obj stream:stream]; +} ++(ICEOptionalFormat) optionalFormat +{ + return ICEOptionalFormatVSize; +} +@end + +@implementation ICEFixedSequenceOptionalHelper ++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper +{ + [stream skipSize]; + return [helper readRetained:stream]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper +{ + // + // The container size is the number of elements * the size of + // an element and the size-encoded number of elements (1 or + // 5 depending on the number of elements). + // + ICEInt n = [helper count:obj]; + ICEInt sz = [[helper getElementHelper] minWireSize]; + [stream writeSize:sz * n + (n < 255 ? 1 : 5)]; + [helper write:obj stream:stream]; +} ++(ICEOptionalFormat) optionalFormat +{ + return ICEOptionalFormatVSize; +} +@end + +@implementation ICEFixedSize1SequenceOptionalHelper ++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper +{ + return [helper readRetained:stream]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper +{ + [helper write:obj stream:stream]; +} ++(ICEOptionalFormat) optionalFormat +{ + return ICEOptionalFormatVSize; +} +@end + +@implementation ICEFixedDictionaryOptionalHelper ++(id) readRetained:(id<ICEInputStream>)stream helper:(Class)helper +{ + [stream skipSize]; + return [helper readRetained:stream]; +} ++(void) write:(id)obj stream:(id<ICEOutputStream>)stream helper:(Class)helper +{ + // + // The container size is the number of elements * the size of + // an element and the size-encoded number of elements (1 or + // 5 depending on the number of elements). + // + ICEInt n = [helper count:obj]; + ICEKeyValueTypeHelper h = [helper getKeyValueHelper]; + ICEInt sz = [h.key minWireSize] + [h.value minWireSize]; + [stream writeSize:sz * n + (n < 255 ? 1 : 5)]; + [helper write:obj stream:stream]; +} ++(ICEOptionalFormat) optionalFormat +{ + return ICEOptionalFormatVSize; +} +@end + +@implementation ICEOptionalGetter ++(BOOL) get:(id)value type:(Class)cl +{ + if(value == ICENone) + { + return NO; + } + else + { + if(value != nil && ![value isKindOfClass:cl]) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"unexpected type" userInfo:cl]; + } + return YES; + } +} ++(BOOL) get:(id)value value:(id*)v type:(Class)cl +{ + if([self get:value type:cl]) + { + *v = value; + return YES; + } + return NO; +} ++(BOOL) getRetained:(id)value value:(id*)v type:(Class)cl +{ + BOOL r = [self get:value value:v type:cl]; + [*v retain]; + return r; +} ++(BOOL) getByte:(id)value value:(ICEByte*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value unsignedCharValue]; + return YES; + } + return NO; +} ++(BOOL) getBool:(id)value value:(BOOL*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value boolValue]; + return YES; + } + return NO; +} ++(BOOL) getShort:(id)value value:(ICEShort*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value shortValue]; + return YES; + } + return NO; +} ++(BOOL) getInt:(id)value value:(ICEInt*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value intValue]; + return YES; + } + return NO; +} ++(BOOL) getLong:(id)value value:(ICELong*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value longValue]; + return YES; + } + return NO; +} ++(BOOL) getFloat:(id)value value:(ICEFloat*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value floatValue]; + return YES; + } + return NO; +} ++(BOOL) getDouble:(id)value value:(ICEDouble*)v +{ + if([self get:value type:[NSNumber class]]) + { + *v = [value doubleValue]; + return YES; + } + return NO; +} +@end diff --git a/objective-c/src/Ice/StreamI.h b/objective-c/src/Ice/StreamI.h new file mode 100644 index 00000000000..650e9c4eefb --- /dev/null +++ b/objective-c/src/Ice/StreamI.h @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Stream.h> +#import <objc/Ice/LocalObject.h> + +#include <Ice/Stream.h> + +@interface ICEInputStream : ICELocalObject<ICEInputStream> +{ + Ice::InputStream* is_; +} ++(Ice::Object*)createObjectReader:(ICEObject*)obj; +-(Ice::InputStream*) is; +@end + +@interface ICEOutputStream : ICELocalObject<ICEOutputStream> +{ + Ice::OutputStream* os_; + std::map<ICEObject*, Ice::ObjectPtr>* objectWriters_; +} +-(Ice::OutputStream*) os; +@end diff --git a/objective-c/src/Ice/Util.h b/objective-c/src/Ice/Util.h new file mode 100644 index 00000000000..d1efff67f89 --- /dev/null +++ b/objective-c/src/Ice/Util.h @@ -0,0 +1,244 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <Foundation/NSException.h> + +#import <objc/Ice/Config.h> +#import <objc/Ice/Current.h> + +#include <Ice/Proxy.h> +#include <Ice/Endpoint.h> + +#import <EndpointI.h> + +#include <exception> +#include <vector> +#include <map> +#include <string> + +@class ICEAsyncResult; +@class ICEObjectPrx; +@class ICEException; +@class ICEEndpoint; + +void cppCall(void (^fn)()); +void cppCall(void (^fn)(const Ice::Context&), ICEContext*); +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&), ICEObjectPrx* = nil); +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::CallbackPtr&), + void (^completed)(const Ice::AsyncResultPtr&), + void (^exception)(ICEException*), + void (^sent)(BOOL), + ICEObjectPrx* = nil); +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&), ICEContext*, ICEObjectPrx* = nil); +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&, const Ice::CallbackPtr&), + ICEContext*, + void (^completed)(const Ice::AsyncResultPtr&), + void (^exception)(ICEException*), + void (^sent)(BOOL), + ICEObjectPrx* = nil); +void endCppCall(void (^fn)(const Ice::AsyncResultPtr&), ICEAsyncResult*); + + +NSException* toObjCException(const std::exception&); +void rethrowCxxException(id, bool = false); + +// +// The toXXX methods don't auto release the returned object: the caller +// must assume ownership of the returned object. +// + +inline NSObject<NSCopying>* toObjC(bool v) { return [[NSNumber alloc] initWithBool:v]; } +inline NSObject<NSCopying>* toObjC(ICEByte v) { return [[NSNumber alloc] initWithUnsignedChar:v]; } +inline NSObject<NSCopying>* toObjC(ICEShort v) { return [[NSNumber alloc] initWithShort:v]; } +inline NSObject<NSCopying>* toObjC(ICEInt v) { return [[NSNumber alloc] initWithInt:v]; } +inline NSObject<NSCopying>* toObjC(ICELong v) { return [[NSNumber alloc] initWithLongLong:v]; } +inline NSObject<NSCopying>* toObjC(ICEFloat v) { return [[NSNumber alloc] initWithFloat:v]; } +inline NSObject<NSCopying>* toObjC(ICEDouble v) { return [[NSNumber alloc] initWithDouble:v]; } + +inline void fromObjC(id object, bool& v) { v = [object boolValue]; } +inline void fromObjC(id object, ICEByte& v) { v = [object unsignedCharValue]; } +inline void fromObjC(id object, ICEShort& v) { v = [object shortValue]; } +inline void fromObjC(id object, ICEInt& v) { v = [object intValue];} +inline void fromObjC(id object, ICELong& v) { v = [object longLongValue]; } +inline void fromObjC(id object, ICEFloat& v) { v = [object floatValue]; } +inline void fromObjC(id object, ICEDouble& v) { v = [object doubleValue]; } + +inline NSObject<NSCopying>* +toObjC(const std::string& s) +{ + return [[NSString alloc] initWithUTF8String:s.c_str()]; +} + +inline void +fromObjC(id object, std::string& s) +{ + s = object == [NSNull null] ? ::std::string() : [object UTF8String]; +} + +NSObject<NSCopying>* toObjC(const Ice::EndpointPtr& endpoint); +void fromObjC(id object, Ice::EndpointPtr& endpoint); + +ICEObject* toObjC(const Ice::ObjectPtr& object); + +inline NSMutableArray* +toNSArray(const char* arr[], size_t size) +{ + NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:size]; + for(size_t i = 0; i < size; ++i) + { + NSObject* obj = [[NSString alloc] initWithUTF8String:arr[i]]; + [array addObject:obj]; + [obj release]; + } + return array; +} + +template<typename T> NSMutableArray* +toNSArray(const std::vector<T>& seq) +{ + NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:seq.size()]; + for(typename std::vector<T>::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + NSObject* obj = toObjC(*p); + [array addObject:obj]; + [obj release]; + } + return array; +} + +template<typename T> NSMutableData* +toNSData(const std::vector<T>& seq) +{ + NSMutableData* array = [[NSMutableData alloc] initWithLength:seq.size() * sizeof(T)]; + T* target = (T*)[array bytes]; + for(typename std::vector<T>::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + *target++ = *p; + } + return array; +} + +template<typename T> std::vector<T>& +fromNSArray(NSArray* array, std::vector<T>& seq) +{ + if(array != nil) + { + seq.reserve([array count]); + NSEnumerator* enumerator = [array objectEnumerator]; + id obj = nil; + while((obj = [enumerator nextObject])) + { + T v; + fromObjC(obj, v); + seq.push_back(v); + } + } + return seq; +} + +template<typename T> std::vector<T>& +fromNSData(NSData* array, std::vector<T>& seq) +{ + if(array != nil) + { + int len = [array length] / sizeof(T); + seq.reserve(len); + T* src = (T*)[array bytes]; + while(len-- > 0) + { + seq.push_back(*src++); + } + } + return seq; +} + +template<typename K, typename V> NSMutableDictionary* +toNSDictionary(const std::map<K, V>& dict) +{ + NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] initWithCapacity:dict.size()]; + for(typename std::map<K, V>::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + NSObject<NSCopying>* key = toObjC(p->first); + NSObject* value = toObjC(p->second); + [dictionary setObject:value forKey:key]; + [key release]; + [value release]; + } + return dictionary; +} + +template<typename K, typename V> std::map<K, V>& +fromNSDictionary(NSDictionary* dictionary, std::map<K, V>& dict) +{ + if(dictionary != nil) + { + NSEnumerator* enumerator = [dictionary keyEnumerator]; + id obj = nil; + while((obj = [enumerator nextObject])) + { + K k; + fromObjC(obj, k); + V v; + fromObjC([dictionary objectForKey:obj], v); + dict.insert(std::pair<K, V>(k, v)); + } + } + return dict; +} + +inline NSString* +toNSString(const char* s) +{ + return [[NSString alloc] initWithCString:s encoding:[NSString defaultCStringEncoding]]; +} + +inline NSString* +toNSString(const std::string& s) +{ + return [[NSString alloc] initWithUTF8String:s.c_str()]; +} + +inline NSMutableString* +toNSMutableString(const std::string& s) +{ + return [[NSMutableString alloc] initWithUTF8String:s.c_str()]; +} + +inline std::string +fromNSString(NSString* s) +{ + return s == nil ? std::string() : [s UTF8String]; +} + +std::string toObjCSliceId(const std::string&, NSDictionary*); + +namespace IceObjC +{ + +class Exception : public IceUtil::Exception +{ +public: + + Exception(id<NSObject>); + Exception(const Exception&); + virtual ~Exception() throw(); + + virtual std::string ice_name() const; + virtual void ice_print(std::ostream& os) const; + virtual Exception* ice_clone() const; + virtual void ice_throw() const; + + id<NSObject> exception() const { return _ex; } + +private: + + id<NSObject> _ex; +}; + +} diff --git a/objective-c/src/Ice/Util.mm b/objective-c/src/Ice/Util.mm new file mode 100644 index 00000000000..4462431c96f --- /dev/null +++ b/objective-c/src/Ice/Util.mm @@ -0,0 +1,482 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <Util.h> +#import <ExceptionI.h> +#import <StreamI.h> +#import <ProxyI.h> +#import <LocalObjectI.h> +#import <ObjectI.h> +#import <PropertiesI.h> + +#import <objc/Ice/LocalException.h> + +#include <Ice/LocalException.h> +#include <Ice/Initialize.h> + +#include <Block.h> + +#import <objc/runtime.h> + +namespace +{ + +class AsyncCallback : public IceUtil::Shared +{ +public: + +AsyncCallback(void (^completed)(const Ice::AsyncResultPtr&), void (^exception)(ICEException*), void (^sent)(BOOL)) : + _completed(Block_copy(completed)), _exception(Block_copy(exception)), _sent(Block_copy(sent)) +{ +} + +virtual ~AsyncCallback() +{ + Block_release(_completed); + Block_release(_exception); + Block_release(_sent); +} + +void completed(const Ice::AsyncResultPtr& result) +{ + NSException* exception = nil; + @autoreleasepool + { + @try + { + try + { + _completed(result); + } + catch(const Ice::Exception& ex) + { + @try + { + NSException* nsex = toObjCException(ex); + @throw nsex; + } + @catch(ICEException* e) + { + if(_exception) + { + _exception(e); + } + } + } + } + @catch(NSException* e) + { + exception = [e retain]; + } + } + + if(exception != nil) + { + rethrowCxxException(exception, true); // True = release the exception. + } +} + +void sent(const Ice::AsyncResultPtr& result) +{ + if(!_sent) + { + return; + } + + NSException* exception = nil; + @autoreleasepool + { + @try + { + _sent(result->sentSynchronously()); + } + @catch(NSException* e) + { + exception = [e retain]; + } + } + + if(exception != nil) + { + rethrowCxxException(exception, true); // True = release the exception. + } +} + +private: + +void (^_completed)(const Ice::AsyncResultPtr&); +void (^_exception)(ICEException*); +void (^_sent)(BOOL); + +}; + +}; + +void cppCall(void (^fn)()) +{ + NSException* nsex = nil; + try + { + fn(); + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +void cppCall(void (^fn)(const Ice::Context&), ICEContext* context) +{ + NSException* nsex = nil; + try + { + Ice::Context ctx; + fromNSDictionary(context, ctx); + fn(ctx); + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&), ICEObjectPrx* prx) +{ + NSException* nsex = nil; + try + { + Ice::AsyncResultPtr r; + fn(r); + return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::CallbackPtr&), + void (^completed)(const Ice::AsyncResultPtr&), + void (^exception)(ICEException*), + void (^sent)(BOOL), + ICEObjectPrx* prx) +{ + NSException* nsex = nil; + try + { + AsyncCallback* cb = new AsyncCallback(completed, exception, sent); + Ice::AsyncResultPtr r; + Ice::CallbackPtr callback = Ice::newCallback(cb, &AsyncCallback::completed, &AsyncCallback::sent); + fn(r, callback); + return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&), + ICEContext* context, + ICEObjectPrx* prx) +{ + NSException* nsex = nil; + try + { + Ice::Context ctx; + fromNSDictionary(context, ctx); + Ice::AsyncResultPtr r; + fn(r, ctx); + return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +ICEAsyncResult* beginCppCall(void (^fn)(Ice::AsyncResultPtr&, const Ice::Context&, const Ice::CallbackPtr&), + ICEContext* context, + void (^completed)(const Ice::AsyncResultPtr&), + void (^exception)(ICEException*), + void (^sent)(BOOL), + ICEObjectPrx* prx) +{ + NSException* nsex = nil; + try + { + Ice::Context ctx; + fromNSDictionary(context, ctx); + AsyncCallback* cb = new AsyncCallback(completed, exception, sent); + Ice::AsyncResultPtr r; + Ice::CallbackPtr callback = Ice::newCallback(cb, &AsyncCallback::completed, &AsyncCallback::sent); + fn(r, ctx, callback); + return [ICEAsyncResult asyncResultWithAsyncResult__:r operation:nil proxy:prx]; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +void endCppCall(void (^fn)(const Ice::AsyncResultPtr&), ICEAsyncResult* r) +{ + NSException* nsex = nil; + try + { + fn([r asyncResult__]); + return; + } + catch(const std::exception& ex) + { + nsex = toObjCException(ex); + } + @throw nsex; +} + +NSException* +toObjCException(const std::exception& ex) +{ + const Ice::LocalException* lex = dynamic_cast<const Ice::LocalException*>(&ex); + if(lex) + { + std::string typeId = std::string("ICE") + lex->ice_name().substr(5); + Class c = objc_getClass(typeId.c_str()); + if(c != nil) + { + return [c localExceptionWithLocalException:*lex]; + } + else + { + Ice::UnknownLocalException ulex(__FILE__, __LINE__, ex.what()); + return [ICEUnknownLocalException localExceptionWithLocalException:ulex]; + } + } + + const Ice::UserException* uex = dynamic_cast<const Ice::UserException*>(&ex); + if(uex) + { + Ice::UnknownUserException uuex(__FILE__, __LINE__, ex.what()); + return [ICEUnknownUserException localExceptionWithLocalException:uuex]; + } + + const IceUtil::IllegalArgumentException* iaex = dynamic_cast<const IceUtil::IllegalArgumentException*>(&ex); + if(iaex) + { + return [NSException exceptionWithName:NSInvalidArgumentException + reason:[NSString stringWithUTF8String:iaex->reason().c_str()] + userInfo:nil]; + } + + const IceObjC::Exception* objCEx = dynamic_cast<const IceObjC::Exception*>(&ex); + if(objCEx) + { + id<NSObject> oex = objCEx->exception(); + if(oex == nil) + { + return [NSException exceptionWithName:@"unknown Objective-C exception" + reason:[NSString stringWithUTF8String:ex.what()] + userInfo:nil]; + } + else if([oex isKindOfClass:[NSException class]]) + { + return [[(NSException*)oex retain] autorelease]; + } + else + { + return [NSException exceptionWithName:@"unknown Objective-C exception" + reason:[oex description] + userInfo:nil]; + } + } + + // + // std::exception from the Ice runtime are translated to NSException. + // + return [NSException exceptionWithName:@"std::exception" + reason:[NSString stringWithUTF8String:ex.what()] + userInfo:nil]; +} + +void +rethrowCxxException(id e, bool release) +{ + @try + { + @throw e; + } + @catch(ICEUserException* ex) + { + Ice::UnknownUserException uuex(__FILE__, __LINE__, fromNSString([ex description])); + if(release) + { + [ex release]; + } + throw uuex; + } + @catch(ICELocalException* ex) + { + if(release) + { + try + { + [ex rethrowCxx]; + } + catch(const std::exception&) + { + [ex release]; + throw; + } + } + else + { + [ex rethrowCxx]; + } + } + @catch(id ex) + { + if([ex conformsToProtocol:@protocol(NSObject)]) + { + IceObjC::Exception exo(ex); + if(release) + { + [ex release]; + } + throw exo; + } + else + { + throw IceObjC::Exception(nil); + } + } +} + +std::string +toObjCSliceId(const std::string& sliceId, NSDictionary* prefixTable) +{ + std::string objcType = sliceId; + + if(objcType.find("::Ice::") == 0) + { + return objcType.replace(0, 7, "ICE"); + } + + std::string::size_type pos = objcType.rfind("::"); + if(pos != std::string::npos) + { + NSString* moduleName = toNSString(objcType.substr(0, pos)); + NSString* prefix = [prefixTable objectForKey:moduleName]; + [moduleName release]; + if(prefix) + { + return objcType.replace(0, pos + 2, fromNSString(prefix)); + } + } + + while((pos = objcType.find("::")) != std::string::npos) + { + objcType = objcType.replace(pos, 2, ""); + } + return objcType; +} + +IceObjC::Exception::Exception(id<NSObject> ex) : _ex([ex retain]) +{ +} + +IceObjC::Exception::Exception(const IceObjC::Exception& ex) : _ex([ex._ex retain]) +{ +} + +IceObjC::Exception::~Exception() throw() +{ + [_ex release]; +} + +std::string +IceObjC::Exception::ice_name() const +{ + return "IceObjC::Exception"; +} + +void +IceObjC::Exception::ice_print(std::ostream& os) const +{ + IceUtil::Exception::ice_print(os); + if(_ex != nil) + { + os << ":\n" << fromNSString([_ex description]); + } +} + +IceObjC::Exception* +IceObjC::Exception::ice_clone() const +{ + return new Exception(*this); +} + +void +IceObjC::Exception::ice_throw() const +{ + throw *this; +} + +NSObject<NSCopying>* +toObjC(const Ice::EndpointPtr& endpoint) +{ + return [ICEEndpoint localObjectWithCxxObjectNoAutoRelease:endpoint.get()]; +} + +void +fromObjC(id object, Ice::EndpointPtr& endpoint) +{ + endpoint = object == [NSNull null] ? 0 : [object endpoint]; +} + +ICEObject* +toObjC(const Ice::ObjectPtr& object) +{ + if(!object) + { + return nil; + } + + IceObjC::ObjectWrapperPtr wrapper = IceObjC::ObjectWrapperPtr::dynamicCast(object); + if(wrapper) + { + // + // Given object is an Objective-C servant wrapped into a C++ + // object, return the wrapped Objective-C object. + // + return [[wrapper->getObject() retain] autorelease]; + } + else if(Ice::NativePropertiesAdminPtr::dynamicCast(object)) + { + // + // Given object is a properties admin facet, return the + // Objective-C wrapper. + // + return [ICENativePropertiesAdmin objectWrapperWithCxxObject:object.get()]; + } + else + { + // + // Given object is a C++ servant, return an Objective-C wrapper. + // + return [ICEObjectWrapper objectWrapperWithCxxObject:object.get()]; + } +} diff --git a/objective-c/src/Ice/VersionI.h b/objective-c/src/Ice/VersionI.h new file mode 100644 index 00000000000..d894260dca3 --- /dev/null +++ b/objective-c/src/Ice/VersionI.h @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/Ice/Version.h> + +#include <Ice/Version.h> + +@interface ICEProtocolVersion (ICEInternal) ++(void) load; +-(ICEProtocolVersion*)initWithProtocolVersion:(const Ice::ProtocolVersion&)arg; +-(Ice::ProtocolVersion)protocolVersion; ++(ICEProtocolVersion*)protocolVersionWithProtocolVersion:(const Ice::ProtocolVersion&)arg; +@end + +@interface ICEEncodingVersion (ICEInternal) ++(void) load; +-(ICEEncodingVersion*)initWithEncodingVersion:(const Ice::EncodingVersion&)arg; +-(Ice::EncodingVersion)encodingVersion; ++(ICEEncodingVersion*)encodingVersionWithEncodingVersion:(const Ice::EncodingVersion&)arg; +@end + diff --git a/objective-c/src/Ice/VersionI.mm b/objective-c/src/Ice/VersionI.mm new file mode 100644 index 00000000000..d1c3b263f08 --- /dev/null +++ b/objective-c/src/Ice/VersionI.mm @@ -0,0 +1,127 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <VersionI.h> +#import <Util.h> + +ICE_API ICEEncodingVersion* ICEEncoding_1_0; +ICE_API ICEEncodingVersion* ICEEncoding_1_1; +ICE_API ICEEncodingVersion* ICECurrentEncoding; + +@implementation ICEEncodingVersion (ICEInternal) + ++(void) load +{ + ICEEncoding_1_0 = [[ICEEncodingVersion alloc] init:1 minor:0]; + ICEEncoding_1_1 = [[ICEEncodingVersion alloc] init:1 minor:1]; + ICECurrentEncoding = [[ICEEncodingVersion alloc] init:IceInternal::encodingMajor minor:IceInternal::encodingMinor]; +} + +-(ICEEncodingVersion*) initWithEncodingVersion:(const Ice::EncodingVersion&)arg +{ + self = [super init]; + if(!self) + { + return nil; + } + major = arg.major; + minor = arg.minor; + return self; +} + +-(Ice::EncodingVersion) encodingVersion +{ + Ice::EncodingVersion v; + v.major = major; + v.minor = minor; + return v; +} + ++(ICEEncodingVersion*) encodingVersionWithEncodingVersion:(const Ice::EncodingVersion&)arg +{ + if(arg == Ice::Encoding_1_0) + { + return ICEEncoding_1_0; + } + else if(arg == Ice::Encoding_1_1) + { + return ICEEncoding_1_1; + } + else if(arg == Ice::currentEncoding) + { + return ICECurrentEncoding; + } + else + { + return [[[ICEEncodingVersion alloc] initWithEncodingVersion:arg] autorelease]; + } +} + +-(NSString*) description +{ + return [toNSString(Ice::encodingVersionToString([self encodingVersion])) autorelease]; +} +@end + + +ICEProtocolVersion* ICEProtocol_1_0; +ICEProtocolVersion* ICECurrentProtocol; +ICEEncodingVersion* ICECurrentProtocolEncoding; + +@implementation ICEProtocolVersion (ICEInternal) + ++(void) load +{ + ICEProtocol_1_0 = [[ICEProtocolVersion alloc] init:1 minor:0]; + ICECurrentProtocol = [[ICEProtocolVersion alloc] init:IceInternal::protocolMajor minor:IceInternal::protocolMinor]; + ICECurrentProtocolEncoding = [[ICEEncodingVersion alloc] init:IceInternal::protocolEncodingMajor + minor:IceInternal::protocolEncodingMinor]; +} + +-(ICEProtocolVersion*) initWithProtocolVersion:(const Ice::ProtocolVersion&)arg +{ + self = [super init]; + if(!self) + { + return nil; + } + major = arg.major; + minor = arg.minor; + return self; +} + +-(Ice::ProtocolVersion) protocolVersion +{ + Ice::ProtocolVersion v; + v.major = major; + v.minor = minor; + return v; +} + ++(ICEProtocolVersion*) protocolVersionWithProtocolVersion:(const Ice::ProtocolVersion&)arg +{ + if(arg == Ice::Protocol_1_0) + { + return ICEProtocol_1_0; + } + else if(arg == Ice::currentProtocol) + { + return ICECurrentProtocol; + } + else + { + return [[[ICEProtocolVersion alloc] initWithProtocolVersion:arg] autorelease]; + } +} + +-(NSString*) description +{ + return [toNSString(Ice::protocolVersionToString([self protocolVersion])) autorelease]; +} +@end diff --git a/objective-c/src/IceGrid/.gitignore b/objective-c/src/IceGrid/.gitignore new file mode 100644 index 00000000000..1d8a22c0997 --- /dev/null +++ b/objective-c/src/IceGrid/.gitignore @@ -0,0 +1,28 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +Admin.m +Descriptor.m +Discovery.m +Exception.m +FileParser.m +Locator.m +Observer.m +PluginFacade.m +Query.m +Registry.m +Session.m +UserAccountMapper.m +Admin.h +Descriptor.h +Discovery.h +Exception.h +FileParser.h +Locator.h +Observer.h +PluginFacade.h +Query.h +Registry.h +Session.h +UserAccountMapper.h diff --git a/objective-c/src/IceGrid/Makefile b/objective-c/src/IceGrid/Makefile new file mode 100644 index 00000000000..6aca248fa09 --- /dev/null +++ b/objective-c/src/IceGrid/Makefile @@ -0,0 +1,55 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +LIBFILENAME = $(call mklibfilename,IceGridObjC,$(VERSION)) +SONAME = $(call mksoname,IceGridObjC,$(SOVERSION)) +LIBNAME = $(call mklibname,IceGridObjC) + +TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) + +SLICE_OBJS = Admin.o \ + Descriptor.o \ + Exception.o \ + FileParser.o \ + Locator.o \ + Observer.o \ + PluginFacade.o \ + Query.o \ + Registry.o \ + Session.o \ + UserAccountMapper.o + +OBJS = $(SLICE_OBJS) + +HDIR = $(headerdir)/objc/IceGrid +SDIR = $(slicedir)/IceGrid + +include $(top_srcdir)/config/Make.rules + +SLICE2OBJCFLAGS := --ice --include-dir objc/IceGrid --dll-export ICE_GRID_API $(SLICE2OBJCFLAGS) +LINKWITH := -lGlacier2ObjC $(LIBS) + +$(libdir)/$(LIBFILENAME): $(OBJS) + @mkdir -p $(dir $@) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + @mkdir -p $(libdir) + rm -f $@ + ln -s $(SONAME) $@ + +install:: all + $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/objective-c/src/IceSSL/.gitignore b/objective-c/src/IceSSL/.gitignore new file mode 100644 index 00000000000..6252a80b316 --- /dev/null +++ b/objective-c/src/IceSSL/.gitignore @@ -0,0 +1,8 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +EndpointInfo.m +ConnectionInfo.m +EndpointInfo.h +ConnectionInfo.h diff --git a/objective-c/src/IceSSL/ConnectionInfoI.mm b/objective-c/src/IceSSL/ConnectionInfoI.mm new file mode 100644 index 00000000000..20b88aa5551 --- /dev/null +++ b/objective-c/src/IceSSL/ConnectionInfoI.mm @@ -0,0 +1,51 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/IceSSL/ConnectionInfo.h> +#import <ConnectionI.h> +#import <LocalObjectI.h> +#import <Util.h> + +#include <IceSSL/ConnectionInfo.h> + +@implementation ICESSLConnectionInfo (IceSSL) + +-(id) initWithSSLConnectionInfo:(IceSSL::ConnectionInfo*)sslConnectionInfo +{ + self = [super initWithIPConnectionInfo:sslConnectionInfo]; + if(self) + { + self->cipher = [[NSString alloc] initWithUTF8String:sslConnectionInfo->cipher.c_str()]; + self->certs = toNSArray(sslConnectionInfo->certs); + } + return self; +} + +@end + +@implementation ICEConnectionInfo (IceSSL) + ++(id) connectionInfoWithType_ssl:(NSValue*)connectionInfo +{ + if(!connectionInfo) + { + return nil; + } + + IceUtil::Shared* shared = reinterpret_cast<IceUtil::Shared*>([connectionInfo pointerValue]); + IceSSL::ConnectionInfo* obj = dynamic_cast<IceSSL::ConnectionInfo*>(shared); + if(obj) + { + return [[[ICESSLConnectionInfo alloc] initWithSSLConnectionInfo:obj] autorelease]; + } + return nil; +} + +@end + diff --git a/objective-c/src/IceSSL/EndpointInfoI.mm b/objective-c/src/IceSSL/EndpointInfoI.mm new file mode 100644 index 00000000000..ca65883d7a0 --- /dev/null +++ b/objective-c/src/IceSSL/EndpointInfoI.mm @@ -0,0 +1,49 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#import <objc/IceSSL/EndpointInfo.h> +#import <ConnectionI.h> +#import <LocalObjectI.h> +#import <Util.h> + +#include <IceSSL/EndpointInfo.h> + +@implementation ICESSLEndpointInfo (IceSSL) + +-(id) initWithSSLEndpointInfo:(IceSSL::EndpointInfo*)sslEndpointInfo +{ + self = [super initWithIPEndpointInfo:sslEndpointInfo]; + if(self) + { + } + return self; +} + +@end + +@implementation ICEEndpointInfo (IceSSL) + ++(id) endpointInfoWithType_2:(NSValue*)endpointInfo +{ + if(!endpointInfo) + { + return nil; + } + + IceUtil::Shared* shared = reinterpret_cast<IceUtil::Shared*>([endpointInfo pointerValue]); + IceSSL::EndpointInfo* obj = dynamic_cast<IceSSL::EndpointInfo*>(shared); + if(obj) + { + return [[[ICESSLEndpointInfo alloc] initWithSSLEndpointInfo:obj] autorelease]; + } + return nil; +} + +@end + diff --git a/objective-c/src/IceSSL/Makefile b/objective-c/src/IceSSL/Makefile new file mode 100644 index 00000000000..d25103405a1 --- /dev/null +++ b/objective-c/src/IceSSL/Makefile @@ -0,0 +1,50 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +LIBFILENAME = $(call mklibfilename,IceSSLObjC,$(VERSION)) +SONAME = $(call mksoname,IceSSLObjC,$(SOVERSION)) +LIBNAME = $(call mklibname,IceSSLObjC) + +TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) + +SLICE_OBJS = EndpointInfo.o \ + ConnectionInfo.o + +OBJCXX_OBJS = EndpointInfoI.o \ + ConnectionInfoI.o + +OBJS = $(SLICE_OBJS) $(OBJCXX_OBJS) + +HDIR = $(headerdir)/objc/IceSSL +SDIR = $(slicedir)/IceSSL + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I../Ice -I$(ice_cpp_dir)/include $(CPPFLAGS) +SLICE2OBJCFLAGS := --ice --include-dir objc/IceSSL --dll-export ICE_SSL_API $(SLICE2OBJCFLAGS) +LINKWITH := -lIceObjC$(libsuffix) $(BASELIBS) + +$(libdir)/$(LIBFILENAME): $(OBJS) + @mkdir -p $(dir $@) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + @mkdir -p $(libdir) + rm -f $@ + ln -s $(SONAME) $@ + +install:: all + $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/objective-c/src/IceStorm/.gitignore b/objective-c/src/IceStorm/.gitignore new file mode 100644 index 00000000000..166500719d4 --- /dev/null +++ b/objective-c/src/IceStorm/.gitignore @@ -0,0 +1,8 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +.depend +Metrics.m +IceStorm.m +Metrics.h +IceStorm.h diff --git a/objective-c/src/IceStorm/Makefile b/objective-c/src/IceStorm/Makefile new file mode 100644 index 00000000000..1c55d69ffae --- /dev/null +++ b/objective-c/src/IceStorm/Makefile @@ -0,0 +1,45 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +LIBFILENAME = $(call mklibfilename,IceStormObjC,$(VERSION)) +SONAME = $(call mksoname,IceStormObjC,$(SOVERSION)) +LIBNAME = $(call mklibname,IceStormObjC) + +TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) + +SLICE_OBJS = Metrics.o \ + IceStorm.o + +OBJS = $(SLICE_OBJS) + +HDIR = $(headerdir)/objc/IceStorm +SDIR = $(slicedir)/IceStorm + +include $(top_srcdir)/config/Make.rules + +SLICE2OBJCFLAGS := --ice --include-dir objc/IceStorm --dll-export ICE_STORM_API $(SLICE2OBJCFLAGS) + +$(libdir)/$(LIBFILENAME): $(OBJS) + @mkdir -p $(dir $@) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(OBJS),$(LIBS)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + @mkdir -p $(libdir) + rm -f $@ + ln -s $(SONAME) $@ + +install:: all + $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/objective-c/src/Makefile b/objective-c/src/Makefile new file mode 100644 index 00000000000..ef3ea47451d --- /dev/null +++ b/objective-c/src/Makefile @@ -0,0 +1,40 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = Ice IceSSL Glacier2 IceStorm IceGrid + +.PHONY: $(EVERYTHING) $(SUBDIRS) + +# +# Dependencies for 'all' target when using -jx +# + +IceSSL Glacier2 IceStorm IceGrid: Ice + +IceGrid: Glacier2 + +all:: $(SUBDIRS) + +$(SUBDIRS): + @echo "making all in $@" + @$(MAKE) all --directory=$@ + +$(EVERYTHING_EXCEPT_ALL):: + @for subdir in $(SUBDIRS); \ + do \ + if test -d $$subdir ; \ + then \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + fi; \ + done |