/*
 * QEMU I/O channels
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef QIO_CHANNEL_H__
#define QIO_CHANNEL_H__

#include "qemu-common.h"
#include "qapi/error.h"
#include "qom/object.h"

#define TYPE_QIO_CHANNEL "qio-channel"
#define QIO_CHANNEL(obj)                                    \
    OBJECT_CHECK(QIOChannel, (obj), TYPE_QIO_CHANNEL)
#define QIO_CHANNEL_CLASS(klass)                                    \
    OBJECT_CLASS_CHECK(QIOChannelClass, klass, TYPE_QIO_CHANNEL)
#define QIO_CHANNEL_GET_CLASS(obj)                                  \
    OBJECT_GET_CLASS(QIOChannelClass, obj, TYPE_QIO_CHANNEL)

typedef struct QIOChannel QIOChannel;
typedef struct QIOChannelClass QIOChannelClass;

#define QIO_CHANNEL_ERR_BLOCK -2

typedef enum QIOChannelFeature QIOChannelFeature;

enum QIOChannelFeature {
    QIO_CHANNEL_FEATURE_FD_PASS  = (1 << 0),
    QIO_CHANNEL_FEATURE_SHUTDOWN = (1 << 1),
};


typedef enum QIOChannelShutdown QIOChannelShutdown;

enum QIOChannelShutdown {
    QIO_CHANNEL_SHUTDOWN_BOTH,
    QIO_CHANNEL_SHUTDOWN_READ,
    QIO_CHANNEL_SHUTDOWN_WRITE,
};

typedef gboolean (*QIOChannelFunc)(QIOChannel *ioc,
                                   GIOCondition condition,
                                   gpointer data);

/**
 * QIOChannel:
 *
 * The QIOChannel defines the core API for a generic I/O channel
 * class hierarchy. It is inspired by GIOChannel, but has the
 * following differences
 *
 *  - Use QOM to properly support arbitrary subclassing
 *  - Support use of iovecs for efficient I/O with multiple blocks
 *  - None of the character set translation, binary data exclusively
 *  - Direct support for QEMU Error object reporting
 *  - File descriptor passing
 *
 * This base class is abstract so cannot be instantiated. There
 * will be subclasses for dealing with sockets, files, and higher
 * level protocols such as TLS, WebSocket, etc.
 */

struct QIOChannel {
    Object parent;
    unsigned int features; /* bitmask of QIOChannelFeatures */
};

/**
 * QIOChannelClass:
 *
 * This class defines the contract that all subclasses
 * must follow to provide specific channel implementations.
 * The first five callbacks are mandatory to support, others
 * provide additional optional features.
 *
 * Consult the corresponding public API docs for a description
 * of the semantics of each callback
 */
struct QIOChannelClass {
    ObjectClass parent;

    /* Mandatory callbacks */
    ssize_t (*io_writev)(QIOChannel *ioc,
                         const struct iovec *iov,
                         size_t niov,
                         int *fds,
                         size_t nfds,
                         Error **errp);
    ssize_t (*io_readv)(QIOChannel *ioc,
                        const struct iovec *iov,
                        size_t niov,
                        int **fds,
                        size_t *nfds,
                        Error **errp);
    int (*io_close)(QIOChannel *ioc,
                    Error **errp);
    GSource * (*io_create_watch)(QIOChannel *ioc,
                                 GIOCondition condition);
    int (*io_set_blocking)(QIOChannel *ioc,
                           bool enabled,
                           Error **errp);

    /* Optional callbacks */
    int (*io_shutdown)(QIOChannel *ioc,
                       QIOChannelShutdown how,
                       Error **errp);
    void (*io_set_cork)(QIOChannel *ioc,
                        bool enabled);
    void (*io_set_delay)(QIOChannel *ioc,
                         bool enabled);
    off_t (*io_seek)(QIOChannel *ioc,
                     off_t offset,
                     int whence,
                     Error **errp);
};

/* General I/O handling functions */

/**
 * qio_channel_has_feature:
 * @ioc: the channel object
 * @feature: the feature to check support of
 *
 * Determine whether the channel implementation supports
 * the optional feature named in @feature.
 *
 * Returns: true if supported, false otherwise.
 */
bool qio_channel_has_feature(QIOChannel *ioc,
                             QIOChannelFeature feature);

/**
 * qio_channel_readv_full:
 * @ioc: the channel object
 * @iov: the array of memory regions to read data into
 * @niov: the length of the @iov array
 * @fds: pointer to an array that will received file handles
 * @nfds: pointer filled with number of elements in @fds on return
 * @errp: pointer to an uninitialized error object
 *
 * Read data from the IO channel, storing it in the
 * memory regions referenced by @iov. Each element
 * in the @iov will be fully populated with data
 * before the next one is used. The @niov parameter
 * specifies the total number of elements in @iov.
 *
 * It is not required for all @iov to be filled with
 * data. If the channel is in blocking mode, at least
 * one byte of data will be read, but no more is
 * guaranteed. If the channel is non-blocking and no
 * data is available, it will return QIO_CHANNEL_ERR_BLOCK
 *
 * If the channel has passed any file descriptors,
 * the @fds array pointer will be allocated and
 * the elements filled with the received file
 * descriptors. The @nfds pointer will be updated
 * to indicate the size of the @fds array that
 * was allocated. It is the callers responsibility
 * to call close() on each file descriptor and to
 * call g_free() on the array pointer in @fds.
 *
 * It is an error to pass a non-NULL @fds parameter
 * unless qio_channel_has_feature() returns a true
 * value for the QIO_CHANNEL_FEATURE_FD_PASS constant.
 *
 * Returns: the number of bytes read, or -1 on error,
 * or QIO_CHANNEL_ERR_BLOCK if no data is available
 * and the channel is non-blocking
 */
