/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2010 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"

#include <errno.h>

#include "gpollableinputstream.h"
#include "gasynchelper.h"
#include "glibintl.h"

/**
 * SECTION:gpollableinputstream
 * @short_description: Interface for pollable input streams
 * @include: gio/gio.h
 * @see_also: #GInputStream, #GPollableOutputStream, #GFileDescriptorBased
 *
 * #GPollableInputStream is implemented by #GInputStreams that
 * can be polled for readiness to read. This can be used when
 * interfacing with a non-GIO API that expects
 * UNIX-file-descriptor-style asynchronous I/O rather than GIO-style.
 *
 * Since: 2.28
 */

G_DEFINE_INTERFACE (GPollableInputStream, g_pollable_input_stream, G_TYPE_INPUT_STREAM)

static gboolean g_pollable_input_stream_default_can_poll         (GPollableInputStream *stream);
static gssize   g_pollable_input_stream_default_read_nonblocking (GPollableInputStream  *stream,
								  void                  *buffer,
								  gsize                  count,
								  GError               **error);

static void
g_pollable_input_stream_default_init (GPollableInputStreamInterface *iface)
{
  iface->can_poll         = g_pollable_input_stream_default_can_poll;
  iface->read_nonblocking = g_pollable_input_stream_default_read_nonblocking;
}

static gboolean
g_pollable_input_stream_default_can_poll (GPollableInputStream *stream)
{
  return TRUE;
}

/**
 * g_pollable_input_stream_can_poll:
 * @stream: a #GPollableInputStream.
 *
 * Checks if @stream is actually pollable. Some classes may implement
 * #GPollableInputStream but have only certain instances of that class
 * be pollable. If this method returns %FALSE, then the behavior of
 * other #GPollableInputStream methods is undefined.
 *
 * For any given stream, the value returned by this method is constant;
 * a stream cannot switch from pollable to non-pollable or vice versa.
 *
 * Returns: %TRUE if @stream is pollable, %FALSE if not.
 *
 * Since: 2.28
 */
gboolean
g_pollable_input_stream_can_poll (GPollableInputStream *stream)
{
  g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), FALSE);

  return G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->can_poll (stream);
}

/**
 * g_pollable_input_stream_is_readable:
 * @stream: a #GPollableInputStream.
 *
 * Checks if @stream can be read.
 *
 * Note that some stream types may not be able to implement this 100%
 * reliably, and it is possible that a call to g_input_stream_read()
 * after this returns %TRUE would still block. To guarantee
 * non-blocking behavior, you should always use
 * g_pollable_input_stream_read_nonblocking(), which will return a
 * %G_IO_ERROR_WOULD_BLOCK error rather than blocking.
 *
 * Returns: %TRUE if @stream is readable, %FALSE if not. If an error
 *   has occurred on @stream, this will result in
 *   g_pollable_input_stream_is_readable() returning %TRUE, and the
 *   next attempt to read will return the error.
 *
 * Since: 2.28
 */
gboolean
g_pollable_input_stream_is_readable (GPollableInputStream *stream)
{
  g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), FALSE);

  return G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->is_readable (stream);
}

/**
 * g_pollable_input_stream_create_source:
 * @stream: a #GPollableInputStream.
 * @cancellable: (allow-none): a #GCancellable, or %NULL
 *
 * Creates a #GSource that triggers when @stream can be read, or
 * @cancellable is triggered or an error occurs. The callback on the
 * source is of the #GPollableSourceFunc type.
 *
 * As with g_pollable_input_stream_is_readable(), it is possible that
 * the stream may not actually be readable even after the source
 * triggers, so you should use g_pollable_input_stream_read_nonblocking()
 * rather than g_input_stream_read() from the callback.
 *
 * Returns: (transfer full): a new #GSource
 *
 * Since: 2.28
 */
GSource *
g_pollable_input_stream_create_source (GPollableInputStream *stream,
				       GCancellable         *cancellable)
{
  g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), NULL);

  return G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->
	  create_source (stream, cancellable);
}

static gssize
g_pollable_input_stream_default_read_nonblocking (GPollableInputStream  *stream,
						  void                  *buffer,
						  gsize                  count,
						  GError               **error)
{
  if (!g_pollable_input_stream_is_readable (stream))
    {
      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
                           g_strerror (EAGAIN));
      return -1;
    }

  return G_INPUT_STREAM_GET_CLASS (stream)->
    read_fn (G_INPUT_STREAM (stream), buffer, count, NULL, error);
}

/**
 * g_pollable_input_stream_read_nonblocking:
 * @stream: a #GPollableInputStream
 * @buffer: a buffer to read data into (which should be at least @count
 *     bytes long).
 * @count: the number of bytes you want to read
 * @cancellable: (allow-none): a #GCancellable, or %NULL
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Attempts to read up to @count bytes from @stream into @buffer, as
 * with g_input_stream_read(). If @stream is not currently readable,
 * this will immediately return %G_IO_ERROR_WOULD_BLOCK, and you can
 * use g_pollable_input_stream_create_source() to create a #GSource
 * that will be triggered when @stream is readable.
 *
 * Note that since this method never blocks, you cannot actually
 * use @cancellable to cancel it. However, it will return an error
 * if @cancellable has already been cancelled when you call, which
 * may happen if you call this method after a source triggers due
 * to having been cancelled.
 *
 * Virtual: read_nonblocking
 * Return value: the number of bytes read, or -1 on error (including
 *   %G_IO_ERROR_WOULD_BLOCK).
 */
gssize
g_pollable_input_stream_read_nonblocking (GPollableInputStream  *stream,
					  void                  *buffer,
					  gsize                  count,
					  GCancellable          *cancellable,
					  GError               **error)
{
  gssize res;

  g_return_val_if_fail (G_IS_POLLABLE_INPUT_STREAM (stream), -1);
  g_return_val_if_fail (buffer != NULL, 0);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  if (count == 0)
    return 0;

  if (((gssize) count) < 0)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
		   _("Too large count value passed to %s"), G_STRFUNC);
      return -1;
    }

  if (cancellable)
    g_cancellable_push_current (cancellable);

  res = G_POLLABLE_INPUT_STREAM_GET_INTERFACE (stream)->
    read_nonblocking (stream, buffer, count, error);

  if (cancellable)
    g_cancellable_pop_current (cancellable);

  return res;
}
