/* rygel-data-source.c generated by valac 0.40.8, the Vala compiler
 * generated from rygel-data-source.vala, do not modify */

/*
 * Copyright (C) 2012 Intel Corporation.
 * Copyright (C) 2013 Cable Television Laboratories, Inc.
 *
 * Author: Jens Georg <jensg@openismus.com>
 *         Craig Pratt <craig@ecaspia.com>
 *
 * This file is part of Rygel.
 *
 * Rygel 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.1 of the License, or (at your option) any later version.
 *
 * Rygel 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */


#include <glib.h>
#include <glib-object.h>
#include <gee.h>


#define RYGEL_TYPE_DATA_SOURCE (rygel_data_source_get_type ())
#define RYGEL_DATA_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_DATA_SOURCE, RygelDataSource))
#define RYGEL_IS_DATA_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_DATA_SOURCE))
#define RYGEL_DATA_SOURCE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), RYGEL_TYPE_DATA_SOURCE, RygelDataSourceIface))

typedef struct _RygelDataSource RygelDataSource;
typedef struct _RygelDataSourceIface RygelDataSourceIface;

#define RYGEL_TYPE_HTTP_SEEK_REQUEST (rygel_http_seek_request_get_type ())
#define RYGEL_HTTP_SEEK_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_HTTP_SEEK_REQUEST, RygelHTTPSeekRequest))
#define RYGEL_HTTP_SEEK_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_HTTP_SEEK_REQUEST, RygelHTTPSeekRequestClass))
#define RYGEL_IS_HTTP_SEEK_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_HTTP_SEEK_REQUEST))
#define RYGEL_IS_HTTP_SEEK_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_HTTP_SEEK_REQUEST))
#define RYGEL_HTTP_SEEK_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_HTTP_SEEK_REQUEST, RygelHTTPSeekRequestClass))

typedef struct _RygelHTTPSeekRequest RygelHTTPSeekRequest;
typedef struct _RygelHTTPSeekRequestClass RygelHTTPSeekRequestClass;

#define RYGEL_TYPE_PLAY_SPEED_REQUEST (rygel_play_speed_request_get_type ())
#define RYGEL_PLAY_SPEED_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_PLAY_SPEED_REQUEST, RygelPlaySpeedRequest))
#define RYGEL_PLAY_SPEED_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_PLAY_SPEED_REQUEST, RygelPlaySpeedRequestClass))
#define RYGEL_IS_PLAY_SPEED_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_PLAY_SPEED_REQUEST))
#define RYGEL_IS_PLAY_SPEED_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_PLAY_SPEED_REQUEST))
#define RYGEL_PLAY_SPEED_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_PLAY_SPEED_REQUEST, RygelPlaySpeedRequestClass))

typedef struct _RygelPlaySpeedRequest RygelPlaySpeedRequest;
typedef struct _RygelPlaySpeedRequestClass RygelPlaySpeedRequestClass;

#define RYGEL_TYPE_HTTP_RESPONSE_ELEMENT (rygel_http_response_element_get_type ())
#define RYGEL_HTTP_RESPONSE_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_HTTP_RESPONSE_ELEMENT, RygelHTTPResponseElement))
#define RYGEL_HTTP_RESPONSE_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_HTTP_RESPONSE_ELEMENT, RygelHTTPResponseElementClass))
#define RYGEL_IS_HTTP_RESPONSE_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_HTTP_RESPONSE_ELEMENT))
#define RYGEL_IS_HTTP_RESPONSE_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_HTTP_RESPONSE_ELEMENT))
#define RYGEL_HTTP_RESPONSE_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_HTTP_RESPONSE_ELEMENT, RygelHTTPResponseElementClass))

typedef struct _RygelHTTPResponseElement RygelHTTPResponseElement;
typedef struct _RygelHTTPResponseElementClass RygelHTTPResponseElementClass;
enum  {
	RYGEL_DATA_SOURCE_DATA_AVAILABLE_SIGNAL,
	RYGEL_DATA_SOURCE_DONE_SIGNAL,
	RYGEL_DATA_SOURCE_ERROR_SIGNAL,
	RYGEL_DATA_SOURCE_NUM_SIGNALS
};
static guint rygel_data_source_signals[RYGEL_DATA_SOURCE_NUM_SIGNALS] = {0};

