Ejemplo n.º 1
0
static struct playlist_provider *
playlist_open_remote(const char *uri, GMutex *mutex, GCond *cond,
		     struct input_stream **is_r)
{
	assert(uri_has_scheme(uri));

	struct playlist_provider *playlist =
		playlist_list_open_uri(uri, mutex, cond);
	if (playlist != NULL) {
		*is_r = NULL;
		return playlist;
	}

	GError *error = NULL;
	struct input_stream *is = input_stream_open(uri, mutex, cond, &error);
	if (is == NULL) {
		if (error != NULL) {
			g_warning("Failed to open %s: %s",
				  uri, error->message);
			g_error_free(error);
		}

		return NULL;
	}

	playlist = playlist_list_open_stream(is, uri);
	if (playlist == NULL) {
		input_stream_close(is);
		return NULL;
	}

	*is_r = is;
	return playlist;
}
Ejemplo n.º 2
0
static struct archive_file *
bz2_open(const char *pathname, GError **error_r)
{
	struct bz2_archive_file *context;
	int len;

	context = g_malloc(sizeof(*context));
	archive_file_init(&context->base, &bz2_archive_plugin);
	refcount_init(&context->ref);

	//open archive
	static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
	context->istream = input_stream_open(pathname,
					     g_static_mutex_get_mutex(&mutex),
					     NULL,
					     error_r);
	if (context->istream == NULL) {
		g_free(context);
		return NULL;
	}

	context->name = g_path_get_basename(pathname);

	//remove suffix
	len = strlen(context->name);
	if (len > 4) {
		context->name[len - 4] = 0; //remove .bz2 suffix
	}

	return &context->base;
}
Ejemplo n.º 3
0
/**
 * Opens the input stream with input_stream_open(), and waits until
 * the stream gets ready.  If a decoder STOP command is received
 * during that, it cancels the operation (but does not close the
 * stream).
 *
 * Unlock the decoder before calling this function.
 *
 * @return an input_stream on success or if #DECODE_COMMAND_STOP is
 * received, NULL on error
 */
static struct input_stream *
decoder_input_stream_open(struct decoder_control *dc, const char *uri)
{
	GError *error = NULL;
	struct input_stream *is;

	is = input_stream_open(uri, &error);
	if (is == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	/* wait for the input stream to become ready; its metadata
	   will be available then */

	while (!is->ready &&
	       decoder_lock_get_command(dc) != DECODE_COMMAND_STOP) {
		int ret;

		ret = input_stream_buffer(is, &error);
		if (ret < 0) {
			input_stream_close(is);
			g_warning("%s", error->message);
			g_error_free(error);
			return NULL;
		}
	}

	return is;
}
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
	GError *error = NULL;
	struct input_stream *is;
	int ret;

	if (argc != 2) {
		g_printerr("Usage: run_input URI\n");
		return 1;
	}

	/* initialize GLib */

	g_thread_init(NULL);
	g_log_set_default_handler(my_log_func, NULL);

	/* initialize MPD */

	tag_pool_init();
	config_global_init();

#ifdef ENABLE_ARCHIVE
	archive_plugin_init_all();
#endif

	if (!input_stream_global_init(&error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return 2;
	}

	/* open the stream and dump it */

	is = input_stream_open(argv[1], &error);
	if (is != NULL) {
		ret = dump_input_stream(is);
		input_stream_close(is);
	} else {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		} else
			g_printerr("input_stream_open() failed\n");
		ret = 2;
	}

	/* deinitialize everything */

	input_stream_global_finish();

#ifdef ENABLE_ARCHIVE
	archive_plugin_deinit_all();
#endif

	config_global_finish();
	tag_pool_deinit();

	return ret;
}
Ejemplo n.º 5
0
struct input_desc *input_open(const char *fname, int *fds, int fds_size)
{
  struct input_desc *res;
  struct timeval tv;
  char *c;