ssize_t qio_channel_readv_full(QIOChannel *ioc,
                               const struct iovec *iov,
                               size_t niov,
                               int **fds,
                               size_t *nfds,
                               Error **errp);


/**
 * qio_channel_writev_full:
 * @ioc: the channel object
 * @iov: the array of memory regions to write data from
 * @niov: the length of the @iov array
 * @fds: an array of file handles to send
 * @nfds: number of file handles in @fds
 * @errp: pointer to an uninitialized error object
 *
 * Write data to the IO channel, reading it from the
 * memory regions referenced by @iov. Each element
 * in the @iov will be fully sent, before the next
 * one is used. The @niov parameter specifies the
 * total number of elements in @iov.
 *
 * It is not required for all @iov data to be fully
 * sent. If the channel is in blocking mode, at least
 * one byte of data will be sent, but no more is
 * guaranteed. If the channel is non-blocking and no
 * data can be sent, it will return QIO_CHANNEL_ERR_BLOCK
 *
 * If there are file descriptors to send, the @fds
 * array should be non-NULL and provide the handles.
 * All file descriptors will be sent if at least one
 * byte of data was sent.
 *
 * It is an error to pass a non-NULL @fds parameter
 * unless qio_channel_has_feature() returns a true
 * value for the QIO_CHANNEL_FEATURE_FD_PASS constant.
 *
 * Returns: the number of bytes sent, or -1 on error,
 * or QIO_CHANNEL_ERR_BLOCK if no data is can be sent
 * and the channel is non-blocking
 */
ssize_t qio_channel_writev_full(QIOChannel *ioc,
                                const struct iovec *iov,
                                size_t niov,
                                int *fds,
                                size_t nfds,
                                Error **errp);

/**
 * qio_channel_readv:
 * @ioc: the channel object
 * @iov: the array of memory regions to read data into
 * @niov: the length of the @iov array
 * @errp: pointer to an uninitialized error object
 *
 * Behaves as qio_channel_readv_full() but does not support
 * receiving of file handles.
 */
ssize_t qio_channel_readv(QIOChannel *ioc,
                          const struct iovec *iov,
                          size_t niov,
                          Error **errp);

/**
 * qio_channel_writev:
 * @ioc: the channel object
 * @iov: the array of memory regions to write data from
 * @niov: the length of the @iov array
 * @errp: pointer to an uninitialized error object
 *
 * Behaves as qio_channel_writev_full() but does not support
 * sending of file handles.
 */
ssize_t qio_channel_writev(QIOChannel *ioc,
                           const struct iovec *iov,
                           size_t niov,
                           Error **errp);

/**
 * qio_channel_readv:
 * @ioc: the channel object
 * @buf: the memory region to read data into
 * @buflen: the length of @buf
 * @errp: pointer to an uninitialized error object
 *
 * Behaves as qio_channel_readv_full() but does not support
 * receiving of file handles, and only supports reading into
 * a single memory region.
 */
ssize_t qio_channel_read(QIOChannel *ioc,
                         char *buf,
                         size_t buflen,
                         Error **errp);

/**
 * qio_channel_writev:
 * @ioc: the channel object
 * @buf: the memory regions to send data from
 * @buflen: the length of @buf
 * @errp: pointer to an uninitialized error object
 *
 * Behaves as qio_channel_writev_full() but does not support
 * sending of file handles, and only supports writing from a
 * single memory region.
 */
ssize_t qio_channel_write(QIOChannel *ioc,
                          const char *buf,
                          size_t buflen,
                          Error **errp);

/**
 * qio_channel_set_blocking:
 * @ioc: the channel object
 * @enabled: the blocking flag state
 * @errp: pointer to an uninitialized error object
 *
 * If @enabled is true, then the channel is put into
 * blocking mode, otherwise it will be non-blocking.
 *
 * In non-blocking mode, read/write operations may
 * return QIO_CHANNEL_ERR_BLOCK if they would otherwise
 * block on I/O
 */
int qio_channel_set_blocking(QIOChannel *ioc,
                             bool enabled,
                             Error **errp);

/**
 * qio_channel_close:
 * @ioc: the channel object
 * @errp: pointer to an uninitialized error object
 *
 * Close the channel, flushing any pending I/O
 *
 * Returns: 0 on success, -1 on error
 */
int qio_channel_close(QIOChannel *ioc,
                      Error **errp);