typedef enum  {
	RYGEL_DATA_SOURCE_ERROR_GENERAL,
	RYGEL_DATA_SOURCE_ERROR_SEEK_FAILED,
	RYGEL_DATA_SOURCE_ERROR_PLAYSPEED_FAILED
} RygelDataSourceError;
#define RYGEL_DATA_SOURCE_ERROR rygel_data_source_error_quark ()
struct _RygelDataSourceIface {
	GTypeInterface parent_iface;
	GeeList* (*preroll) (RygelDataSource* self, RygelHTTPSeekRequest* seek, RygelPlaySpeedRequest* playspeed, GError** error);
	void (*start) (RygelDataSource* self, GError** error);
	void (*freeze) (RygelDataSource* self);
	void (*thaw) (RygelDataSource* self);
	void (*stop) (RygelDataSource* self);
};



GQuark rygel_data_source_error_quark (void);
GType rygel_http_seek_request_get_type (void) G_GNUC_CONST;
GType rygel_play_speed_request_get_type (void) G_GNUC_CONST;
GType rygel_http_response_element_get_type (void) G_GNUC_CONST;
GType rygel_data_source_get_type (void) G_GNUC_CONST;
GeeList* rygel_data_source_preroll (RygelDataSource* self,
                                    RygelHTTPSeekRequest* seek,
                                    RygelPlaySpeedRequest* playspeed,
                                    GError** error);
void rygel_data_source_start (RygelDataSource* self,
                              GError** error);
void rygel_data_source_freeze (RygelDataSource* self);
void rygel_data_source_thaw (RygelDataSource* self);
void rygel_data_source_stop (RygelDataSource* self);
static void g_cclosure_user_marshal_VOID__POINTER_INT (GClosure * closure,
                                                GValue * return_value,
                                                guint n_param_values,
                                                const GValue * param_values,
                                                gpointer invocation_hint,
                                                gpointer marshal_data);


GQuark
rygel_data_source_error_quark (void)
{
	return g_quark_from_static_string ("rygel_data_source_error-quark");
}


/**
     * Preroll the data with the given seek and playspeed.
     *
     * @param seek    optional seek/range specifier
     * @param playspeed optional playback rate specifier. This will only be
     *                  provided when a scaled rate is requested (the speed
     *                  will not be 0.0 or 1.0)
     *
     * @return List of HTTPResponseElements appropriate for the content request
     *         and optional seek/playspeed (e.g. Content-Range,
     *         TimeSeekRange.dlna.org, etc) or null/empty list if none are
     *         appropriate. Note: the list will be processed in-order by the
     *         caller.
     *
     * @throws Error if anything goes wrong while prerolling the stream.
     *         Throws DataSourceError.SEEK_FAILED if a seek method is not
     *         supported or the range is not fulfillable.
     *         Throws PLAYSPEED_FAILED if the rate is not supported or
     *         fulfillable.
     */
GeeList*
rygel_data_source_preroll (RygelDataSource* self,
                           RygelHTTPSeekRequest* seek,
                           RygelPlaySpeedRequest* playspeed,
                           GError** error)
{
	g_return_val_if_fail (self != NULL, NULL);
	return RYGEL_DATA_SOURCE_GET_INTERFACE (self)->preroll (self, seek, playspeed, error);
}


/**
     * Start producing the data.
     *
     * @throws Error if anything goes wrong while starting the stream.
     */
void
rygel_data_source_start (RygelDataSource* self,
                         GError** error)
{
	g_return_if_fail (self != NULL);
	RYGEL_DATA_SOURCE_GET_INTERFACE (self)->start (self, error);
}


/**
     * Temporarily stop data generation.
     *
     * May be called multiple times. If the source is already frozen, the
     * following calles to freeze are ignored. After callging freeze(), so
     * data_available() signal should be emitted.
     */
void
rygel_data_source_freeze (RygelDataSource* self)
{
	g_return_if_fail (self != NULL);
	RYGEL_DATA_SOURCE_GET_INTERFACE (self)->freeze (self);
}


/**
     * Resume data generation from a previous freeze call.
     *
     * May be called multiple times, will be ignored if the source is not
     * frozen.
     */
