// // Copyright (c) ZeroC, Inc. All rights reserved. // #include #import #import #import #import #import #import #import namespace IceObjC { class UnknownSlicedValueFactoryI : public Ice::ValueFactory { public: virtual Ice::ObjectPtr create(const std::string&) { ICEUnknownSlicedValue* obj = [[ICEUnknownSlicedValue alloc] init]; Ice::ObjectPtr o = [ICEInputStream createObjectReader:obj]; [obj release]; return o; } }; class ValueFactoryI : public Ice::ValueFactory { public: ValueFactoryI(NSDictionary* factories, NSDictionary* prefixTable) : _factories(factories), _prefixTable(prefixTable) { CFRetain(_factories); CFRetain(_prefixTable); } ~ValueFactoryI() { CFRelease(_factories); CFRelease(_prefixTable); } virtual Ice::ObjectPtr create(const std::string& type) { NSString* sliceId = [[NSString alloc] initWithUTF8String:type.c_str()]; NSException* ex = nil; @try { ICEValueFactory factory = nil; @synchronized(_factories) { factory = [_factories objectForKey:sliceId]; if(factory == nil) { factory = [_factories objectForKey:@""]; } } ICEObject* obj = nil; if(factory != nil) { obj = factory(sliceId); } if(obj == nil) { std::string tId = toObjCSliceId(type, _prefixTable); Class c = objc_lookUpClass(tId.c_str()); if(c == nil) { return 0; // No value 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 exc) { ex = exc; } @finally { [sliceId release]; } if(ex != nil) { rethrowCxxException(ex); } return nil; // Keep the compiler happy. } private: NSDictionary* _factories; NSDictionary* _prefixTable; }; } @implementation ICEValueFactoryManager -(id) init:(Ice::Communicator*)com prefixTable:(NSDictionary*)prefixTable { self = [super init]; if(!self) { return nil; } valueFactories_ = [[NSMutableDictionary alloc] init]; com->getValueFactoryManager()->add(new IceObjC::UnknownSlicedValueFactoryI, "::Ice::Object"); com->getValueFactoryManager()->add(new IceObjC::ValueFactoryI(valueFactories_, prefixTable), ""); return self; } -(void) dealloc { [valueFactories_ release]; [super dealloc]; } -(void) add:(ICEValueFactory)factory sliceId:(NSString*)sliceId { @synchronized(valueFactories_) { [valueFactories_ setObject:ICE_AUTORELEASE([factory copy]) forKey:sliceId]; } } -(ICEValueFactory) find:(NSString*)sliceId { @synchronized(valueFactories_) { return [valueFactories_ objectForKey:sliceId]; } return nil; // Keep the compiler happy. } @end