Improve the g_file_make_symbolic_link docs
[platform/upstream/glib.git] / gio / gwin32outputstream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2006-2010 Red Hat, Inc.
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  * Author: Alexander Larsson <alexl@redhat.com>
21  * Author: Tor Lillqvist <tml@iki.fi>
22  */
23
24 #include "config.h"
25
26 #include <windows.h>
27
28 #include <io.h>
29
30 #include <glib.h>
31 #include <glib/gstdio.h>
32 #include "gioerror.h"
33 #include "gwin32outputstream.h"
34 #include "gcancellable.h"
35 #include "gsimpleasyncresult.h"
36 #include "gasynchelper.h"
37 #include "glibintl.h"
38
39 #include "gioalias.h"
40
41 /**
42  * SECTION:gwin32outputstream
43  * @short_description: Streaming output operations for Windows file handles
44  * @include: gio/gwin32outputstream.h
45  * @see_also: #GOutputStream
46  *
47  * #GWin32OutputStream implements #GOutputStream for writing to a
48  * Windows file handle.
49  *
50  * Note that <filename>&lt;gio/gwin32outputstream.h&gt;</filename> belongs
51  * to the Windows-specific GIO interfaces, thus you have to use the
52  * <filename>gio-windows-2.0.pc</filename> pkg-config file when using it.
53  */
54
55 enum {
56   PROP_0,
57   PROP_HANDLE,
58   PROP_CLOSE_HANDLE
59 };
60
61 G_DEFINE_TYPE (GWin32OutputStream, g_win32_output_stream, G_TYPE_OUTPUT_STREAM);
62
63
64 struct _GWin32OutputStreamPrivate {
65   HANDLE handle;
66   gboolean close_handle;
67 };
68
69 static void     g_win32_output_stream_set_property (GObject              *object,
70                                                     guint                 prop_id,
71                                                     const GValue         *value,
72                                                     GParamSpec           *pspec);
73 static void     g_win32_output_stream_get_property (GObject              *object,
74                                                     guint                 prop_id,
75                                                     GValue               *value,
76                                                     GParamSpec           *pspec);
77 static gssize   g_win32_output_stream_write        (GOutputStream        *stream,
78                                                     const void           *buffer,
79                                                     gsize                 count,
80                                                     GCancellable         *cancellable,
81                                                     GError              **error);
82 static gboolean g_win32_output_stream_close        (GOutputStream        *stream,
83                                                     GCancellable         *cancellable,
84                                                     GError              **error);
85
86
87 static void
88 g_win32_output_stream_finalize (GObject *object)
89 {
90   G_OBJECT_CLASS (g_win32_output_stream_parent_class)->finalize (object);
91 }
92
93 static void
94 g_win32_output_stream_class_init (GWin32OutputStreamClass *klass)
95 {
96   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
97   GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
98
99   g_type_class_add_private (klass, sizeof (GWin32OutputStreamPrivate));
100
101   gobject_class->get_property = g_win32_output_stream_get_property;
102   gobject_class->set_property = g_win32_output_stream_set_property;
103   gobject_class->finalize = g_win32_output_stream_finalize;
104
105   stream_class->write_fn = g_win32_output_stream_write;
106   stream_class->close_fn = g_win32_output_stream_close;
107
108    /**
109    * GWin32OutputStream:handle:
110    *
111    * The file handle that the stream writes to.
112    *
113    * Since: 2.26
114    */
115   g_object_class_install_property (gobject_class,
116                                    PROP_HANDLE,
117                                    g_param_spec_pointer ("handle",
118                                                          P_("File handle"),
119                                                          P_("The file handle to write to"),
120                                                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
121
122   /**
123    * GWin32OutputStream:close-handle:
124    *
125    * Whether to close the file handle when the stream is closed.
126    *
127    * Since: 2.26
128    */
129   g_object_class_install_property (gobject_class,
130                                    PROP_CLOSE_HANDLE,
131                                    g_param_spec_boolean ("close-handle",
132                                                          P_("Close file handle"),
133                                                          P_("Whether to close the file handle when the stream is closed"),
134                                                          TRUE,
135                                                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
136 }
137
138 static void
139 g_win32_output_stream_set_property (GObject         *object,
140                                     guint            prop_id,
141                                     const GValue    *value,
142                                     GParamSpec      *pspec)
143 {
144   GWin32OutputStream *win32_stream;
145
146   win32_stream = G_WIN32_OUTPUT_STREAM (object);
147
148   switch (prop_id)
149     {
150     case PROP_HANDLE:
151       win32_stream->priv->handle = g_value_get_pointer (value);
152       break;
153     case PROP_CLOSE_HANDLE:
154       win32_stream->priv->close_handle = g_value_get_boolean (value);
155       break;
156     default:
157       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
158       break;
159     }
160 }
161
162 static void
163 g_win32_output_stream_get_property (GObject    *object,
164                                     guint       prop_id,
165                                     GValue     *value,
166                                     GParamSpec *pspec)
167 {
168   GWin32OutputStream *win32_stream;
169
170   win32_stream = G_WIN32_OUTPUT_STREAM (object);
171
172   switch (prop_id)
173     {
174     case PROP_HANDLE:
175       g_value_set_pointer (value, win32_stream->priv->handle);
176       break;
177     case PROP_CLOSE_HANDLE:
178       g_value_set_boolean (value, win32_stream->priv->close_handle);
179       break;
180     default:
181       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
182     }
183 }
184
185 static void
186 g_win32_output_stream_init (GWin32OutputStream *win32_stream)
187 {
188   win32_stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (win32_stream,
189                                                     G_TYPE_WIN32_OUTPUT_STREAM,
190                                                     GWin32OutputStreamPrivate);
191
192   win32_stream->priv->handle = NULL;
193   win32_stream->priv->close_handle = TRUE;
194 }
195
196 /**
197  * g_win32_output_stream_new:
198  * @handle: a Win32 file handle
199  * @close_handle: %TRUE to close the handle when done
200  *
201  * Creates a new #GWin32OutputStream for the given @handle.
202  *
203  * If @close_handle, is %TRUE, the handle will be closed when the
204  * output stream is destroyed.
205  *
206  * Returns: a new #GOutputStream
207  *
208  * Since: 2.26
209 **/
210 GOutputStream *
211 g_win32_output_stream_new (void    *handle,
212                            gboolean close_handle)
213 {
214   GWin32OutputStream *stream;
215
216   g_return_val_if_fail (handle != NULL, NULL);
217
218   stream = g_object_new (G_TYPE_WIN32_OUTPUT_STREAM,
219                          "handle", handle,
220                          "close-handle", close_handle,
221                          NULL);
222
223   return G_OUTPUT_STREAM (stream);
224 }
225
226 /**
227  * g_win32_output_stream_set_close_handle:
228  * @stream: a #GWin32OutputStream
229  * @close_handle: %TRUE to close the handle when done
230  *
231  * Sets whether the handle of @stream shall be closed when the stream
232  * is closed.
233  *
234  * Since: 2.26
235  */
236 void
237 g_win32_output_stream_set_close_handle (GWin32OutputStream *stream,
238                                         gboolean           close_handle)
239 {
240   g_return_if_fail (G_IS_WIN32_OUTPUT_STREAM (stream));
241
242   close_handle = close_handle != FALSE;
243   if (stream->priv->close_handle != close_handle)
244     {
245       stream->priv->close_handle = close_handle;
246       g_object_notify (G_OBJECT (stream), "close-handle");
247     }
248 }
249
250 /**
251  * g_win32_output_stream_get_close_handle:
252  * @stream: a #GWin32OutputStream
253  *
254  * Returns whether the handle of @stream will be closed when the
255  * stream is closed.
256  *
257  * Return value: %TRUE if the handle is closed when done
258  *
259  * Since: 2.26
260  */
261 gboolean
262 g_win32_output_stream_get_close_handle (GWin32OutputStream *stream)
263 {
264   g_return_val_if_fail (G_IS_WIN32_OUTPUT_STREAM (stream), FALSE);
265
266   return stream->priv->close_handle;
267 }
268
269 /**
270  * g_win32_output_stream_get_handle:
271  * @stream: a #GWin32OutputStream
272  *
273  * Return the Windows handle that the stream writes to.
274  *
275  * Return value: The handle descriptor of @stream
276  *
277  * Since: 2.26
278  */
279 void *
280 g_win32_output_stream_get_handle (GWin32OutputStream *stream)
281 {
282   g_return_val_if_fail (G_IS_WIN32_OUTPUT_STREAM (stream), NULL);
283
284   return stream->priv->handle;
285 }
286
287 static gssize
288 g_win32_output_stream_write (GOutputStream  *stream,
289                             const void     *buffer,
290                             gsize           count,
291                             GCancellable   *cancellable,
292                             GError        **error)
293 {
294   GWin32OutputStream *win32_stream;
295   BOOL res;
296   DWORD nbytes, nwritten;
297
298   win32_stream = G_WIN32_OUTPUT_STREAM (stream);
299
300   if (g_cancellable_set_error_if_cancelled (cancellable, error))
301     return -1;
302
303   if (count > G_MAXINT)
304     nbytes = G_MAXINT;
305   else
306     nbytes = count;
307
308   res = WriteFile (win32_stream->priv->handle, buffer, nbytes, &nwritten, NULL);
309   if (!res)
310     {
311       int errsv = GetLastError ();
312       gchar *emsg = g_win32_error_message (errsv);
313
314       if (errsv == ERROR_HANDLE_EOF)
315         return 0;
316
317       g_set_error (error, G_IO_ERROR,
318                    g_io_error_from_win32_error (errsv),
319                    _("Error writing to handle: %s"),
320                    emsg);
321       g_free (emsg);
322       return -1;
323     }
324
325   return nwritten;
326 }
327
328 static gboolean
329 g_win32_output_stream_close (GOutputStream  *stream,
330                              GCancellable   *cancellable,
331                              GError        **error)
332 {
333   GWin32OutputStream *win32_stream;
334   BOOL res;
335
336   win32_stream = G_WIN32_OUTPUT_STREAM (stream);
337
338   if (!win32_stream->priv->close_handle)
339     return TRUE;
340
341   res = CloseHandle (win32_stream->priv->handle);
342   if (!res)
343     {
344       int errsv = GetLastError ();
345       gchar *emsg = g_win32_error_message (errsv);
346
347       g_set_error (error, G_IO_ERROR,
348                    g_io_error_from_win32_error (errsv),
349                    _("Error closing handle: %s"),
350                    emsg);
351       g_free (emsg);
352       return FALSE;
353     }
354
355   return TRUE;
356 }
357
358 #define __G_WIN32_OUTPUT_STREAM_C__
359 #include "gioaliasdef.c"