vitorsousa pushed a commit to branch master.

http://git.enlightenment.org/tools/examples.git/commit/?id=566b5c3ee732b1f76d873d0544638fc53ae24b73

commit 566b5c3ee732b1f76d873d0544638fc53ae24b73
Author: Vitor Sousa <vitorsousasi...@gmail.com>
Date:   Thu Mar 1 10:28:17 2018 -0300

    net_mono: add net reference examples to the C# binding
---
 reference/csharp/net/meson.build            |  10 ++
 reference/csharp/net/src/meson.build        |  22 +++
 reference/csharp/net/src/net_io.cs          | 269 ++++++++++++++++++++++++++++
 reference/csharp/net/src/net_io_buffered.cs | 181 +++++++++++++++++++
 reference/csharp/net/src/net_session.cs     | 135 ++++++++++++++
 5 files changed, 617 insertions(+)

diff --git a/reference/csharp/net/meson.build b/reference/csharp/net/meson.build
new file mode 100644
index 0000000..18a8171
--- /dev/null
+++ b/reference/csharp/net/meson.build
@@ -0,0 +1,10 @@
+project(
+  'efl-reference-net', 'c',
+  version : '0.0.1',
+  meson_version : '>= 0.38.0')
+
+efl_mono = dependency('efl-mono', version : '>=1.20.99')
+efl_mono_libs = efl_mono.get_pkgconfig_variable('mono_libs')
+
+subdir('src')
+
diff --git a/reference/csharp/net/src/meson.build 
b/reference/csharp/net/src/meson.build
new file mode 100644
index 0000000..9897ac6
--- /dev/null
+++ b/reference/csharp/net/src/meson.build
@@ -0,0 +1,22 @@
+deps = [efl_mono]
+
+executable('efl_reference_net_io',
+  files(['net_io.cs']),
+  dependencies : deps,
+  cs_args : efl_mono_libs,
+  install : true
+)
+
+executable('efl_reference_net_io_buffered',
+  files(['net_io_buffered.cs']),
+  dependencies : deps,
+  cs_args : efl_mono_libs,
+  install : true
+)
+
+executable('efl_reference_net_session',
+  files(['net_session.cs']),
+  dependencies : deps,
+  cs_args : efl_mono_libs,
+  install : true
+)
diff --git a/reference/csharp/net/src/net_io.cs 
b/reference/csharp/net/src/net_io.cs
new file mode 100644
index 0000000..f797867
--- /dev/null
+++ b/reference/csharp/net/src/net_io.cs
@@ -0,0 +1,269 @@
+/*
+ * Efl.Net input/output examples.
+ *
+ * This example builds on the core_io example by connecting to a remote server
+ * using a dialer and a command queue. The response is printed to stdout.
+ */
+
+using System;
+
+public class ExampleRunner
+{
+    private eina.List<efl.io.Copier> waiting = null;
+    private eina.List<string> commands = null;
+    private eina.Slice delimiter;
+    private efl.net.dialer.Tcp dialer = null;
+    private efl.io.Copier sender = null;
+    private efl.io.Copier receiver = null;
+
+    public void Run()
+    {
+        efl.ui.Config.Run();
+    }
+
+    // call this method to cleanly shut down our example
+    public void Quit()
+    {
+        if (waiting != null)
+        {
+            Console.Error.WriteLine("ERROR: {0} operations were waiting!", 
waiting.Length);
+            waiting.Dispose();
+            waiting = null;
+        }
+
+        if (receiver != null)
+        {
+            receiver.Close();
+            receiver.GetDestination().Dispose();
+            receiver.Dispose();
+            receiver = null;
+        }
+
+        if (sender)
+        {
+            sender.Close();
+            sender.GetSource().Dispose();
+            source.Dispose();
+        }
+
+        if (dialer)
+            dialer.Dispose();
+
+        // efl_exit(retval); // TODO missing
+        efl.ui.Config.Exit();
+    }
+
+    // iterate through the commands to send through the dialler
+    public void CommandNext()
+    {
+        efl.io.Reader send_queue = sender.GetSource();
+        if (commands != null)
+        {
+            send_queue.EosMark();
+            return;
+        }
+
+        string cmd = commands[0];
+        // commands.RemoveAt(0); // TODO missing
+
+        eina.Slice slice;
+        // slice = (Eina_Slice)EINA_SLICE_STR(cmd); // TODO missing
+        send_queue.Write(slice, null);
+        // Console.WriteLine("INFO: sent '{0}'", EINA_SLICE_STR_PRINT(slice)); 
// TODO missing
+
+        // don't use delimiter directly, 'Len' may be changed!
+        slice = delimiter;
+        send_queue.Write(slice, null);
+    }
+
+    void ReceiverData(efl.io.Queue sender, EventArgs e)
+    {
+        eina.Slice slice = sender.GetSlice();
+
+        // Can be caused when we issue efl.io.Queue.Clear()
+        if (slice.Len == 0) return;
+
+        // If the server didn't send us the line terminator and closed the
+        // connection (ie: efl_io_reader_eos_get() == true) or if the buffer
+        // limit was reached then we may have a line without a trailing 
delimiter.
+
+        // if (slice.EndsWith(delimiter)) // TODO missing
+        //    slice.Len -= delimiter.Len;
+
+        // Console.WriteLine("INFO: received '{0}'", 
EINA_SLICE_STR_PRINT(slice)); // TODO missing
+
+        sender.Clear();
+        CommandNext();
+    }
+
+    void DialerConnected(efl.net.dialer.Tcp sender, EventArgs e)
+    {
+        Console.WriteLine("INFO: connected to {0} ({1})", 
sender.GetAddressDial(), sender.GetAddressRemote());
+
+        CommandNext();
+    }
+
+    void CopierDone(efl.io.Copier sender, EventArgs e)
+    {
+        Console.WriteLine("INFO: {0} done", sender.GetName());
+
+        // waiting.Remove(sender); // TODO missing
+        if (waiting.Empty())
+            Quit(EXIT_SUCCESS);
+    }
+
+    void CopierError(efl.io.Copier sender, eina.Error perr)
+    {
+        Console.Error.WriteLine(stderr, "INFO: {0} error: #{1} '{2}'", 
sender.GetName(), perr, perr.Message);
+
+        Quit(EXIT_FAILURE);
+    }
+
+    private static void SetCopierCbs(efl.io.Copier copier)
+    {
+        copier.DONE += CopierDone;
+        copier.ERROR += CopierError;
+    }
+
+
+    public ExampleRunner()
+    {
+        string address = "example.com:80";
+        ulong buffer_limit = 128;
+        efl.io.Queue send_queue, receive_queue;
+
+        commands = new eina.List<string>();
+        commands.Append("HEAD / HTTP/1.1\r\nHost: example.com\r\nConnection: 
close\r\n\r\n");
+        // delimiter = (Eina_Slice)EINA_SLICE_STR("\r\n"); // TODO missing
+
+        // Without a send_queue we'd have to manually implement an
+        // efl.io.Reader object that would provide partial data when
+        // efl.io.Reader.read() is called by efl.io.Copier. This is
+        // cumbersome... we just want to write a full command and have the
+        // queue to handle that for us.
+        //
+        // Our example's usage is to write each command at once followed by
+        // the line delimiter, then wait for a reply from the server, then
+        // write another.
+
+        try
+        {
+            send_queue = new efl.io.QueueConcrete(null, (efl.io.Queue equeue) 
=> {
+                equeue.SetName("send_queue");
+                equeue.SetLimit(buffer_limit);
+            });
+        }
+        catch
+        {
+            Console.Error.WriteLine("ERROR: could not create efl.io.Queue 
(send)");
+            Quit(EXIT_FAILURE);
+            throw;
+        }
+
+        // Without a receive_queue we'd have to manually implement an
+        // efl.io.Writer object that would handle write of partial data
+        // with efl.io.Writer.write() is called by efl.io.Copier.
+        //
+        // For output we could have another solution as well: use null
+        // destination and handle "line" or "data" events manually,
+        // stealing the buffer so it doesn't grow.
+        //
+        // Our example's usage is to peek its data with GetSlice() then
+        // Clear().
+        try
+        {
+            receive_queue = new efl.io.QueueConcrete(null, (efl.io.Queue 
equeue) => {
+                equeue.SetName("receive_queue");
+                equeue.SetLimit(buffer_limit);
+            });
+            receive_queue.SLICE_CHANGED += ReceiverData;
+        }
+        catch
+        {
+            Console.Error.WriteLine("ERROR: could not create efl.io.Queue 
(receive)");
+            Quit(EXIT_FAILURE);
+            throw;
+        }
+
+        // some objects such as the Efl.Io.Copier and Efl.Net.Dialer.Tcp
+        // depend on main loop, thus their parent must be a loop
+        // provider. We use the loop passed to our main method.
+        // efl.Loop loop = ev->object; // TODO missing
+
+        // The TCP client to use to send/receive network data
+        try
+        {
+            dialer = new efl.net.dialer.TcpConcrete(loop, (efl.net.dialer.Tcp 
edialer) => {
+                edialer.SetName("dialer");
+            });
+            dialer.CONNECTED += DialerConnected;
+        }
+        catch
+        {
+            Console.Error.WriteLine("ERROR: could not create 
efl.net.dialer.Tcp");
+            Quit(EXIT_FAILURE);
+            throw;
+        }
+
+        // sender: send_queue->network
+        try
+        {
+            sender = new efl.io.CopierConcrete(loop, (efl.io.Copier esender) 
=> {
+                esender.SetName("sender");
+                esender.SetLineDelimiter(delimiter);
+                esender.SetSource(send_queue);
+                esender.SetDestination(dialer);
+            });
+            SetCopierCbs(sender);
+        }
+        catch
+        {
+            Console.Error.WriteLine("ERROR: could not create efl.io.Copier 
(sender)");
+            Quit(EXIT_FAILURE);
+            throw;
+        }
+
+        // receiver: network->receive_queue
+        try
+        {
+            receiver = new efl.io.CopierConcrete(loop, (efl.io.Copier 
ereceiver) => {
+                ereceiver.SetName("receiver");
+                ereceiver.SetLineDelimiter(delimiter);
+                ereceiver.SetSource(dialer);
+                ereceiver.SetDestination(send_queue);
+            });
+            SetCopierCbs(receiver);
+        }
+        catch
+        {
+            Console.Error.WriteLine("ERROR: could not create Efl_Io_Copier 
(receiver)");
+            Quit(EXIT_FAILURE);
+            throw;
+        }
+
+        eina.Error err = dialer.Dial(address);
+        if (err != eina.Error.NO_ERROR)
+        {
+            var msg = $"ERROR: could not dial {address}: {err.Message}";
+            Console.Error.WriteLine(msg);
+            Quit(EXIT_FAILURE);
+            throw new SEHException(msg);
+        }
+
+        waiting.Append(sender);
+        waiting.Append(receiver);
+    }
+}
+
+public static class Example
+{
+    public static void Main()
+    {
+        efl.All.Init(efl.Components.Basic);
+
+        var exr = new ExampleRunner();
+        exr.Run();
+
+        efl.All.Shutdown();
+    }
+}
diff --git a/reference/csharp/net/src/net_io_buffered.cs 
b/reference/csharp/net/src/net_io_buffered.cs
new file mode 100644
index 0000000..3a159e7
--- /dev/null
+++ b/reference/csharp/net/src/net_io_buffered.cs
@@ -0,0 +1,181 @@
+/*
+ * Efl.Net buffered input/output examples.
+ *
+ * This example builds on the net_io example by using a buffered_stream to
+ * simplify the logic. This helpfully provides the input and output queues
+ * and a copier internally. They can be accessed from the buffered stream
+ * if required but as demonstrated here that is likely not necessary.
+ */
+
+using System;
+
+public class ExampleRunner
+{
+    private eina.List<string> commands = null;
+    private eina.Slice delimiter;
+    private efl.net.dialer.Tcp dialer = null;
+    private efl.io.buffered.Stream stream = null;
+
+    public void Run()
+    {
+        efl.ui.Config.Run();
+    }
+
+    public void Quit(int retval)
+    {
+        if (stream != null)
+        {
+            stream.Close();
+            stream.Dispose();
+            stream = null;
+        }
+
+        if (dialer != null)
+        {
+            dialer.Dispose();
+            dialer = null;
+        }
+
+        // efl_exit(retval); TODO missing
+        efl.ui.Config.Exit();
+    }
+
+    public void CommandNext()
+    {
+        if (commands.Empty())
+        {
+            stream.EosMark();
+            return;
+        }
+
+        string cmd = commands[0];
+        // commands.RemoveAt(0); // TODO missing
+
+        // eina.Slice slice = (Eina_Slice)EINA_SLICE_STR(cmd); // TODO missing
+        stream.Write(slice, null);
+        // Console.Error.WriteLine("INFO: sent '{0}'", 
EINA_SLICE_STR_PRINT(slice)); // TODO missing
+
+        // don't use delimiter directly, 'Len' may be changed!
+        slice = delimiter;
+        stream.Write(slice, null);
+    }
+
+    void StreamLine(efl.io.buffered.Stream sender, EventArgs e)
+    {
+        eina.Slice slice = sender.GetSlice();
+
+        // Can be caused when we issue efl.io.buffered.Stream.Clear()
+        if (slice.Len == 0) return;
+
+        // If the server didn't send us the line terminator and closed the
+        // connection (ie: efl_io_reader_eos_get() == true) or if the buffer
+        // limit was reached then we may have a line without a trailing 
delimiter.
+        // if (slice.EndsWith(delimiter)) // TODO missing
+        //     slice.Len -= delimiter.Len;
+
+        // Console.WriteLine("INFO: received '{0}'", 
EINA_SLICE_STR_PRINT(slice)); // TODO missing
+
+        sender.Clear();
+        CommandNext();
+    }
+
+    void DialerConnected(efl.net.dialer.Tcp sender, EventArgs e)
+    {
+        Console.WriteLine("INFO: connected to {0} ({1})", 
sender.GetAddressDial(), sender.GetAddressRemote());
+
+        CommandNext();
+    }
+
+    void StreamDone(efl.io.buffered.Stream sender, EventArgs e)
+    {
+        Console.WriteLine("INFO: {0} done", sender.GetName());
+
+        Quit(EXIT_SUCCESS);
+    }
+
+    void StreamError(efl.io.buffered.Stream sender, eina.Error err)
+    {
+        Console.Error.WriteLine("INFO: {0} error: #{1} '{2}'", 
sender;GetName(), err, err.Message);
+
+        Quit(EXIT_FAILURE);
+    }
+
+    private static void SetStreamCbs(efl.io.buffered.Stream s)
+    {
+        s.LINE += StreamLine;
+        s.EOS += StreamDone;
+        s.ERROR += StreamError;
+    }
+
+    public ExampleRunner()
+    {
+        string address = "example.com:80";
+        ulong bufferLimit = 128;
+
+        commands = new eina.List<string>();
+        commands.Append("HEAD / HTTP/1.1\r\nHost: example.com\r\nConnection: 
close\r\n\r\n");
+        // delimiter = (Eina_Slice)EINA_SLICE_STR("\r\n"); // TODO missing
+
+        // some objects such as the Efl.Io.Copier and Efl.Net.Dialer.Tcp
+        // depend on main loop, thus their parent must be a loop
+        // provider. We use the loop passed to our main method.
+        // efl.Loop loop = ev->object; // TODO missing
+
+        // The TCP client to use to send/receive network data
+        try
+        {
+            dialer = new efl.net.dialer.TcpConcrete(loop, (efl.net.dialer.Tcp 
edialer) => {
+                edialer.SetName("dialer");
+            });
+            dialer.CONNECTED += DialerConnected;
+        }
+        catch
+        {
+            Console.Error.WriteLine("ERROR: could not create 
efl.net.dialer.Tcp");
+            Quit(EXIT_FAILURE);
+            throw;
+        }
+
+
+        // Without the buffered stream we'd have to create two Efl.Io.Queue
+        // ourselves, as well as two Efl.Io.Copier to link them with the
+        // dialer.
+        //
+        // Our example's usage is to write each command at once followed by
+        // the line delimiter, then wait for a reply from the server, then
+        // write another.
+        //
+        // On incoming data we peek at it with GetSlice() and then Clear().
+
+        stream = new efl.io.buffered.StreamConcrete(loop, 
(efl.io.buffered.Stream estream) => {
+            estream.SetName("stream");
+            estream.SetInnerIo(dialer);
+            estream.SetDelimiter(delimiter);
+            estream.SetMaxQueueSizeInput(bufferLimit);
+            estream.SetMaxQueueSizeOutput(bufferLimit);
+        });
+        SetStreamCbs(stream);
+
+        eina.Error err = dialer.Dial(address);
+        if (err != eina.Error.NO_ERROR)
+        {
+            var msg = $"ERROR: could not dial {address}: {err.Message}";
+            Console.Error.WriteLine(msg);
+            Quit(EXIT_FAILURE);
+            throw new SEHException(msg);
+        }
+    }
+}
+
+public class Example
+{
+    public static void Main()
+    {
+        efl.All.Init(efl.Components.Basic);
+
+        var exr = new ExampleRunner();
+        exr.Run();
+
+        efl.All.Shutdown();
+    }
+}
diff --git a/reference/csharp/net/src/net_session.cs 
b/reference/csharp/net/src/net_session.cs
new file mode 100644
index 0000000..2c70397
--- /dev/null
+++ b/reference/csharp/net/src/net_session.cs
@@ -0,0 +1,135 @@
+/*
+ * Efl.Net session/connectivity examples.
+ *
+ * NOTE: This example currently requires the Connman backend to be running.
+ *
+ * This example uses the Efl.Net.Session APIs to get connectivity information
+ * about the current networking setup. It then sets up a callback for network
+ * changes and will print the details on any change.
+ */
+
+using System;
+
+public class Example
+{
+    // Convert a session state to a string for printing.
+    public static string StateName(efl.net.session.State state)
+    {
+        switch (state)
+        {
+        case efl.net.session.State.Offline:
+            return "offline";
+        case efl.net.session.State.Local:
+            return "local";
+        case efl.net.session.State.Online:
+            return "online";
+        default:
+            return "???";
+        }
+    }
+
+    private static readonly Dictionary<efl.net.session.Technology, string> 
names =
+        new Dictionary<efl.net.session.Technology, string> {
+            { efl.net.session.Technology.Unknown, "unknown" },
+            { efl.net.session.Technology.Ethernet, "ethernet" },
+            { efl.net.session.Technology.Wifi, "wifi" },
+            { efl.net.session.Technology.Bluetooth, "bluetooth" },
+            { efl.net.session.Technology.Cellular, "cellular" },
+            { efl.net.session.Technology.Vpn, "vpn" },
+            { efl.net.session.Technology.Gadget, "gadget" }
+        };
+
+    // Convert a session technology to a string for printing.
+    public static string TechnologyName(efl.net.session.Technology tech)
+    {
+        string name;
+        if (!names.TryGetValue(tech, out name))
+            return "???";
+        return name;
+    }
+
+    // Tthe callback that indicates some connectivity changed within the 
session.
+    // Print information about the session to the console.
+    static void SessionChanged(efl.net.Session session, EventArgs e)
+    {
+        Console.WriteLine("Session changed:");
+        Console.WriteLine("  name: '{0}'", session.GetName());
+        Console.WriteLine("  state: {0}", StateName(session.GetState()));
+        Console.WriteLine("  technology: {0}", 
TechnologyName(session.GetTechnology()));
+        Console.WriteLine("  interface: '{0}'", session.GetInterface());
+
+        // print out additional information if we have an IPv4 session
+        string ip, netmask, gateway;
+        session.GetIpv4(out ip, out netmask, out gateway);
+        if (ip != null)
+        {
+            Console.WriteLine($"  IPv4: {ip}, gateway={gateway}, 
netmask={netmask}");
+        }
+
+        // print out additional information if we have an IPv6 session
+        byte prefix;
+        session.GetIpv6(out ip, out prefix, out netmask, out gateway);
+        if (ip != null)
+        {
+            Console.WriteLine($"  IPv6: {ip}/{prefix}, gateway={gateway}, 
netmask={netmask}");
+        }
+    }
+
+    // Quit the app after a timer tick.
+    static void QuitCb(object sender, EventArgs e)
+    {
+        // efl_exit(0); // TODO missing
+        efl.ui.Config.Exit();
+    }
+
+    public static void Main()
+    {
+        bool doConnect = true;
+        bool requireOnline = false;
+
+        efl.All.Init(efl.Components.Basic);
+
+        // efl.Loop loop = ev->object; // TODO missing
+
+        // create a session that watches specifically for ethernet, wifi and 
bluetooth
+        int technologies = efl.net.session.Technology.Ethernet |
+            efl.net.session.Technology.Wifi | 
efl.net.session.Technology.Bluetooth;
+
+        try
+        {
+            efl.net.Session session = new efl.net.SessionConcrete(loop, 
(efl.net.Session esession) => {
+                esession.SetName("Example Session");
+                // register the change callback for network state
+                esession.CHANGED += SessionChanged;
+            });
+        }
+        catch
+        {
+            eina.Log.Error("Could not create Efl.Net.Session object.\n");
+            // efl_exit(EXIT_FAILURE); // TODO missing
+            efl.ui.Config.Exit();
+            throw;
+        }
+
+        if (doConnect)
+        {
+            Console.WriteLine("Requesting a {0} connection.", requireOnline ? 
"online" : "local");
+            session.Connect(requireOnline, technologies);
+        }
+
+        Console.WriteLine("The session will remain active while this 
application runs.");
+        Console.WriteLine("Use ^C (Control + C) to close it");
+
+        // Wait for 10 seconds before exiting this example
+        new efl.loop.TimerConcrete(loop, (efl.loop.Timer etimer) => {
+                etimer.SetInterval(10.0);
+                etimer.TICK += QuitCb;
+        });
+
+        // start the main loop
+        efl.ui.Config.Run();
+
+        efl.All.Shutdown();
+    }
+}
+

-- 


Reply via email to