with the sync API calls.
#include <glib.h>
#include <gio/gio.h>
+#include "gsocket.h"
#include "gnetworkinputstream.h"
G_DEFINE_TYPE (GNetworkInputStream, g_network_input_stream, G_TYPE_INPUT_STREAM);
+enum
+{
+ PROP_0,
+ PROP_SOCKET
+};
+
+struct _GNetworkInputStreamPrivate
+{
+ GSocket *socket;
+};
+
+static void
+g_network_input_stream_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GNetworkInputStream *stream = G_NETWORK_INPUT_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOCKET:
+ g_value_set_object (value, stream->priv->socket);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_network_input_stream_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GNetworkInputStream *stream = G_NETWORK_INPUT_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOCKET:
+ stream->priv->socket = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_network_input_stream_finalize (GObject *object)
+{
+ if (G_OBJECT_CLASS (g_network_input_stream_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_network_input_stream_parent_class)->finalize) (object);
+}
+
+static void
+g_network_input_stream_dispose (GObject *object)
+{
+ if (G_OBJECT_CLASS (g_network_input_stream_parent_class)->dispose)
+ (*G_OBJECT_CLASS (g_network_input_stream_parent_class)->dispose) (object);
+}
+
+static gssize
+g_network_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GNetworkInputStream *input_stream = G_NETWORK_INPUT_STREAM (stream);
+
+ return g_socket_receive (input_stream->priv->socket, (gchar *) buffer, count, error);
+}
+
static void
g_network_input_stream_class_init (GNetworkInputStreamClass *klass)
{
- GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GInputStreamClass *ginputstream_class = G_INPUT_STREAM_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GNetworkInputStreamPrivate));
+
+ gobject_class->finalize = g_network_input_stream_finalize;
+ gobject_class->dispose = g_network_input_stream_dispose;
+ gobject_class->get_property = g_network_input_stream_get_property;
+ gobject_class->set_property = g_network_input_stream_set_property;
+
+ ginputstream_class->read_fn = g_network_input_stream_read;
+
+ g_object_class_install_property (gobject_class, PROP_SOCKET,
+ g_param_spec_object ("socket",
+ "socket",
+ "the socket that this stream wraps",
+ G_TYPE_SOCKET,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
}
static void
-g_network_input_stream_init (GNetworkInputStream *address)
+g_network_input_stream_init (GNetworkInputStream *stream)
{
+ stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, G_TYPE_NETWORK_INPUT_STREAM, GNetworkInputStreamPrivate);
+
+ stream->priv->socket = NULL;
+}
+GNetworkInputStream *
+_g_network_input_stream_new (GSocket *socket)
+{
+ return G_NETWORK_INPUT_STREAM (g_object_new (G_TYPE_NETWORK_INPUT_STREAM, "socket", socket, NULL));
}
#include <glib-object.h>
#include <gio/gio.h>
+#include <gnio/gsocket.h>
+
G_BEGIN_DECLS
-#define G_TYPE_NETWORK_INPUT_STREAM (g_socket_get_type ())
+#define G_TYPE_NETWORK_INPUT_STREAM (g_network_input_stream_get_type ())
#define G_NETWORK_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_INPUT_STREAM, GNetworkInputStream))
#define G_NETWORK_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_INPUT_STREAM, GNetworkInputStreamClass))
#define G_IS_NETWORK_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_INPUT_STREAM))
typedef struct _GNetworkInputStream GNetworkInputStream;
typedef struct _GNetworkInputStreamClass GNetworkInputStreamClass;
+typedef struct _GNetworkInputStreamPrivate GNetworkInputStreamPrivate;
struct _GNetworkInputStream
{
GInputStream parent;
+
+ GNetworkInputStreamPrivate *priv;
};
struct _GNetworkInputStreamClass
GType g_network_input_stream_get_type (void) G_GNUC_CONST;
-GNetworkInputStream * g_network_input_stream_new (void);
+GNetworkInputStream * _g_network_input_stream_new (GSocket *socket);
G_END_DECLS
#include <glib.h>
#include <gio/gio.h>
+#include "gsocket.h"
#include "gnetworkoutputstream.h"
G_DEFINE_TYPE (GNetworkOutputStream, g_network_output_stream, G_TYPE_OUTPUT_STREAM);
+enum
+{
+ PROP_0,
+ PROP_SOCKET
+};
+
+struct _GNetworkOutputStreamPrivate
+{
+ GSocket *socket;
+};
+
+static void
+g_network_output_stream_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GNetworkOutputStream *stream = G_NETWORK_OUTPUT_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOCKET:
+ g_value_set_object (value, stream->priv->socket);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_network_output_stream_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GNetworkOutputStream *stream = G_NETWORK_OUTPUT_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOCKET:
+ stream->priv->socket = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_network_output_stream_finalize (GObject *object)
+{
+ if (G_OBJECT_CLASS (g_network_output_stream_parent_class)->finalize)
+ (*G_OBJECT_CLASS (g_network_output_stream_parent_class)->finalize) (object);
+}
+
+static void
+g_network_output_stream_dispose (GObject *object)
+{
+ if (G_OBJECT_CLASS (g_network_output_stream_parent_class)->dispose)
+ (*G_OBJECT_CLASS (g_network_output_stream_parent_class)->dispose) (object);
+}
+
+static gssize
+g_network_output_stream_write (GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GNetworkOutputStream *output_stream = G_NETWORK_OUTPUT_STREAM (stream);
+
+ return g_socket_send (output_stream->priv->socket, (const gchar *) buffer, count, error);
+}
+
static void
g_network_output_stream_class_init (GNetworkOutputStreamClass *klass)
{
- GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GOutputStreamClass *goutputstream_class = G_OUTPUT_STREAM_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GNetworkOutputStreamPrivate));
+
+ gobject_class->finalize = g_network_output_stream_finalize;
+ gobject_class->dispose = g_network_output_stream_dispose;
+ gobject_class->get_property = g_network_output_stream_get_property;
+ gobject_class->set_property = g_network_output_stream_set_property;
+
+ goutputstream_class->write_fn = g_network_output_stream_write;
+
+ g_object_class_install_property (gobject_class, PROP_SOCKET,
+ g_param_spec_object ("socket",
+ "socket",
+ "the socket that this stream wraps",
+ G_TYPE_SOCKET,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
}
static void
-g_network_output_stream_init (GNetworkOutputStream *address)
+g_network_output_stream_init (GNetworkOutputStream *stream)
{
+ stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, G_TYPE_NETWORK_OUTPUT_STREAM, GNetworkOutputStreamPrivate);
+
+ stream->priv->socket = NULL;
+}
+GNetworkOutputStream *
+_g_network_output_stream_new (GSocket *socket)
+{
+ return G_NETWORK_OUTPUT_STREAM (g_object_new (G_TYPE_NETWORK_OUTPUT_STREAM, "socket", socket, NULL));
}
G_BEGIN_DECLS
-#define G_TYPE_NETWORK_OUTPUT_STREAM (g_socket_get_type ())
+#define G_TYPE_NETWORK_OUTPUT_STREAM (g_network_output_stream_get_type ())
#define G_NETWORK_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_NETWORK_OUTPUT_STREAM, GNetworkOutputStream))
#define G_NETWORK_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_NETWORK_OUTPUT_STREAM, GNetworkOutputStreamClass))
#define G_IS_NETWORK_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NETWORK_OUTPUT_STREAM))
typedef struct _GNetworkOutputStream GNetworkOutputStream;
typedef struct _GNetworkOutputStreamClass GNetworkOutputStreamClass;
+typedef struct _GNetworkOutputStreamPrivate GNetworkOutputStreamPrivate;
struct _GNetworkOutputStream
{
GOutputStream parent;
+
+ GNetworkOutputStreamPrivate *priv;
};
struct _GNetworkOutputStreamClass
GType g_network_output_stream_get_type (void) G_GNUC_CONST;
-GNetworkOutputStream * g_network_output_stream_new (void);
+GNetworkOutputStream * _g_network_output_stream_new (GSocket *socket);
G_END_DECLS
g_warning ("Error setting socket status flags: %s", g_strerror (errno));
socket->priv->blocking = blocking;
+
+ g_object_notify (G_OBJECT (socket), "blocking");
}
gboolean
g_warning ("error setting reuse address: %s", g_strerror (errno));
socket->priv->reuse_address = reuse;
+
+ g_object_notify (G_OBJECT (socket), "reuse-address");
}
gboolean
gssize
g_socket_send (GSocket *socket,
- gchar *buffer,
+ const gchar *buffer,
gsize size,
GError **error)
{
GError **error);
gssize g_socket_send (GSocket *socket,
- gchar *buffer,
+ const gchar *buffer,
gsize size,
GError **error);
return G_TCP_CLIENT (g_object_new (G_TYPE_TCP_CLIENT, "address", address, NULL));
}
+GNetworkInputStream *
+g_tcp_client_get_input_stream (GTcpClient *client)
+{
+ if (!client->priv->socket)
+ return NULL;
+
+ return _g_network_input_stream_new (client->priv->socket);
+}
+
+GNetworkOutputStream *
+g_tcp_client_get_output_stream (GTcpClient *client)
+{
+ if (!client->priv->socket)
+ return NULL;
+
+ return _g_network_output_stream_new (client->priv->socket);
+}
+
gboolean
g_tcp_client_connect (GTcpClient *client,
GCancellable *cancellable,
gsize address_length;
} ConnectData;
+/*
static gboolean
connect_callback (ConnectData *data,
GIOCondition condition,
{
return FALSE;
}
+*/
void
g_tcp_client_connect_async (GTcpClient *client,
GMainLoop *loop;
-void print_address (GInetAddress *address, gpointer data);
+static void print_address (GInetAddress *address, gpointer data);
-void
+static void
print_address (GInetAddress *address, gpointer data)
{
gchar *string = g_inet_address_to_string (G_INET_ADDRESS (address));
g_free (string);
}
-void
+static void
resolve_callback (GObject *source, GAsyncResult *result, gpointer data)
{
GError *error = NULL;
int main (int argc, char *argv[])
{
GTcpClient *client;
+ GInputStream *input;
+ GOutputStream *output;
GError *error = NULL;
+ gchar buffer[512] = {0};
+ gssize count;
g_thread_init (NULL);
loop = g_main_loop_new (NULL, FALSE);
- client = g_tcp_client_new ("localhost", 90);
+ client = g_tcp_client_new ("www.google.com", 80);
g_print ("connecting to www.google.com:80\n");
g_print ("connected!\n");
+ output = G_OUTPUT_STREAM (g_tcp_client_get_output_stream (client));
+
+ input = G_INPUT_STREAM (g_tcp_client_get_input_stream (client));
+
+ g_print ("writing...\n");
+
+ if ((count = g_output_stream_write (output, "GET / HTTP/1.0\r\n\r\n", 19, NULL, &error)) < 0) {
+ g_warning (error->message);
+ return 1;
+ }
+
+ g_print ("wrote %d bytes\n", count);
+
+ if ((count = g_input_stream_read (input, buffer, 512, NULL, &error)) < 0) {
+ g_warning (error->message);
+ return 1;
+ }
+
+ g_print ("read %d bytes: %s\n", count, buffer);
+
g_object_unref (G_OBJECT (client));
// g_main_loop_run (loop);