  res = malloc(sizeof(struct input_desc));
  if (res == NULL) {
    return NULL;
  }

  c = strchr(fname,',');
  if (c) {
    *(c++) = 0;
  }
  res->s = input_stream_open(fname, &res->interframe, c);
  if (res->s == NULL) {
    free(res);
    res = NULL;
    return res;
  }
  if (res->interframe == 0) {
    const int *my_fds;
    int i = 0;

    my_fds = input_get_fds(res->s);
    while(my_fds[i] != -1) {
      fds[i] = my_fds[i];
      i = i + 1;
    }
    fds[i] = -1;
  } else {
    if (fds_size >= 1) {
      fds[0] = -1; //This input module needs no fds to monitor
    }
    gettimeofday(&tv, NULL);
    res->start_time = tv.tv_usec + tv.tv_sec * 1000000ULL;
    res->first_ts = 0;
    res->id = 0; //(res->start_time / res->interframe) % INT_MAX; //TODO: verify 32/64 bit

    if(initial_id == -1) {
      res->id = (res->start_time / res->interframe) % INT_MAX; //TODO: verify 32/64 bit
    } else {
      res->id = initial_id;
    }

    fprintf(stderr,"Initial Chunk Id %d\n", res->id);
  }

  return res;
}
Ejemplo n.º 6
0
/**
 * Simple data fetcher.
 * @param url path or url of data to fetch.
 * @return data fetched, or NULL on error. Must be freed with g_free.
 */
static char *
lastfm_get(const char *url, GMutex *mutex, GCond *cond)
{
	struct input_stream *input_stream;
	GError *error = NULL;
	char buffer[4096];
	size_t length = 0, nbytes;

	input_stream = input_stream_open(url, mutex, cond, &error);
	if (input_stream == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	g_mutex_lock(mutex);

	input_stream_wait_ready(input_stream);

	do {
		nbytes = input_stream_read(input_stream, buffer + length,
					   sizeof(buffer) - length, &error);
		if (nbytes == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}

			if (input_stream_eof(input_stream))
				break;

			/* I/O error */
			g_mutex_unlock(mutex);
			input_stream_close(input_stream);
			return NULL;
		}

		length += nbytes;
	} while (length < sizeof(buffer));

	g_mutex_unlock(mutex);

	input_stream_close(input_stream);
	return g_strndup(buffer, length);
}
Ejemplo n.º 7
0
static bool
wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc,
		 struct wavpack_input *wpi)
{
	char *utf8url;
	char *wvc_url = NULL;
	bool ret;
	char first_byte;
	size_t nbytes;

	/*
	 * As we use dc->utf8url, this function will be bad for
	 * single files. utf8url is not absolute file path :/
	 */
	utf8url = decoder_get_uri(decoder);
	if (utf8url == NULL) {
		return false;
	}

	wvc_url = g_strconcat(utf8url, "c", NULL);
	g_free(utf8url);

	ret = input_stream_open(is_wvc, wvc_url);
	g_free(wvc_url);

	if (!ret) {
		return false;
	}

	/*
	 * And we try to buffer in order to get know
	 * about a possible 404 error.
	 */
	nbytes = decoder_read(
		decoder, is_wvc, &first_byte, sizeof(first_byte)
	);
	if (nbytes == 0) {
		input_stream_close(is_wvc);
		return false;
	}

