PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/gio/gsocketinputstream.c

https://gitlab.com/ImageMagick/glib
C | 225 lines | 166 code | 36 blank | 23 comment | 3 complexity | ac71d39b6a0bf44ac7a2c3fba6ca9fbe MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. /* GIO - GLib Input, Output and Streaming Library
  2. *
  3. * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
  4. * © 2009 codethink
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General
  17. * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. *
  19. * Authors: Christian Kellner <gicmo@gnome.org>
  20. * Samuel Cormier-Iijima <sciyoshi@gmail.com>
  21. * Ryan Lortie <desrt@desrt.ca>
  22. */
  23. #include "config.h"
  24. #include "gsocketinputstream.h"
  25. #include "glibintl.h"
  26. #include "gcancellable.h"
  27. #include "gpollableinputstream.h"
  28. #include "gioerror.h"
  29. #include "gfiledescriptorbased.h"
  30. struct _GSocketInputStreamPrivate
  31. {
  32. GSocket *socket;
  33. /* pending operation metadata */
  34. gpointer buffer;
  35. gsize count;
  36. };
  37. static void g_socket_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface);
  38. #ifdef G_OS_UNIX
  39. static void g_socket_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface);
  40. #endif
  41. #define g_socket_input_stream_get_type _g_socket_input_stream_get_type
  42. #ifdef G_OS_UNIX
  43. G_DEFINE_TYPE_WITH_CODE (GSocketInputStream, g_socket_input_stream, G_TYPE_INPUT_STREAM,
  44. G_ADD_PRIVATE (GSocketInputStream)
  45. G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, g_socket_input_stream_pollable_iface_init)
  46. G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, g_socket_input_stream_file_descriptor_based_iface_init)
  47. )
  48. #else
  49. G_DEFINE_TYPE_WITH_CODE (GSocketInputStream, g_socket_input_stream, G_TYPE_INPUT_STREAM,
  50. G_ADD_PRIVATE (GSocketInputStream)
  51. G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM, g_socket_input_stream_pollable_iface_init)
  52. )
  53. #endif
  54. enum
  55. {
  56. PROP_0,
  57. PROP_SOCKET
  58. };
  59. static void
  60. g_socket_input_stream_get_property (GObject *object,
  61. guint prop_id,
  62. GValue *value,
  63. GParamSpec *pspec)
  64. {
  65. GSocketInputStream *stream = G_SOCKET_INPUT_STREAM (object);
  66. switch (prop_id)
  67. {
  68. case PROP_SOCKET:
  69. g_value_set_object (value, stream->priv->socket);
  70. break;
  71. default:
  72. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  73. }
  74. }
  75. static void
  76. g_socket_input_stream_set_property (GObject *object,
  77. guint prop_id,
  78. const GValue *value,
  79. GParamSpec *pspec)
  80. {
  81. GSocketInputStream *stream = G_SOCKET_INPUT_STREAM (object);
  82. switch (prop_id)
  83. {
  84. case PROP_SOCKET:
  85. stream->priv->socket = g_value_dup_object (value);
  86. break;
  87. default:
  88. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  89. }
  90. }
  91. static void
  92. g_socket_input_stream_finalize (GObject *object)
  93. {
  94. GSocketInputStream *stream = G_SOCKET_INPUT_STREAM (object);
  95. if (stream->priv->socket)
  96. g_object_unref (stream->priv->socket);
  97. G_OBJECT_CLASS (g_socket_input_stream_parent_class)->finalize (object);
  98. }
  99. static gssize
  100. g_socket_input_stream_read (GInputStream *stream,
  101. void *buffer,
  102. gsize count,
  103. GCancellable *cancellable,
  104. GError **error)
  105. {
  106. GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (stream);
  107. return g_socket_receive_with_blocking (input_stream->priv->socket,
  108. buffer, count, TRUE,
  109. cancellable, error);
  110. }
  111. static gboolean
  112. g_socket_input_stream_pollable_is_readable (GPollableInputStream *pollable)
  113. {
  114. GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (pollable);
  115. return g_socket_condition_check (input_stream->priv->socket, G_IO_IN);
  116. }
  117. static GSource *
  118. g_socket_input_stream_pollable_create_source (GPollableInputStream *pollable,
  119. GCancellable *cancellable)
  120. {
  121. GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (pollable);
  122. GSource *socket_source, *pollable_source;
  123. pollable_source = g_pollable_source_new (G_OBJECT (input_stream));
  124. socket_source = g_socket_create_source (input_stream->priv->socket,
  125. G_IO_IN, cancellable);
  126. g_source_set_dummy_callback (socket_source);
  127. g_source_add_child_source (pollable_source, socket_source);
  128. g_source_unref (socket_source);
  129. return pollable_source;
  130. }
  131. static gssize
  132. g_socket_input_stream_pollable_read_nonblocking (GPollableInputStream *pollable,
  133. void *buffer,
  134. gsize size,
  135. GError **error)
  136. {
  137. GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (pollable);
  138. return g_socket_receive_with_blocking (input_stream->priv->socket,
  139. buffer, size, FALSE,
  140. NULL, error);
  141. }
  142. #ifdef G_OS_UNIX
  143. static int
  144. g_socket_input_stream_get_fd (GFileDescriptorBased *fd_based)
  145. {
  146. GSocketInputStream *input_stream = G_SOCKET_INPUT_STREAM (fd_based);
  147. return g_socket_get_fd (input_stream->priv->socket);
  148. }
  149. #endif
  150. static void
  151. g_socket_input_stream_class_init (GSocketInputStreamClass *klass)
  152. {
  153. GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  154. GInputStreamClass *ginputstream_class = G_INPUT_STREAM_CLASS (klass);
  155. gobject_class->finalize = g_socket_input_stream_finalize;
  156. gobject_class->get_property = g_socket_input_stream_get_property;
  157. gobject_class->set_property = g_socket_input_stream_set_property;
  158. ginputstream_class->read_fn = g_socket_input_stream_read;
  159. g_object_class_install_property (gobject_class, PROP_SOCKET,
  160. g_param_spec_object ("socket",
  161. P_("socket"),
  162. P_("The socket that this stream wraps"),
  163. G_TYPE_SOCKET, G_PARAM_CONSTRUCT_ONLY |
  164. G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  165. }
  166. #ifdef G_OS_UNIX
  167. static void
  168. g_socket_input_stream_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface)
  169. {
  170. iface->get_fd = g_socket_input_stream_get_fd;
  171. }
  172. #endif
  173. static void
  174. g_socket_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface)
  175. {
  176. iface->is_readable = g_socket_input_stream_pollable_is_readable;
  177. iface->create_source = g_socket_input_stream_pollable_create_source;
  178. iface->read_nonblocking = g_socket_input_stream_pollable_read_nonblocking;
  179. }
  180. static void
  181. g_socket_input_stream_init (GSocketInputStream *stream)
  182. {
  183. stream->priv = g_socket_input_stream_get_instance_private (stream);
  184. }
  185. GSocketInputStream *
  186. _g_socket_input_stream_new (GSocket *socket)
  187. {
  188. return g_object_new (G_TYPE_SOCKET_INPUT_STREAM, "socket", socket, NULL);
  189. }