[openrtm-commit:01851] r800 - in trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC: . port
openrtm @ openrtm.org
openrtm @ openrtm.org
2016年 3月 14日 (月) 18:43:15 JST
Author: win-ei
Date: 2016-03-14 18:43:15 +0900 (Mon, 14 Mar 2016)
New Revision: 800
Added:
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMConsumer.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMProvider.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMConsumer.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMProvider.java
Modified:
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/FactoryInit.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/SharedMemory.java
Log:
Not implemented yet. refs #3395
Modified: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/FactoryInit.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/FactoryInit.java 2016-03-10 02:30:56 UTC (rev 799)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/FactoryInit.java 2016-03-14 09:43:15 UTC (rev 800)
@@ -11,6 +11,10 @@
import jp.go.aist.rtm.RTC.port.OutPortCorbaCdrConsumer;
import jp.go.aist.rtm.RTC.port.InPortDirectProvider;
import jp.go.aist.rtm.RTC.port.InPortDirectConsumer;
+import jp.go.aist.rtm.RTC.port.InPortSHMProvider;
+import jp.go.aist.rtm.RTC.port.InPortSHMConsumer;
+import jp.go.aist.rtm.RTC.port.OutPortSHMProvider;
+import jp.go.aist.rtm.RTC.port.OutPortSHMConsumer;
/**
* {@.ja Factory初期処理用クラス}
@@ -47,5 +51,10 @@
OutPortCorbaCdrProvider.OutPortCorbaCdrProviderInit();
InPortDirectProvider.InPortDirectProviderInit();
InPortDirectConsumer.InPortDirectConsumerInit();
+
+ InPortSHMProvider.InPortSHMProviderInit();
+ InPortSHMConsumer.InPortSHMConsumerInit();
+ OutPortSHMProvider.OutPortSHMProviderInit();
+ OutPortSHMConsumer.OutPortSHMConsumerInit();
}
}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMConsumer.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMConsumer.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMConsumer.java 2016-03-14 09:43:15 UTC (rev 800)
@@ -0,0 +1,484 @@
+package jp.go.aist.rtm.RTC.port;
+
+import java.util.UUID;
+
+import jp.go.aist.rtm.RTC.InPortConsumerFactory;
+import jp.go.aist.rtm.RTC.ObjectCreator;
+import jp.go.aist.rtm.RTC.ObjectDestructor;
+import jp.go.aist.rtm.RTC.log.Logbuf;
+import jp.go.aist.rtm.RTC.util.NVUtil;
+import jp.go.aist.rtm.RTC.util.ORBUtil;
+import jp.go.aist.rtm.RTC.util.Properties;
+
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.portable.OutputStream;
+
+import _SDOPackage.NVListHolder;
+import OpenRTM.PortSharedMemory;
+
+
+/**
+ * {@.ja InPortSHMConsumer クラス}
+ * {@.en InPortSHMConsumer class}
+ * <p>
+ * {@.ja 通信手段に 共有メモリ を利用した入力ポートコンシューマの実装クラス。}
+ * {@.en This is an implementation class of the input port Consumer
+ * that uses shared memory for means of communication. }
+ */
+
+public class InPortSHMConsumer extends CorbaConsumer< PortSharedMemory >implements InPortConsumer, ObjectCreator<InPortConsumer>, ObjectDestructor {
+ /**
+ * {@.ja コンストラクタ}
+ * {@.en Constructor}
+ * <p>
+ * {@.en buffer 当該コンシューマに割り当てるバッファオブジェクト}
+ * {@.en buffer The buffer object that is attached to this Consumer}
+ *
+ */
+ public InPortSHMConsumer() {
+// super();
+ super(OpenRTM.PortSharedMemory.class);
+ rtcout = new Logbuf("InPortSHMConsumer");
+
+// m_shm_address = UUID.randomUUID().toString();
+
+// rtcout.setLevel("PARANOID");
+// m_orb = ORBUtil.getOrb();
+ }
+ /**
+ * {@.ja 設定初期化}
+ * {@.en Initializing configuration}
+ * <p>
+ * {@.ja InPortConsumerの各種設定を行う。実装クラスでは、与えられた
+ * Propertiesから必要な情報を取得して各種設定を行う。この init() 関
+ * 数は、InPortProvider生成直後および、接続時にそれぞれ呼ばれる可
+ * 能性がある。したがって、この関数は複数回呼ばれることを想定して記
+ * 述されるべきである。}
+ * {@.en This operation would be called to configure in initialization.
+ * In the concrete class, configuration should be performed
+ * getting appropriate information from the given Properties data.
+ * This function might be called right after instantiation and
+ * connection sequence respectivly. Therefore, this function
+ * should be implemented assuming multiple call.}
+ *
+ * @param prop
+ * {@.ja 設定情報}
+ * {@.en Configuration information}
+ */
+ public void init(Properties prop) {
+ rtcout.println(Logbuf.TRACE, "init()");
+ m_properties = prop;
+ String ds = prop.getProperty("shem_default_size");
+ //m_memory_size = m_shmem.string_to_MemorySize(ds);
+ }
+
+ /**
+ * <p> Send data to the destination port </p>
+ * <p> Pure virtual function to send data to the destination port. </p>
+ *
+ */
+ /**
+ * {@.ja 接続先へのデータ送信}
+ * {@.en Send data to the destination port}
+ * <p>
+ * {@.ja 接続先のポートへデータを送信するための純粋仮想関数。
+ *
+ * この関数は、以下のリターンコードを返す。
+ * <ul>
+ * <li>- PORT_OK: 正常終了。
+ * <li>- PORT_ERROR: データ送信の過程で何らかのエラーが発生した。
+ * <li>- SEND_FULL: データを送信したが、相手側バッファがフルだった。
+ * <li>- SEND_TIMEOUT:データを送信したが、相手側バッファがタイムアウトした。
+ * <li>- UNKNOWN_ERROR:原因不明のエラー</ul>}
+ * {@.en Pure virtual function to send data to the destination port.
+ *
+ * This function might the following return codes
+ * <ul>
+ * <li>- PORT_OK: Normal return
+ * <li>- PORT_ERROR: Error occurred in data transfer process
+ * <li>- SEND_FULL: Buffer full although OutPort tried to send data
+ * <li>- SEND_TIMEOUT: Timeout although OutPort tried to send data
+ * <li>- UNKNOWN_ERROR: Unknown error</ul>}
+ *
+ * @param data
+ * {@.ja 送信するデータ}
+ * {@.en Data sent by this operation.}
+ * @return
+ * {@.ja リターンコード}
+ * {@.en ReturnCode}
+ */
+ public ReturnCode put(final OutputStream data) {
+ rtcout.println(Logbuf.PARANOID, "put");
+
+ EncapsOutputStreamExt cdr;
+ cdr = (EncapsOutputStreamExt)data;
+ byte[] ch = cdr.getByteArray();
+ EncapsOutputStreamExt output_stream
+ = new EncapsOutputStreamExt(m_orb, m_connector.isLittleEndian());
+ output_stream.write_octet_array(ch,0,ch.length);
+
+ try {
+ //OpenRTM.PortStatus ret = _ptr().put(output_stream.getByteArray());
+ OpenRTM.PortStatus ret = _ptr().put();
+ return convertReturn(ret);
+ }
+ catch (Exception e) {
+ return ReturnCode.CONNECTION_LOST;
+ }
+ }
+ /**
+ * {@.ja InterfaceProfile情報を公開する}
+ * {@.en Publish InterfaceProfile information}
+ * <p>
+ * {@.ja InterfaceProfile情報を公開する。
+ * 引数で指定するプロパティ情報内の NameValue オブジェクトの
+ * dataport.interface_type 値を調べ、当該ポートに設定されている
+ * インターフェースタイプと一致する場合のみ情報を取得する。}
+ * {@.en Publish interfaceProfile information.
+ * Check the dataport.interface_type value of the NameValue object
+ * specified by an argument in property information and get information
+ * only when the interface type of the specified port is matched.}
+ *
+ * @param properties
+ * {@.ja InterfaceProfile情報を受け取るプロパティ}
+ * {@.en Properties to get InterfaceProfile information}
+ */
+ public void publishInterfaceProfile(NVListHolder properties) {
+ return;
+ }
+ /**
+ * {@.ja データ送信通知への登録}
+ * {@.en Subscribe to the data sending notification}
+ * <p>
+ * {@.ja 指定されたプロパティに基づいて、データ送出通知の受け取り
+ * に登録する。}
+ * {@.en Subscribe to the data sending notification based on specified
+ * property information.}
+ *
+ * @param properties
+ * {@.ja 登録情報}
+ * {@.en Information for subscription}
+ *
+ * @return
+ * {@.ja 登録処理結果(登録成功:true、登録失敗:false)}
+ * {@.en Subscription result (Successful:true, Failed:false)}
+ */
+ public boolean subscribeInterface(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE, "subscribeInterface()");
+ if(properties.value == null){
+ rtcout.println(Logbuf.DEBUG, "NVListHolder is null.");
+ return false;
+ }
+ rtcout.println(Logbuf.DEBUG,
+ "Length of NVListHolder:"+properties.value.length);
+ rtcout.println(Logbuf.DEBUG, NVUtil.toString(properties));
+
+ // getting InPort's ref from IOR string
+ if (subscribeFromIor(properties)) {
+ return true;
+ }
+
+ // getting InPort's ref from Object reference
+ if (subscribeFromRef(properties)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@.ja データ送信通知からの登録解除}
+ * {@.en Unsubscribe the data send notification}
+ * <p>
+ * {@.ja データ送出通知の受け取りから登録を解除する。}
+ * {@.en Unsubscribe the data send notification.}
+ *
+ * @param properties
+ * {@.ja 登録解除情報}
+ * {@.en Information for unsubscription}
+ */
+ public void unsubscribeInterface(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE, "unsubscribeInterface()");
+ rtcout.println(Logbuf.DEBUG, NVUtil.toString(properties));
+
+ if (unsubscribeFromIor(properties)) {
+ return;
+ }
+ unsubscribeFromRef(properties);
+ }
+
+ /**
+ * {@.ja IOR文字列からオブジェクト参照を取得する}
+ * {@.en Getting object reference fromn IOR string}
+ * @param properties
+ * {@.ja Information for subscription}
+ * {@.en Information for subscription}
+ *
+ * @return
+ * {@.ja true: 正常取得, false: 取得失敗}
+ * {@.en true: succeeded, false: failed}
+ */
+ private boolean subscribeFromIor(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE, "subscribeFromIor()");
+
+ int index;
+ index = NVUtil.find_index(properties,
+ "dataport.corba_cdr.inport_ior");
+ if (index < 0) {
+ rtcout.println(Logbuf.ERROR, "inport_ior not found");
+ return false;
+ }
+ rtcout.println(Logbuf.DEBUG, "index:"+index);
+
+ final String ior;
+
+ try {
+ rtcout.println(Logbuf.DEBUG,
+ "type:"+properties.value[index].value.type());
+ if( properties.value[index].value.type().kind() ==
+ TCKind.tk_wstring ) {
+ ior = properties.value[index].value.extract_wstring();
+ } else {
+ ior = properties.value[index].value.extract_string();
+ }
+ }
+ catch(BAD_OPERATION e) {
+ rtcout.println(Logbuf.ERROR, "inport_ior has no string");
+ return false;
+ }
+
+ ORB orb = ORBUtil.getOrb();
+ org.omg.CORBA.Object obj = orb.string_to_object(ior);
+
+ if (obj==null) {
+ rtcout.println(Logbuf.ERROR, "invalid IOR string has been passed");
+ return false;
+ }
+
+ if (!super.setObject(obj)) {
+ rtcout.println(Logbuf.WARN, "Setting object to consumer failed.");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * {@.ja Anyから直接オブジェクト参照を取得する}
+ * {@.en Getting object reference fromn Any directry}
+ * @param properties
+ * {@.ja Information for subscription}
+ * {@.en Information for subscription}
+ * @return
+ * {@.ja true: 正常取得, false: 取得失敗}
+ * {@.en true: succeeded, false: failed}
+ *
+ */
+ private boolean subscribeFromRef(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE, "subscribeFromRef()");
+ int index;
+ index = NVUtil.find_index(properties,
+ "dataport.corba_cdr.inport_ref");
+ if (index < 0) {
+ rtcout.println(Logbuf.ERROR, "inport_ref not found");
+ return false;
+ }
+
+ org.omg.CORBA.Object obj;
+ try {
+ obj = properties.value[index].value.extract_Object();
+ }
+ catch(BAD_OPERATION e){
+ rtcout.println(Logbuf.ERROR, "prop[inport_ref] is not objref");
+ return true;
+ }
+
+ if (obj==null) {
+ rtcout.println(Logbuf.ERROR, "prop[inport_ref] is not objref");
+ return false;
+ }
+
+ if (!super.setObject(obj)) {
+ rtcout.println(Logbuf.ERROR, "Setting object to consumer failed.");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * {@.ja 接続解除(IOR版)}
+ * {@.en ubsubscribing (IOR version)}
+ *
+ * @param properties
+ * {@.ja Information for unsubscription}
+ * {@.en Information for unsubscription}
+ *
+ * @return
+ * {@.ja true: 正常取得, false: 取得失敗}
+ * {@.en true: succeeded, false: failed}
+ */
+ private boolean unsubscribeFromIor(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE, "unsubscribeFromIor()");
+ int index;
+ index = NVUtil.find_index(properties,
+ "dataport.corba_cdr.inport_ior");
+ if (index < 0) {
+ rtcout.println(Logbuf.ERROR, "inport_ior not found");
+ return false;
+ }
+
+ final String ior;
+ try {
+ if( properties.value[index].value.type().kind() ==
+ TCKind.tk_wstring ) {
+ ior = properties.value[index].value.extract_wstring();
+ } else {
+ ior = properties.value[index].value.extract_string();
+ }
+ }
+ catch(BAD_OPERATION e) {
+ rtcout.println(Logbuf.ERROR, "inport_ior has no string");
+ return false;
+ }
+
+ ORB orb = ORBUtil.getOrb();
+ org.omg.CORBA.Object var = orb.string_to_object(ior);
+ if (!(_ptr()._is_equivalent(var))) {
+ rtcout.println(Logbuf.ERROR, "connector property inconsistency");
+ return false;
+ }
+
+ releaseObject();
+ return true;
+ }
+
+ /**
+ * {@.ja 接続解除(Object reference版)}
+ * {@.en ubsubscribing (Object reference version)}
+ *
+ * @param properties
+ * {@.ja Information for unsubscription}
+ * {@.en Information for unsubscription}
+ * @return
+ * {@.ja true: 正常取得, false: 取得失敗}
+ * {@.en true: succeeded, false: failed}
+ */
+ private boolean unsubscribeFromRef(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE, "unsubscribeFromRef()");
+ int index;
+ index = NVUtil.find_index(properties,
+ "dataport.corba_cdr.inport_ref");
+ if (index < 0) {
+ return false;
+ }
+
+ org.omg.CORBA.Object obj;
+ try {
+ obj = properties.value[index].value.extract_Object();
+ }
+ catch(BAD_OPERATION e){
+ rtcout.println(Logbuf.ERROR, "prop[inport_ref] is not objref");
+ return false;
+ }
+
+ if (!(_ptr()._is_equivalent(obj))) {
+ rtcout.println(Logbuf.ERROR, "connector property inconsistency");
+ return false;
+ }
+
+ releaseObject();
+ return true;
+ }
+ /**
+ * {@.ja PortStatusをReturnCodeに変換する。}
+ * {@.en Converts PortStatus into ReturnCode.}
+ *
+ * @param status
+ * {@.ja PortStatus}
+ * {@.en PortStatus}
+ * @return
+ * {@.ja ReturnCode}
+ * {@.en ReturnCode}
+ */
+ protected ReturnCode convertReturn(OpenRTM.PortStatus status) {
+ switch (status.value()) {
+ case 0:
+ return ReturnCode.PORT_OK;
+ case 1:
+ return ReturnCode.PORT_ERROR;
+ case 2:
+ return ReturnCode.BUFFER_FULL;
+ case 3:
+ return ReturnCode.BUFFER_EMPTY;
+ case 4:
+ return ReturnCode.BUFFER_TIMEOUT;
+ default:
+ return ReturnCode.UNKNOWN_ERROR;
+ }
+ }
+
+ /**
+ * {@.ja InPortSHMConsumer を生成する}
+ * {@.en Creats InPortSHMConsumer}
+ *
+ * @return
+ * {@.ja 生成されたInPortConsumer}
+ * {@.en Object Created instances}
+ *
+ *
+ */
+ public InPortConsumer creator_() {
+ return new InPortSHMConsumer();
+ }
+ /**
+ * {@.ja Object を破棄する}
+ * {@.en Destructs Object}
+ *
+ * @param obj
+ * {@.ja 破棄するインタスタンス}
+ * {@.en The target instances for destruction}
+ *
+ */
+ public void destructor_(Object obj) {
+ obj = null;
+ }
+ /**
+ * {@.ja モジュール初期化関数}
+ * {@.en Module initialization}
+ * <p>
+ * {@.ja InPortSHMConsumer のファクトリを登録する初期化関数。}
+ * {@.en This initialization function registers InPortSHMConsumer's
+ * factory.}
+ */
+ public static void InPortSHMConsumerInit() {
+ final InPortConsumerFactory<InPortConsumer,String> factory
+ = InPortConsumerFactory.instance();
+
+ factory.addFactory("shared_memory",
+ new InPortSHMConsumer(),
+ new InPortSHMConsumer());
+
+ }
+ /**
+ * {@.ja Connectorを設定する。}
+ * {@.en set Connector}
+ *
+ * @param connector
+ * {@.ja OutPortConnector}
+ * {@.en OutPortConnector}
+ */
+ public void setConnector(OutPortConnector connector) {
+ m_connector = connector;
+ }
+
+ private Logbuf rtcout;
+ private Properties m_properties;
+ private OutPortConnector m_connector;
+ private ORB m_orb;
+ private String m_shm_address = new String();
+ //private SharedMemory m_shmem = new SharedMemory();
+ private long m_memory_size;
+}
+
+
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMProvider.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMProvider.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/InPortSHMProvider.java 2016-03-14 09:43:15 UTC (rev 800)
@@ -0,0 +1,764 @@
+package jp.go.aist.rtm.RTC.port;
+
+import jp.go.aist.rtm.RTC.InPortProviderFactory;
+import jp.go.aist.rtm.RTC.ObjectCreator;
+import jp.go.aist.rtm.RTC.ObjectDestructor;
+import jp.go.aist.rtm.RTC.buffer.BufferBase;
+import jp.go.aist.rtm.RTC.log.Logbuf;
+import jp.go.aist.rtm.RTC.util.CORBA_SeqUtil;
+import jp.go.aist.rtm.RTC.util.NVListHolderFactory;
+import jp.go.aist.rtm.RTC.util.NVUtil;
+import jp.go.aist.rtm.RTC.util.ORBUtil;
+import jp.go.aist.rtm.RTC.util.POAUtil;
+import jp.go.aist.rtm.RTC.util.Properties;
+
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.OutputStream;
+
+import OpenRTM.PortSharedMemoryPOA;
+import _SDOPackage.NVListHolder;
+
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * {@.ja InPortSHMProvider クラス}
+ * {@.en InPortSHMProvider class}
+ * <p>
+ * {@.ja データ転送に CORBA の OpenRTM::PortSharedMemory インターフェースを
+ * 利用した、push 型データフロー型を実現する InPort プロバイダクラス。}
+ * {@.en This is an implementation class of the input port Provider
+ * that uses CORBA for means of communication.}
+ *
+ *
+ */
+public class InPortSHMProvider extends PortSharedMemoryPOA implements InPortProvider, ObjectCreator<InPortProvider>, ObjectDestructor {
+ /**
+ * {@.ja コンストラクタ}
+ * {@.en Constructor}
+ *
+ *
+ */
+ public InPortSHMProvider() {
+ m_buffer = null;
+ rtcout = new Logbuf("InPortSHMProvider");
+ // PortProfile setting
+ setInterfaceType("shared_memory");
+
+ // ConnectorProfile setting
+ m_objref = this._this();
+
+ // set InPort's reference
+ ORB orb = ORBUtil.getOrb();
+ CORBA_SeqUtil.push_back(m_properties,
+ NVUtil.newNVString("dataport.corba_cdr.inport_ior",
+ orb.object_to_string(m_objref)));
+ CORBA_SeqUtil.push_back(m_properties,
+ NVUtil.newNV("dataport.corba_cdr.inport_ref",
+ m_objref, OpenRTM.PortSharedMemory.class ));
+
+ m_orb = ORBUtil.getOrb();
+
+ }
+ /**
+ * {@.ja 当該OpenRTM.PortSharedMemoryのCORBAオブジェクト参照を取得する。}
+ * {@.en Gets CORBA object referense of this OpenRTM.PortSharedMemory}
+ *
+ * @return
+ * {@.ja 当該PortのCORBAオブジェクト参照}
+ * {@.en CORBA object referense of this OpenRTM.PortSharedMemory}
+ *
+ */
+ public OpenRTM.PortSharedMemory _this() {
+
+ if (this.m_objref == null) {
+ try {
+ this.m_objref =
+ OpenRTM.PortSharedMemoryHelper.narrow(POAUtil.getRef(this));
+ } catch (Exception e) {
+ rtcout.println(Logbuf.WARN, "The exception was caught.");
+ throw new IllegalStateException(e);
+ }
+ }
+
+ return this.m_objref;
+ }
+ /**
+ * {@.ja 設定初期化}
+ * {@.en Initializing configuration}
+ * <p>
+ * {@.ja InPortSHMProvider の各種設定を行う。与えられた
+ * Propertiesから必要な情報を取得して各種設定を行う。この init() 関
+ * 数は、InPortProvider生成直後および、接続時にそれぞれ呼ばれる可
+ * 能性がある。したがって、この関数は複数回呼ばれることを想定して記
+ * 述されるべきである。}
+ * {@.en This operation would be called to configure in initialization.
+ * In the concrete class, configuration should be performed
+ * getting appropriate information from the given Properties data.
+ * This function might be called right after instantiation and
+ * connection sequence respectivly. Therefore, this function
+ * should be implemented assuming multiple call.}
+ *
+ * @param prop
+ * {@.ja 設定情報}
+ * {@.en Configuration information}
+ */
+ public void init(Properties prop){
+ }
+ /**
+ * {@.ja バッファをセットする}
+ * {@.en Setting outside buffer's pointer}
+ * <p>
+ * {@.ja OutPortProvider がデータを取り出すバッファをセットする。
+ * すでにセットされたバッファがある場合、以前のバッファへの
+ * ポインタに対して上書きされる。
+ * OutPortProviderはバッファの所有権を仮定していないので、
+ * バッファの削除はユーザの責任で行わなければならない。}
+ * {@.en A pointer to a buffer from which OutPortProvider retrieve data.
+ * If already buffer is set, previous buffer's pointer will be
+ * overwritten by the given pointer to a buffer. Since
+ * OutPortProvider does not assume ownership of the buffer
+ * pointer, destructor of the buffer should be done by user.}
+ *
+ * @param buffer
+ * {@.ja OutPortProviderがデータを取り出すバッファへのポインタ}
+ * {@.en A pointer to a data buffer to be used by OutPortProvider}
+ */
+ public void setBuffer(BufferBase<OutputStream> buffer) {
+ m_buffer = buffer;
+ }
+
+ /**
+ * {@.ja [CORBA interface] バッファにデータを書き込む}
+ * {@.en [CORBA interface] Write data into the buffer}
+ *
+ * <p>
+ * {@.ja 設定されたバッファにデータを書き込む。}
+ * {@.en Write data into the specified buffer.}
+ * </p>
+ *
+ * @param data
+ * {@.ja 書込対象データ}
+ * {@.en The target data for writing}
+ *
+ */
+ public OpenRTM.PortStatus put(byte[] data)
+ throws SystemException {
+
+ rtcout.println(Logbuf.PARANOID, "InPortSHMProvider.put()");
+
+ if (m_buffer == null) {
+ EncapsOutputStreamExt cdr
+ = new EncapsOutputStreamExt(m_orb,m_connector.isLittleEndian());
+ cdr.write_octet_array(data, 0, data.length);
+ onReceiverError(cdr);
+ return OpenRTM.PortStatus.PORT_ERROR;
+ }
+
+
+ rtcout.println(Logbuf.PARANOID, "received data size: "+data.length);
+
+
+ EncapsOutputStreamExt cdr
+ = new EncapsOutputStreamExt(m_orb,m_connector.isLittleEndian());
+ cdr.write_octet_array(data, 0, data.length);
+
+ int len = cdr.getByteArray().length;
+ rtcout.println(Logbuf.PARANOID, "converted CDR data size: "+len);
+ onReceived(cdr);
+ jp.go.aist.rtm.RTC.buffer.ReturnCode ret = m_buffer.write(cdr);
+ return convertReturn(ret,cdr);
+ }
+
+ /**
+ * {@.ja [CORBA interface] バッファにデータを書き込む}
+ * {@.en [CORBA interface] Write data into the buffer}
+ * <p>
+ * {@.ja 設定されたバッファにデータを書き込む。}
+ * {@.en Write data into the specified buffer.}
+ *
+ * @param data
+ * {@.ja 書込対象データ}
+ * {@.en The target data for writing}
+ *
+ * @return
+ * {@.ja ステータス}
+ * {@.en Prot status}
+ */
+/*
+ public OpenRTM.PortStatus put(final OpenRTM.CdrDataHolder data)
+ throws SystemException {
+ return put(data.value);
+
+ }
+*/
+ /**
+ * {@.ja リターンコード変換}
+ * {p.en Return codes conversion}
+ *
+ * @param status
+ * {@.ja ReturnCode}
+ * {@.en ReturnCode}
+ * @return
+ * {@.ja PortStatus}
+ * {@.en PortStatus}
+ */
+ protected OpenRTM.PortStatus
+ convertReturn(jp.go.aist.rtm.RTC.buffer.ReturnCode status,
+ final EncapsOutputStreamExt data) {
+ switch (status) {
+ case BUFFER_OK:
+ onBufferWrite(data);
+ return OpenRTM.PortStatus.from_int(OpenRTM.PortStatus._PORT_OK);
+ case BUFFER_ERROR:
+ onReceiverError(data);
+ return OpenRTM.PortStatus.from_int(
+ OpenRTM.PortStatus._PORT_ERROR);
+
+ case BUFFER_FULL:
+ onBufferFull(data);
+ onReceiverFull(data);
+ return OpenRTM.PortStatus.from_int(
+ OpenRTM.PortStatus._BUFFER_FULL);
+
+ case BUFFER_EMPTY:
+ // never come here
+ return OpenRTM.PortStatus.from_int(
+ OpenRTM.PortStatus._BUFFER_EMPTY);
+ case TIMEOUT:
+ onBufferWriteTimeout(data);
+ onReceiverTimeout(data);
+ return OpenRTM.PortStatus.from_int(
+ OpenRTM.PortStatus._BUFFER_TIMEOUT);
+ case PRECONDITION_NOT_MET:
+ onReceiverError(data);
+ return OpenRTM.PortStatus.from_int(
+ OpenRTM.PortStatus._PORT_ERROR);
+ default:
+ onReceiverError(data);
+ return OpenRTM.PortStatus.from_int(
+ OpenRTM.PortStatus._UNKNOWN_ERROR);
+ }
+ }
+
+
+ /**
+ * {@.ja InPortSHMProvider を生成する}
+ * {@.en Creats InPortSHMProvider}
+ *
+ * @return
+ * {@.ja 生成されたInPortProvider}
+ * {@.en Object Created instances}
+ *
+ */
+ public InPortProvider creator_() {
+ return new InPortSHMProvider();
+ }
+ /**
+ * {@.ja InPortSHMProvider を破棄する}
+ * {@.en Destructs InPortSHMProvider}
+ *
+ * @param obj
+ * {@.ja 破棄するインタスタンス}
+ * {@.en The target instances for destruction}
+ *
+ */
+ public void destructor_(Object obj) {
+ try{
+ byte[] oid
+ = _default_POA().servant_to_id((InPortSHMProvider)obj);
+ _default_POA().deactivate_object(oid);
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+ obj = null;
+ }
+
+ /**
+ * {@.ja モジュール初期化関数}
+ * {@.en Module initialization}
+ * <p>
+ * {@.ja InPortSHMConsumer のファクトリを登録する初期化関数。}
+ * {@.en This initialization function registers InPortSHMConsumer's
+ * factory.}
+ */
+ public static void InPortSHMProviderInit() {
+ final InPortProviderFactory<InPortProvider,String> factory
+ = InPortProviderFactory.instance();
+
+ factory.addFactory("shared_memory",
+ new InPortSHMProvider(),
+ new InPortSHMProvider());
+
+ }
+ /**
+ * <p>InterfaceProfile情報を公開します。</p>
+ *
+ * @param properties InterfaceProfile情報を受け取るホルダオブジェクト
+ */
+ /**
+ * {@.ja InterfaceProfile情報を公開する}
+ * {@.en Publish InterfaceProfile information}
+ *
+ * <p>
+ * {@.ja InterfaceProfile情報を公開する。
+ * 引数で指定するプロパティ情報内の NameValue オブジェクトの
+ * dataport.interface_type 値を調べ、当該ポートに設定されている
+ * インターフェースタイプと一致する場合のみ情報を取得する。}
+ * {@.en Publish interfaceProfile information.
+ * Check the dataport.interface_type value of the NameValue object
+ * specified by an argument in property information and get information
+ * only when the interface type of the specified port is matched.}
+ *
+ * @param properties
+ * {@.ja InterfaceProfile情報を受け取るホルダオブジェクト}
+ * {@.en Holder object to get InterfaceProfile information}
+ *
+ */
+ public void publishInterfaceProfile(NVListHolder properties) {
+
+ NVUtil.appendStringValue(properties, "dataport.interface_type",
+ this.m_interfaceType);
+ NVUtil.append(properties, this.m_properties);
+ }
+
+ /**
+ * {@.ja Interface情報を公開する}
+ * {@.en Publish interface information}
+ * <p>
+ * {@.ja Interface情報を公開する。引数で指定するプロパティ情報内の
+ * NameValue オブジェクトのdataport.interface_type 値を調べ、当該ポー
+ * トに設定されていなければNameValue に情報を追加する。すでに同一イ
+ * ンターフェースが登録済みの場合は何も行わない。}
+ * {@.en Publish interface information. Check the
+ * dataport.interface_type value of the NameValue object specified
+ * by an argument in the property information, and add the
+ * information to the NameValue if this port is not specified.
+ * This does not do anything if the same interface is already
+ * subscribed.}
+ *
+ * @param properties
+ * {@.ja properties Interface情報を受け取るホルダオブジェクト}
+ * {@.en Holder object to receive interface information}
+ * @return
+ * {@.ja true: 正常終了}
+ * {@.en true: normal return}
+ */
+ public boolean publishInterface(NVListHolder properties) {
+
+ rtcout.println(Logbuf.TRACE, "publishInterface()");
+ rtcout.println(Logbuf.DEBUG, NVUtil.toString(properties));
+
+
+ if (! NVUtil.isStringValue(properties,
+ "dataport.interface_type",
+ this.m_interfaceType)) {
+ return false;
+ }
+
+ NVUtil.append(properties, this.m_properties);
+ return true;
+
+ }
+
+ /**
+ * {@.ja リスナを設定する。}
+ * {@.en Set the listener.}
+ *
+ * <p>
+ * {@.ja InPort はデータ送信処理における各種イベントに対して特定のリスナ
+ * オブジェクトをコールするコールバック機構を提供する。詳細は
+ * ConnectorListener.h の ConnectorDataListener, ConnectorListener
+ * 等を参照のこと。InPortSHMProvider では、以下のコールバック
+ * が提供される。}
+ * {@.en InPort provides callback functionality that calls specific
+ * listener objects according to the events in the data publishing
+ * process. For details, see documentation of
+ * ConnectorDataListener class and ConnectorListener class in
+ * ConnectorListener.h. In this InPortSHMProvider provides
+ * the following callbacks.}
+ * <ul>
+ * <li>- ON_BUFFER_WRITE
+ * <li>- ON_BUFFER_FULL
+ * <li>- ON_BUFFER_WRITE_TIMEOUT
+ * <li>- ON_BUFFER_OVERWRITE
+ * <li>- ON_RECEIVED
+ * <li>- ON_RECEIVER_FULL
+ * <li>- ON_RECEIVER_FULL
+ * <li>- ON_RECEIVER_TIMEOUT
+ * <li>- ON_RECEIVER_ERROR </li></ul>
+ *
+ *
+ * @param info
+ * {@.ja 接続情報}
+ * {@.en Connector information}
+ * @param listeners
+ * {@.ja リスナオブジェクト}
+ * {@.en Listener objects}
+ */
+ public void setListener(ConnectorBase.ConnectorInfo info,
+ ConnectorListeners listeners) {
+ m_profile = info;
+ m_listeners = listeners;
+ }
+ /**
+ * {@.ja Connectorを設定する。}
+ * {@.en set Connector}
+ * <p>
+ * {@.ja InPort は接続確立時に InPortConnector オブジェクトを生成し、生
+ * 成したオブジェクトのポインタと共にこの関数を呼び出す。所有権は
+ * InPort が保持するので InPortProvider は InPortConnector を削
+ * 除してはいけない。}
+ * {@.en InPort creates InPortConnector object when it establishes
+ * connection between InPort and InPort, and it calls this
+ * function with a pointer to the connector object. Since the
+ * InPort has the ownership of this connector, InPortProvider
+ * should not delete it.}
+ *
+ * @param connector
+ * {@.ja InPortConnector}
+ * {@.en InPortConnector}
+ */
+ public void setConnector(InPortConnector connector) {
+ m_connector = connector;
+ }
+ /**
+ * {@.ja インタフェースプロフィールのデータタイプを設定する。}
+ * {@.en Sets DataType of the interface profile}
+ *
+ * @param dataType
+ * {@.ja データタイプ}
+ * {@.en dataType}
+ */
+ protected void setDataType(final String dataType) {
+ this.m_dataType = dataType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのインタフェースタイプを設定する。}
+ * {@.en Sets interface Type of the interface profile}
+ *
+ * @param interfaceType
+ * {@.ja インタフェースタイプ}
+ * {@.en Intereface Type}
+ */
+ protected void setInterfaceType(final String interfaceType) {
+ rtcout.println(Logbuf.TRACE, "setInterfaceType("+interfaceType+")");
+ this.m_interfaceType = interfaceType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのデータフロータイプを設定する。}
+ * {@.en Sets data flow type of the interface profile}
+ *
+ * @param dataflowType
+ * {@.ja データフロータイプ}
+ * {@.en Data flow type}
+ */
+ protected void setDataFlowType(final String dataflowType) {
+ rtcout.println(Logbuf.TRACE, "setDataFlowType("+dataflowType+")");
+ this.m_dataflowType = dataflowType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのサブスクリプションタイプを設定する。}
+ * {@.en Sets subscription type of the interface profile}
+ *
+ * @param subscriptionType
+ * {@.ja サブスクリプションタイプ}
+ * {@.en Subscription type}
+ */
+ protected void setSubscriptionType(final String subscriptionType) {
+ rtcout.println(Logbuf.TRACE,
+ "setSubscriptionType("+subscriptionType+")");
+ this.m_subscriptionType = subscriptionType;
+ }
+
+ /**
+ * <p> Connector data listener functions </p>
+ */
+ /**
+ * {@.ja ON_BUFFER_WRITE のリスナへ通知する。}
+ * {@.en Notify an ON_BUFFER_WRITE event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onBufferWrite(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_BUFFER_FULL のリスナへ通知する。}
+ * {@.en Notify an ON_BUFFER_FULL event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onBufferFull(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_FULL].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_BUFFER_WRITE_TIMEOUT のリスナへ通知する。}
+ * {@.en Notify an ON_BUFFER_WRITE_TIMEOUT event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onBufferWriteTimeout(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE_TIMEOUT].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_BUFFER_WRITE_OVERWRITE のリスナへ通知する。}
+ * {@.en Notify an ON_BUFFER_WRITE_OVERWRITE event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onBufferWriteOverwrite(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(m_profile, data);
+ }
+
+// private void onBufferRead(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_READ].notify(m_profile, data);
+// }
+
+// private void onSend(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_SEND].notify(m_profile, data);
+// }
+
+ /**
+ * {@.ja ON_RECEIVED のリスナへ通知する。}
+ * {@.en Notify an ON_RECEIVED event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onReceived(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVED].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_RECEIVER_FULL のリスナへ通知する。}
+ * {@.en Notify an ON_RECEIVER_FULL event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onReceiverFull(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_FULL].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_RECEIVER_TIMEOUT のリスナへ通知する。}
+ * {@.en Notify an ON_RECEIVER_TIMEOUT event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onReceiverTimeout(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_TIMEOUT].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_RECEIVER_ERRORのリスナへ通知する。}
+ * {@.en Notify an ON_RECEIVER_ERROR event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onReceiverError(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_ERROR].notify(m_profile, data);
+ }
+
+ /**
+ * <p> Connector listener functions </p>
+ */
+// private void onBufferEmpty() {
+// m_listeners.connector_[ConnectorDataListenerType.ON_BUFFER_EMPTY].notify(m_profile);
+// }
+
+// privaet void onBufferReadTimeout(){
+// m_listeners.connector_[ConnectorDataListenerType.ON_BUFFER_READ_TIMEOUT].notify(m_profile);
+// }
+
+// privaet void onSenderEmpty() {
+// m_listeners.connector_[ConnectorDataListenerType.ON_SENDER_EMPTY].notify(m_profile);
+// }
+
+// privaet void onSenderTimeout() {
+// m_listeners.connector_[ConnectorDataListenerType.ON_SENDER_TIMEOUT].notify(m_profile);
+// }
+
+// private void onSenderError(){
+// m_listeners.connector_[ConnectorDataListenerType.ON_SENDER_ERROR].notify(m_profile);
+// }
+
+
+
+ /**
+ *
+ * {@.ja 共有メモリのマッピングを行う}
+ * {@.en Open a shared memory.}
+ *
+ * @param memory_size
+ * {@.ja 共有メモリのサイズ}
+ * {@.en size of shared momoery}
+ * @param shm_address
+ * {@.ja 空間名}
+ * {@.en name of memory}
+ # void open_memory(int memory_size, string shm_address);
+ */
+ public void open_memory (int memory_size, String shm_address){
+ rtcout.println(Logbuf.TRACE,
+ "open():memory_size="
+ + memory_size +",shm_address=" + shm_address);
+ m_memory_size = memory_size;
+ m_shm_address = shm_address;
+ try{
+ RandomAccessFile file = new RandomAccessFile(m_shm_address, "rw");
+ file.setLength(m_memory_size);
+ }
+ catch(Exception ex) {
+ rtcout.println(Logbuf.ERROR,"Open error "+ex.toString() );
+ }
+/*
+ self._rtcout.RTC_TRACE("open():memory_size="+str(memory_size)+",shm_address="+str(shm_address))
+ self._memory_size = memory_size
+ self._shm_address = shm_address
+ if self._shmem is None:
+ if platform.system() == "Windows":
+ self._shmem = mmap.mmap(0, self._memory_size, self._shm_address, mmap.ACCESS_READ)
+ else:
+ O_RDWR = 2
+ self.fd = self.rt.shm_open(self._shm_address,O_RDWR,0)
+ if self.fd < 0:
+ return self.UNKNOWN_ERROR
+ self.rt.ftruncate(self.fd, self._memory_size)
+ self._shmem = mmap.mmap(self.fd, self._memory_size, mmap.MAP_SHARED)
+ self.rt.close( self.fd )
+
+*/
+ }
+ /**
+ *
+ * {@.ja 共有メモリの初期化}
+ * {@.en Initializes a shared memory.}
+ *
+ * # windowsではページングファイル上に領域を確保する
+ * # Linuxでは/dev/shm以下にファイルを作成する
+ * # 作成したファイルの内容を仮想アドレスにマッピングする
+ *
+ * @param memory_size
+ * {@.ja 共有メモリのサイズ}
+ * {@.en Size of a shared momory}
+ * @param shm_address
+ * {@.ja 空間名}
+ * {@.en name of memory}
+ * # void create_memory(int memory_size, string shm_address);
+ */
+ public void create_memory (int memory_size, String shm_address){
+ rtcout.println(Logbuf.TRACE,
+ "create():memory_size="
+ + memory_size +",shm_address=" + shm_address);
+ m_memory_size = memory_size;
+ m_shm_address = shm_address;
+ }
+ /**
+ *
+ * {@.ja マッピングした共有メモリをアンマップする}
+ * {@.en Close a shared memory.}
+ *
+ * @param unlink
+ * {@.ja Linuxで/dev/shm以下に作成したファイルを削除する場合にTrueにする}
+ * {@.en }
+ *
+ # void close_memory(boolean unlink);
+ */
+ public void close_memory(boolean unlink){
+ File file = new File(m_shm_address);
+ file.delete();
+/*
+ self._rtcout.RTC_TRACE("open()")
+ if self._shmem:
+ self._shmem.close()
+ if platform.system() == "Windows":
+ pass
+ else:
+ if unlink:
+ self.rt.shm_unlink(self._shm_address)
+ self._shmem = None
+
+ if self._smInterface:
+ self._smInterface.close_memory(False)
+*/
+ }
+
+ public void close_memory(){
+ close_memory(false);
+ }
+
+
+ /**
+ *
+ * {@.ja 通信先のCORBAインターフェースを登録する}
+ * {@.en Registers CORBA interfaces.}
+ * <p>
+ * {@.ja 登録する事により共有メモリの初期化したときに、
+ * 通信先でもマッピングをやり直すことができる}
+ *
+ * @param sm
+ * {@.ja SharedMemoryのオブジェクトリファレンス}
+ * {@.en Object reference of shared momory}
+ */
+ public void setInterface (OpenRTM.PortSharedMemory sm){
+ //self._smInterface = sm
+ }
+
+ /**
+ *
+ * {@.ja データの送信を要求する}
+ * {@.en Get data.}
+ */
+ public OpenRTM.PortStatus get(){
+ return OpenRTM.PortStatus.UNKNOWN_ERROR;
+ }
+ /**
+ *
+ * {@.ja データの送信を知らせる}
+ * {@.en Put data.}
+ */
+ public OpenRTM.PortStatus put(){
+ return OpenRTM.PortStatus.UNKNOWN_ERROR;
+ }
+ /**
+ * <p>インタフェース情報を保持するオブジェクトです。</p>
+ */
+ protected NVListHolder m_properties = NVListHolderFactory.create();
+
+ private String m_dataType = new String();
+ private String m_interfaceType = new String();
+ private String m_dataflowType = new String();
+ private String m_subscriptionType = new String();
+
+ private BufferBase<OutputStream> m_buffer;
+ private OpenRTM.PortSharedMemory m_objref;
+
+ private ORB m_orb;
+ private InPortConnector m_connector;
+ private ConnectorListeners m_listeners;
+ private ConnectorBase.ConnectorInfo m_profile;
+
+ private Logbuf rtcout;
+ private String m_shm_address = new String();
+ private int m_memory_size;
+}
+
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMConsumer.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMConsumer.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMConsumer.java 2016-03-14 09:43:15 UTC (rev 800)
@@ -0,0 +1,534 @@
+package jp.go.aist.rtm.RTC.port;
+
+import jp.go.aist.rtm.RTC.Manager;
+import jp.go.aist.rtm.RTC.ObjectCreator;
+import jp.go.aist.rtm.RTC.ObjectDestructor;
+import jp.go.aist.rtm.RTC.OutPortConsumerFactory;
+import jp.go.aist.rtm.RTC.buffer.BufferBase;
+import jp.go.aist.rtm.RTC.log.Logbuf;
+import jp.go.aist.rtm.RTC.util.NVUtil;
+import jp.go.aist.rtm.RTC.util.Properties;
+
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.portable.OutputStream;
+
+import _SDOPackage.NVListHolder;
+import OpenRTM.PortSharedMemory;
+/**
+ * {@.ja OutPortSHMConsumer クラス}
+ * {@.en OutPortSHMConsumer class}
+ * <p>
+ * {@.ja データ転送に CORBA の OpenRTM::PortSharedMemory インターフェースを利用し
+ * た、pull 型データフロー型を実現する OutPort コンシューマクラス。}
+ * {@.en This is an implementation class of the output Consumer
+ * that uses CORBA for means of communication.}
+ *
+ * @param DataType Data type for this port
+ * @param DataType
+ * {@.ja ポートのためのDataType}
+ * {@.en Data type for this port}
+ *
+ */
+public class OutPortSHMConsumer extends CorbaConsumer<PortSharedMemory> implements OutPortConsumer, ObjectCreator<OutPortConsumer>, ObjectDestructor {
+ /**
+ * {@.ja コンストラクタ}
+ * {@.en Constructor}
+ *
+ */
+ public OutPortSHMConsumer() {
+ super(OpenRTM.PortSharedMemory.class);
+ rtcout = new Logbuf("OutPortSHMConsumer");
+ }
+
+ /**
+ *
+ *
+ * {@.ja 設定初期化}
+ * {@.en Initializing configuration}
+ * <p>
+ * {@.ja OutPortConsumerの各種設定を行う。実装クラスでは、与えられた
+ * Propertiesから必要な情報を取得して各種設定を行う。この init() 関
+ * 数は、OutPortProvider生成直後および、接続時にそれぞれ呼ばれる可
+ * 能性がある。したがって、この関数は複数回呼ばれることを想定して記
+ * 述されるべきである。}
+ * {@.en This operation would be called to configure in initialization.
+ * In the concrete class, configuration should be performed
+ * getting appropriate information from the given Properties data.
+ * This function might be called right after instantiation and
+ * connection sequence respectivly. Therefore, this function
+ * should be implemented assuming multiple call.}
+ *
+ * @param prop
+ * {@.ja 設定情報}
+ * {@.en Configuration information}
+ *
+ */
+ public void init(Properties prop) {
+ rtcout.println(Logbuf.TRACE, "OutPortSHMConsumer.init()");
+ }
+
+ /**
+ * {@.ja バッファをセットする}
+ * {@.en Setting outside buffer's pointer}
+ * <p>
+ * {@.ja OutPortConsumerがデータを取り出すバッファをセットする。
+ * すでにセットされたバッファがある場合、以前のバッファへの
+ * ポインタに対して上書きされる。
+ * OutPortProviderはバッファの所有権を仮定していないので、
+ * バッファの削除はユーザの責任で行わなければならない。}
+ * {@.en A pointer to a buffer from which OutPortProvider retrieve data.
+ * If already buffer is set, previous buffer's pointer will be
+ * overwritten by the given pointer to a buffer. Since
+ * OutPortProvider does not assume ownership of the buffer
+ * pointer, destructor of the buffer should be done by user.}
+ *
+ * @param buffer
+ * {@.ja OutPortProviderがデータを取り出すバッファへのポインタ}
+ * {@.en A pointer to a data buffer to be used by OutPortProvider}
+ *
+ */
+ public void setBuffer(BufferBase<OutputStream> buffer) {
+ rtcout.println(Logbuf.TRACE, "OutPortSHMConsumer.setBuffer()");
+ m_buffer = buffer;
+ }
+ /**
+ * {@.ja リスナを設定する。}
+ * {@.en Set the listener.}
+ * <p>
+ * {@.ja InPort はデータ送信処理における各種イベントに対して特定のリスナ
+ * オブジェクトをコールするコールバック機構を提供する。詳細は
+ * ConnectorListener.h の ConnectorDataListener, ConnectorListener
+ * 等を参照のこと。OutPortSHMProvider では、以下のコールバック
+ * が提供される。
+ * <ol>
+ * <li>- ON_BUFFER_WRITE
+ * <li>- ON_BUFFER_FULL
+ * <li>- ON_RECEIVED
+ * <li>- ON_RECEIVER_FULL
+ * <li>- ON_SENDER_EMPTY
+ * <li>- ON_SENDER_TIMEOUT
+ * <li>- ON_SENDER_ERROR</ol>}
+ * {@.en OutPort provides callback functionality that calls specific
+ * listener objects according to the events in the data publishing
+ * process. For details, see documentation of
+ * ConnectorDataListener class and ConnectorListener class in
+ * ConnectorListener.h. In this OutPortSHMProvider provides
+ * the following callbacks.
+ * <ol>
+ * <li>- ON_BUFFER_WRITE
+ * <li>- ON_BUFFER_FULL
+ * <li>- ON_RECEIVED
+ * <li>- ON_RECEIVER_FULL
+ * <li>- ON_SENDER_EMPTY
+ * <li>- ON_SENDER_TIMEOUT
+ * <li>- ON_SENDER_ERROR</ol>}
+ *
+ * @param info
+ * {@.ja 接続情報}
+ * {@.en Connector information}
+ * @param listeners
+ * {@.ja リスナオブジェクト}
+ * {@.en Listener objects}
+ */
+ public void setListener(ConnectorBase.ConnectorInfo info,
+ ConnectorListeners listeners) {
+ rtcout.println(Logbuf.TRACE, "OutPortSHMConsumer.setListener()");
+ m_listeners = listeners;
+ m_profile = info;
+ }
+
+
+ /**
+ *
+ * {@.ja データを読み出す}
+ * {@.en Reads data}
+ * <p>
+ * {@.ja 設定されたデータを読み出す。}
+ * {@.en Reads data set}
+ *
+ * @param data
+ * {@.ja 読み出したデータを受け取るオブジェクト}
+ * {@.en Object to receive the read data}
+ *
+ * @return
+ * {@.ja データ読み出し処理結果(読み出し成功:true、読み出し失敗:false)}
+ * {@.en Read result (Successful:true, Failed:false)}
+ *
+ */
+ public ReturnCode get(OutputStream data) {
+ rtcout.println(Logbuf.TRACE, "OutPortSHMConsumer.get()");
+ OpenRTM.CdrDataHolder cdr_data = new OpenRTM.CdrDataHolder();
+ try {
+ OpenRTM.PortStatus ret = _ptr().get();
+ //OpenRTM.PortStatus ret = _ptr().get(cdr_data);
+ if (ret == OpenRTM.PortStatus.PORT_OK) {
+ rtcout.println(Logbuf.DEBUG, "get() successful");
+ data.write_octet_array(cdr_data.value, 0,
+ cdr_data.value.length);
+ rtcout.println(Logbuf.PARANOID,
+ "CDR data length: "+cdr_data.value.length);
+
+ onReceived(data);
+ onBufferWrite(data);
+
+ if (m_buffer.full()) {
+ rtcout.println(Logbuf.INFO,
+ "InPort buffer is full.");
+ onBufferFull(data);
+ onReceiverFull(data);
+ }
+
+ m_buffer.put(data);
+ m_buffer.advanceWptr();
+ m_buffer.advanceRptr();
+
+ return ReturnCode.PORT_OK;
+ }
+ return convertReturn(ret);
+ }
+ catch (Exception e) {
+ rtcout.println(Logbuf.WARN,
+ "Exception caought from OutPort.get().");
+ return ReturnCode.CONNECTION_LOST;
+ }
+ }
+
+ /**
+ *
+ * {@.ja データ受信通知への登録}
+ * {@.en Subscribe the data receive notification}
+ * <p>
+ * {@.ja 指定されたプロパティに基づいて、データ受信通知の受け取りに
+ * 登録する。}
+ * {@.en Subscribe the data receive notification based on specified
+ * property information}
+ *
+ * @param properties
+ * {@.ja 登録情報}
+ * {@.en Subscription information}
+ *
+ * @return
+ * {@.ja 登録処理結果(登録成功:true、登録失敗:false)}
+ * {@.en Subscription result (Successful:true, Failed:false)}
+ *
+ */
+ public boolean subscribeInterface(final NVListHolder properties) {
+
+ rtcout.println(Logbuf.TRACE,
+ "OutPortSHMConsumer.subscribeInterface()");
+ int index;
+ index = NVUtil.find_index(properties,
+ "dataport.corba_cdr.outport_ior");
+ if (index < 0) {
+ rtcout.println(Logbuf.DEBUG,
+ "dataport.corba_cdr.outport_ior not found.");
+ return false;
+ }
+
+ if (NVUtil.isString(properties,
+ "dataport.corba_cdr.outport_ior")) {
+ rtcout.println(Logbuf.DEBUG,
+ "dataport.corba_cdr.outport_ior found.");
+ final String ior;
+ try {
+ if( properties.value[index].value.type().kind() ==
+ TCKind.tk_wstring ) {
+ ior = properties.value[index].value.extract_wstring();
+ } else {
+ ior = properties.value[index].value.extract_string();
+ }
+ }
+ catch(BAD_OPERATION e) {
+ rtcout.println(Logbuf.ERROR, "outport_ior has no string");
+ return false;
+ }
+
+ ORB orb = Manager.instance().getORB();
+ Object var = orb.string_to_object(ior);
+ if (var==null) {
+ rtcout.println(Logbuf.ERROR,
+ "invalid IOR string has been passed");
+ return false;
+ }
+
+ if (!super.setObject(var)) {
+ rtcout.println(Logbuf.ERROR,
+ "Invalid object reference.");
+ return false;
+ }
+ rtcout.println(Logbuf.DEBUG,
+ "CorbaConsumer was set successfully.");
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * {@.ja データ受信通知からの登録解除}
+ * {@.en Unsubscribe the data receive notification}
+ * <p>
+ * {@.ja データ受信通知の受け取りから登録を解除する。}
+ * {@.en Unsubscribe the data receive notification.}
+ *
+ * @param properties
+ * {@.ja 登録解除情報}
+ * {@.en Unsubscription information}
+ *
+ */
+ public void unsubscribeInterface(final NVListHolder properties) {
+ rtcout.println(Logbuf.TRACE,
+ "OutPortSHMConsumer.unsubscribeInterface()");
+ int index;
+ index = NVUtil.find_index(properties,
+ "dataport.corba_cdr.outport_ior");
+ if (index < 0) {
+ rtcout.println(Logbuf.DEBUG,
+ "dataport.corba_cdr.outport_ior not found.");
+ return;
+ }
+
+ final String ior;
+ try {
+ if( properties.value[index].value.type().kind() ==
+ TCKind.tk_wstring ) {
+ ior = properties.value[index].value.extract_wstring();
+ } else {
+ ior = properties.value[index].value.extract_string();
+ }
+ }
+ catch(BAD_OPERATION e) {
+ rtcout.println(Logbuf.ERROR, "inport_ior has no string");
+ return;
+ }
+ rtcout.println(Logbuf.DEBUG,
+ "dataport.corba_cdr.outport_ior found.");
+ ORB orb = Manager.instance().getORB();
+ Object var = orb.string_to_object(ior);
+ if (_ptr()._is_equivalent(var)) {
+ releaseObject();
+ rtcout.println(Logbuf.DEBUG,
+ "CorbaConsumer's reference was released.");
+ return;
+ }
+ rtcout.println(Logbuf.ERROR,
+ "hmm. Inconsistent object reference.");
+ }
+
+ /**
+ * {@.ja リターンコード変換 (DataPortStatus -> BufferStatus)}
+ * {@.en Return codes conversion}
+ * @param status
+ * {@.ja PortStatus}
+ * {@.en PortStatus}
+ * @return
+ * {@.ja ReturnCode}
+ * {@.en ReturnCode}
+ */
+ protected ReturnCode convertReturn(OpenRTM.PortStatus status) {
+ switch (status.value()) {
+ case OpenRTM.PortStatus._PORT_OK:
+ // never comes here
+ return ReturnCode.PORT_OK;
+
+ case OpenRTM.PortStatus._PORT_ERROR:
+ onSenderError();
+ return ReturnCode.PORT_ERROR;
+
+ case OpenRTM.PortStatus._BUFFER_FULL:
+ // never comes here
+ return ReturnCode.BUFFER_FULL;
+
+ case OpenRTM.PortStatus._BUFFER_EMPTY:
+ onSenderEmpty();
+ return ReturnCode.BUFFER_EMPTY;
+
+ case OpenRTM.PortStatus._BUFFER_TIMEOUT:
+ onSenderTimeout();
+ return ReturnCode.BUFFER_TIMEOUT;
+
+ case OpenRTM.PortStatus._UNKNOWN_ERROR:
+ onSenderError();
+ return ReturnCode.UNKNOWN_ERROR;
+
+ default:
+ onSenderError();
+ return ReturnCode.UNKNOWN_ERROR;
+ }
+ }
+ /**
+ * {@.ja OutPortSHMConsumer を生成する}
+ * {@.en Creats OutPortSHMConsumer}
+ *
+ * @return
+ * {@.ja 生成されたOutPortConsumer}
+ * {@.en Object Created instances}
+ *
+ *
+ */
+ public OutPortConsumer creator_() {
+ return new OutPortSHMConsumer();
+ }
+ /**
+ * {@.ja Object を破棄する}
+ * {@.en Destructs Object}
+ *
+ * @param obj
+ * {@.ja 破棄するインタスタンス}
+ * {@.en The target instances for destruction}
+ *
+ */
+ public void destructor_(java.lang.Object obj) {
+ obj = null;
+ }
+ /**
+ * <p> OutPortSHMConsumerInit </p>
+ *
+ */
+ /**
+ * {@.ja モジュール初期化関数}
+ * {@.en Module initialization}
+ * <p>
+ * {@.ja OutPortSHMConsumer のファクトリを登録する初期化関数。}
+ * {@.en This initialization function registers OutPortSHMConsumer's
+ * factory.}
+ */
+ public static void OutPortSHMConsumerInit() {
+ final OutPortConsumerFactory<OutPortConsumer,String> factory
+ = OutPortConsumerFactory.instance();
+
+ factory.addFactory("shared_memory",
+ new OutPortSHMConsumer(),
+ new OutPortSHMConsumer());
+
+ }
+ /**
+ * {@.ja Connectorを設定する。}
+ * {@.en set Connector}
+ *
+ * @param connector
+ * {@.ja InPortConnector}
+ * {@.en InPortConnector}
+ */
+ public void setConnector(InPortConnector connector) {
+ m_connector = connector;
+ }
+
+ /**
+ * <p> Connector data listener functions </p>
+ */
+ /**
+ * {@.ja ON_BUFFER_WRITE のリスナへ通知する。}
+ * {@.en Notify an ON_BUFFER_WRITE event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onBufferWrite(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_BUFFER_FULL のリスナへ通知する。}
+ * {@.en Notify an ON_BUFFER_FULL event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onBufferFull(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_FULL].notify(m_profile, data);
+ }
+
+// private void onBufferWriteTimeout(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE_TIMEOUT].notify(m_profile, data);
+// }
+
+// private void onBufferWriteOverwrite(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(m_profile, data);
+// }
+
+// private void onBufferRead(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_BUFFER_READ].notify(m_profile, data);
+// }
+
+// private void onSend(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_SEND].notify(m_profile, data);
+// }
+
+ /**
+ * {@.ja ON_RECEIVED のリスナへ通知する。}
+ * {@.en Notify an ON_RECEIVED event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onReceived(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVED].notify(m_profile, data);
+ }
+
+ /**
+ * {@.ja ON_RECEIVER_FULL のリスナへ通知する。}
+ * {@.en Notify an ON_RECEIVER_FULL event to listeners}
+ * @param data
+ * {@.ja OutputStream}
+ * {@.en OutputStream}
+ */
+ private void onReceiverFull(final OutputStream data) {
+ m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_FULL].notify(m_profile, data);
+ }
+
+// private void onReceiverTimeout(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_TIMEOUT].notify(m_profile, data);
+// }
+
+// private void onReceiverError(final OutputStream data) {
+// m_listeners.connectorData_[ConnectorDataListenerType.ON_RECEIVER_ERROR].notify(m_profile, data);
+// }
+
+ /**
+ * <p> Connector listener functions </p>
+ */
+// private void onBufferEmpty() {
+// m_listeners.connector_[ConnectorDataListenerType.ON_BUFFER_EMPTY].notify(m_profile);
+// }
+
+// private void onBufferReadTimeout() {
+// m_listeners.connector_[ConnectorDataListenerType.ON_BUFFER_READ_TIMEOUT].notify(m_profile);
+// }
+
+ /**
+ * {@.ja ON_SENDER_EMPTYのリスナへ通知する。}
+ * {@.en Notify an ON_SENDER_EMPTY event to listeners}
+ */
+ private void onSenderEmpty() {
+ m_listeners.connector_[ConnectorListenerType.ON_SENDER_EMPTY].notify(m_profile);
+ }
+
+ /**
+ * {@.ja ON_SENDER_TIMEOUT のリスナへ通知する。}
+ * {@.en Notify an ON_SENDER_TIMEOUT event to listeners}
+ */
+ private void onSenderTimeout() {
+ m_listeners.connector_[ConnectorListenerType.ON_SENDER_TIMEOUT].notify(m_profile);
+ }
+
+ /**
+ * {@.ja ON_SENDER_ERRORのリスナへ通知する。}
+ * {@.en Notify an ON_SENDER_ERROR event to listeners}
+ */
+ private void onSenderError() {
+ m_listeners.connector_[ConnectorListenerType.ON_SENDER_ERROR].notify(m_profile);
+ }
+
+ // RTC::PortSharedMemory_var m_outport;
+ private BufferBase<OutputStream> m_buffer;
+
+ private Logbuf rtcout;
+ private InPortConnector m_connector;
+ private ConnectorListeners m_listeners;
+ private ConnectorBase.ConnectorInfo m_profile;
+}
+
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMProvider.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMProvider.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/OutPortSHMProvider.java 2016-03-14 09:43:15 UTC (rev 800)
@@ -0,0 +1,700 @@
+package jp.go.aist.rtm.RTC.port;
+
+import jp.go.aist.rtm.RTC.ObjectCreator;
+import jp.go.aist.rtm.RTC.ObjectDestructor;
+import jp.go.aist.rtm.RTC.OutPortProviderFactory;
+import jp.go.aist.rtm.RTC.buffer.BufferBase;
+import jp.go.aist.rtm.RTC.log.Logbuf;
+import jp.go.aist.rtm.RTC.util.CORBA_SeqUtil;
+import jp.go.aist.rtm.RTC.util.DataRef;
+import jp.go.aist.rtm.RTC.util.NVListHolderFactory;
+import jp.go.aist.rtm.RTC.util.NVUtil;
+import jp.go.aist.rtm.RTC.util.ORBUtil;
+import jp.go.aist.rtm.RTC.util.POAUtil;
+import jp.go.aist.rtm.RTC.util.Properties;
+
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.portable.OutputStream;
+
+import OpenRTM.PortSharedMemoryPOA;
+import _SDOPackage.NVListHolder;
+
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * {@.ja OutPortSHMProvider クラス}
+ * {@.en OutPortSHMProvider class}
+ * <p>
+ * {@.ja データ転送に CORBA の OpenRTM::PortSharedMemory インターフェースを利用し
+ * た、pull 型データフロー型を実現する OutPort プロバイダクラス。}
+ * {@.en This is an implementation class of OutPort Provider that uses
+ * CORBA for mean of communication.}
+ *
+ * @param DataType
+ * {@.ja プロバイダに割り当てられたバッファによって確保されたDataType}
+ * {@.en Data type held by the buffer that is assigned to this
+ * provider}
+ *
+ */
+public class OutPortSHMProvider extends PortSharedMemoryPOA implements OutPortProvider, ObjectCreator<OutPortProvider>, ObjectDestructor {
+ /**
+ * {@.ja コンストラクタ}
+ * {@.en Constructor}
+ *
+ */
+ public OutPortSHMProvider() {
+ m_buffer = null;
+ rtcout = new Logbuf("OutPortSHMProvider");
+ // PortProfile setting
+ setInterfaceType("shared_memory");
+
+ // ConnectorProfile setting
+ m_objref = this._this();
+
+ // set outPort's reference
+ ORB orb = ORBUtil.getOrb();
+ CORBA_SeqUtil.
+ push_back(m_properties,
+ NVUtil.newNVString("dataport.corba_cdr.outport_ior",
+ orb.object_to_string(m_objref)));
+ CORBA_SeqUtil.
+ push_back(m_properties,
+ NVUtil.newNV("dataport.corba_cdr.outport_ref",
+ m_objref, OpenRTM.PortSharedMemory.class ));
+ }
+ /**
+ * {@.ja 当該OpenRTM.PortSharedMemoryのCORBAオブジェクト参照を取得する。}
+ * {@.en Gets CORBA object referense of this OpenRTM.PortSharedMemory}
+ *
+ * @return
+ * {@.ja 当該PortのCORBAオブジェクト参照}
+ * {@.en CORBA object referense of this OpenRTM.PortSharedMemory}
+ *
+ */
+ public OpenRTM.PortSharedMemory _this() {
+
+ if (this.m_objref == null) {
+ try {
+ this.m_objref
+ = OpenRTM.PortSharedMemoryHelper.narrow(POAUtil.getRef(this));
+
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ return this.m_objref;
+ }
+
+ /**
+ *
+ * {@.ja 設定初期化}
+ * {@.en Initializing configuration}
+ * <p>
+ * {@.ja OutPortSHMProvider の各種設定を行う。与えられた
+ * Propertiesから必要な情報を取得して各種設定を行う。この init() 関
+ * 数は、OutPortProvider生成直後および、接続時にそれぞれ呼ばれる可
+ * 能性がある。したがって、この関数は複数回呼ばれることを想定して記
+ * 述されるべきである。}
+ * {@.en This operation would be called to configure in initialization.
+ * In the concrete class, configuration should be performed
+ * getting appropriate information from the given Properties data.
+ * This function might be called right after instantiation and
+ * connection sequence respectivly. Therefore, this function
+ * should be implemented assuming multiple call.}
+ *
+ * @param prop
+ * {@.ja 設定情報}
+ * {@.en Configuration information}
+ *
+ */
+ public void init(Properties prop) {
+ }
+
+ /**
+ * {@.ja バッファをセットする}
+ * {@.en Setting outside buffer's pointer}
+ * <p>
+ * {@.ja OutPortProvider がデータを取り出すバッファをセットする。
+ * すでにセットされたバッファがある場合、以前のバッファへの
+ * ポインタに対して上書きされる。
+ * OutPortProviderはバッファの所有権を仮定していないので、
+ * バッファの削除はユーザの責任で行わなければならない。}
+ * {@.en A pointer to a buffer from which OutPortProvider retrieve data.
+ * If already buffer is set, previous buffer's pointer will be
+ * overwritten by the given pointer to a buffer. Since
+ * OutPortProvider does not assume ownership of the buffer
+ * pointer, destructor of the buffer should be done by user.}
+ *
+ * @param buffer
+ * {@.ja OutPortProviderがデータを取り出すバッファへのポインタ}
+ * {@.en A pointer to a data buffer to be used by OutPortProvider}
+ *
+ */
+ public void setBuffer(BufferBase<OutputStream> buffer){
+ m_buffer = buffer;
+ }
+
+ /**
+ * {@.ja [CORBA interface] バッファからデータを取得する}
+ * {@.en [CORBA interface] Get data from the buffer}
+ *
+ * <p>
+ * {@.ja 設定された内部バッファからデータを取得する。}
+ * {@.en Get data from the internal buffer.}
+ *
+ * @param data
+ * {@.ja 取得データを格納するバッファ}
+ * {@.en The buffer to get data.}
+ *
+ * @return
+ * {@.ja ステータス}
+ * {@.en Prot status}
+ *
+ */
+ public OpenRTM.PortStatus get(OpenRTM.CdrDataHolder data) {
+ rtcout.println(Logbuf.PARANOID, "OutPortSHMProvider.get()");
+
+ if (m_buffer == null) {
+ onSenderError();
+ rtcout.println(Logbuf.PARANOID, "m_buffer is null.");
+ return OpenRTM.PortStatus.UNKNOWN_ERROR;
+ }
+
+ OutputStream cdr = null;
+ DataRef<OutputStream> cdr_ref = new DataRef<OutputStream>(cdr);
+ jp.go.aist.rtm.RTC.buffer.ReturnCode ret
+ = m_buffer.read(cdr_ref,0,0);
+
+ if (ret.equals(jp.go.aist.rtm.RTC.buffer.ReturnCode.BUFFER_OK)) {
+
+ EncapsOutputStreamExt outcdr;
+ outcdr = (EncapsOutputStreamExt)cdr_ref.v;
+ data.value = outcdr.getByteArray();
+
+ }
+ return convertReturn(ret);
+ }
+ /**
+ * {@.ja ReturnCodeをPortStatusに変換する。}
+ * {@.en Converts ReturnCode into PortStatus.}
+ *
+ * @param status
+ * {@.ja ReturnCode}
+ * {@.en ReturnCode}
+ * @return
+ * {@.ja PortStatus}
+ * {@.en PortStatus}
+ */
+ protected OpenRTM.PortStatus
+ convertReturn(jp.go.aist.rtm.RTC.buffer.ReturnCode status) {
+ switch (status) {
+ case BUFFER_OK:
+ return OpenRTM.PortStatus.from_int(0);
+ case BUFFER_EMPTY:
+ return OpenRTM.PortStatus.from_int(3);
+ case TIMEOUT:
+ return OpenRTM.PortStatus.from_int(4);
+ case PRECONDITION_NOT_MET:
+ return OpenRTM.PortStatus.from_int(1);
+ default:
+ return OpenRTM.PortStatus.from_int(5);
+ }
+ }
+
+
+
+ /**
+ * {@.ja OutPortSHMProvider を生成する}
+ * {@.en Creats OutPortSHMProvider}
+ *
+ * @return
+ * {@.ja 生成されたOutPortProvider}
+ * {@.en Object Created instances}
+ *
+ */
+ public OutPortProvider creator_() {
+ return new OutPortSHMProvider();
+ }
+ /**
+ * {@.ja OutPortSHMProvider を破棄する}
+ * {@.en Destructs OutPortSHMProvider}
+ *
+ * @param obj
+ * {@.ja 破棄するインタスタンス}
+ * {@.en The target instances for destruction}
+ *
+ */
+ public void destructor_(Object obj) {
+ try{
+ byte[] oid = _default_POA().servant_to_id((InPortSHMProvider)obj);
+ _default_POA().deactivate_object(oid);
+ }
+ catch(Exception e){
+ e.printStackTrace();
+ }
+ obj = null;
+ }
+ /**
+ * {@.ja モジュール初期化関数}
+ * {@.en Module initialization}
+ * <p>
+ * {@.ja OutPortSHMProvider のファクトリを登録する初期化関数。}
+ * {@.en This initialization function registers OutPortSHMProvider's
+ * factory.}
+ *
+ */
+ public static void OutPortSHMProviderInit() {
+ final OutPortProviderFactory<OutPortProvider,String> factory
+ = OutPortProviderFactory.instance();
+
+ factory.addFactory("corba_cdr",
+ new OutPortSHMProvider(),
+ new OutPortSHMProvider());
+
+ }
+
+ /**
+ * {@.ja InterfaceProfile情報を公開する}
+ * {@.en Publish InterfaceProfile information}
+ *
+ * <p>
+ * {@.ja InterfaceProfile情報を公開する。
+ * 引数で指定するプロパティ情報内の NameValue オブジェクトの
+ * dataport.interface_type 値を調べ、当該ポートに設定されている
+ * インターフェースタイプと一致する場合のみ情報を取得する。}
+ * {@.en Publish interfaceProfile information.
+ * Check the dataport.interface_type value of the NameValue object
+ * specified by an argument in property information and get information
+ * only when the interface type of the specified port is matched.}
+ *
+ * @param properties
+ * {@.ja InterfaceProfile情報を受け取るプロパティ}
+ * {@.en Properties to get InterfaceProfile information}
+ *
+ */
+ public void publishInterfaceProfile(NVListHolder properties) {
+
+ NVUtil.appendStringValue(properties, "dataport.data_type",
+ this.m_dataType);
+ NVUtil.appendStringValue(properties, "dataport.interface_type",
+ this.m_interfaceType);
+ NVUtil.appendStringValue(properties, "dataport.dataflow_type",
+ this.m_dataflowType);
+ NVUtil.appendStringValue(properties, "dataport.subscription_type",
+ this.m_subscriptionType);
+ }
+ /**
+ * {@.ja Interface情報を公開する}
+ * {@.en Publish interface information}
+ * <p>
+ * {@.ja Interface情報を公開する。引数で指定するプロパティ情報内の
+ * NameValue オブジェクトのdataport.interface_type 値を調べ、当該ポー
+ * トに設定されていなければNameValue に情報を追加する。すでに同一イ
+ * ンターフェースが登録済みの場合は何も行わない。}
+ * {@.en Publish interface information. Check the
+ * dataport.interface_type value of the NameValue object specified
+ * by an argument in the property information, and add the
+ * information to the NameValue if this port is not specified.
+ * This does not do anything if the same interface is already
+ * subscribed.}
+ *
+ * @param properties
+ * {@.ja Interface情報を受け取るプロパティ}
+ * {@.en Properties to receive interface information}
+ * @return
+ * {@.ja true: 正常終了}
+ * {@.en true: normal return}
+ */
+ public boolean publishInterface(NVListHolder properties) {
+
+ if (!NVUtil.isStringValue(properties,
+ "dataport.interface_type",
+ this.m_interfaceType)) {
+ return false;
+ }
+
+ NVUtil.append(properties, this.m_properties);
+ return true;
+ }
+ /**
+ * {@.ja Connectorを設定する。}
+ * {@.en set Connector}
+ * <p>
+ * {@.ja OutPort は接続確立時に OutPortConnector オブジェクトを生成し、生
+ * 成したオブジェクトのポインタと共にこの関数を呼び出す。所有権は
+ * OutPort が保持するので OutPortProvider は OutPortConnector を削
+ * 除してはいけない。}
+ * {@.en OutPort creates OutPortConnector object when it establishes
+ * connection between OutPort and InPort, and it calls this
+ * function with a pointer to the connector object. Since the
+ * OutPort has the ownership of this connector, OutPortProvider
+ * should not delete it.}
+ *
+ * @param connector
+ * {@.ja OutPortConnector}
+ * {@.en OutPortConnector}
+ */
+ public void setConnector(OutPortConnector connector) {
+ m_connector = connector;
+ }
+ /**
+ * {@.ja インタフェースプロフィールのポートタイプを設定する。}
+ * {@.en Sets PortProfile of the interface profile}
+ *
+ * @param portType
+ * {@.ja ポートタイプ}
+ * {@.en port type}
+ */
+ protected void setPortType(final String portType) {
+
+ this.m_portType = portType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのデータタイプを設定する。}
+ * {@.en Sets DataType of the interface profile}
+ *
+ * @param dataType
+ * {@.ja データタイプ}
+ * {@.en dataType}
+ */
+ protected void setDataType(final String dataType) {
+
+ this.m_dataType = dataType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのインタフェースタイプを設定する。}
+ * {@.en Sets interface Type of the interface profile}
+ *
+ * @param interfaceType
+ * {@.ja インタフェースタイプ}
+ * {@.en Intereface Type}
+ */
+ protected void setInterfaceType(final String interfaceType) {
+
+ this.m_interfaceType = interfaceType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのデータフロータイプを設定する。}
+ * {@.en Sets data flow type of the interface profile}
+ *
+ * @param dataFlowType
+ * {@.ja データフロータイプ}
+ * {@.en Data flow type}
+ */
+ protected void setDataFlowType(final String dataFlowType) {
+
+ this.m_dataflowType = dataFlowType;
+ }
+
+ /**
+ * {@.ja インタフェースプロフィールのサブスクリプションタイプを設定する。}
+ * {@.en Sets subscription type of the interface profile}
+ *
+ * @param subscriptionType
+ * {@.ja サブスクリプションタイプ}
+ * {@.en Subscription type}
+ */
+ protected void setSubscriptionType(final String subscriptionType) {
+
+ this.m_subscriptionType = subscriptionType;
+ }
+ /**
+ * {@.ja リスナを設定する。}
+ * {@.en Set the listener.}
+ *
+ * <p>
+ * {@.ja OutPort はデータ送信処理における各種イベントに対して特定のリスナ
+ * オブジェクトをコールするコールバック機構を提供する。詳細は
+ * ConnectorListener.h の ConnectorDataListener, ConnectorListener
+ * 等を参照のこと。OutPortSHMProvider では、以下のコールバック
+ * が提供される。
+ * <ol>
+ * <li>- ON_BUFFER_READ
+ * <li>- ON_SEND
+ * <li>- ON_BUFFER_EMPTY
+ * <li>- ON_BUFFER_READ_TIMEOUT
+ * <li>- ON_SENDER_EMPTY
+ * <li>- ON_SENDER_TIMEOUT
+ * <li>- ON_SENDER_ERROR </ol>}
+ * {@.en OutPort provides callback functionality that calls specific
+ * listener objects according to the events in the data publishing
+ * process. For details, see documentation of
+ * ConnectorDataListener class and ConnectorListener class in
+ * ConnectorListener.h. In this OutPortSHMProvider provides
+ * the following callbacks.
+ * <ol>
+ * <li>- ON_BUFFER_READ
+ * <li>- ON_SEND
+ * <li>- ON_BUFFER_EMPTY
+ * <li>- ON_BUFFER_READ_TIMEOUT
+ * <li>- ON_SENDER_EMPTY
+ * <li>- ON_SENDER_TIMEOUT
+ * <li>- ON_SENDER_ERROR </ol>}
+ *
+ * @param info
+ * {@.ja 接続情報}
+ * {@.en @param info Connector information}
+ * @param listeners
+ * {@.ja リスナオブジェクト}
+ * {@.en Listener objects}
+ */
+ public void setListener(ConnectorBase.ConnectorInfo info,
+ ConnectorListeners listeners) {
+ m_profile = info;
+ m_listeners = listeners;
+ }
+ /**
+ * <p>接続プロフィールを保持するメンバ変数です。</p>
+ */
+ protected NVListHolder m_properties = NVListHolderFactory.create();
+
+ /**
+ * <p> Connector data listener functions </p>
+ */
+// private void onBufferWrite(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE].notify(m_profile, data);
+// }
+//
+// private void onBufferFull(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_BUFFER_FULL].notify(m_profile, data);
+// }
+//
+// private void onBufferWriteTimeout(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_BUFFER_WRITE_TIMEOUT].notify(m_profile, data);
+// }
+//
+// private void onBufferWriteOverwrite(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_BUFFER_OVERWRITE].notify(m_profile, data);
+// }
+
+ private void onBufferRead(final OutputStream data)
+ {
+ m_listeners.
+ connectorData_[ConnectorDataListenerType.ON_BUFFER_READ].notify(m_profile, data);
+ }
+
+ private void onSend(final OutputStream data)
+ {
+ m_listeners.
+ connectorData_[ConnectorDataListenerType.ON_SEND].notify(m_profile, data);
+ }
+
+// private void onReceived(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_RECEIVED].notify(m_profile, data);
+// }
+//
+// private void onReceiverFull(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_RECEIVER_FULL].notify(m_profile, data);
+// }
+//
+// private void onReceiverTimeout(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_RECEIVER_TIMEOUT].notify(m_profile, data);
+// }
+//
+// private void onReceiverError(final OutputStream data)
+// {
+// m_listeners.
+// connectorData_[ConnectorDataListenerType.ON_RECEIVER_ERROR].notify(m_profile, data);
+// }
+
+ /**
+ * <p> Connector listener functions </p>
+ */
+ private void onBufferEmpty() {
+ m_listeners.
+ connector_[ConnectorListenerType.ON_BUFFER_EMPTY].notify(m_profile);
+ }
+
+ private void onBufferReadTimeout() {
+ m_listeners.
+ connector_[ConnectorListenerType.ON_BUFFER_READ_TIMEOUT].notify(m_profile);
+ }
+
+ private void onSenderEmpty() {
+ m_listeners.
+ connector_[ConnectorListenerType.ON_SENDER_EMPTY].notify(m_profile);
+ }
+
+ private void onSenderTimeout() {
+ m_listeners.
+ connector_[ConnectorListenerType.ON_SENDER_TIMEOUT].notify(m_profile);
+ }
+
+ private void onSenderError() {
+ m_listeners.
+ connector_[ConnectorListenerType.ON_SENDER_ERROR].notify(m_profile);
+ }
+ /**
+ *
+ * {@.ja 共有メモリのマッピングを行う}
+ * {@.en Open a shared memory.}
+ *
+ * @param memory_size
+ * {@.ja 共有メモリのサイズ}
+ * {@.en size of shared momoery}
+ * @param shm_address
+ * {@.ja 空間名}
+ * {@.en name of memory}
+ # void open_memory(int memory_size, string shm_address);
+ */
+ public void open_memory (int memory_size, String shm_address){
+ rtcout.println(Logbuf.TRACE,
+ "open():memory_size="
+ + memory_size +",shm_address=" + shm_address);
+ m_memory_size = memory_size;
+ m_shm_address = shm_address;
+ try{
+ RandomAccessFile file = new RandomAccessFile(m_shm_address, "rw");
+ file.setLength(m_memory_size);
+ }
+ catch(Exception ex) {
+ rtcout.println(Logbuf.ERROR,"Open error "+ex.toString() );
+ }
+/*
+ self._rtcout.RTC_TRACE("open():memory_size="+str(memory_size)+",shm_address="+str(shm_address))
+ self._memory_size = memory_size
+ self._shm_address = shm_address
+ if self._shmem is None:
+ if platform.system() == "Windows":
+ self._shmem = mmap.mmap(0, self._memory_size, self._shm_address, mmap.ACCESS_READ)
+ else:
+ O_RDWR = 2
+ self.fd = self.rt.shm_open(self._shm_address,O_RDWR,0)
+ if self.fd < 0:
+ return self.UNKNOWN_ERROR
+ self.rt.ftruncate(self.fd, self._memory_size)
+ self._shmem = mmap.mmap(self.fd, self._memory_size, mmap.MAP_SHARED)
+ self.rt.close( self.fd )
+
+*/
+ }
+ /**
+ *
+ * {@.ja 共有メモリの初期化}
+ * {@.en Initializes a shared memory.}
+ *
+ * # windowsではページングファイル上に領域を確保する
+ * # Linuxでは/dev/shm以下にファイルを作成する
+ * # 作成したファイルの内容を仮想アドレスにマッピングする
+ *
+ * @param memory_size
+ * {@.ja 共有メモリのサイズ}
+ * {@.en Size of a shared momory}
+ * @param shm_address
+ * {@.ja 空間名}
+ * {@.en name of memory}
+ * # void create_memory(int memory_size, string shm_address);
+ */
+ public void create_memory (int memory_size, String shm_address){
+ rtcout.println(Logbuf.TRACE,
+ "create():memory_size="
+ + memory_size +",shm_address=" + shm_address);
+ m_memory_size = memory_size;
+ m_shm_address = shm_address;
+ }
+ /**
+ *
+ * {@.ja マッピングした共有メモリをアンマップする}
+ * {@.en Close a shared memory.}
+ *
+ * @param unlink
+ * {@.ja Linuxで/dev/shm以下に作成したファイルを削除する場合にTrueにする}
+ * {@.en }
+ *
+ # void close_memory(boolean unlink);
+ */
+ public void close_memory(boolean unlink){
+ File file = new File(m_shm_address);
+ file.delete();
+/*
+ self._rtcout.RTC_TRACE("open()")
+ if self._shmem:
+ self._shmem.close()
+ if platform.system() == "Windows":
+ pass
+ else:
+ if unlink:
+ self.rt.shm_unlink(self._shm_address)
+ self._shmem = None
+
+ if self._smInterface:
+ self._smInterface.close_memory(False)
+*/
+ }
+
+ public void close_memory(){
+ close_memory(false);
+ }
+
+
+ /**
+ *
+ * {@.ja 通信先のCORBAインターフェースを登録する}
+ * {@.en Registers CORBA interfaces.}
+ * <p>
+ * {@.ja 登録する事により共有メモリの初期化したときに、
+ * 通信先でもマッピングをやり直すことができる}
+ *
+ * @param sm
+ * {@.ja SharedMemoryのオブジェクトリファレンス}
+ * {@.en Object reference of shared momory}
+ */
+ public void setInterface (OpenRTM.PortSharedMemory sm){
+ //self._smInterface = sm
+ }
+
+ /**
+ *
+ * {@.ja データの送信を要求する}
+ * {@.en Get data.}
+ */
+ public OpenRTM.PortStatus get(){
+ return OpenRTM.PortStatus.UNKNOWN_ERROR;
+ }
+ /**
+ *
+ * {@.ja データの送信を知らせる}
+ * {@.en Put data.}
+ */
+ public OpenRTM.PortStatus put(){
+ return OpenRTM.PortStatus.UNKNOWN_ERROR;
+ }
+ private String m_portType = new String();
+ private String m_dataType = new String();
+ private String m_interfaceType = new String();
+ private String m_dataflowType = new String();
+ private String m_subscriptionType = new String();
+ private Logbuf rtcout;
+ private BufferBase<OutputStream> m_buffer;
+ private OpenRTM.PortSharedMemory m_objref;
+ private OutPortConnector m_connector;
+ private ConnectorListeners m_listeners;
+ private ConnectorBase.ConnectorInfo m_profile;
+
+ private String m_shm_address = new String();
+ private int m_memory_size;
+}
+
Modified: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/SharedMemory.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/SharedMemory.java 2016-03-10 02:30:56 UTC (rev 799)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/port/SharedMemory.java 2016-03-14 09:43:15 UTC (rev 800)
@@ -1,5 +1,7 @@
-package jp.go.aist.rtm.RTC.util;
+package jp.go.aist.rtm.RTC.port;
+import java.lang.Long;
+
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
@@ -61,7 +63,17 @@
# int string_to_MemorySize(string size_str);
*/
public long string_to_MemorySize(String size_str){
- return DEFAULT_MEMORY_SIZE;
+ if( size_str==null || size_str.equals("") ) {
+ return DEFAULT_MEMORY_SIZE;
+ }
+ String str = size_str.toUpperCase();
+ if(str.indexOf('M')>0){
+ return (1024 * 1024 * Long.parseLong(str.split("M")[0]));
+ }
+ else if(str.indexOf('K')>0){
+ return (1024 * Long.parseLong(str.split("K")[0]));
+ }
+ return (Long.parseLong(str));
/*
memory_size = SharedMemory.default_memory_size
if size_str:
@@ -91,7 +103,7 @@
* @param shm_address
* {@.ja 空間名}
* {@.en name of memory}
- # void create_memory(int memory_size, string shm_address);
+ * # void create_memory(int memory_size, string shm_address);
*/
public void create_memory (int memory_size, String shm_address){
rtcout.println(Logbuf.TRACE,
@@ -236,6 +248,13 @@
MappedByteBuffer buffer
= channel.map(FileChannel.MapMode.READ_WRITE, 0, length);
buffer.order(ByteOrder.LITTLE_ENDIAN);
+/*
+ OutPort out = (OutPort)m_outport;
+ OutputStream cdr
+ = new EncapsOutputStreamExt(m_orb,m_isLittleEndian);
+ out.write_stream(data,cdr);
+*/
+
// buffer.putInt((offset * 4/* size of int */), value);
@@ -283,6 +302,22 @@
# void read(::OpenRTM::CdrData_out data);
*/
public void read(CdrDataHolder data){
+ rtcout.println(Logbuf.TRACE, "read()");
+ try {
+ RandomAccessFile file = new RandomAccessFile(m_shm_address, "rw");
+ FileChannel channel = file.getChannel();
+ int length = (int)channel.size();
+ MappedByteBuffer buffer
+ = channel.map(FileChannel.MapMode.READ_WRITE, 0, length);
+ buffer.order(ByteOrder.LITTLE_ENDIAN);
+ //int value = buffer.getInt(offset * 4/* size of int */);
+ channel.close();
+ file.close();
+ }
+ catch(Exception ex) {
+ rtcout.println(Logbuf.ERROR,"read error "+ex.toString() );
+ }
+
/*
self._rtcout.RTC_TRACE("read()")
if self._shmem:
More information about the openrtm-commit
mailing list