00001
00020 #include <iostream>
00021 #include <algorithm>
00022 #include <functional>
00023 #include <iterator>
00024 #include <coil/stringutil.h>
00025
00026 #include <rtm/ConnectorBase.h>
00027 #include <rtm/OutPortPushConnector.h>
00028 #include <rtm/OutPortPullConnector.h>
00029 #include <rtm/OutPortBase.h>
00030 #include <rtm/PublisherBase.h>
00031
00032
00033 namespace RTC
00034 {
00042 struct OutPortBase::provider_cleanup
00043 {
00044 provider_cleanup()
00045 : m_factory(OutPortProviderFactory::instance())
00046 {
00047 }
00048 void operator()(OutPortProvider* p)
00049 {
00050 m_factory.deleteObject(p);
00051 }
00052 OutPortProviderFactory& m_factory;
00053 };
00054
00062 struct OutPortBase::connector_cleanup
00063 {
00064 connector_cleanup()
00065 {
00066 }
00067 void operator()(OutPortConnector* c)
00068 {
00069 delete c;
00070 }
00071 };
00072
00073
00081 OutPortBase::OutPortBase(const char* name, const char* data_type)
00082 : PortBase(name), m_littleEndian(true)
00083 {
00084 RTC_DEBUG(("Port name: %s", name));
00085
00086 RTC_DEBUG(("setting port.port_type: DataOutPort"));
00087 addProperty("port.port_type", "DataOutPort");
00088
00089 RTC_DEBUG(("setting dataport.data_type: %s", data_type));
00090 addProperty("dataport.data_type", data_type);
00091
00092
00093 PublisherFactory& factory(PublisherFactory::instance());
00094 std::string pubs = coil::flatten(factory.getIdentifiers());
00095
00096
00097 coil::eraseBlank(pubs);
00098 RTC_DEBUG(("available subscription_type: %s", pubs.c_str()));
00099 addProperty("dataport.subscription_type", pubs.c_str());
00100
00101 };
00102
00110 OutPortBase::~OutPortBase(void)
00111 {
00112 RTC_TRACE(("~OutPortBase()"));
00113
00114 std::for_each(m_connectors.begin(),
00115 m_connectors.end(),
00116 connector_cleanup());
00117 }
00118
00126 void OutPortBase::init(coil::Properties& prop)
00127 {
00128 RTC_TRACE(("init()"));
00129 RTC_PARANOID(("given properties:"));
00130 RTC_DEBUG_STR((prop));
00131
00132 m_properties << prop;
00133
00134 RTC_PARANOID(("updated properties:"));
00135 RTC_DEBUG_STR((m_properties));
00136
00137 configure();
00138
00139 initConsumers();
00140 initProviders();
00141 int num(-1);
00142 if (!coil::stringTo(num,
00143 m_properties.getProperty("connection_limit","-1").c_str()))
00144 {
00145 RTC_ERROR(("invalid connection_limit value: %s",
00146 m_properties.getProperty("connection_limit").c_str()));
00147 }
00148
00149 setConnectionLimit(num);
00150 }
00151
00159 coil::Properties& OutPortBase::properties()
00160 {
00161 RTC_TRACE(("properties()"));
00162 return m_properties;
00163 }
00164
00172 const std::vector<OutPortConnector*>& OutPortBase::connectors()
00173 {
00174 RTC_TRACE(("connectors(): size = %d", m_connectors.size()));
00175 return m_connectors;
00176 }
00177
00185 ConnectorInfoList OutPortBase::getConnectorProfiles()
00186 {
00187 RTC_TRACE(("getConnectorProfiles(): size = %d", m_connectors.size()));
00188 ConnectorInfoList profs;
00189 for (int i(0), len(m_connectors.size()); i < len; ++i)
00190 {
00191 profs.push_back(m_connectors[i]->profile());
00192 }
00193 return profs;
00194 }
00195
00203 coil::vstring OutPortBase::getConnectorIds()
00204 {
00205 coil::vstring ids;
00206 for (int i(0), len(m_connectors.size()); i < len; ++i)
00207 {
00208 ids.push_back(m_connectors[i]->id());
00209 }
00210 RTC_TRACE(("getConnectorIds(): %s", coil::flatten(ids).c_str()));
00211 return ids;
00212 }
00213
00221 coil::vstring OutPortBase::getConnectorNames()
00222 {
00223 coil::vstring names;
00224 for (int i(0), len(m_connectors.size()); i < len; ++i)
00225 {
00226 names.push_back(m_connectors[i]->name());
00227 }
00228 RTC_TRACE(("getConnectorNames(): %s", coil::flatten(names).c_str()));
00229 return names;
00230 }
00231
00239 OutPortConnector* OutPortBase::getConnectorById(const char* id)
00240 {
00241 RTC_TRACE(("getConnectorById(id = %s)", id));
00242
00243 std::string sid(id);
00244 for (int i(0), len(m_connectors.size()); i < len; ++i)
00245 {
00246 if (sid == m_connectors[i]->id())
00247 {
00248 return m_connectors[i];
00249 }
00250 }
00251 RTC_WARN(("ConnectorProfile with the id(%s) not found.", id));
00252 return 0;
00253 }
00254
00262 OutPortConnector* OutPortBase::getConnectorByName(const char* name)
00263 {
00264 RTC_TRACE(("getConnectorByName(name = %s)", name));
00265
00266 std::string sname(name);
00267 for (int i(0), len(m_connectors.size()); i < len; ++i)
00268 {
00269 if (sname == m_connectors[i]->name())
00270 {
00271 return m_connectors[i];
00272 }
00273 }
00274 RTC_WARN(("ConnectorProfile with the name(%s) not found.", name));
00275 return 0;
00276 }
00277
00285 bool OutPortBase::getConnectorProfileById(const char* id,
00286 ConnectorInfo& prof)
00287 {
00288 RTC_TRACE(("getConnectorProfileById(id = %s)", id));
00289 OutPortConnector* conn(getConnectorById(id));
00290 if (conn == 0)
00291 {
00292 return false;
00293 }
00294 prof = conn->profile();
00295 return true;
00296 }
00297
00305 bool OutPortBase::getConnectorProfileByName(const char* name,
00306 ConnectorInfo& prof)
00307 {
00308 RTC_TRACE(("getConnectorProfileByName(name = %s)", name));
00309 OutPortConnector* conn(getConnectorByName(name));
00310 if (conn == 0)
00311 {
00312 return false;
00313 }
00314 prof = conn->profile();
00315 return true;
00316 }
00317
00325 void OutPortBase::activateInterfaces()
00326 {
00327 RTC_TRACE(("activateInterfaces()"));
00328
00329 for (int i(0), len(m_connectors.size()); i < len; ++i)
00330 {
00331 m_connectors[i]->activate();
00332 }
00333 }
00334
00342 void OutPortBase::deactivateInterfaces()
00343 {
00344 RTC_TRACE(("deactivateInterfaces()"));
00345
00346 for (int i(0), len(m_connectors.size()); i < len; ++i)
00347 {
00348 m_connectors[i]->deactivate();
00349 }
00350 }
00351
00352
00364 void OutPortBase::
00365 addConnectorDataListener(ConnectorDataListenerType type,
00366 ConnectorDataListener* listener,
00367 bool autoclean)
00368 {
00369 if (type < CONNECTOR_DATA_LISTENER_NUM)
00370 {
00371 RTC_TRACE(("addConnectorDataListener(%s)",
00372 ConnectorDataListener::toString(type)));
00373 m_listeners.connectorData_[type].addListener(listener, autoclean);
00374 return;
00375 }
00376 RTC_ERROR(("addConnectorDataListener(): Unknown Listener Type"));
00377 return;
00378 }
00379
00389 void OutPortBase::
00390 removeConnectorDataListener(ConnectorDataListenerType type,
00391 ConnectorDataListener* listener)
00392 {
00393 if (type < CONNECTOR_DATA_LISTENER_NUM)
00394 {
00395 RTC_TRACE(("removeConnectorDataListener(%s)",
00396 ConnectorDataListener::toString(type)));
00397 m_listeners.connectorData_[type].removeListener(listener);
00398 return;
00399 }
00400 RTC_ERROR(("removeConnectorDataListener(): Unknown Listener Type"));
00401 return;
00402 }
00403
00413 void OutPortBase::addConnectorListener(ConnectorListenerType type,
00414 ConnectorListener* listener,
00415 bool autoclean)
00416 {
00417 if (type < CONNECTOR_LISTENER_NUM)
00418 {
00419 RTC_TRACE(("addConnectorListener(%s)",
00420 ConnectorListener::toString(type)));
00421 m_listeners.connector_[type].addListener(listener, autoclean);
00422 return;
00423 }
00424 RTC_ERROR(("addConnectorListener(): Unknown Listener Type"));
00425 return;
00426 }
00427
00437 void OutPortBase::removeConnectorListener(ConnectorListenerType type,
00438 ConnectorListener* listener)
00439 {
00440 if (type < CONNECTOR_LISTENER_NUM)
00441 {
00442 RTC_TRACE(("removeConnectorListener(%s)",
00443 ConnectorListener::toString(type)));
00444 m_listeners.connector_[type].removeListener(listener);
00445 return;
00446 }
00447 RTC_ERROR(("removeConnectorListener(): Unknown Listener Type"));
00448 return;
00449 }
00450
00458 bool OutPortBase::isLittleEndian()
00459 {
00460 return m_littleEndian;
00461 }
00462
00470 ReturnCode_t OutPortBase::connect(ConnectorProfile& connector_profile)
00471 throw (CORBA::SystemException)
00472 {
00473 RTC_TRACE(("OutPortBase::connect()"));
00474
00475
00476 CORBA::Long index(NVUtil::find_index(connector_profile.properties,
00477 "dataport.serializer.cdr.endian"));
00478 if (index < 0)
00479 {
00480 RTC_TRACE(("ConnectorProfile dataport.serializer.cdr.endian set."));
00481
00482 CORBA_SeqUtil::push_back(connector_profile.properties,
00483 NVUtil::newNV("dataport.serializer.cdr.endian", "little,big"));
00484 }
00485 return PortBase::connect(connector_profile);
00486 }
00487
00488
00489
00490
00491
00499 void OutPortBase::configure()
00500 {
00501
00502 }
00503
00504
00512 ReturnCode_t OutPortBase::publishInterfaces(ConnectorProfile& cprof)
00513 {
00514 RTC_TRACE(("publishInterfaces()"));
00515
00516 ReturnCode_t returnvalue = _publishInterfaces();
00517 if(returnvalue!=RTC::RTC_OK)
00518 {
00519 return returnvalue;
00520 }
00521
00522
00523 coil::Properties prop(m_properties);
00524 {
00525 coil::Properties conn_prop;
00526 NVUtil::copyToProperties(conn_prop, cprof.properties);
00527 prop << conn_prop.getNode("dataport");
00528
00529
00530
00531
00532
00533
00534 prop << conn_prop.getNode("dataport.outport");
00535 }
00536 RTC_DEBUG(("ConnectorProfile::properties are as follows."));
00537 RTC_PARANOID_STR((prop));
00538
00539
00540
00541
00542
00543
00544
00545 std::string dflow_type(prop["dataflow_type"]);
00546 coil::normalize(dflow_type);
00547
00548 if (dflow_type == "push")
00549 {
00550 RTC_PARANOID(("dataflow_type = push .... do nothing"));
00551 return RTC::RTC_OK;
00552 }
00553 else if (dflow_type == "pull")
00554 {
00555 RTC_PARANOID(("dataflow_type = pull .... create PullConnector"));
00556
00557 OutPortProvider* provider(createProvider(cprof, prop));
00558 if (provider == 0)
00559 {
00560 return RTC::BAD_PARAMETER;
00561 }
00562
00563
00564 OutPortConnector* connector(createConnector(cprof, prop, provider));
00565 if (connector == 0)
00566 {
00567 return RTC::RTC_ERROR;
00568 }
00569
00570
00571 provider->setConnector(connector);
00572
00573 RTC_DEBUG(("publishInterface() successfully finished."));
00574 return RTC::RTC_OK;
00575 }
00576
00577 RTC_ERROR(("unsupported dataflow_type"));
00578
00579 return RTC::BAD_PARAMETER;
00580 }
00581
00589 ReturnCode_t OutPortBase::subscribeInterfaces(const ConnectorProfile& cprof)
00590 {
00591 RTC_TRACE(("subscribeInterfaces()"));
00592
00593
00594 coil::Properties prop(m_properties);
00595 {
00596 coil::Properties conn_prop;
00597 NVUtil::copyToProperties(conn_prop, cprof.properties);
00598 prop << conn_prop.getNode("dataport");
00599
00600
00601
00602
00603
00604
00605 prop << conn_prop.getNode("dataport.outport");
00606 }
00607 RTC_DEBUG(("ConnectorProfile::properties are as follows."));
00608 RTC_DEBUG_STR((prop));
00609
00610 bool littleEndian;
00611 if (!checkEndian(prop, littleEndian))
00612 {
00613 RTC_ERROR(("unsupported endian"));
00614 return RTC::UNSUPPORTED;
00615 }
00616 RTC_TRACE(("endian: %s", m_littleEndian ? "little":"big"));
00617
00618
00619
00620
00621
00622
00623
00624 std::string& dflow_type(prop["dataflow_type"]);
00625 coil::normalize(dflow_type);
00626
00627 if (dflow_type == "push")
00628 {
00629 RTC_PARANOID(("dataflow_type is push."));
00630
00631
00632 InPortConsumer* consumer(createConsumer(cprof, prop));
00633 if (consumer == 0)
00634 {
00635 return RTC::BAD_PARAMETER;
00636 }
00637
00638
00639 OutPortConnector* connector(createConnector(cprof, prop, consumer));
00640 if (connector == 0)
00641 {
00642 return RTC::RTC_ERROR;
00643 }
00644
00645 RTC_DEBUG(("subscribeInterfaces() successfully finished."));
00646 return RTC::RTC_OK;
00647 }
00648 else if (dflow_type == "pull")
00649 {
00650 RTC_PARANOID(("dataflow_type is pull."));
00651
00652
00653 OutPortConnector* conn(getConnectorById(cprof.connector_id));
00654 if (conn == 0)
00655 {
00656 RTC_ERROR(("specified connector not found: %s",
00657 (const char*)cprof.connector_id));
00658 return RTC::RTC_ERROR;
00659 }
00660 conn->setEndian(littleEndian);
00661 RTC_DEBUG(("subscribeInterfaces() successfully finished."));
00662 return RTC::RTC_OK;
00663 }
00664
00665 RTC_ERROR(("unsupported dataflow_type: %s", dflow_type.c_str()));
00666 return RTC::BAD_PARAMETER;
00667 }
00668
00676 void
00677 OutPortBase::unsubscribeInterfaces(const ConnectorProfile& connector_profile)
00678 {
00679 RTC_TRACE(("unsubscribeInterfaces()"));
00680
00681 std::string id(connector_profile.connector_id);
00682 RTC_PARANOID(("connector_id: %s", id.c_str()));
00683
00684 ConnectorList::iterator it(m_connectors.begin());
00685
00686 while (it != m_connectors.end())
00687 {
00688 if (id == (*it)->id())
00689 {
00690
00691 delete *it;
00692 m_connectors.erase(it);
00693 RTC_TRACE(("delete connector: %s", id.c_str()));
00694 return;
00695 }
00696 ++it;
00697 }
00698 RTC_ERROR(("specified connector not found: %s", id.c_str()));
00699 return;
00700 }
00701
00709 void OutPortBase::initProviders()
00710 {
00711 RTC_TRACE(("initProviders()"));
00712
00713
00714 OutPortProviderFactory& factory(OutPortProviderFactory::instance());
00715 coil::vstring provider_types(factory.getIdentifiers());
00716 RTC_PARANOID(("available OutPortProviders: %s",
00717 coil::flatten(provider_types).c_str()));
00718
00719 #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION
00720 if (m_properties.hasKey("provider_types") &&
00721 coil::normalize(m_properties["provider_types"]) != "all")
00722 {
00723 RTC_DEBUG(("allowed providers: %s",
00724 m_properties["provider_types"].c_str()));
00725
00726 coil::vstring temp_types(provider_types);
00727 provider_types.clear();
00728 coil::vstring
00729 active_types(coil::split(m_properties["provider_types"], ","));
00730
00731 std::sort(temp_types.begin(), temp_types.end());
00732 std::sort(active_types.begin(), active_types.end());
00733 std::set_intersection(temp_types.begin(), temp_types.end(),
00734 active_types.begin(), active_types.end(),
00735 std::back_inserter(provider_types));
00736 }
00737 #endif
00738
00739
00740 if (provider_types.size() > 0)
00741 {
00742 RTC_DEBUG(("dataflow_type pull is supported"));
00743 appendProperty("dataport.dataflow_type", "pull");
00744 appendProperty("dataport.interface_type",
00745 coil::flatten(provider_types).c_str());
00746 }
00747
00748 m_providerTypes = provider_types;
00749 }
00750
00758 void OutPortBase::initConsumers()
00759 {
00760 RTC_TRACE(("initConsumers()"));
00761
00762
00763 InPortConsumerFactory& factory(InPortConsumerFactory::instance());
00764 coil::vstring consumer_types(factory.getIdentifiers());
00765 RTC_PARANOID(("available InPortConsumer: %s",
00766 coil::flatten(consumer_types).c_str()));
00767
00768 #ifndef RTC_NO_DATAPORTIF_ACTIVATION_OPTION
00769 if (m_properties.hasKey("consumer_types") &&
00770 coil::normalize(m_properties["consumer_types"]) != "all")
00771 {
00772 RTC_DEBUG(("allowed consumers: %s",
00773 m_properties["consumer_types"].c_str()));
00774
00775 coil::vstring temp_types(consumer_types);
00776 consumer_types.clear();
00777 coil::vstring
00778 active_types(coil::split(m_properties["consumer_types"], ","));
00779
00780 std::sort(temp_types.begin(), temp_types.end());
00781 std::sort(active_types.begin(), active_types.end());
00782 std::set_intersection(temp_types.begin(), temp_types.end(),
00783 active_types.begin(), active_types.end(),
00784 std::back_inserter(consumer_types));
00785 }
00786 #endif
00787
00788
00789 if (consumer_types.size() > 0)
00790 {
00791 RTC_PARANOID(("dataflow_type push is supported"));
00792 appendProperty("dataport.dataflow_type", "push");
00793 appendProperty("dataport.interface_type",
00794 coil::flatten(consumer_types).c_str());
00795 }
00796
00797 m_consumerTypes = consumer_types;
00798 }
00799
00807 bool OutPortBase::checkEndian(const coil::Properties& prop,
00808 bool& littleEndian)
00809 {
00810
00811 if(prop.hasKey("serializer") == NULL)
00812 {
00813 littleEndian = true;
00814 return true;
00815 }
00816
00817
00818 std::string endian_type(prop.getProperty("serializer.cdr.endian", ""));
00819 RTC_DEBUG(("endian_type: %s", endian_type.c_str()));
00820 coil::normalize(endian_type);
00821 std::vector<std::string> endian(coil::split(endian_type, ","));
00822
00823 if(endian.empty()) { return false; }
00824 if(endian[0] == "little")
00825 {
00826 littleEndian = true;
00827 return true;
00828 }
00829 else if(endian[0] == "big")
00830 {
00831 littleEndian = false;
00832 return true;
00833 }
00834 return false;
00835 }
00836
00844 OutPortProvider*
00845 OutPortBase::createProvider(ConnectorProfile& cprof, coil::Properties& prop)
00846 {
00847 if (!prop["interface_type"].empty() &&
00848 !coil::includes((coil::vstring)m_providerTypes, prop["interface_type"]))
00849 {
00850 RTC_ERROR(("no provider found"));
00851 RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
00852 RTC_DEBUG(("interface_types: %s",
00853 coil::flatten(m_providerTypes).c_str()));
00854 return 0;
00855 }
00856
00857 RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
00858 OutPortProvider* provider;
00859 provider = OutPortProviderFactory::
00860 instance().createObject(prop["interface_type"].c_str());
00861
00862 if (provider != 0)
00863 {
00864 RTC_TRACE(("provider created"));
00865 provider->init(prop.getNode("provider"));
00866
00867 #ifndef ORB_IS_RTORB
00868 if (!provider->publishInterface(cprof.properties))
00869 {
00870 RTC_ERROR(("publishing interface information error"));
00871 OutPortProviderFactory::instance().deleteObject(provider);
00872 return 0;
00873 }
00874 #else // ORB_IS_RTORB
00875 ::SDOPackage::NVList_ptr prop_ref(cprof.properties);
00876 if (!provider->publishInterface(*prop_ref))
00877 {
00878 RTC_ERROR(("publishing interface information error"));
00879 OutPortProviderFactory::instance().deleteObject(provider);
00880 return 0;
00881 }
00882 #endif // ORB_IS_RTORB
00883 return provider;
00884 }
00885
00886 RTC_ERROR(("provider creation failed"));
00887 return 0;
00888 }
00889
00890
00898 InPortConsumer* OutPortBase::createConsumer(const ConnectorProfile& cprof,
00899 coil::Properties& prop)
00900 {
00901 if (!prop["interface_type"].empty() &&
00902 !coil::includes((coil::vstring)m_consumerTypes, prop["interface_type"]))
00903 {
00904 RTC_ERROR(("no consumer found"));
00905 RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
00906 RTC_DEBUG(("interface_types: %s",
00907 coil::flatten(m_consumerTypes).c_str()));
00908 return 0;
00909 }
00910
00911 RTC_DEBUG(("interface_type: %s", prop["interface_type"].c_str()));
00912 InPortConsumer* consumer;
00913 consumer = InPortConsumerFactory::
00914 instance().createObject(prop["interface_type"].c_str());
00915
00916 if (consumer != 0)
00917 {
00918 RTC_TRACE(("consumer created"));
00919 consumer->init(prop.getNode("consumer"));
00920
00921 if (!consumer->subscribeInterface(cprof.properties))
00922 {
00923 RTC_ERROR(("interface subscription failed."));
00924 InPortConsumerFactory::instance().deleteObject(consumer);
00925 return 0;
00926 }
00927
00928 return consumer;
00929 }
00930
00931 RTC_ERROR(("consumer creation failed"));
00932 return 0;
00933 }
00934
00942 OutPortConnector*
00943 OutPortBase::createConnector(const ConnectorProfile& cprof,
00944 coil::Properties& prop,
00945 InPortConsumer* consumer)
00946 {
00947 #ifndef ORB_IS_RTORB
00948 ConnectorInfo profile(cprof.name,
00949 cprof.connector_id,
00950 CORBA_SeqUtil::refToVstring(cprof.ports),
00951 prop);
00952 #else // ORB_IS_RTORB
00953 ConnectorInfo profile(cprof.name,
00954 cprof.connector_id,
00955 CORBA_SeqUtil::
00956 refToVstring(RTC::PortServiceList(cprof.ports)),
00957 prop);
00958 #endif // ORB_IS_RTORB
00959
00960 OutPortConnector* connector(0);
00961 try
00962 {
00963 connector = new OutPortPushConnector(profile, consumer, m_listeners);
00964
00965 if (connector == 0)
00966 {
00967 RTC_ERROR(("old compiler? new returned 0;"));
00968 return 0;
00969 }
00970 RTC_TRACE(("OutPortPushConnector created"));
00971
00972
00973 connector->setEndian(m_littleEndian);
00974 m_connectors.push_back(connector);
00975 RTC_PARANOID(("connector pushback done: size = %d",
00976 m_connectors.size()));
00977 return connector;
00978 }
00979 catch (std::bad_alloc& e)
00980 {
00981 RTC_ERROR(("OutPortPushConnector creation failed"));
00982 return 0;
00983 }
00984 RTC_FATAL(("never comes here: createConnector()"));
00985 return 0;
00986 }
00987
00995 OutPortConnector*
00996 OutPortBase::createConnector(const ConnectorProfile& cprof,
00997 coil::Properties& prop,
00998 OutPortProvider* provider)
00999 {
01000 RTC_VERBOSE(("createConnector()"));
01001 #ifndef ORB_IS_RTORB
01002 ConnectorInfo profile(cprof.name,
01003 cprof.connector_id,
01004 CORBA_SeqUtil::refToVstring(cprof.ports),
01005 prop);
01006 #else // ORB_IS_RTORB
01007 ConnectorInfo profile(cprof.name,
01008 cprof.connector_id,
01009 CORBA_SeqUtil::
01010 refToVstring(RTC::PortServiceList(cprof.ports)),
01011 prop);
01012 #endif // ORB_IS_RTORB
01013
01014 OutPortConnector* connector(0);
01015 try
01016 {
01017 connector = new OutPortPullConnector(profile, provider, m_listeners);
01018
01019 if (connector == 0)
01020 {
01021 RTC_ERROR(("old compiler? new returned 0;"));
01022 return 0;
01023 }
01024 RTC_TRACE(("OutPortPullConnector created"));
01025
01026 m_connectors.push_back(connector);
01027 RTC_PARANOID(("connector pushback done: size = %d", m_connectors.size()));
01028 return connector;
01029 }
01030 catch (std::bad_alloc& e)
01031 {
01032 RTC_ERROR(("OutPortPullConnector creation failed"));
01033 return 0;
01034 }
01035 RTC_FATAL(("never comes here: createConnector()"));
01036 return 0;
01037 }
01038
01039 };