From: Hwankyu Jhun Date: Fri, 15 Sep 2023 09:29:09 +0000 (+0900) Subject: Update README markdown for protocol version 2 X-Git-Tag: accepted/tizen/8.0/unified/20231208.171926~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0321b0b39eb015c8246ac7e565658dc8928bc03a;p=platform%2Fcore%2Fappfw%2Ftidl.git Update README markdown for protocol version 2 From Tizen 8.0, the following features are supported: - Enum Type - Import Another TIDL File - Method Privilege - Map and Set Container Type - Marshalling Type Info - Struct Inheritance - Remote Exception - Local Execution Mode - Private Sharing (without -b option) Change-Id: I60bce05d855423576ff9868c0f74fc40518ee98c Signed-off-by: Hwankyu Jhun --- diff --git a/README.md b/README.md index 8d78daf..b1f4bfb 100755 --- a/README.md +++ b/README.md @@ -1,12 +1,43 @@ - + # Welcome to TIDL! - TIDL is programming language to define interfaces for communicating among apps in Tizen. It provides methods to make a RPC(Remote Procedure Call) or RMI (Remote Method Invocation) in Tizen. + +## Contents +- [Welcome to TIDL!](#welcome-to-tidl) + - [Contents](#contents) + - [TIDLC](#tidlc) + - [Usage](#usage) + - [TIDL Syntax](#tidl-syntax) + - ['interface'](#interface) + - [Attributes](#attributes) + - ['async'](#async) + - ['delegate'](#delegate) + - ['struct'](#struct) + - [TIDL Type System](#tidl-type-system) + - [TIDL Generated Code](#tidl-generated-code) + - [Struct](#struct-1) + - [Proxy Interface](#proxy-interface) + - [Stub Interface](#stub-interface) + - [Protocol Version 2](#protocol-version-2) + - [Enum Type](#enum-type) + - [Import Another TIDL File](#import-another-tidl-file) + - [Method Privilege](#method-privilege) + - [Map and Set Container Type](#map-and-set-container-type) + - [Marshalling Type Info](#marshalling-type-info) + - [Struct Inheritance](#struct-inheritance) + - [Remote Exception](#remote-exception) + - [Local Execution Mode](#local-execution-mode) + - [Private Sharing](#private-sharing) + - [TIDL Generated Code for Protocol Version 2](#tidl-generated-code-for-protocol-version-2) + - [Proxy Interface](#proxy-interface-1) + - [Stub Interface](#stub-interface-1) + + ## TIDLC - **TIDLC** is a compiler for making stub or proxy code block from **TIDL** file. + ### Usage ``` Usage: @@ -32,9 +63,10 @@ Application Options: -v, --version Show version information ``` - + ## TIDL Syntax + ### 'interface' It makes an interface to communicate between proxy and stub. @@ -58,6 +90,7 @@ interface ITest { } ``` + ### Attributes It indicates required privileges and trusted signature. By default, ‘trusted” is ‘false’. @@ -82,6 +115,7 @@ interface ITest {} interface ITest2 {} ``` + ### 'async' It denotes one-way-call. @@ -113,6 +147,7 @@ interface ITest { } ``` + ### 'struct' It allows developers to define user-defined types. It is also possible to be used in other user-defined types or method syntax. @@ -134,6 +169,7 @@ struct Student { } ``` + ## TIDL Type System - Built-in type (‘in’ direction case) @@ -164,8 +200,10 @@ struct Student { - User-defined type - Name defined by ‘struct’ syntax + ## TIDL Generated Code + ### Struct **TIDL** ```csharp @@ -237,6 +275,7 @@ class Foo { } ``` + ### Proxy Interface **TIDL** @@ -359,6 +398,7 @@ class Runnable extends ProxyBase { } ``` + ### Stub Interface **TIDL** @@ -507,3 +547,1017 @@ class Runnable extends StubBase { final ServiceBuilder _serviceBuilder; } ``` + + +## Protocol Version 2 +**TIDLC** supports 'protocol version 2' since Tizen 8.0. +To use 'protocol version 2', you must fill **'protocol 2'** in the .tidl file. +'protocol version 2' of **TIDL** supports the following features: + + +### Enum Type + - **'enum'** type is added. + - You can declare an **enum** type inside a 'struct' or 'interface' and use it as a member variable or parameter. + ```tidl + struct Message { + enum Type { + T1 = 0, + T2, + T3 + } + + Type t; + int id; + string str; + } + + interface Hello { + enum Version { + V1, + V2, + V3 + } + + string SayHello(Version ver, string str, Message.Type msg); + } + ``` +- When using a struct's enum type as a method parameter, it must be specified as **"."**. + + +### Import Another TIDL File +- **'import'** keyword is added. +- You can add and use other TIDL files in the same directory as the current TIDL file using the **'import'** keyword. +- During the compilation process, the contents of other TIDL files are integrated and generated as one code. +- The following example shows how to use the **'import'** keyword: + ```tidl + import + + interface Message { + int Send(string name, string msg); + } + ``` + + +### Method Privilege +- The protocol version 2 of TIDL supports the method privilege feature. +- You can set privileges for each method of an interface by writing them as below: + ```tidl + interface PackageManager { + [privilege = "http://tizen.org/privilege/packagemanager.info"] + int GetPackages(out list packages); + + [privilege = "http://tizen.org/privilege/packagemanager.admin"] + int Install(file path); + + [privilege = "http://tizen.org/privilege/packagemanager.admin"] + int Uninstall(string package); + } + ``` +- To use the GetPackages method in the example, the client application needs to have the privilege that is "http://tizen.org/privilege/packagemanager.info". + + +### Map and Set Container Type +- You can use map and set container types in TIDL. +- The map type is **'map\'**. The set type is **'set\'**. + ```tidl + struct Message { + string name; + map envelope; + set keys; + } + ``` + > **Note** + > + > The key type of map and set container must be TIDL's builtin types. + + +### Marshalling Type Info +- From protocol version 2, the type information and variable names of method parameters are also transmitted. +- Even if variable names are changed, added, or deleted due to interface modifications, it does not affect communication. +- If there are no variables to be passed, they are passed as initial values. + - Example 1. Original tidl code + + ```tidl + interface Hello { + int GetPackages(out list packages); + } + ``` + - Example 2. Revised tidl code + ```tidl + interface Hello { + int GetPackages(out list packages, out int size); + } + `````` +- In the example, the GetPackages() method has an added size parameter. +- Even if the stub only returns the existing packages parameter, there is no problem with communication. + + +### Struct Inheritance +- **'struct'** inheritance is supported. +- Here is an example that supports **'struct'** inheritance: + ```tidl + struct MessageBase { + int id; + string name; + } + + struct MessageDerived : MessageBase { + string msg; + } + ``` +- In this example, **MessageDerived** inherits **MessageBase**. + > **Note** + > + > The inherited struct MUST not have elements of the base struct." + +- If the method of the interface is a base struct, communication can be performed using the derived struct that is inherited. (Polymophism) + ```tidl + struct MessageBase { + int id; + string name; + } + + struct MessageDerived : MessageBase { + string msg; + } + + struct Envelope : MessageBase { + string address; + string msg; + } + + interface Message { + int SendMessage(MessageBase msg); + } + ``` +- When using the **Message** interface, you can use **Envelope** or **MessageDerived** to call the **SendMessage()** method. + + +### Remote Exception +- The stub can use **RemoteException** to throw an exception to the proxy. +- This feature is available when the method operates synchronously. +- When the proxy sends a request and waits for a result, if the stub throws an exception, it is passed to the proxy. + + +### Local Execution Mode +- If the stub that the proxy sends a request to is in the same application, a function call occurs instead of RPC. + + +### Private Sharing +- Since protocol version 2, the file keyword can be used without the '-b' option. +- The proxy or the stub can use this to share a specific file in the data directory with the intended recipient for communication. +- The recipient who receives the shared file can access it with read-only permission. + + +### TIDL Generated Code for Protocol Version 2 + +**TIDL** +```tidl +protocol 2 + +struct MessageBase { + int id; + string name; + string msg; +} + +struct MessageDerived : MessageBase { + string address; +} + +interface Message { + void OnReceived(string sender, MessageBase message) delegate; + + int Register(string sender, OnReceived callback); + void Unregister() async; + int Send(MessageBase message); +} +``` +- In the example, the MessageDerived structure inherits from MessageBase. +- When calling the Send method of the Message interface, you can use a MessageDerived instance. + + +#### Proxy Interface + +**C** +```c +// Handle for 'MessageBase' structure. +typedef void *rpc_port_proxy_MessageBase_h; + +// Handle for 'MessageDerived' structure. +typedef void *rpc_port_proxy_MessageDerived_h; + +// Handle for Remote Exception. +typedef struct rpc_port_proxy_remote_exception_s *rpc_port_proxy_remote_exception_h; + +// Handle for 'Message' interface. +typedef struct rpc_port_proxy_Message_s *rpc_port_proxy_Message_h; + +// Handle for 'OnReceived' delegate of 'Message' interface. +typedef struct rpc_port_proxy_Message_OnReceived_s *rpc_port_proxy_Message_OnReceived_h; + +// Function for creating MessageBase handle. +int rpc_port_proxy_MessageBase_create(rpc_port_proxy_MessageBase_h *h); + +// Function for destroying MessageBase handle. +int rpc_port_proxy_MessageBase_destroy(rpc_port_proxy_MessageBase_h h); + +// Function for cloning MessageBase handle. +int rpc_port_proxy_MessageBase_clone(rpc_port_proxy_MessageBase_h h, rpc_port_proxy_MessageBase_h *clone); + +// Function for setting id to MessageBase handle. +int rpc_port_proxy_MessageBase_set_id(rpc_port_proxy_MessageBase_h h, int value); + +// Function for getting id from MessageBase handle. +int rpc_port_proxy_MessageBase_get_id(rpc_port_proxy_MessageBase_h h, int *value); + +// Function for setting name to MessageBase handle. +int rpc_port_proxy_MessageBase_set_name(rpc_port_proxy_MessageBase_h h, const char *value); + +// Function for getting name from MessageBase handle. +int rpc_port_proxy_MessageBase_get_name(rpc_port_proxy_MessageBase_h h, char **value); + +// Function for setting msg to MessageBase handle. +int rpc_port_proxy_MessageBase_set_msg(rpc_port_proxy_MessageBase_h h, const char *value); + +// Function for getting msg from MessageBase handle. +int rpc_port_proxy_MessageBase_get_msg(rpc_port_proxy_MessageBase_h h, char **value); + +// Function for creating MessageDerived handle. +int rpc_port_proxy_MessageDerived_create(rpc_port_proxy_MessageDerived_h *h); + +// Function for destroying MessageDerived handle. +int rpc_port_proxy_MessageDerived_destroy(rpc_port_proxy_MessageDerived_h h); + +// Function for cloning MessageDerived handle. +int rpc_port_proxy_MessageDerived_clone(rpc_port_proxy_MessageDerived_h h, rpc_port_proxy_MessageDerived_h *clone); + +// Function for setting id to MessageDerived handle. +int rpc_port_proxy_MessageDerived_set_id(rpc_port_proxy_MessageDerived_h h, int value); + +// Function for getting id from MessageDerived handle. +int rpc_port_proxy_MessageDerived_get_id(rpc_port_proxy_MessageDerived_h h, int *value); + +// Function for setting id to MessageDerived handle. +int rpc_port_proxy_MessageDerived_set_name(rpc_port_proxy_MessageDerived_h h, const char *value); + +// Function for getting name from MessageDerived handle. +int rpc_port_proxy_MessageDerived_get_name(rpc_port_proxy_MessageDerived_h h, char **value); + +// Function for setting msg to MessageDerived handle. +int rpc_port_proxy_MessageDerived_set_msg(rpc_port_proxy_MessageDerived_h h, const char *value); + +// Function for getting msg from MessageDerived handle. +int rpc_port_proxy_MessageDerived_get_msg(rpc_port_proxy_MessageDerived_h h, char **value); + +// Function for setting address to MessageDerived handle. +int rpc_port_proxy_MessageDerived_set_address(rpc_port_proxy_MessageDerived_h h, const char *value); + +// Function for getting address from MessageDerived handle. +int rpc_port_proxy_MessageDerived_get_address(rpc_port_proxy_MessageDerived_h h, char **value); + +// Function for creating Remote Exception handle. +int rpc_port_proxy_remote_exception_create(rpc_port_proxy_remote_exception_h *h); + +// Function for setting cause to Remote Exception handle. +int rpc_port_proxy_remote_exception_set_cause(rpc_port_proxy_remote_exception_h h, int cause); + +// Function for setting msessage to Remote Exception handle. +int rpc_port_proxy_remote_exception_set_message(rpc_port_proxy_remote_exception_h h, const char *message); + +// Function for getting cause from Remote Exception handle. +int rpc_port_proxy_remote_exception_get_cause(rpc_port_proxy_remote_exception_h h, int *cause); + +// Function for getting message from Remote Exception handle. +int rpc_port_proxy_remote_exception_get_message(rpc_port_proxy_remote_exception_h, char **message); + +// Function for destroying Remote Exception handle. +int rpc_port_proxy_remote_exception_destroy(rpc_port_proxy_remote_exception_h h); + +// Function for getting Remote Exception handle. +int rpc_port_proxy_get_remote_exception(rpc_port_proxy_remote_exception_h *h); + +// Callback function for OnReceived of Message interface. +typedef void (*rpc_port_proxy_Message_OnReceived_cb)(void *user_data, const char *sender, rpc_port_proxy_MessageBase_h message); + +// Function for creating OnReceived handle. +int rpc_port_proxy_Message_OnReceived_create(rpc_port_proxy_Message_OnReceived_h *h); + +// Function for destroying OnReceived handle. +int rpc_port_proxy_Message_OnReceived_destroy(rpc_port_proxy_Message_OnReceived_h h); + +// Function for cloning OnReceived handle. +int rpc_port_proxy_Message_OnReceived_clone(rpc_port_proxy_Message_OnReceived_h h, rpc_port_proxy_Message_OnReceived_h *clone); + +// Function for setting callback to OnReceived handle. +int rpc_port_proxy_Message_OnReceived_set_callback(rpc_port_proxy_Message_OnReceived_h h, rpc_port_proxy_Message_OnReceived_cb callback, void *user_data); + +// Function for setting once flag to OnReceived handle. +int rpc_port_proxy_Message_OnReceived_set_once(rpc_port_proxy_Message_OnReceived_h h, bool once); + +// Function for getting id from OnReceived handle. +int rpc_port_proxy_Message_OnReceived_get_id(rpc_port_proxy_Message_OnReceived_h h, int *id); + +// Function for getting seq_id from OnReceived handle. +int rpc_port_proxy_Message_OnReceived_get_seq_id(rpc_port_proxy_Message_OnReceived_h h, int *seq_id); + +// Function for checking once flag from OnReceived handle. +int rpc_port_proxy_Message_OnReceived_is_once(rpc_port_proxy_Message_OnReceived_h h, bool *once); + +// Function for getting tag from OnReceived handle. +int rpc_port_proxy_Message_OnReceived_get_tag(rpc_port_proxy_Message_OnReceived_h h, char **tag); + +// Function for dispoing OnReceived handle. +int rpc_port_proxy_Message_OnReceived_dispose(rpc_port_proxy_Message_h proxy, rpc_port_proxy_Message_OnReceived_h h); + +// Called when receiving connected event. +typedef void (*rpc_port_proxy_Message_connected_cb)(rpc_port_proxy_Message_h h, void *user_data); + +// Called when receiving disconnected event. +typedef void (*rpc_port_proxy_Message_disconnected_cb)(rpc_port_proxy_Message_h h, void *user_data); + +// Called when receiving rejected event. +typedef void (*rpc_port_proxy_Message_rejected_cb)(rpc_port_proxy_Message_h h, void *user_data); + +// Structure for receiving events of Message interface. +typedef struct { + rpc_port_proxy_Message_connected_cb connected; + rpc_port_proxy_Message_disconnected_cb disconnected; + rpc_port_proxy_Message_rejected_cb rejected; +} rpc_port_proxy_Message_callback_s; + +// Function for creating Message handle. +int rpc_port_proxy_Message_create(const char *stub_appid, rpc_port_proxy_Message_callback_s *callback, void *user_data, rpc_port_proxy_Message_h *h); + +// Function for destroying Message handle. +int rpc_port_proxy_Message_destroy(rpc_port_proxy_Message_h h); + +// Function for connecting to Message server. +int rpc_port_proxy_Message_connect(rpc_port_proxy_Message_h h); + +// Function for connecting to Message server synchronously. +int rpc_port_proxy_Message_connect_sync(rpc_port_proxy_Message_h h); + +// Function for disconnecting from Message server. +int rpc_port_proxy_Message_disconnect(rpc_port_proxy_Message_h h); + +// Function for Register method of Message interface. +int rpc_port_proxy_Message_invoke_Register(rpc_port_proxy_Message_h h, const char *sender, rpc_port_proxy_Message_OnReceived_h callback); + +// Function for Unregister method of Message interface. +void rpc_port_proxy_Message_invoke_Unregister(rpc_port_proxy_Message_h h); + +// Function for Send method of Message interface. +int rpc_port_proxy_Message_invoke_Send(rpc_port_proxy_Message_h h, rpc_port_proxy_MessageBase_h message); +``` + +**C++** +```cpp +// Class for Bundle. +class Bundle final { + public: + Bundle(); + explicit Bundle(bundle* handle, bool copy = true, bool own = true); + Bundle(std::string raw); + ~Bundle(); + + Bundle(const Bundle& b); + Bundle& operator = (const Bundle& b); + Bundle(Bundle&& b) noexcept; + Bundle& operator = (Bundle&&) noexcept; + + bundle* GetHandle() const; + bundle* Detach(); +}; + +// class for File. +class File final { + public: + File(std::string filename = ""); + + const std::string& GetFileName() const; + int Share(rpc_port_h port); +}; + +// class for 'MessageBase' structure. +class MessageBase { + public: + MessageBase(); + MessageBase(int id, std::string name, std::string msg); + + int Getid() const; + void Setid(int id); + + const std::string& Getname() const; + void Setname(std::string name); + + const std::string& Getmsg() const; + void Setmsg(std::string msg); +}; + +// class for 'MessageDerived' structure. +class MessageDerived : public MessageBase { + public: + MessageDerived(); + MessageDerived(int id, std::string name, std::string msg, std::string address); + + const std::string& Getaddress() const; + void Setaddress(std::string address); +}; + +namespace proxy { +class Exception {}; +class NotConnectedSocketException : public Exception {}; +class InvalidProtocolException : public Exception {}; +class InvalidIOException : public Exception {}; +class PermissionDeniedException : public Exception {}; +class InvalidIDException : public Exception {}; +class InvalidArgumentException : public Exception {}; +class OutOfMemoryException : public Exception {}; + +// class for RemoteException. +class RemoteException : public Exception { + public: + RemoteException(); + RemoteException(std::string message); + RemoteException(int cause, std::string message); + + int GetCause() const; + const std::string& GetMessage() const; +}; + +// class for 'Message' interface. +class Message : public LocalExecution::IEvent { + public: + + class CallbackBase { + public: + CallbackBase() = default; + CallbackBase(int delegate_id, bool once); + virtual ~CallbackBase() = default; + + virtual void OnReceivedEvent(const UnitMap& unit_map); + int GetId() const; + void SetId(int id); + int GetSeqId() const; + void SetSeqId(int seq_id); + bool IsOnce() const; + void SetOnce(bool once); + std::string GetTag() const; + }; + + class OnReceived : public CallbackBase { + public: + OnReceived(bool once = false); + virtual void OnReceived(std::string sender, MessageBase message); + }; + + class IEventListener { + public: + virtual ~IEventListener() = 0; + // Called when connected event is delivered. + virtual void OnConnected() = 0; + + // Called when disconnected event is delivered. + virtual void OnDisconnected() = 0; + + // Called when rejected event is delivered. + virtual void OnRejected() = 0; + }; + + // Constructor. + Message(IEventListener* listener, std::string target_appid); + + // Desctructor. + virtual ~Message(); + + // Method for connecting to 'Message' server. + void Connect(bool sync = false); + + // Method for disconnecting from 'Message' server. + void Disconnect(); + + // Method for disposing delegate from Message intstance. + void DisposeCallback(const std::string& tag); + + // Method for 'Register' method of 'Message' interface. + int Register(std::string sender, std::unique_ptr callback); + + // Method for 'Unregister' method of 'Message' interface. + void Unregister(); + + // Method for 'Send' method of 'Message' interface. + int Send(MessageBase message); +}; +} // namespace proxy +``` + +**C#** +```csharp +// class for 'MessageBase' structure. +public class MessageBase +{ + public int id; + public string name; + public string msg; + + public MessageBase(); +} + +// class for 'MessageDerived' structure. +public class MessageDerived : MessageBase +{ + public string address; + + public MessageDerived(); +} + +// class for RemoteException. +public class RemoteException : Exception +{ + public RemoteException(); + public RemoteException(string message); + public RemoteException(string message, int cause); + public new string Message; + public int Cause; +} + +namespace Proxy +{ + // class for 'Message' interface. + public class Message : ProxyBase + { + public event EventHandler Connected; + public event EventHandler Disconnected; + public event EventHandler Rejected; + + public class CallbackBase + { + public string Tag; + public CallbackBase(int delegateId, bool once) + } + + public sealed class OnReceived : CallbackBase + { + public OnReceived(bool once = false) : base((int)DelegateId.OnReceived, once); + public delegate void Callback(string sender, MessageBase message); + public event Callback Received; + } + + // Called when connected event is delivered. + protected override void OnConnectedEvent(string endPoint, string portName, Port port); + + // Called when disconnected event is delivered. + protected override void OnDisconnectedEvent(string endPoint, string portName); + + // Called when rejected event is delivered. + protected override void OnRejectedEvent(string endPoint, string portName); + + // Called when received event is delivered. + protected override void OnReceivedEvent(string endPoint, string portName); + + // Constructor. + public Message(string appId); + + // Method for connecting to 'Message' server. + public void Connect(); + + // Method for disconnecting from 'Message' server. + public void Disconnect(); + + // Method for connecting to 'Message' server sychronously. + public void ConnectSync(); + + // Method for disposing delegate from Message instance. + void DisposeCallback(string tag); + + // Method for 'Register' method of 'Message' interface. + public int Register(string sender, OnReceived callback); + + // Method for 'Unregister' method of 'Message' interface. + public void Unregister(); + + // Method for 'Send' method of 'Message' interface. + public int Send(MessageBase message); + } +} +``` + + + +#### Stub Interface + +**C** +```c +// Handle for 'MessageBase' structure. +typedef void *rpc_port_stub_MessageBase_h; + +// Handle for 'MessageDerived' structure. +typedef void *rpc_port_stub_MessageDerived_h; + +// Handle for Remote Exception. +typedef struct rpc_port_stub_remote_exception_s *rpc_port_stub_remote_exception_h; + +// Handle for context of 'Message' interface. +typedef struct rpc_port_stub_Message_context_s *rpc_port_stub_Message_context_h; + +// Handle for 'OnReceived' delegate of 'Message' interface. +typedef struct rpc_port_stub_Message_OnReceived_s *rpc_port_stub_Message_OnReceived_h; + +// Function for creating MessageBase handle. +int rpc_port_stub_MessageBase_create(rpc_port_stub_MessageBase_h *h); + +// Function for destroying MessageBase handle. +int rpc_port_stub_MessageBase_destroy(rpc_port_stub_MessageBase_h h); + +// Function for cloning MessageBase handle. +int rpc_port_stub_MessageBase_clone(rpc_port_stub_MessageBase_h h, rpc_port_stub_MessageBase_h *clone); + +// Function for setting id to MessageBase handle. +int rpc_port_stub_MessageBase_set_id(rpc_port_stub_MessageBase_h h, int value); + +// Function for getting id from MessageBase handle. +int rpc_port_stub_MessageBase_get_id(rpc_port_stub_MessageBase_h h, int *value); + +// Function for setting name to MessageBase handle. +int rpc_port_stub_MessageBase_set_name(rpc_port_stub_MessageBase_h h, const char *value); + +// Function for getting name from MessageBase handle. +int rpc_port_stub_MessageBase_get_name(rpc_port_stub_MessageBase_h h, char **value); + +// Function for setting msg to MessageBase handle. +int rpc_port_stub_MessageBase_set_msg(rpc_port_stub_MessageBase_h h, const char *value); + +// Function for getting msg to MessageBase handle. +int rpc_port_stub_MessageBase_get_msg(rpc_port_stub_MessageBase_h h, char **value); + +// Function for creating MessageDerived handle. +int rpc_port_stub_MessageDerived_create(rpc_port_stub_MessageDerived_h *h); + +// Function for destroying MessageDerived handle. +int rpc_port_stub_MessageDerived_destroy(rpc_port_stub_MessageDerived_h h); + +// Function for cloning MessageDerived handle. +int rpc_port_stub_MessageDerived_clone(rpc_port_stub_MessageDerived_h h, rpc_port_stub_MessageDerived_h *clone); + +// Function for setting id to MessageDerived handle. +int rpc_port_stub_MessageDerived_set_id(rpc_port_stub_MessageDerived_h h, int value); + +// Function for getting id from MessageDerived handle. +int rpc_port_stub_MessageDerived_get_id(rpc_port_stub_MessageDerived_h h, int *value); + +// Function for setting name to MessageDerived handle. +int rpc_port_stub_MessageDerived_set_name(rpc_port_stub_MessageDerived_h h, const char *value); + +// Function for getting name from MessageDerived handle. +int rpc_port_stub_MessageDerived_get_name(rpc_port_stub_MessageDerived_h h, char **value); + +// Function for setting msg to MessageDerived handle. +int rpc_port_stub_MessageDerived_set_msg(rpc_port_stub_MessageDerived_h h, const char *value); + +// Function for getting msg to MessageDerived handle. +int rpc_port_stub_MessageDerived_get_msg(rpc_port_stub_MessageDerived_h h, char **value); + +// Function for setting address to MessageDerived handle. +int rpc_port_stub_MessageDerived_set_address(rpc_port_stub_MessageDerived_h h, const char *value); + +// Function for getting address from MessageDerived handle. +int rpc_port_stub_MessageDerived_get_address(rpc_port_stub_MessageDerived_h h, char **value); + +// Function for creating Remote Exception handle. +int rpc_port_stub_remote_exception_create(rpc_port_stub_remote_exception_h *h); + +// Function for setting cause to Remote Exception handle. +int rpc_port_stub_remote_exception_set_cause(rpc_port_stub_remote_exception_h h, int cause); + +// Function for setting message to Remote Exception handle. +int rpc_port_stub_remote_exception_set_message(rpc_port_stub_remote_exception_h h, const char *message); + +// Function for getting cause from Remote Exception handle. +int rpc_port_stub_remote_exception_get_cause(rpc_port_stub_remote_exception_h h, int *cause); + +// Function for getting message from Remote Exception handle. +int rpc_port_stub_remote_exception_get_message(rpc_port_stub_remote_exception_h, char **message); + +// Function for destroying Remote Exception handle. +int rpc_port_stub_remote_exception_destroy(rpc_port_stub_remote_exception_h h); + +// Function for throwing Remote Exception handle. +int rpc_port_stub_remote_exception_throw(rpc_port_stub_remote_exception_h h); + +// Called when client is connected. +typedef void (*rpc_port_stub_Message_create_cb)(rpc_port_stub_Message_context_h context, void *user_data); + +// Called when client is disconnected. +typedef void (*rpc_port_stub_Message_terminate_cb)(rpc_port_stub_Message_context_h context, void *user_data); + +// Called when retreiving contexts of Message handle. +typedef bool (*rpc_port_stub_Message_context_cb)(rpc_port_stub_Message_context_h context, void *user_data); + +// Called when receiving 'Register' event from client. +typedef int (*rpc_port_stub_Message_Register_cb)(rpc_port_stub_Message_context_h context, const char *sender, rpc_port_stub_Message_OnReceived_h callback, void *user_data); + +// Called when receiving 'Unregister' event from client. +typedef void (*rpc_port_stub_Message_Unregister_cb)(rpc_port_stub_Message_context_h context, void *user_data); + +// Called when receiving 'Send' event from client. +typedef int (*rpc_port_stub_Message_Send_cb)(rpc_port_stub_Message_context_h context, rpc_port_stub_MessageBase_h message, void *user_data); + +// Function for setting tag to Message context handle. +int rpc_port_stub_Message_context_set_tag(rpc_port_stub_Message_context_h context, void *tag); + +// Function for getting tag from Message context handle. +int rpc_port_stub_Message_context_get_tag(rpc_port_stub_Message_context_h context, void **tag); + +// Function for getting sender from Message context handle. +int rpc_port_stub_Message_context_get_sender(rpc_port_stub_Message_context_h context, char **sender); + +// Function for getting instance from Message context handle. +int rpc_port_stub_Message_context_get_instance(rpc_port_stub_Message_context_h context, char **instance); + +// Function for disconnecting from client. +int rpc_port_stub_Message_context_disconnect(rpc_port_stub_Message_context_h context); + +// Function for creating OnReceived handle. +int rpc_port_stub_Message_OnReceived_create(rpc_port_stub_Message_OnReceived_h *h); + +// Function for destroying OnReceived handle. +int rpc_port_stub_Message_OnReceived_destroy(rpc_port_stub_Message_OnReceived_h h); + +// Function for cloning OnReceived handle. +int rpc_port_stub_Message_OnReceived_clone(rpc_port_stub_Message_OnReceived_h h, rpc_port_stub_Message_OnReceived_h *clone); + +// Function for getting id from OnReceived handle. +int rpc_port_stub_Message_OnReceived_get_id(rpc_port_stub_Message_OnReceived_h h, int *id); + +// Function for getting seq_id from OnReceived handle. +int rpc_port_stub_Message_OnReceived_get_seq_id(rpc_port_stub_Message_OnReceived_h h, int *seq_id); + +// Function for checking once flag from OnReceived handle. +int rpc_port_stub_Message_OnReceived_is_once(rpc_port_stub_Message_OnReceived_h h, bool *once); + +// Function for getting tag from OnReceived handle. +int rpc_port_stub_Message_OnReceived_get_tag(rpc_port_stub_Message_OnReceived_h h, char **tag); + +// Function for invoking OnReceived callback function of 'Message' client. +int rpc_port_stub_Message_OnReceived_invoke(rpc_port_stub_Message_OnReceived_h h, const char *sender, rpc_port_stub_MessageBase_h message); + +// Structure for receiving events of Message interface. +typedef struct { + rpc_port_stub_Message_create_cb create; + rpc_port_stub_Message_terminate_cb terminate; + rpc_port_stub_Message_Register_cb Register; + rpc_port_stub_Message_Unregister_cb Unregister; + rpc_port_stub_Message_Send_cb Send; +} rpc_port_stub_Message_callback_s; + +// Function for registering callback functions of Message interface to be invoked when events are received. +int rpc_port_stub_Message_register(rpc_port_stub_Message_callback_s *callback, void *user_data); + +// Function for unregistering callback functions of Message interface. +int rpc_port_stub_Message_unregister(void); + +// Function for retreving connected context of clients of Message interface. +int rpc_port_stub_Message_foreach_context(rpc_port_stub_Message_context_cb callback, void *user_data); + +// Function for getting client number from Message interface. +int rpc_port_stub_Message_get_client_number(unsigned int *client_number); +``` + +**C++** +```cpp +// class for Bundle. +class Bundle final { + public: + Bundle(); + explicit Bundle(bundle* handle, bool copy = true, bool own = true); + Bundle(std::string raw); + ~Bundle(); + + Bundle(const Bundle& b); + Bundle& operator = (const Bundle& b); + Bundle(Bundle&& b) noexcept; + Bundle& operator = (Bundle&&) noexcept; + + bundle* GetHandle() const; + bundle* Detach(); +}; + + +// class for File. +class File final { + public: + File(std::string filename = ""); + + const std::string& GetFileName() const; + int Share(rpc_port_h port); +}; + +// class for 'MessageBase' structure. +class MessageBase { + public: + MessageBase(); + MessageBase(int id, std::string name, std::string msg); + + int Getid() const; + void Setid(int id); + const std::string& Getname() const; + void Setname(std::string name); + const std::string& Getmsg() const; + void Setmsg(std::string msg); +}; + +// class for 'MessageDerived' structure. +class MessageDerived : public MessageBase { + public: + MessageDerived(); + MessageDerived(int id, std::string name, std::string msg, std::string address); + + const std::string& Getaddress() const; + void Setaddress(std::string address); +}; + +namespace stub { + +class Exception {}; +class NotConnectedSocketException : public Exception {}; +class InvalidProtocolException : public Exception {}; +class InvalidIOException : public Exception {}; +class PermissionDeniedException : public Exception {}; +class InvalidIDException : public Exception {}; +class InvalidArgumentException : public Exception {}; +class OutOfMemoryException : public Exception {}; + +// class for Remote Exception. +class RemoteException : public Exception { + public: + RemoteException(); + RemoteException(std::string message); + RemoteException(int cause, std::string message); + + int GetCause() const; + const std::string& GetMessage() const; +}; + +// class for 'Message' interface. +class Message : public LocalExecution::IEvent { + public: + class ServiceBase; + class CallbackBase { + public: + CallbackBase(int delegate_id, bool once); + CallbackBase() = default; + virtual ~CallbackBase() = default; + + int GetId() const; + void SetId(int id); + int GetSeqId() const; + void SetSeqId(int seq_id); + bool IsOnce() const; + void SetOnce(bool once); + + std::string GetTag() const; + + void SetContext(void* context); + void* GetContext() const; + }; + + class OnReceived : public CallbackBase { + public: + OnReceived(rpc_port_h callback_port, std::weak_ptr service) : CallbackBase(static_cast(DelegateId::OnReceived), false), callback_port_(callback_port), service_(std::move(service)) {} + + void Invoke(std::string sender, MessageBase message); + }; + + class ServiceBase : public std::enable_shared_from_this { + public: + class Factory { + public: + virtual ~Factory() = default; + virtual std::unique_ptr CreateService(std::string sender, std::string instance) = 0; + }; + + virtual ~ServiceBase() = default; + const std::string& GetSender() const { + return sender_; + } + const std::string& GetInstance() const { + return instance_; + } + + void SetPort(rpc_port_h port); + void Disconnect(); + virtual void OnCreate() = 0; + virtual void OnTerminate() = 0; + void SetContext(void* context); + void* GetContext() const; + void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel, std::shared_ptr service); + void Dispatch(rpc_port_h port, rpc_port_h callback_port, rpc_port_parcel_h parcel); + + virtual int Register(std::string sender, std::unique_ptr callback) = 0; + virtual void Unregister() = 0; + virtual int Send(MessageBase message) = 0; + + protected: + ServiceBase(std::string sender, std::string instance); + }; + + // Constructor. + Message(); + + // Destructor. + ~Message(); + + // Method for listening Message events. + void Listen(std::shared_ptr service_factory); + + // Method for getting instance of ServiceBase of clients. + const std::list>& GetServices() const { + return services_; + } +}; + +} // namespace stub +``` + +**C#** +```csharp +// class for 'MessageBase' structure. +public class MessageBase +{ + public int id; + public string name; + public string msg; + + public MessageBase(); +} + +// class for 'MessageDerived' structure. +public class MessageDerived : MessageBase +{ + public string address; + + public MessageDerived(); +} + +// class for Remote Exception. +public class RemoteException : Exception +{ + public RemoteException(); + public RemoteException(string message); + public RemoteException(string message, int cause); + public new string Message; + public int Cause; +} + +namespace Stub +{ + public sealed class Message : StubBase + { + public abstract class ServiceBase + { + public string Sender; + public string Instance; + public Port Port; + protected ServiceBase(); + public void Disconnect(); + public abstract void OnCreate(); + public abstract void OnTerminate(); + public abstract int Register(string sender, OnReceived callback); + public abstract void Unregister(); + public abstract int Send(MessageBase message); + } + + public class CallbackBase + { + public string Tag; + public CallbackBase(int delegateId, bool once); + } + + public sealed class OnReceived : CallbackBase + { + public void Invoke(string sender, MessageBase message); + } + + // Called when client sends a request. + protected override bool OnReceivedEvent(string sender, string instance, Port port); + + // Called when client is connected. + protected override void OnConnectedEvent(string sender, string instance); + + // Called when client is disconnected. + protected override void OnDisconnectedEvent(string sender, string instance); + + // Constructor. + public Message(); + + // Method for listening events of Message interface. + public void Listen(Type serviceType); + + // Method for getting instance of connected clients. + public IEnumerable GetServices(); + + ... + } +} +```