Added SILC Thread Queue API
[silc.git] / lib / silcutil / silcstream.h
1 /*
2
3   silcstream.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2005 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 /****h* silcutil/SILC Stream Interface
21  *
22  * DESCRIPTION
23  *
24  * SILC Stream API is a generic representation of a stream.  A common API
25  * is defined that can be used to read from and write to the stream.  Any
26  * other stream API derived from this API can use this same interface for
27  * reading and writing.
28  *
29  * Note that stream implementations usually are not thread-safe.  Always
30  * verify whether a stream implementation is thread-safe by checking their
31  * corresponding documentation.
32  *
33  ***/
34
35 #ifndef SILCSTREAM_H
36 #define SILCSTREAM_H
37
38 /****s* silcutil/SilcStreamAPI/SilcStream
39  *
40  * NAME
41  *
42  *    typedef void *SilcStream;
43  *
44  * DESCRIPTION
45  *
46  *    Abstact stream context representing any stream.  All streams are using
47  *    this abstraction so that the stream can be accessed using the standard
48  *    silc_stream_* functions.  All streams are destroyed by calling the
49  *    silc_stream_destroy function.
50  *
51  ***/
52 typedef void *SilcStream;
53
54 /****d* silcutil/SilcStreamAPI/SilcStreamStatus
55  *
56  * NAME
57  *
58  *    typedef enum { ... } SilcStreamStatus;
59  *
60  * DESCRIPTION
61  *
62  *    Stream status.  This status is returned into the SilcStreamNotifier
63  *    callback function to indicate the status of the stream at a given
64  *    moment.
65  *
66  * SOURCE
67  */
68 typedef enum {
69   SILC_STREAM_CAN_READ,         /* Data available for reading */
70   SILC_STREAM_CAN_WRITE,        /* Stream ready for writing */
71 } SilcStreamStatus;
72 /***/
73
74 /****f* silcutil/SilcStreamAPI/SilcStreamNotifier
75  *
76  * SYNOPSIS
77  *
78  *    typedef void (*SilcStreamNotifier)(SilcStream stream,
79  *                                       SilcStreamStatus status,
80  *                                       void *context);
81  *
82  * DESCRIPTION
83  *
84  *    A callback of this type is called as stream notifier to notify of a
85  *    certain action taken over the stream.  This is called to notify for
86  *    example that data is ready for reading, or writing or that end of
87  *    stream occurred.
88  *
89  ***/
90 typedef void (*SilcStreamNotifier)(SilcStream stream,
91                                    SilcStreamStatus status,
92                                    void *context);
93
94 /****s* silcutil/SilcStreamAPI/SilcStreamOps
95  *
96  * NAME
97  *
98  *    typedef struct { ... } SilcStreamOps;
99  *
100  * DESCRIPTION
101  *
102  *    SILC Stream operations structure.  This structure includes callback
103  *    functions to the actual stream implementation.  Any stream that
104  *    use SILC Stream abstraction must fill this structure with the actual
105  *    stream implementation.
106  *
107  *    Each stream implementation MUST set this structure as the first field
108  *    in their stream structure.  As it is that structure that is passed
109  *    to the silc_stream_* routines, the SILC Stream API expects that the
110  *    SilcStream context starts with this structure.
111  *
112  * EXAMPLE
113  *
114  *    typedef struct {
115  *      const SilcStreamOps *ops;
116  *      ... other stuff ...
117  *    } *SilcFooStream;
118  *
119  *    SilcFooStream foo;
120  *    silc_stream_write(foo, data, data_len);
121  *
122  * SOURCE
123  */
124 typedef struct {
125   /* This is called to read data from the stream.  This is called when
126      silc_stream_read function was called. */
127   int (*read)(SilcStream stream, unsigned char *buf, SilcUInt32 buf_len);
128
129   /* This is called when writing data to the stream.  This is called when
130      silc_stream_write function was called. */
131   int (*write)(SilcStream stream, const unsigned char *data,
132                SilcUInt32 data_len);
133
134   /* This is called to close the stream.  This is called when the
135      silc_stream_close function was called. */
136   SilcBool (*close)(SilcStream stream);
137
138   /* This is called to destroy the stream.  This is called when the
139      silc_stream_destroy function was called. */
140   void (*destroy)(SilcStream stream);
141
142   /* This is called to set a notifier callback to the stream and schedule
143      the stream.  Stream should not be scheduled before calling this
144      function.  If stream does not need scheduler then the scheduler can
145      be ignored.  This is called when silc_stream_set_notifier was called.
146      Returns FALSE if the stream could not be scheduled. */
147   SilcBool (*notifier)(SilcStream stream, SilcSchedule schedule,
148                        SilcStreamNotifier callback, void *context);
149
150   /* This is called to return the associated scheduler, if set.  This is
151      called when silc_stream_get_schedule was called. */
152   SilcSchedule (*get_schedule)(SilcStream stream);
153 } SilcStreamOps;
154 /***/
155
156 /****f* silcutil/SilcStreamAPI/silc_stream_read
157  *
158  * SYNOPSIS
159  *
160  *    int silc_stream_read(SilcStream stream, unsigned char *buf,
161  *                         SilcUInt32 buf_len);
162  *
163  * DESCRIPTION
164  *
165  *    Reads data from the stream indicated by `stream' into the data buffer
166  *    indicated by `buf' which is size of `buf_len'.  This returns the amount
167  *    of data read, zero (0) if end of stream occurred, -1 if data could
168  *    not be read at this moment, or -2 if error occurred.  If -1 is returned
169  *    the notifier callback will later be called with SILC_STREAM_CAN_READ
170  *    status when stream is again ready for reading.
171  *
172  *    If error occurred the error code can be retrieved with silc_errno.
173  *
174  ***/
175 int silc_stream_read(SilcStream stream, unsigned char *buf,
176                      SilcUInt32 buf_len);
177
178 /****f* silcutil/SilcStreamAPI/silc_stream_write
179  *
180  * SYNOPSIS
181  *
182  *    int silc_stream_write(SilcStream stream, const unsigned char *data,
183  *                          SilcUInt32 data_len);
184  *
185  * DESCRIPTION
186  *
187  *    Writes `data_len' bytes of data to the stream indicated by `stream' from
188  *    data buffer indicated by `data'.  Returns the amount of data written,
189  *    zero (0) if end of stream occurred, -1 if data could not be written
190  *    at this moment, or -2 if error occurred.  If -1 is returned the
191  *    notifier callback will later be called with SILC_STREAM_CAN_WRITE
192  *    status when stream is again ready for writing.
193  *
194  *    If error occurred the error code can be retrieved with silc_errno.
195  *
196  ***/
197 int silc_stream_write(SilcStream stream, const unsigned char *data,
198                       SilcUInt32 data_len);
199
200 /****f* silcutil/SilcStreamAPI/silc_stream_close
201  *
202  * SYNOPSIS
203  *
204  *    SilcBool silc_stream_close(SilcStream stream);
205  *
206  * DESCRIPTION
207  *
208  *    Closes the stream indicated by `stream'.  No data can be read or written
209  *    to the stream after calling this function.  Return TRUE if the stream
210  *    could be closed.  If action is taken on closed stream the notifier
211  *    callback may be called with an error status.
212  *
213  ***/
214 SilcBool silc_stream_close(SilcStream stream);
215
216 /****f* silcutil/SilcStreamAPI/silc_stream_destroy
217  *
218  * SYNOPSIS
219  *
220  *    void silc_stream_destroy(SilcStream stream);
221  *
222  * DESCRIPTION
223  *
224  *    Destroy the stream indicated by `stream'.  The `stream' will become
225  *    invalid after this function returns.  All streams are destroyed by
226  *    calling this function.  The silc_stream_close should be called
227  *    before calling this function.  However, if it is not called this
228  *    function will call it.
229  *
230  ***/
231 void silc_stream_destroy(SilcStream stream);
232
233 /****f* silcutil/SilcStreamAPI/silc_stream_set_notifier
234  *
235  * SYNOPSIS
236  *
237  *    SilcBool silc_stream_set_notifier(SilcStream stream,
238  *                                      SilcSchedule schedule,
239  *                                      SilcStreamNotifier notifier,
240  *                                      void *context);
241  *
242  * DESCRIPTION
243  *
244  *    Schedule `stream' for stream events.  Set the `notifier' callback to
245  *    be called when some event takes place on the stream.  The event will
246  *    be delievered to the `notifier' callback with the `context'.  It is
247  *    called for example when data is available for reading or writing, or
248  *    if an error occurs.  This can be called at any time for valid stream.
249  *    This call will also set the `stream' into non-blocking mode.
250  *
251  *    If `notifier' is set to NULL no callback will be called for the stream,
252  *    and the stream is not scheduled anymore.
253  *
254  *    This function returns FALSE if the stream could not be scheduled.
255  *    Returns TRUE on success.  The `schedule' must always be non-NULL.
256  *
257  ***/
258 SilcBool silc_stream_set_notifier(SilcStream stream, SilcSchedule schedule,
259                                   SilcStreamNotifier notifier, void *context);
260
261 /****f* silcutil/SilcStreamAPI/silc_stream_get_schedule
262  *
263  * SYNOPSIS
264  *
265  *    SilcSchedule silc_stream_get_schedule(SilcStream stream);
266  *
267  * DESCRIPTION
268  *
269  *    Returns the scheduler that has been associated with the `stream', or
270  *    NULL if one has not been set for the `stream'.
271  *
272  ***/
273 SilcSchedule silc_stream_get_schedule(SilcStream stream);
274
275 #endif /* SILCSTREAM_H */