Changed SILC Stream API implementation static inline functions.
[runtime.git] / lib / silcutil / silcstream.h
index 31c6d078942933daa27f1286945951ba4e545cc5..b6d82d90009489e0b050ba1beaafa3c47a4a2bd5 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2005 Pekka Riikonen
+  Copyright (C) 2005 - 2008 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
 
 */
 
-/****h* silcutil/SILC Stream Interface
+/****h* silcutil/Stream Interface
  *
  * DESCRIPTION
  *
  * SILC Stream API is a generic representation of a stream.  A common API
  * is defined that can be used to read from and write to the stream.  Any
  * other stream API derived from this API can use this same interface for
- * sending and receiving.
+ * reading and writing.
+ *
+ * The SilcStream is an abstraction.  It can represent any stream; socket
+ * stream, file descriptor stream, packet stream, etc.  See examples in
+ * silcsocketstream.h and silcfdstream.h.
+ *
+ * Note that stream implementations usually are not thread-safe.  Always
+ * verify whether a stream implementation is thread-safe by checking their
+ * corresponding documentation.
  *
  ***/
 
 #ifndef SILCSTREAM_H
 #define SILCSTREAM_H
 
-/****s* silcutil/SilcStreamAPI/SilcStream
+/****s* silcutil/SilcStream
  *
  * NAME
  *
@@ -47,7 +55,7 @@
  ***/
 typedef void *SilcStream;
 
-/****d* silcutil/SilcStreamAPI/SilcStreamStatus
+/****d* silcutil/SilcStreamStatus
  *
  * NAME
  *
@@ -64,15 +72,10 @@ typedef void *SilcStream;
 typedef enum {
   SILC_STREAM_CAN_READ,                /* Data available for reading */
   SILC_STREAM_CAN_WRITE,       /* Stream ready for writing */
-  SILC_STREAM_EOS,             /* End of stream */
-  SILC_STREAM_CLOSED,          /* Stream is closed */
-  SILC_STREAM_INVALID,         /* Stream is invalid */
-  SILC_STREAM_NO_MEMORY,       /* System out of memory */
-  SILC_STREAM_ERROR,           /* Unknown error */
 } SilcStreamStatus;
 /***/
 
-/****f* silcutil/SilcStreamAPI/SilcStreamNotifier
+/****f* silcutil/SilcStreamNotifier
  *
  * SYNOPSIS
  *
@@ -92,7 +95,7 @@ typedef void (*SilcStreamNotifier)(SilcStream stream,
                                   SilcStreamStatus status,
                                   void *context);
 
-/****s* silcutil/SilcStreamAPI/SilcStreamOps
+/****s* silcutil/SilcStreamOps
  *
  * NAME
  *
@@ -118,7 +121,7 @@ typedef void (*SilcStreamNotifier)(SilcStream stream,
  *    } *SilcFooStream;
  *
  *    SilcFooStream foo;
- *    silc_stream_write(foo, data, data_len);
+ *    silc_stream_write((SilcStream)foo, data, data_len);
  *
  * SOURCE
  */
@@ -140,14 +143,26 @@ typedef struct {
      silc_stream_destroy function was called. */
   void (*destroy)(SilcStream stream);
 
-  /* This is called to set a notifier callback to the stream.  This is
-     called when silc_stream_set_notifier was called. */
-  void (*notifier)(SilcStream stream, SilcStreamNotifier callback,
-                  void *context);
+  /* This is called to set a notifier callback to the stream and schedule
+     the stream.  Stream should not be scheduled before calling this
+     function.  If stream does not need scheduler then the scheduler can
+     be ignored.  This is called when silc_stream_set_notifier was called.
+     Returns FALSE if the stream could not be scheduled. */
+  SilcBool (*notifier)(SilcStream stream, SilcSchedule schedule,
+                      SilcStreamNotifier callback, void *context);
+
+  /* This is called to return the associated scheduler, if set.  This is
+     called when silc_stream_get_schedule was called. */
+  SilcSchedule (*get_schedule)(SilcStream stream);
 } SilcStreamOps;
 /***/
 
-/****f* silcutil/SilcStreamAPI/silc_stream_read
+/* Stream header */
+typedef struct SilcStreamHeaderObject {
+  SilcStreamOps *ops;
+} *SilcStreamHeader, SilcStreamHeaderStruct;
+
+/****f* silcutil/silc_stream_read
  *
  * SYNOPSIS
  *
@@ -163,11 +178,18 @@ typedef struct {
  *    the notifier callback will later be called with SILC_STREAM_CAN_READ
  *    status when stream is again ready for reading.
  *
+ *    If error occurred the error code can be retrieved with silc_errno.
+ *
  ***/