	/* push it back */
	wavpack_input_init(wpi, decoder, is_wvc);
	wpi->last_byte = first_byte;
	return true;
}
Ejemplo n.º 8
0
/* this is primarily used for getting total time for tags */
static int mp3_total_file_time(const char *file)
{
	struct input_stream input_stream;
	struct mp3_data data;
	int ret;

	if (!input_stream_open(&input_stream, file))
		return -1;
	mp3_data_init(&data, NULL, &input_stream);
	if (!mp3_decode_first_frame(&data, NULL, NULL))
		ret = -1;
	else
		ret = data.total_time + 0.5;
	mp3_data_finish(&data);
	input_stream_close(&input_stream);

	return ret;
}
Ejemplo n.º 9
0
/**
 * Opens the input stream with input_stream_open(), and waits until
 * the stream gets ready.  If a decoder STOP command is received
 * during that, it cancels the operation (but does not close the
 * stream).
 *
 * Unlock the decoder before calling this function.
 *
 * @return an input_stream on success or if #DECODE_COMMAND_STOP is
 * received, NULL on error
 */
static struct input_stream *
decoder_input_stream_open(struct decoder_control *dc, const char *uri)
{
	GError *error = NULL;
	struct input_stream *is;

	is = input_stream_open(uri, dc->mutex, dc->cond, &error);
	if (is == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	/* wait for the input stream to become ready; its metadata
	   will be available then */

	decoder_lock(dc);

	input_stream_update(is);
	while (!is->ready &&
	       dc->command != DECODE_COMMAND_STOP) {
		decoder_wait(dc);

		input_stream_update(is);
	}

	if (!input_stream_check(is, &error)) {
		decoder_unlock(dc);

		g_warning("%s", error->message);
		g_error_free(error);

		return NULL;
	}

	decoder_unlock(dc);

	return is;
}
Ejemplo n.º 10
0
struct playlist_provider *
playlist_list_open_path(const char *path_fs)
{
	GError *error = NULL;
	const char *suffix;
	struct input_stream *is;
	struct playlist_provider *playlist;

	assert(path_fs != NULL);

	suffix = uri_get_suffix(path_fs);
	if (suffix == NULL || !playlist_suffix_supported(suffix))
		return NULL;

	is = input_stream_open(path_fs, &error);
	if (is == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}

		return NULL;
	}

	while (!is->ready) {
		int ret = input_stream_buffer(is, &error);
		if (ret < 0) {
			input_stream_close(is);
			g_warning("%s", error->message);
			g_error_free(error);
			return NULL;
		}
	}

	playlist = playlist_list_open_stream_suffix(is, suffix);
	if (playlist == NULL)
		input_stream_close(is);

	return playlist;
}
Ejemplo n.º 11
0
static struct input_stream *
wavpack_open_wvc(struct decoder *decoder, const char *uri,
		 struct wavpack_input *wpi)
{
	struct input_stream *is_wvc;
	char *wvc_url = NULL;
	char first_byte;
	size_t nbytes;

	/*
	 * As we use dc->utf8url, this function will be bad for
	 * single files. utf8url is not absolute file path :/
	 */
	if (uri == NULL)
		return false;

	wvc_url = g_strconcat(uri, "c", NULL);
	is_wvc = input_stream_open(wvc_url, NULL);
	g_free(wvc_url);

	if (is_wvc == NULL)
		return NULL;

	/*
	 * And we try to buffer in order to get know
	 * about a possible 404 error.
	 */
	nbytes = decoder_read(
		decoder, is_wvc, &first_byte, sizeof(first_byte)
	);
	if (nbytes == 0) {
		input_stream_close(is_wvc);
		return NULL;
	}

