Merge main loop into head. This probably breaks Win32, until
[platform/upstream/glib.git] / glib / giochannel.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * giochannel.c: IO Channel abstraction
5  * Copyright 1998 Owen Taylor
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "glib.h"
24 #include <unistd.h>
25
26 typedef struct _GIOChannelPrivate GIOChannelPrivate;
27
28 struct _GIOChannelPrivate {
29   GIOChannel channel;
30   GIOFuncs *funcs;
31   guint ref_count;
32   gboolean closed;
33 };
34
35 GIOChannel *
36 g_io_channel_new (GIOFuncs *funcs,
37                   gpointer  channel_data)
38 {
39   GIOChannelPrivate *result;
40   GIOChannel *channel;
41   
42   g_return_val_if_fail (funcs != NULL, NULL);
43   
44   result = g_new (GIOChannelPrivate, 1);
45   channel = (GIOChannel *)result;
46   
47   result->funcs = funcs;
48   result->ref_count = 1;
49   result->closed = FALSE;
50
51   channel->channel_data = channel_data;
52   return channel;
53 }
54
55
56 void 
57 g_io_channel_ref (GIOChannel *channel)
58 {
59   GIOChannelPrivate *private;
60   g_return_if_fail (channel != NULL);
61
62   private = (GIOChannelPrivate *)channel;
63
64   private->ref_count++;
65 }
66
67 void 
68 g_io_channel_unref (GIOChannel *channel)
69 {
70   GIOChannelPrivate *private;
71   g_return_if_fail (channel != NULL);
72
73   private = (GIOChannelPrivate *)channel;
74
75   private->ref_count--;
76   if (private->ref_count == 0)
77     {
78       /* We don't want to close the channel here, because
79        * the channel may just be wrapping a file or socket
80        * that the app is independently manipulating.
81        */
82       private->funcs->io_free (channel);
83       g_free (private);
84     }
85 }
86
87 GIOError 
88 g_io_channel_read (GIOChannel *channel, 
89                    gchar      *buf, 
90                    guint       count,
91                    guint      *bytes_read)
92 {
93   GIOChannelPrivate *private = (GIOChannelPrivate *)channel;
94
95   g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
96   g_return_val_if_fail (!private->closed, G_IO_ERROR_UNKNOWN);
97
98   return private->funcs->io_read (channel, buf, count, bytes_read);
99 }
100
101 GIOError 
102 g_io_channel_write (GIOChannel *channel, 
103                     gchar      *buf, 
104                     guint       count,
105                     guint      *bytes_written)
106 {
107   GIOChannelPrivate *private = (GIOChannelPrivate *)channel;
108
109   g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
110   g_return_val_if_fail (!private->closed, G_IO_ERROR_UNKNOWN);
111
112   return private->funcs->io_write (channel, buf, count, bytes_written);
113 }
114
115 GIOError 
116 g_io_channel_seek  (GIOChannel   *channel,
117                     gint        offset, 
118                     GSeekType   type)
119 {
120   GIOChannelPrivate *private = (GIOChannelPrivate *)channel;
121
122   g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
123   g_return_val_if_fail (!private->closed, G_IO_ERROR_UNKNOWN);
124
125   return private->funcs->io_seek (channel, offset, type);
126 }
127      
128 void
129 g_io_channel_close (GIOChannel *channel)
130 {
131   GIOChannelPrivate *private = (GIOChannelPrivate *)channel;
132
133   g_return_if_fail (channel != NULL);
134   g_return_if_fail (!private->closed);
135
136   private->closed = TRUE;
137   private->funcs->io_close (channel);
138 }
139
140 guint 
141 g_io_add_watch_full (GIOChannel      *channel,
142                      gint           priority,
143                      GIOCondition   condition,
144                      GIOFunc        func,
145                      gpointer       user_data,
146                      GDestroyNotify notify)
147 {
148   GIOChannelPrivate *private = (GIOChannelPrivate *)channel;
149
150   g_return_val_if_fail (channel != NULL, 0);
151   g_return_val_if_fail (!private->closed, 0);
152
153   return private->funcs->io_add_watch (channel, priority, condition,
154                                        func, user_data, notify);
155 }
156
157 guint 
158 g_io_add_watch (GIOChannel      *channel,
159                 GIOCondition   condition,
160                 GIOFunc        func,
161                 gpointer       user_data)
162 {
163   return g_io_add_watch_full (channel, 0, condition, func, user_data, NULL);
164 }