+static inline
 int silc_stream_read(SilcStream stream, unsigned char *buf,
-                    SilcUInt32 buf_len);
+                    SilcUInt32 buf_len)
+{
+  SilcStreamHeader h = stream;
+  return h->ops->read(stream, buf, buf_len);
+}
 
-/****f* silcutil/SilcStreamAPI/silc_stream_write
+/****f* silcutil/silc_stream_write
  *
  * SYNOPSIS
  *
@@ -183,11 +205,18 @@ int silc_stream_read(SilcStream stream, unsigned char *buf,
  *    notifier callback will later be called with SILC_STREAM_CAN_WRITE
  *    status when stream is again ready for writing.
  *
+ *    If error occurred the error code can be retrieved with silc_errno.
+ *
  ***/
+static inline
 int silc_stream_write(SilcStream stream, const unsigned char *data,
-                     SilcUInt32 data_len);
+                     SilcUInt32 data_len)
+{
+  SilcStreamHeader h = stream;
+  return h->ops->write(stream, data, data_len);
+}
 
-/****f* silcutil/SilcStreamAPI/silc_stream_close
+/****f* silcutil/silc_stream_close
  *
  * SYNOPSIS
  *
@@ -198,12 +227,17 @@ int silc_stream_write(SilcStream stream, const unsigned char *data,
  *    Closes the stream indicated by `stream'.  No data can be read or written
  *    to the stream after calling this function.  Return TRUE if the stream
  *    could be closed.  If action is taken on closed stream the notifier
- *    callback will be called with an error status.
+ *    callback may be called with an error status.
  *
  ***/
-SilcBool silc_stream_close(SilcStream stream);
+static inline
+SilcBool silc_stream_close(SilcStream stream)
+{
+  SilcStreamHeader h = stream;
+  return h->ops->close(stream);
+}
 
-/****f* silcutil/SilcStreamAPI/silc_stream_destroy
+/****f* silcutil/silc_stream_destroy
  *
  * SYNOPSIS
  *
@@ -218,26 +252,63 @@ SilcBool silc_stream_close(SilcStream stream);
  *    function will call it.
  *
  ***/
-void silc_stream_destroy(SilcStream stream);
+static inline
+void silc_stream_destroy(SilcStream stream)
+{
+  SilcStreamHeader h = stream;
+  h->ops->destroy(stream);
+}
+
+/****f* silcutil/silc_stream_set_notifier
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_stream_set_notifier(SilcStream stream,
+ *                                      SilcSchedule schedule,
+ *                                      SilcStreamNotifier notifier,
+ *                                      void *context);
+ *
+ * DESCRIPTION
+ *
+ *    Schedule `stream' for stream events.  Set the `notifier' callback to
+ *    be called when some event takes place on the stream.  The event will
+ *    be delievered to the `notifier' callback with the `context'.  It is
+ *    called for example when data is available for reading or writing, or
+ *    if an error occurs.  This can be called at any time for valid stream.
+ *    This call will also set the `stream' into non-blocking mode.
+ *
+ *    If `notifier' is set to NULL no callback will be called for the stream,
+ *    and the stream is not scheduled anymore.
+ *
+ *    This function returns FALSE if the stream could not be scheduled.
+ *    Returns TRUE on success.  The `schedule' must always be non-NULL.
+ *
+ ***/
+static inline
+SilcBool silc_stream_set_notifier(SilcStream stream, SilcSchedule schedule,
+                                 SilcStreamNotifier notifier, void *context)
+{
+  SilcStreamHeader h = stream;
+  return h->ops->notifier(stream, schedule, notifier, context);
+}
 
-/****f* silcutil/SilcStreamAPI/silc_stream_set_notifier
+/****f* silcutil/silc_stream_get_schedule
  *
  * SYNOPSIS
  *
- *    void silc_stream_set_notifier(SilcStream stream,
- *                                  SilcStreamNotifier notifier,
- *                                  void *context);
+ *    SilcSchedule silc_stream_get_schedule(SilcStream stream);
  *
  * DESCRIPTION
  *
- *    Set a notifier callback for the stream indicated by `stream' to be called
- *    when some action takes place on the stream.  It is called for example
- *    when data is available for reading or writing, or if an error occurs.
- *    This can be called at any time for valid stream.  If `notifier' is set
- *    to NULL no callback will be called for the stream.
+ *    Returns the scheduler that has been associated with the `stream', or
+ *    NULL if one has not been set for the `stream'.
  *
  ***/
-void silc_stream_set_notifier(SilcStream stream, SilcStreamNotifier notifier,
-                             void *context);
+static inline
+SilcSchedule silc_stream_get_schedule(SilcStream stream)
+{
+  SilcStreamHeader h = stream;
+  return h->ops->get_schedule(stream);
+}
 
 #endif /* SILCSTREAM_H */