/**
 * qio_channel_shutdown:
 * @ioc: the channel object
 * @how: the direction to shutdown
 * @errp: pointer to an uninitialized error object
 *
 * Shutdowns transmission and/or receiving of data
 * without closing the underlying transport.
 *
 * Not all implementations will support this facility,
 * so may report an error. To avoid errors, the
 * caller may check for the feature flag
 * QIO_CHANNEL_FEATURE_SHUTDOWN prior to calling
 * this method.
 *
 * Returns: 0 on success, -1 on error
 */
int qio_channel_shutdown(QIOChannel *ioc,
                         QIOChannelShutdown how,
                         Error **errp);

/**
 * qio_channel_set_delay:
 * @ioc: the channel object
 * @enabled: the new flag state
 *
 * Controls whether the underlying transport is
 * permitted to delay writes in order to merge
 * small packets. If @enabled is true, then the
 * writes may be delayed in order to opportunistically
 * merge small packets into larger ones. If @enabled
 * is false, writes are dispatched immediately with
 * no delay.
 *
 * When @enabled is false, applications may wish to
 * use the qio_channel_set_cork() method to explicitly
 * control write merging.
 *
 * On channels which are backed by a socket, this
 * API corresponds to the inverse of TCP_NODELAY flag,
 * controlling whether the Nagle algorithm is active.
 *
 * This setting is merely a hint, so implementations are
 * free to ignore this without it being considered an
 * error.
 */
void qio_channel_set_delay(QIOChannel *ioc,
                           bool enabled);

/**
 * qio_channel_set_cork:
 * @ioc: the channel object
 * @enabled: the new flag state
 *
 * Controls whether the underlying transport is
 * permitted to dispatch data that is written.
 * If @enabled is true, then any data written will
 * be queued in local buffers until @enabled is
 * set to false once again.
 *
 * This feature is typically used when the automatic
 * write coalescing facility is disabled via the
 * qio_channel_set_delay() method.
 *
 * On channels which are backed by a socket, this
 * API corresponds to the TCP_CORK flag.
 *
 * This setting is merely a hint, so implementations are
 * free to ignore this without it being considered an
 * error.
 */
void qio_channel_set_cork(QIOChannel *ioc,
                          bool enabled);


/**
 * qio_channel_seek:
 * @ioc: the channel object
 * @offset: the position to seek to, relative to @whence
 * @whence: one of the (POSIX) SEEK_* constants listed below
 * @errp: pointer to an uninitialized error object
 *
 * Moves the current I/O position within the channel
 * @ioc, to be @offset. The value of @offset is
 * interpreted relative to @whence:
 *
 * SEEK_SET - the position is set to @offset bytes
 * SEEK_CUR - the position is moved by @offset bytes
 * SEEK_END - the position is set to end of the file plus @offset bytes
 *
 * Not all implementations will support this facility,
 * so may report an error.
 *
 * Returns: the new position on success, (off_t)-1 on failure
 */
off_t qio_channel_io_seek(QIOChannel *ioc,
                          off_t offset,
                          int whence,
                          Error **errp);


/**
 * qio_channel_create_watch:
 * @ioc: the channel object
 * @condition: the I/O condition to monitor
 *
 * Create a new main loop source that is used to watch
 * for the I/O condition @condition. Typically the
 * qio_channel_add_watch() method would be used instead
 * of this, since it directly attaches a callback to
 * the source
 *
 * Returns: the new main loop source.
 */
GSource *qio_channel_create_watch(QIOChannel *ioc,
                                  GIOCondition condition);

/**
 * qio_channel_add_watch:
 * @ioc: the channel object
 * @condition: the I/O condition to monitor
 * @func: callback to invoke when the source becomes ready
 * @user_data: opaque data to pass to @func
 * @notify: callback to free @user_data
 *
 * Create a new main loop source that is used to watch
 * for the I/O condition @condition. The callback @func
 * will be registered against the source, to be invoked
 * when the source becomes ready. The optional @user_data
 * will be passed to @func when it is invoked. The @notify
 * callback will be used to free @user_data when the
 * watch is deleted
 *
 * The returned source ID can be used with g_source_remove()
 * to remove and free the source when no longer required.
 * Alternatively the @func callback can return a FALSE
 * value.
 *
 * Returns: the source ID
 */
guint qio_channel_add_watch(QIOChannel *ioc,
                            GIOCondition condition,
                            QIOChannelFunc func,
                            gpointer user_data,
                            GDestroyNotify notify);


/**
 * qio_channel_yield:
 * @ioc: the channel object
 * @condition: the I/O condition to wait for
 *
 * Yields execution from the current coroutine until
 * the condition indicated by @condition becomes
 * available.
 *
 * This must only be called from coroutine context
 */
void qio_channel_yield(QIOChannel *ioc,
                       GIOCondition condition);

/**
 * qio_channel_wait:
 * @ioc: the channel object
 * @condition: the I/O condition to wait for
 *
 * Block execution from the current thread until
 * the condition indicated by @condition becomes
 * available.
 *
 * This will enter a nested event loop to perform
 * the wait.
 */
void qio_channel_wait(QIOChannel *ioc,
                      GIOCondition condition);

#endif /* QIO_CHANNEL_H__ */