	/* push it back */
	wavpack_input_init(wpi, decoder, is_wvc);
	wpi->last_byte = first_byte;
	return is_wvc;
}
Ejemplo n.º 12
0
static enum playlist_result
playlist_open_remote_into_queue(const char *uri, struct playlist *dest)
{
	GError *error = NULL;
	struct playlist_provider *playlist;
	struct input_stream *is = NULL;
	enum playlist_result result;

	assert(uri_has_scheme(uri));

	playlist = playlist_list_open_uri(uri);
	if (playlist == NULL) {
		is = input_stream_open(uri, &error);
		if (is == NULL) {
			if (error != NULL) {
				g_warning("Failed to open %s: %s",
					  uri, error->message);
				g_error_free(error);
			}

			return PLAYLIST_RESULT_NO_SUCH_LIST;
		}

		playlist = playlist_list_open_stream(is, uri);
		if (playlist == NULL) {
			input_stream_close(is);
			return PLAYLIST_RESULT_NO_SUCH_LIST;
		}
	}

	result = playlist_load_into_queue(uri, playlist, dest);
	playlist_plugin_close(playlist);

	if (is != NULL)
		input_stream_close(is);

	return result;
}
Ejemplo n.º 13
0
bool
song_file_update(struct song *song)
{
	const char *suffix;
	char *path_fs;
	const struct decoder_plugin *plugin;
	struct stat st;
	struct input_stream *is = NULL;

	assert(song_is_file(song));

	/* check if there's a suffix and a plugin */

	suffix = uri_get_suffix(song->uri);
	if (suffix == NULL)
		return false;

	plugin = decoder_plugin_from_suffix(suffix, NULL);
	if (plugin == NULL)
		return false;

	path_fs = map_song_fs(song);
	if (path_fs == NULL)
		return false;

	if (song->tag != NULL) {
		tag_free(song->tag);
		song->tag = NULL;
	}

	if (stat(path_fs, &st) < 0 || !S_ISREG(st.st_mode)) {
		g_free(path_fs);
		return false;
	}

	song->mtime = st.st_mtime;

	do {
		/* load file tag */
		song->tag = decoder_plugin_tag_dup(plugin, path_fs);
		if (song->tag != NULL)
			break;

		/* fall back to stream tag */
		if (plugin->stream_tag != NULL) {
			/* open the input_stream (if not already
			   open) */
			if (is == NULL)
				is = input_stream_open(path_fs, NULL);

			/* now try the stream_tag() method */
			if (is != NULL) {
				song->tag = decoder_plugin_stream_tag(plugin,
								      is);
				if (song->tag != NULL)
					break;

				input_stream_seek(is, 0, SEEK_SET, NULL);
			}
		}

		plugin = decoder_plugin_from_suffix(suffix, plugin);
	} while (plugin != NULL);

	if (is != NULL)
		input_stream_close(is);

	if (song->tag != NULL && tag_is_empty(song->tag))
		song->tag = tag_fallback(path_fs, song->tag);

	g_free(path_fs);
	return song->tag != NULL;
}
Ejemplo n.º 14
0
static struct playlist_provider *
lastfm_open_uri(const char *uri, GMutex *mutex, GCond *cond)
{
	struct lastfm_playlist *playlist;
	GError *error = NULL;
	char *p, *q, *response, *session;

	/* handshake */

	p = g_strconcat("http://ws.audioscrobbler.com/radio/handshake.php?"
			"version=1.1.1&platform=linux&"
			"username="******"&"
			"passwordmd5=", lastfm_config.md5, "&"
			"debug=0&partner=", NULL);
	response = lastfm_get(p, mutex, cond);
	g_free(p);
	if (response == NULL)
		return NULL;

	/* extract session id from response */

	session = lastfm_find(response, "session");
	g_free(response);
	if (session == NULL) {
		g_warning("last.fm handshake failed");
		return NULL;
	}

	q = g_uri_escape_string(session, NULL, false);
	g_free(session);
	session = q;

	g_debug("session='%s'", session);

	/* "adjust" last.fm radio */

	if (strlen(uri) > 9) {
		char *escaped_uri;

		escaped_uri = g_uri_escape_string(uri, NULL, false);

		p = g_strconcat("http://ws.audioscrobbler.com/radio/adjust.php?"
				"session=", session, "&url=", escaped_uri, "&debug=0",
				NULL);
		g_free(escaped_uri);

		response = lastfm_get(p, mutex, cond);
		g_free(response);
		g_free(p);

		if (response == NULL) {
			g_free(session);
			return NULL;
		}
	}

	/* create the playlist object */

	playlist = g_new(struct lastfm_playlist, 1);
	playlist_provider_init(&playlist->base, &lastfm_playlist_plugin);

	/* open the last.fm playlist */

	p = g_strconcat("http://ws.audioscrobbler.com/radio/xspf.php?"
			"sk=", session, "&discovery=0&desktop=1.5.1.31879",
			NULL);
	g_free(session);

	playlist->is = input_stream_open(p, mutex, cond, &error);
	g_free(p);

	if (playlist->is == NULL) {
		if (error != NULL) {
			g_warning("Failed to load XSPF playlist: %s",
				  error->message);
			g_error_free(error);
		} else
			g_warning("Failed to load XSPF playlist");
		g_free(playlist);
		return NULL;
	}

	g_mutex_lock(mutex);

	input_stream_wait_ready(playlist->is);

	/* last.fm does not send a MIME type, we have to fake it here
	   :-( */
	g_free(playlist->is->mime);
	playlist->is->mime = g_strdup("application/xspf+xml");

	g_mutex_unlock(mutex);

	/* parse the XSPF playlist */

	playlist->xspf = playlist_list_open_stream(playlist->is, NULL);
	if (playlist->xspf == NULL) {
		input_stream_close(playlist->is);
		g_free(playlist);
		g_warning("Failed to parse XSPF playlist");
		return NULL;
	}

	return &playlist->base;
}
Ejemplo n.º 15
0
int main(int argc, char **argv)
{
	GError *error = NULL;
	const char *decoder_name, *path;
	const struct decoder_plugin *plugin;
	struct tag *tag;
	bool empty;

#ifdef HAVE_LOCALE_H
	/* initialize locale */
	setlocale(LC_CTYPE,"");
#endif

	if (argc != 3) {
		g_printerr("Usage: read_tags DECODER FILE\n");
		return 1;
	}

	decoder_name = argv[1];
	path = argv[2];

	tag_pool_init();

	if (!input_stream_global_init(&error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return 2;
	}

	decoder_plugin_init_all();

	plugin = decoder_plugin_from_name(decoder_name);
	if (plugin == NULL) {
		g_printerr("No such decoder: %s\n", decoder_name);
		return 1;
	}

	tag = decoder_plugin_tag_dup(plugin, path);
	if (tag == NULL && plugin->stream_tag != NULL) {
		struct input_stream *is = input_stream_open(path, &error);

		if (is == NULL) {
			g_printerr("Failed to open %s: %s\n",
				   path, error->message);
			g_error_free(error);
			return 1;
		}

		tag = decoder_plugin_stream_tag(plugin, is);
		input_stream_close(is);
	}

	decoder_plugin_deinit_all();
	input_stream_global_finish();
	if (tag == NULL) {
		g_printerr("Failed to read tags\n");
		return 1;
	}

	print_tag(tag);

	empty = tag_is_empty(tag);
	tag_free(tag);

	if (empty) {
		tag = tag_ape_load(path);
		if (tag == NULL)
			tag = tag_id3_load(path);
		if (tag != NULL) {
			print_tag(tag);
			tag_free(tag);
		}
	}

	tag_pool_deinit();

	return 0;
}
Ejemplo n.º 16
0
bool
song_file_update(struct song *song)
{
    const char *suffix;
    char *path_fs;
    const struct decoder_plugin *plugin;
    struct stat st;
    struct input_stream *is = NULL;

    assert(song_is_file(song));

    /* check if there's a suffix and a plugin */

    suffix = uri_get_suffix(song->uri);
    if (suffix == NULL)
        return false;

    plugin = decoder_plugin_from_suffix(suffix, NULL);
    if (plugin == NULL)
        return false;

    path_fs = map_song_fs(song);
    if (path_fs == NULL)
        return false;

    if (song->tag != NULL) {
        tag_free(song->tag);
        song->tag = NULL;
    }

    if (stat(path_fs, &st) < 0 || !S_ISREG(st.st_mode)) {
        g_free(path_fs);
        return false;
    }

    song->mtime = st.st_mtime;

    GMutex *mutex = NULL;
    GCond *cond;
#if !GCC_CHECK_VERSION(4, 2)
    /* work around "may be used uninitialized in this function"
       false positive */
    cond = NULL;
#endif

    do {
        /* load file tag */
        song->tag = tag_new();
        if (decoder_plugin_scan_file(plugin, path_fs,
                                     &full_tag_handler, song->tag))
            break;

        tag_free(song->tag);
        song->tag = NULL;

        /* fall back to stream tag */
        if (plugin->scan_stream != NULL) {
            /* open the input_stream (if not already
               open) */
            if (is == NULL) {
                mutex = g_mutex_new();
                cond = g_cond_new();
                is = input_stream_open(path_fs, mutex, cond,
                                       NULL);
            }

            /* now try the stream_tag() method */
            if (is != NULL) {
                song->tag = tag_new();
                if (decoder_plugin_scan_stream(plugin, is,
                                               &full_tag_handler,
                                               song->tag))
                    break;

                tag_free(song->tag);
                song->tag = NULL;

                input_stream_lock_seek(is, 0, SEEK_SET, NULL);
            }
        }

        plugin = decoder_plugin_from_suffix(suffix, plugin);
    } while (plugin != NULL);

    if (is != NULL)
        input_stream_close(is);

    if (mutex != NULL) {
        g_cond_free(cond);
        g_mutex_free(mutex);
    }

    if (song->tag != NULL && tag_is_empty(song->tag))
        tag_scan_fallback(path_fs, &full_tag_handler, song->tag);

    g_free(path_fs);
    return song->tag != NULL;
}
Ejemplo n.º 17
0
int main(int argc, char **argv)
{
	GError *error = NULL;
	const char *decoder_name;
	struct decoder decoder;

	if (argc != 3) {
		g_printerr("Usage: run_decoder DECODER URI >OUT\n");
		return 1;
	}

	decoder_name = argv[1];
	decoder.uri = argv[2];

	g_log_set_default_handler(my_log_func, NULL);

	tag_pool_init();

	if (!input_stream_global_init(&error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return 2;
	}

	decoder_plugin_init_all();

	decoder.plugin = decoder_plugin_from_name(decoder_name);
	if (decoder.plugin == NULL) {
		g_printerr("No such decoder: %s\n", decoder_name);
		return 1;
	}

	decoder.initialized = false;

	if (decoder.plugin->file_decode != NULL) {
		decoder_plugin_file_decode(decoder.plugin, &decoder,
					   decoder.uri);
	} else if (decoder.plugin->stream_decode != NULL) {
		struct input_stream *is =
			input_stream_open(decoder.uri, &error);
		if (is == NULL) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			} else
				g_printerr("input_stream_open() failed\n");

			return 1;
		}

		decoder_plugin_stream_decode(decoder.plugin, &decoder, is);

		input_stream_close(is);
	} else {
		g_printerr("Decoder plugin is not usable\n");
		return 1;
	}

	decoder_plugin_deinit_all();
	input_stream_global_finish();

	if (!decoder.initialized) {
		g_printerr("Decoding failed\n");
		return 1;
	}

	tag_pool_deinit();

	return 0;
}
Ejemplo n.º 18
0
int main(int argc, char **argv)
{
	const char *uri;
	struct input_stream *is = NULL;
	bool success;
	GError *error = NULL;
	struct playlist_provider *playlist;
	struct song *song;

	if (argc != 3) {
		g_printerr("Usage: dump_playlist CONFIG URI\n");
		return 1;
	}

	uri = argv[2];

	/* initialize GLib */

	g_thread_init(NULL);
	g_log_set_default_handler(my_log_func, NULL);

	/* initialize MPD */

	config_global_init();
	success = config_read_file(argv[1], &error);
	if (!success) {
		g_printerr("%s\n", error->message);
		g_error_free(error);
		return 1;
	}

	io_thread_init();
	if (!io_thread_start(&error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return EXIT_FAILURE;
	}

	if (!input_stream_global_init(&error)) {
		g_warning("%s", error->message);
		g_error_free(error);
		return 2;
	}

	playlist_list_global_init();
	decoder_plugin_init_all();

	/* open the playlist */

	GMutex *mutex = g_mutex_new();
	GCond *cond = g_cond_new();

	playlist = playlist_list_open_uri(uri, mutex, cond);
	if (playlist == NULL) {
		/* open the stream and wait until it becomes ready */

		is = input_stream_open(uri, mutex, cond, &error);
		if (is == NULL) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			} else
				g_printerr("input_stream_open() failed\n");
			return 2;
		}

		input_stream_lock_wait_ready(is);

		/* open the playlist */

		playlist = playlist_list_open_stream(is, uri);
		if (playlist == NULL) {
			input_stream_close(is);
			g_printerr("Failed to open playlist\n");
			return 2;
		}
	}

	/* dump the playlist */

	while ((song = playlist_plugin_read(playlist)) != NULL) {
		g_print("%s\n", song->uri);

		if (song->end_ms > 0)
			g_print("range: %u:%02u..%u:%02u\n",
				song->start_ms / 60000,
				(song->start_ms / 1000) % 60,
				song->end_ms / 60000,
				(song->end_ms / 1000) % 60);
		else if (song->start_ms > 0)
			g_print("range: %u:%02u..\n",
				song->start_ms / 60000,
				(song->start_ms / 1000) % 60);

		if (song->tag != NULL)
			tag_save(stdout, song->tag);

		song_free(song);
	}

	/* deinitialize everything */

	playlist_plugin_close(playlist);
	if (is != NULL)
		input_stream_close(is);

	g_cond_free(cond);
	g_mutex_free(mutex);

	decoder_plugin_deinit_all();
	playlist_list_global_finish();
	input_stream_global_finish();
	io_thread_deinit();
	config_global_finish();

	return 0;
}
Ejemplo n.º 19
-1
/**
 * Read JSON data and parse it using the given YAJL parser.
 * @param url URL of the JSON data.
 * @param hand YAJL parser handle.
 * @return -1 on error, 0 on success.
 */
