fc03627db8d52fd012a0a7d11fcbcdc238cd1041
[cascardo/gnio.git] / gnio / gtcpclient.c
1 /* GNIO - GLib Network Layer of GIO
2  *
3  * Copyright (C) 2008 Christian Kellner, Samuel Cormier-Iijima
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Christian Kellner <gicmo@gnome.org>
21  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
22  */
23
24 #include <config.h>
25 #include <glib.h>
26 #include <gio/gio.h>
27
28 #include <string.h>
29 #include <errno.h>
30
31 #include "gtcpclient.h"
32 #include "gasynchelper.h"
33
34 G_DEFINE_TYPE (GTcpClient, g_tcp_client, G_TYPE_OBJECT);
35
36 enum
37 {
38   PROP_0,
39   PROP_ADDRESS,
40   PROP_HOSTNAME,
41   PROP_PORT
42 };
43
44 struct _GTcpClientPrivate
45 {
46   GInetSocketAddress *address;
47   gchar              *hostname;
48   gushort             port;
49 };
50
51 static void
52 g_tcp_client_constructed (GObject *object)
53 {
54   GTcpClient *client = G_TCP_CLIENT (object);
55
56   if (client->priv->address)
57     {
58       // we've been constructed with an address, extract hostname+port
59       client->priv->hostname = g_inet_address_to_string (g_inet_socket_address_get_address (client->priv->address));
60       client->priv->port = g_inet_socket_address_get_port (client->priv->address);
61       return;
62     }
63 }
64
65 static void
66 g_tcp_client_get_property (GObject    *object,
67                            guint       prop_id,
68                            GValue     *value,
69                            GParamSpec *pspec)
70 {
71   GTcpClient *client = G_TCP_CLIENT (object);
72
73   switch (prop_id)
74     {
75       case PROP_ADDRESS:
76         g_value_set_object (value, client->priv->address);
77         break;
78
79       case PROP_HOSTNAME:
80         g_value_set_string (value, client->priv->hostname);
81         break;
82
83       case PROP_PORT:
84         g_value_set_uint (value, client->priv->port);
85         break;
86
87       default:
88         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
89     }
90 }
91
92 static void
93 g_tcp_client_set_property (GObject      *object,
94                            guint         prop_id,
95                            const GValue *value,
96                            GParamSpec   *pspec)
97 {
98   GTcpClient *client = G_TCP_CLIENT (object);
99
100   switch (prop_id)
101     {
102       case PROP_ADDRESS:
103         // sink the address' floating reference
104         client->priv->address = G_INET_SOCKET_ADDRESS (g_object_ref_sink (g_value_get_object (value)));
105         break;
106
107       case PROP_HOSTNAME:
108         client->priv->hostname = g_value_dup_string (value);
109         break;
110
111       case PROP_PORT:
112         client->priv->port = g_value_get_uint (value);
113         break;
114
115       default:
116         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
117     }
118 }
119
120 static void
121 g_tcp_client_finalize (GObject *object)
122 {
123   GTcpClient *client = G_TCP_CLIENT (object);
124
125   g_object_unref (client->priv->address);
126
127   if (G_OBJECT_CLASS (g_tcp_client_parent_class)->finalize)
128     (*G_OBJECT_CLASS (g_tcp_client_parent_class)->finalize) (object);
129 }
130
131 static void
132 g_tcp_client_dispose (GObject *object)
133 {
134   GTcpClient *client = G_TCP_CLIENT (object);
135
136   g_free (client->priv->hostname);
137
138   if (G_OBJECT_CLASS (g_tcp_client_parent_class)->dispose)
139     (*G_OBJECT_CLASS (g_tcp_client_parent_class)->dispose) (object);
140 }
141
142 static void
143 g_tcp_client_class_init (GTcpClientClass *klass)
144 {
145   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
146
147   g_type_class_add_private (klass, sizeof (GTcpClientPrivate));
148
149   gobject_class->finalize = g_tcp_client_finalize;
150   gobject_class->dispose = g_tcp_client_dispose;
151   gobject_class->constructed = g_tcp_client_constructed;
152   gobject_class->set_property = g_tcp_client_set_property;
153   gobject_class->get_property = g_tcp_client_get_property;
154
155   g_object_class_install_property (gobject_class, PROP_ADDRESS,
156                                    g_param_spec_object ("address",
157                                                         "address",
158                                                         "the remote address the socket will connect to",
159                                                         G_TYPE_INET_SOCKET_ADDRESS,
160                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
161
162   g_object_class_install_property (gobject_class, PROP_HOSTNAME,
163                                    g_param_spec_string ("hostname",
164                                                         "hostname",
165                                                         "the hostname of the remote address the socket will connect to",
166                                                         NULL,
167                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
168
169   g_object_class_install_property (gobject_class, PROP_PORT,
170                                    g_param_spec_uint ("port",
171                                                       "port",
172                                                       "the remote port the socket will connect to",
173                                                       0,
174                                                       G_MAXUSHORT,
175                                                       0,
176                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
177 }
178
179 static void
180 g_tcp_client_init (GTcpClient *client)
181 {
182   client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, G_TYPE_TCP_CLIENT, GTcpClientPrivate);
183
184   client->priv->address = NULL;
185   client->priv->hostname = NULL;
186   client->priv->port = 0;
187 }
188
189 GTcpClient *
190 g_tcp_client_new (const gchar *hostname,
191                   gushort      port)
192 {
193   return G_TCP_CLIENT (g_object_new (G_TYPE_TCP_CLIENT, "hostname", hostname, "port", port, NULL));
194 }
195
196 GTcpClient *
197 g_tcp_client_new_from_address (GInetSocketAddress *address)
198 {
199   return G_TCP_CLIENT (g_object_new (G_TYPE_TCP_CLIENT, "address", address, NULL));
200 }
201
202 gboolean
203 g_tcp_client_connect (GTcpClient    *client,
204                       GCancellable  *cancellable,
205                       GError       **error)
206 {
207   return FALSE;
208 }
209
210 typedef struct {
211   GAsyncReadyCallback  callback;
212   GCancellable        *cancellable;
213   gpointer             user_data;
214   GTcpClient          *client;
215   gchar                address_buffer[256];
216   gsize                address_length;
217 } ConnectData;
218
219 static gboolean
220 connect_callback (ConnectData *data,
221                   GIOCondition condition,
222                   gint fd)
223 {
224   return FALSE;
225 }
226
227 void
228 g_tcp_client_connect_async (GTcpClient          *client,
229                             GCancellable        *cancellable,
230                             GAsyncReadyCallback  callback,
231                             gpointer             user_data)
232 {
233
234 }
235
236 gboolean
237 g_tcp_client_connect_finish (GTcpClient    *client,
238                              GAsyncResult  *result,
239                              GError       **error)
240 {
241   GSimpleAsyncResult *simple;
242
243   g_return_val_if_fail (G_IS_TCP_CLIENT (client), FALSE);
244
245   simple = G_SIMPLE_ASYNC_RESULT (result);
246
247   if (g_simple_async_result_propagate_error (simple, error))
248     return FALSE;
249
250   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_tcp_client_connect_async);
251
252   return TRUE;
253 }
254
255 void
256 g_tcp_client_close (GTcpClient *tcp_client)
257 {
258   g_return_if_fail (G_IS_TCP_CLIENT (tcp_client));
259 }