// // Copyright (c) ZeroC, Inc. All rights reserved. // #include #if TARGET_OS_IPHONE != 0 #include "EndpointI.h" #include "Connector.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace Ice; using namespace IceInternal; namespace { class iAPEndpointFactoryPlugin : public Ice::Plugin { public: iAPEndpointFactoryPlugin(const Ice::CommunicatorPtr& com) { ProtocolPluginFacadePtr f = getProtocolPluginFacade(com); // iAP transport ProtocolInstancePtr iap = new ProtocolInstance(com, iAPEndpointType, "iap", false); f->addEndpointFactory(new IceObjC::iAPEndpointFactory(iap)); // SSL based on iAP transport ProtocolInstancePtr iaps = new ProtocolInstance(com, iAPSEndpointType, "iaps", true); f->addEndpointFactory(new UnderlyingEndpointFactory(iaps, SSLEndpointType, iAPEndpointType)); } virtual void initialize() {} virtual void destroy() {} }; } extern "C" ICEIAP_API Plugin* createIceIAP(const CommunicatorPtr& com, const string&, const StringSeq&) { return new iAPEndpointFactoryPlugin(com); } namespace Ice { ICEIAP_API void registerIceIAP(bool loadOnInitialize) { Ice::registerPluginFactory("IceIAP", createIceIAP, loadOnInitialize); } } // // Objective-C function to allow Objective-C programs to register plugin. // extern "C" ICEIAP_API void ICEregisterIceIAP(bool loadOnInitialize) { Ice::registerIceIAP(loadOnInitialize); } IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, const string& m, const string& o, const string& n, const string& p, Int ti, const string& conId, bool co) : _instance(instance), _manufacturer(m), _modelNumber(o), _name(n), _protocol(p), _timeout(ti), _connectionId(conId), _compress(co) { } IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance) : _instance(instance), _timeout(-1), _compress(false) { } IceObjC::iAPEndpointI::iAPEndpointI(const ProtocolInstancePtr& instance, InputStream* s) : _instance(instance), _timeout(-1), _compress(false) { s->read(const_cast(_manufacturer), false); s->read(const_cast(_modelNumber), false); s->read(const_cast(_name), false); s->read(const_cast(_protocol), false); s->read(const_cast(_timeout)); s->read(const_cast(_compress)); } void IceObjC::iAPEndpointI::streamWriteImpl(OutputStream* s) const { s->write(_manufacturer, false); s->write(_modelNumber, false); s->write(_name, false); s->write(_protocol, false); s->write(_timeout); s->write(_compress); } EndpointInfoPtr IceObjC::iAPEndpointI::getInfo() const ICE_NOEXCEPT { IceIAP::EndpointInfoPtr info = ICE_MAKE_SHARED(InfoI, ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); info->timeout = _timeout; info->compress = _compress; info->manufacturer = _manufacturer; info->modelNumber = _modelNumber; info->name = _name; info->protocol = _protocol; return info; } Short IceObjC::iAPEndpointI::type() const { return _instance->type(); } const string& IceObjC::iAPEndpointI::protocol() const { return _instance->protocol(); } bool IceObjC::iAPEndpointI::datagram() const { return false; } bool IceObjC::iAPEndpointI::secure() const { return _instance->secure(); } Int IceObjC::iAPEndpointI::timeout() const { return _timeout; } EndpointIPtr IceObjC::iAPEndpointI::timeout(Int t) const { if(t == _timeout) { return ICE_SHARED_FROM_CONST_THIS(iAPEndpointI); } else { return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, t, _connectionId, _compress); } } const string& IceObjC::iAPEndpointI::connectionId() const { return _connectionId; } EndpointIPtr IceObjC::iAPEndpointI::connectionId(const string& cId) const { if(cId == _connectionId) { return ICE_SHARED_FROM_CONST_THIS(iAPEndpointI); } else { return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, cId, _compress); } } bool IceObjC::iAPEndpointI::compress() const { return _compress; } EndpointIPtr IceObjC::iAPEndpointI::compress(bool c) const { if(c == _compress) { return ICE_SHARED_FROM_CONST_THIS(iAPEndpointI); } else { return ICE_MAKE_SHARED(iAPEndpointI, _instance, _manufacturer, _modelNumber, _name, _protocol, _timeout, _connectionId, c); } } TransceiverPtr IceObjC::iAPEndpointI::transceiver() const { return 0; } void IceObjC::iAPEndpointI::connectors_async(Ice::EndpointSelectionType /*selType*/, const EndpointI_connectorsPtr& callback) const { try { vector c; EAAccessoryManager* manager = [EAAccessoryManager sharedAccessoryManager]; if(manager == nil) { throw Ice::ConnectFailedException(__FILE__, __LINE__, 0); } NSString* protocol = _protocol.empty() ? @"com.zeroc.ice" : [[NSString alloc] initWithUTF8String:_protocol.c_str()]; NSArray* array = [manager connectedAccessories]; NSEnumerator* enumerator = [array objectEnumerator]; EAAccessory* accessory = nil; while((accessory = [enumerator nextObject])) { if(!accessory.connected) { continue; } if(!_manufacturer.empty() && _manufacturer != [accessory.manufacturer UTF8String]) { continue; } if(!_modelNumber.empty() && _modelNumber != [accessory.modelNumber UTF8String]) { continue; } if(!_name.empty() && _name != [accessory.name UTF8String]) { continue; } if(![accessory.protocolStrings containsObject:protocol]) { continue; } c.push_back(new iAPConnector(_instance, _timeout, _connectionId, protocol, accessory)); } #if defined(__clang__) && !__has_feature(objc_arc) [protocol release]; #endif if(c.empty()) { throw Ice::ConnectFailedException(__FILE__, __LINE__, 0); } callback->connectors(c); } catch(const Ice::LocalException& ex) { callback->exception(ex); } } AcceptorPtr IceObjC::iAPEndpointI::acceptor(const string&) const { assert(false); return 0; } vector IceObjC::iAPEndpointI::expandIfWildcard() const { vector endps; endps.push_back(ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); return endps; } vector IceObjC::iAPEndpointI::expandHost(EndpointIPtr&) const { vector endps; endps.push_back(ICE_SHARED_FROM_CONST_THIS(iAPEndpointI)); return endps; } bool IceObjC::iAPEndpointI::equivalent(const EndpointIPtr& endpoint) const { const iAPEndpointI* endpointI = dynamic_cast(endpoint.get()); if(!endpointI) { return false; } return endpointI->_manufacturer == _manufacturer && endpointI->_modelNumber == _modelNumber && endpointI->_name == _name && endpointI->_protocol == _protocol; } bool #ifdef ICE_CPP11_MAPPING IceObjC::iAPEndpointI::operator==(const Ice::Endpoint& r) const #else IceObjC::iAPEndpointI::operator==(const Ice::LocalObject& r) const #endif { const iAPEndpointI* p = dynamic_cast(&r); if(!p) { return false; } if(this == p) { return true; } if(_manufacturer != p->_manufacturer) { return false; } if(_modelNumber != p->_modelNumber) { return false; } if(_name != p->_name) { return false; } if(_protocol != p->_protocol) { return false; } if(_timeout != p->_timeout) { return false; } if(_connectionId != p->_connectionId) { return false; } if(_compress != p->_compress) { return false; } return true; } bool #ifdef ICE_CPP11_MAPPING IceObjC::iAPEndpointI::operator<(const Ice::Endpoint& r) const #else IceObjC::iAPEndpointI::operator<(const Ice::LocalObject& r) const #endif { const iAPEndpointI* p = dynamic_cast(&r); if(!p) { const IceInternal::EndpointI* e = dynamic_cast(&r); if(!e) { return false; } return type() < e->type(); } if(this == p) { return false; } if(_manufacturer < p->_manufacturer) { return true; } else if(p->_manufacturer < _manufacturer) { return false; } if(_modelNumber < p->_modelNumber) { return true; } else if(p->_modelNumber < _modelNumber) { return false; } if(_name < p->_name) { return true; } else if(p->_name < _name) { return false; } if(_protocol < p->_protocol) { return true; } else if(p->_protocol < _protocol) { return false; } if(_timeout < p->_timeout) { return true; } else if(p->_timeout < _timeout) { return false; } if(_connectionId < p->_connectionId) { return true; } else if(p->_connectionId < _connectionId) { return false; } if(!_compress && p->_compress) { return true; } else if(p->_compress < _compress) { return false; } return false; } string IceObjC::iAPEndpointI::options() const { // // WARNING: Certain features, such as proxy validation in Glacier2, // depend on the format of proxy strings. Changes to toString() and // methods called to generate parts of the reference string could break // these features. Please review for all features that depend on the // format of proxyToString() before changing this and related code. // ostringstream s; if(!_manufacturer.empty()) { s << " -m "; bool addQuote = _manufacturer.find(':') != string::npos; if(addQuote) { s << "\""; } s << _manufacturer; if(addQuote) { s << "\""; } } if(!_modelNumber.empty()) { s << " -o "; bool addQuote = _modelNumber.find(':') != string::npos; if(addQuote) { s << "\""; } s << _modelNumber; if(addQuote) { s << "\""; } } if(!_name.empty()) { s << " -n "; bool addQuote = _name.find(':') != string::npos; if(addQuote) { s << "\""; } s << _name; if(addQuote) { s << "\""; } } if(!_protocol.empty()) { s << " -p "; bool addQuote = _protocol.find(':') != string::npos; if(addQuote) { s << "\""; } s << _protocol; if(addQuote) { s << "\""; } } if(_timeout != -1) { s << " -t " << _timeout; } if(_compress) { s << " -z"; } return s.str(); } Ice::Int IceObjC::iAPEndpointI::hash() const { Ice::Int h = 5381; hashAdd(h, _manufacturer); hashAdd(h, _modelNumber); hashAdd(h, _name); hashAdd(h, _protocol); hashAdd(h, _timeout); hashAdd(h, _connectionId); return h; } bool IceObjC::iAPEndpointI::checkOption(const string& option, const string& argument, const string& endpoint) { switch(option[1]) { case 'm': { if(argument.empty()) { EndpointParseException ex(__FILE__, __LINE__); ex.str = "no argument provided for -h option in endpoint " + endpoint; throw ex; } const_cast(_manufacturer) = argument; break; } case 'o': { if(argument.empty()) { EndpointParseException ex(__FILE__, __LINE__); ex.str = "no argument provided for -h option in endpoint " + endpoint; throw ex; } const_cast(_modelNumber) = argument; break; } case 'n': { if(argument.empty()) { EndpointParseException ex(__FILE__, __LINE__); ex.str = "no argument provided for -h option in endpoint " + endpoint; throw ex; } const_cast(_name) = argument; break; } case 'p': { if(argument.empty()) { EndpointParseException ex(__FILE__, __LINE__); ex.str = "no argument provided for -h option in endpoint " + endpoint; throw ex; } const_cast(_protocol) = argument; break; } case 't': { if(argument == "infinite") { const_cast(_timeout) = -1; } else { istringstream t(argument); if(!(t >> const_cast(_timeout)) || !t.eof() || _timeout < 1) { EndpointParseException ex(__FILE__, __LINE__); ex.str = "invalid timeout value `" + argument + "' in endpoint " + endpoint; throw ex; } } break; } case 'z': { if(!argument.empty()) { EndpointParseException ex(__FILE__, __LINE__); ex.str = "no argument provided for -h option in endpoint " + endpoint; throw ex; } const_cast(_compress) = true; break; } default: { return false; } } return true; } IceObjC::iAPEndpointFactory::iAPEndpointFactory(const ProtocolInstancePtr& instance) : _instance(instance) { } IceObjC::iAPEndpointFactory::~iAPEndpointFactory() { } Short IceObjC::iAPEndpointFactory::type() const { return _instance->type(); } string IceObjC::iAPEndpointFactory::protocol() const { return _instance->protocol(); } EndpointIPtr IceObjC::iAPEndpointFactory::create(vector& args, bool oaEndpoint) const { if(oaEndpoint) { return 0; } EndpointIPtr endpt = ICE_MAKE_SHARED(iAPEndpointI, _instance); endpt->initWithOptions(args); return endpt; } EndpointIPtr IceObjC::iAPEndpointFactory::read(InputStream* s) const { return ICE_MAKE_SHARED(iAPEndpointI, _instance, s); } void IceObjC::iAPEndpointFactory::destroy() { _instance = 0; } EndpointFactoryPtr IceObjC::iAPEndpointFactory::clone(const ProtocolInstancePtr& instance) const { return new iAPEndpointFactory(instance); } #endif