File: gio.cpp

package info (click to toggle)
cppgir 2.0%2Bgit20250629.2a7d9ce-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,220 kB
  • sloc: cpp: 16,451; ansic: 355; python: 86; makefile: 13; sh: 9
file content (98 lines) | stat: -rw-r--r-- 2,558 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#define GI_INLINE 1
#include <gio/gio.hpp>

#include <iostream>

namespace GLib = gi::repository::GLib;
namespace Gio = gi::repository::Gio;

const std::string localhost("127.0.0.1");
static GLib::MainLoop loop;

// many calls here support GError
// so typically will throw here instead
// (unless GError output is explicitly requested in call signature)

// NOTE abundancy of gi::expect not generally needed;
// only needed when using --dl and --expected

static bool
receive(Gio::Socket s, GLib::IOCondition /*cond*/)
{
  guint8 buffer[1024] = {
      0,
  };
  Gio::SocketAddress a;
  int count = gi::expect(s.receive_from(&a, buffer, sizeof(buffer)));
  if (count > 0) {
    // let's see where it came from
    std::string origin("someone");
    auto ia = gi::object_cast<Gio::InetSocketAddress>(a);
    if (ia) {
      origin = gi::expect(gi::expect(ia.get_address()).to_string());
      origin += ":";
      origin += std::to_string(gi::expect(ia.get_port()));
    }
    std::cout << origin << " said " << (char *)buffer << std::endl;
    // quit when idle
    GLib::idle_add([]() {
      loop.quit();
      return GLib::SOURCE_REMOVE_;
    });
  }
  return true;
}

Gio::Socket
open(bool listen)
{
  auto socket = gi::expect(Gio::Socket::new_(Gio::SocketFamily::IPV4_,
      Gio::SocketType::DATAGRAM_, Gio::SocketProtocol::DEFAULT_));

  auto address =
      gi::expect(Gio::InetSocketAddress::new_from_string(localhost, 0));
  socket.bind(address, false);
  socket.set_blocking(false);

  if (listen) {
    // runtime introspection has a hard time here,
    // but with a bit of extra information, we can keep going
#if defined(GI_CALL_ARGS) && CALL_ARGS <= 1
    // so we should have this signature for a function with 1 non-required
    GLib::Source source =
        gi::expect(socket.create_source({.condition = GLib::IOCondition::IN_}));
#else
    GLib::Source source =
        gi::expect(socket.create_source(GLib::IOCondition::IN_, nullptr));
#endif
    source.set_callback<Gio::SocketSourceFunc>(receive);
    source.attach();
  }

  return socket;
}

static void
die(const std::string &why)
{
  std::cerr << why << std::endl;
  exit(2);
}

int
main(int argc, char **argv)
{
  if (argc < 2)
    die("missing argument");

  std::string msg = argv[1];
  std::cout << "will send message " << msg << std::endl;

  auto recv = open(true);
  auto local = gi::expect(recv.get_local_address());
  auto send = open(false);
  send.send_to(local, (guint8 *)msg.data(), msg.size(), nullptr);

  loop = gi::expect(GLib::MainLoop::new_());
  loop.run();
}