void
rygel_data_source_thaw (RygelDataSource* self)
{
	g_return_if_fail (self != NULL);
	RYGEL_DATA_SOURCE_GET_INTERFACE (self)->thaw (self);
}


/**
     * Stop producing data.
     * After calling stop(), calling start() should produce data from the
     * beginning and not resume streaming.
     */
void
rygel_data_source_stop (RygelDataSource* self)
{
	g_return_if_fail (self != NULL);
	RYGEL_DATA_SOURCE_GET_INTERFACE (self)->stop (self);
}


static void
g_cclosure_user_marshal_VOID__POINTER_INT (GClosure * closure,
                                           GValue * return_value,
                                           guint n_param_values,
                                           const GValue * param_values,
                                           gpointer invocation_hint,
                                           gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__POINTER_INT) (gpointer data1, gpointer arg_1, gint arg_2, gpointer data2);
	register GMarshalFunc_VOID__POINTER_INT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__POINTER_INT) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_pointer (param_values + 1), g_value_get_int (param_values + 2), data2);
}


static void
rygel_data_source_default_init (RygelDataSourceIface * iface)
{
	/**
	     * Emitted when the source has produced some data.
	     *
	     * This signal has to be emitted in the main thread.
	     */
	rygel_data_source_signals[RYGEL_DATA_SOURCE_DATA_AVAILABLE_SIGNAL] = g_signal_new ("data-available", RYGEL_TYPE_DATA_SOURCE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__POINTER_INT, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_INT);
	/**
	     * Emitted when the source does not have data anymore.
	     *
	     * This signal has to be emitted in the main thread.
	     */
	rygel_data_source_signals[RYGEL_DATA_SOURCE_DONE_SIGNAL] = g_signal_new ("done", RYGEL_TYPE_DATA_SOURCE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	/**
	     * Emitted when the source encounters a problem during data generation.
	     *
	     * This signal has to be emitted in the main thread.
	     */
	rygel_data_source_signals[RYGEL_DATA_SOURCE_ERROR_SIGNAL] = g_signal_new ("error", RYGEL_TYPE_DATA_SOURCE, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
}


/**
 * Interface for all data streams provided by a #RygelMediaEngine.
 *
 * When Rygel receives a HTTP request to stream a given file, it creates a
 * RygelDataSource object for this new file and instructs the RygelDataSource
 * to begin streaming. The RygelDataSource object will duly pass this request
 * on to the underlying media framework, which will in turn pass streamed bytes
 * back to the RygelDataSource object. The RygelDataSource passes these bytes
 * to Rygel which adds them to the response it sends to the original HTTP
 * request received from the client.
 *
 * The data source is responsible for providing response header information
 * describing the content being produced and a streamable byte-stream
 * via its data_available signal. End-of-stream is signalled by the 
 * done signal, while errors are signalled by the error signal.
 *
 * Implementations should fulfil at least these requirements:
 *
 *  # It should support at least the file:/''''/ URI scheme.
 *  # It should be able to stream any kind of binary data, regardless of the format.
 *
 * RygelDataSource instances are provided by
 * rygel_media_engine_create_data_source() which will return a derived #RygelDataSource
 * that uses a specific IO backend and/or multimedia backend to stream the
 * multimedia data at the URI.
 *
 * The derived RygelDataSource may provide additional API for use by
 * the derived media engine. For instance, rygel_media_engine_get_transcoders()
 * may return derived #RygelTranscoder instances, and these may use that
 * additional API in their create_source() implementations, for instance
 * to access resources or data structures of the specific multimedia backend.
 */
GType
rygel_data_source_get_type (void)
{
	static volatile gsize rygel_data_source_type_id__volatile = 0;
	if (g_once_init_enter (&rygel_data_source_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (RygelDataSourceIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_data_source_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
		GType rygel_data_source_type_id;
		rygel_data_source_type_id = g_type_register_static (G_TYPE_INTERFACE, "RygelDataSource", &g_define_type_info, 0);
		g_type_interface_add_prerequisite (rygel_data_source_type_id, G_TYPE_OBJECT);
		g_once_init_leave (&rygel_data_source_type_id__volatile, rygel_data_source_type_id);
	}
	return rygel_data_source_type_id__volatile;
}