static int
soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* cond)
{
	struct input_stream *input_stream;
	GError *error = NULL;
	char buffer[4096];
	unsigned char *ubuffer = (unsigned char *)buffer;
	size_t nbytes;

	input_stream = input_stream_open(url, mutex, cond, &error);
	if (input_stream == NULL) {
		if (error != NULL) {
			g_warning("%s", error->message);
			g_error_free(error);
		}
		return -1;
	}

	g_mutex_lock(mutex);
	input_stream_wait_ready(input_stream);

	yajl_status stat;
	int done = 0;

	while (!done) {
		nbytes = input_stream_read(input_stream, buffer, sizeof(buffer), &error);
		if (nbytes == 0) {
			if (error != NULL) {
				g_warning("%s", error->message);
				g_error_free(error);
			}
			if (input_stream_eof(input_stream)) {
				done = true;
			} else {
				g_mutex_unlock(mutex);
				input_stream_close(input_stream);
				return -1;
			}
		}

		if (done)
			stat = yajl_parse_complete(hand);
		else
			stat = yajl_parse(hand, ubuffer, nbytes);

		if (stat != yajl_status_ok &&
			stat != yajl_status_insufficient_data)
		{
			unsigned char *str = yajl_get_error(hand, 1, ubuffer, nbytes);
			g_warning("%s", str);
			yajl_free_error(hand, str);
			break;
		}
	}

	g_mutex_unlock(mutex);
	input_stream_close(input_stream);

	return 0;
}