src/lib/transport_internal.h
branchnew-lib-errors
changeset 219 cefec18b8268
parent 183 7bfbe9070c50
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/transport_internal.h	Thu May 28 01:17:36 2009 +0300
@@ -0,0 +1,126 @@
+#ifndef LIBQMSK_TRANSPORT_INTERNAL_H
+#define LIBQMSK_TRANSPORT_INTERNAL_H
+
+/**
+ * @file
+ *
+ * The internal interface for transport implementations.
+ */ 
+#include "transport.h"
+#include "object.h"
+
+#include <stdbool.h>
+
+/**
+ * The object_type for a transport_type
+ */
+extern const struct object_type transport_type_type;
+
+/**
+ * The definition of a transport type
+ */
+struct transport_type {
+    struct object_type base_type;
+
+    /**
+     * Method table for implementation stuff.
+     *
+     * Note that it is the transport's resposibility to implement the behaviour described in transport.h
+     */
+    struct transport_methods {
+        /** For transport_read() */
+        err_t (*read) (transport_t *transport, void *buf, size_t *len, error_t *err);
+
+        /** For transport_write() */
+        err_t (*write) (transport_t *transport, const void *buf, size_t *len, error_t *err);
+
+        /**
+         * The mask of event flags will be set to the given mask if this method is succesfull.
+         *
+         * The old mask is still available in transport::info::ev_mask.
+         */
+        err_t (*events) (transport_t *transport, short mask, error_t *err);
+
+        /** 
+         * Release the transport's internal state, but not the transport itself.
+         *
+         * In other words, this should release everything inside the transport_t, but not free() the transport_t itself.
+         */
+        void (*deinit) (transport_t *transport);
+
+        /**
+         * Used by layered transports to handle transport_connected.
+         *
+         * If this is NULL, transport_connected will call the user callback directly, otherwise, it will proxy through this.
+         *
+         * The \a err param follows the same rules as for transport_connected() - NULL for success, error info otherwise.
+         *
+         * @param transport the transport state
+         * @param err error info if the connect failed
+         */
+        void (*_connected) (transport_t *transport, const error_t *err);
+    } methods;
+};
+
+/**
+ * The base transport type
+ */
+struct transport {
+    struct object base_obj;
+
+    /** User info */
+    struct transport_info info;
+    
+    /** Are we connected? */
+    bool connected;
+};
+
+/**
+ * Bind the given transport to the given type with the given user info.
+ *
+ * \a info may be given as NULL to not have any callbacks, but this will crash if any transport_* is called before
+ * transport_set_callbacks().
+ *
+ * It is a bug to call this with a transport that is already bound.
+ */
+void transport_init (transport_t *transport, const struct transport_type *type, const struct transport_info *info);
+
+/**
+ * Check the type of the transport, and return the transport as a void* suitable for casting to the appropriate struct
+ * for the type, or any of its children.
+ *
+ * It is a bug to call this with a transport of a different type.
+ */
+void* transport_check (transport_t *transport, const struct transport_type *type);
+
+/**
+ * Mark the transport as connected, calling transport_methods::_connected if it exists and \a direct is not given,
+ * transport_callbacks::on_connected/transport_callbacks::on_error otherwise.
+ *
+ * If the connect succeeded, \a err should be given as NULL. If the connect failed, \a err should contain the error
+ * info.
+ *
+ * If called from the transport_methods::_connected method, pass in direct to avoid recursion.
+ *
+ * This sets the transport::connected flag before calling transport_callbacks::on_connected (i.e. directly) without any
+ * error set.
+ *
+ * XXX: implement proper layering of types by taking a transport_type arg and chaining down from there.
+ *
+ * @param transport the transport state
+ * @param err NULL for success, otherwise connect error code
+ * @param direct call the user callback directly, ignoring any method
+ */
+void transport_connected (transport_t *transport, const error_t *err, bool direct);
+
+/**
+ * Invoke the user callbacks based on the given TRANSPORT_* flags
+ */
+void transport_invoke (transport_t *transport, short what);
+
+/**
+ * Mark the transport as failed, calling transport_methods::on_error with the given error code.
+ */
+void transport_error (transport_t *transport, const error_t *err);
+
+#endif