From d3b763a48c09a60a0c0b5ccb6cccd9376875c470 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Dec 2009 23:27:37 +0100 Subject: input_stream: return allocated input_stream objects Major API redesign: don't let the caller allocate the input_stream object. Let each input plugin allocate its own (derived/extended) input_stream pointer. The "data" attribute can now be removed, and all input plugins simply cast the input_stream pointer to their own structure (with an "struct input_stream base" as the first attribute). --- src/archive/bz2_archive_plugin.c | 35 +++++++------ src/archive/iso9660_archive_plugin.c | 27 +++++----- src/archive/zzip_archive_plugin.c | 29 +++++------ src/archive_plugin.c | 6 +-- src/archive_plugin.h | 9 ++-- src/decoder/wavpack_plugin.c | 27 +++++----- src/decoder_thread.c | 42 +++++++-------- src/input/archive_input_plugin.c | 19 ++++--- src/input/curl_input_plugin.c | 97 +++++++++++++++++------------------ src/input/file_input_plugin.c | 44 +++++++++------- src/input/mms_input_plugin.c | 27 +++++----- src/input/rewind_input_plugin.c | 77 +++++++++++++-------------- src/input/rewind_input_plugin.h | 6 +-- src/input_plugin.h | 3 +- src/input_stream.c | 24 ++++----- src/input_stream.h | 27 +++++----- src/playlist/lastfm_playlist_plugin.c | 44 ++++++++-------- src/playlist_list.c | 6 ++- src/playlist_list.h | 4 +- src/playlist_queue.c | 21 ++++---- src/song_update.c | 17 +++--- test/dump_playlist.c | 21 ++++---- test/read_tags.c | 8 +-- test/run_decoder.c | 12 ++--- test/run_input.c | 9 ++-- 25 files changed, 315 insertions(+), 326 deletions(-) diff --git a/src/archive/bz2_archive_plugin.c b/src/archive/bz2_archive_plugin.c index 07d174403..75b4b1ece 100644 --- a/src/archive/bz2_archive_plugin.c +++ b/src/archive/bz2_archive_plugin.c @@ -45,10 +45,12 @@ struct bz2_archive_file { char *name; bool reset; - struct input_stream istream; + struct input_stream *istream; }; struct bz2_input_stream { + struct input_stream base; + struct bz2_archive_file *archive; bool eof; @@ -111,7 +113,8 @@ bz2_open(const char *pathname, GError **error_r) refcount_init(&context->ref); //open archive - if (!input_stream_open(&context->istream, pathname, error_r)) { + context->istream = input_stream_open(pathname, error_r); + if (context->istream == NULL) { g_free(context); return NULL; } @@ -158,44 +161,42 @@ bz2_close(struct archive_file *file) g_free(context->name); - input_stream_close(&context->istream); + input_stream_close(context->istream); g_free(context); } /* single archive handling */ -static bool -bz2_open_stream(struct archive_file *file, struct input_stream *is, +static struct input_stream * +bz2_open_stream(struct archive_file *file, G_GNUC_UNUSED const char *path, GError **error_r) { struct bz2_archive_file *context = (struct bz2_archive_file *) file; struct bz2_input_stream *bis = g_new(struct bz2_input_stream, 1); + input_stream_init(&bis->base, &bz2_inputplugin); + bis->archive = context; - //setup file ops - is->plugin = &bz2_inputplugin; - //insert back reference - is->data = bis; - is->ready = true; - is->seekable = false; + bis->base.ready = true; + bis->base.seekable = false; if (!bz2_alloc(bis, error_r)) { g_free(bis); - return false; + return NULL; } bis->eof = false; refcount_inc(&context->ref); - return true; + return &bis->base; } static void bz2_is_close(struct input_stream *is) { - struct bz2_input_stream *bis = (struct bz2_input_stream *)is->data; + struct bz2_input_stream *bis = (struct bz2_input_stream *)is; bz2_destroy(bis); @@ -215,7 +216,7 @@ bz2_fillbuffer(struct bz2_input_stream *bis, GError **error_r) if (bzstream->avail_in > 0) return true; - count = input_stream_read(&bis->archive->istream, + count = input_stream_read(bis->archive->istream, bis->buffer, sizeof(bis->buffer), error_r); if (count == 0) @@ -230,7 +231,7 @@ static size_t bz2_is_read(struct input_stream *is, void *ptr, size_t length, GError **error_r) { - struct bz2_input_stream *bis = (struct bz2_input_stream *)is->data; + struct bz2_input_stream *bis = (struct bz2_input_stream *)is; bz_stream *bzstream; int bz_result; size_t nbytes = 0; @@ -269,7 +270,7 @@ bz2_is_read(struct input_stream *is, void *ptr, size_t length, static bool bz2_is_eof(struct input_stream *is) { - struct bz2_input_stream *bis = (struct bz2_input_stream *)is->data; + struct bz2_input_stream *bis = (struct bz2_input_stream *)is; return bis->eof; } diff --git a/src/archive/iso9660_archive_plugin.c b/src/archive/iso9660_archive_plugin.c index f6c6ed5f2..38003da94 100644 --- a/src/archive/iso9660_archive_plugin.c +++ b/src/archive/iso9660_archive_plugin.c @@ -163,14 +163,16 @@ iso9660_archive_close(struct archive_file *file) /* single archive handling */ struct iso9660_input_stream { + struct input_stream base; + struct iso9660_archive_file *archive; iso9660_stat_t *statbuf; size_t max_blocks; }; -static bool -iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is, +static struct input_stream * +iso9660_archive_open_stream(struct archive_file *file, const char *pathname, GError **error_r) { struct iso9660_archive_file *context = @@ -178,6 +180,7 @@ iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is, struct iso9660_input_stream *iis; iis = g_new(struct iso9660_input_stream, 1); + input_stream_init(&iis->base, &iso9660_input_plugin); iis->archive = context; iis->statbuf = iso9660_ifs_stat_translate(context->iso, pathname); @@ -185,31 +188,26 @@ iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is, g_free(iis); g_set_error(error_r, iso9660_quark(), 0, "not found in the ISO file: %s", pathname); - return false; + return NULL; } - //setup file ops - is->plugin = &iso9660_input_plugin; - //insert back reference - is->data = iis; - is->ready = true; + iis->base.ready = true; //we are not seekable - is->seekable = false; + iis->base.seekable = false; - is->size = iis->statbuf->size; + iis->base.size = iis->statbuf->size; iis->max_blocks = CEILING(iis->statbuf->size, ISO_BLOCKSIZE); refcount_inc(&context->ref); - return true; + return &iis->base; } static void iso9660_input_close(struct input_stream *is) { - struct iso9660_input_stream *iis = - (struct iso9660_input_stream *)is->data; + struct iso9660_input_stream *iis = (struct iso9660_input_stream *)is; g_free(iis->statbuf); @@ -220,8 +218,7 @@ iso9660_input_close(struct input_stream *is) static size_t iso9660_input_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - struct iso9660_input_stream *iis = - (struct iso9660_input_stream *)is->data; + struct iso9660_input_stream *iis = (struct iso9660_input_stream *)is; int toread, readed = 0; int no_blocks, cur_block; size_t left_bytes = iis->statbuf->size - is->offset; diff --git a/src/archive/zzip_archive_plugin.c b/src/archive/zzip_archive_plugin.c index 3e0c063c2..7e59a0935 100644 --- a/src/archive/zzip_archive_plugin.c +++ b/src/archive/zzip_archive_plugin.c @@ -125,13 +125,15 @@ zzip_archive_close(struct archive_file *file) /* single archive handling */ struct zzip_input_stream { + struct input_stream base; + struct zzip_archive *archive; ZZIP_FILE *file; }; -static bool -zzip_archive_open_stream(struct archive_file *file, struct input_stream *is, +static struct input_stream * +zzip_archive_open_stream(struct archive_file *file, const char *pathname, GError **error_r) { struct zzip_archive *context = (struct zzip_archive *) file; @@ -139,6 +141,7 @@ zzip_archive_open_stream(struct archive_file *file, struct input_stream *is, ZZIP_STAT z_stat; zis = g_new(struct zzip_input_stream, 1); + input_stream_init(&zis->base, &zzip_input_plugin); zis->archive = context; zis->file = zzip_file_open(context->dir, pathname, 0); @@ -146,29 +149,25 @@ zzip_archive_open_stream(struct archive_file *file, struct input_stream *is, g_free(zis); g_set_error(error_r, zzip_quark(), 0, "not found in the ZIP file: %s", pathname); - return false; + return NULL; } - //setup file ops - is->plugin = &zzip_input_plugin; - //insert back reference - is->data = zis; - is->ready = true; + zis->base.ready = true; //we are seekable (but its not recommendent to do so) - is->seekable = true; + zis->base.seekable = true; zzip_file_stat(zis->file, &z_stat); - is->size = z_stat.st_size; + zis->base.size = z_stat.st_size; refcount_inc(&context->ref); - return true; + return &zis->base; } static void zzip_input_close(struct input_stream *is) { - struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data; + struct zzip_input_stream *zis = (struct zzip_input_stream *)is; zzip_file_close(zis->file); zzip_archive_close(&zis->archive->base); @@ -179,7 +178,7 @@ static size_t zzip_input_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data; + struct zzip_input_stream *zis = (struct zzip_input_stream *)is; int ret; ret = zzip_file_read(zis->file, ptr, size); @@ -197,7 +196,7 @@ zzip_input_read(struct input_stream *is, void *ptr, size_t size, static bool zzip_input_eof(struct input_stream *is) { - struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data; + struct zzip_input_stream *zis = (struct zzip_input_stream *)is; return (goffset)zzip_tell(zis->file) == is->size; } @@ -206,7 +205,7 @@ static bool zzip_input_seek(struct input_stream *is, goffset offset, int whence, GError **error_r) { - struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data; + struct zzip_input_stream *zis = (struct zzip_input_stream *)is; zzip_off_t ofs = zzip_seek(zis->file, offset, whence); if (ofs != -1) { g_set_error(error_r, zzip_quark(), ofs, diff --git a/src/archive_plugin.c b/src/archive_plugin.c index b43293e75..60da4d283 100644 --- a/src/archive_plugin.c +++ b/src/archive_plugin.c @@ -80,13 +80,13 @@ archive_file_scan_next(struct archive_file *file) return file->plugin->scan_next(file); } -bool -archive_file_open_stream(struct archive_file *file, struct input_stream *is, +struct input_stream * +archive_file_open_stream(struct archive_file *file, const char *path, GError **error_r) { assert(file != NULL); assert(file->plugin != NULL); assert(file->plugin->open_stream != NULL); - return file->plugin->open_stream(file, is, path, error_r); + return file->plugin->open_stream(file, path, error_r); } diff --git a/src/archive_plugin.h b/src/archive_plugin.h index 254c81f66..b08c93389 100644 --- a/src/archive_plugin.h +++ b/src/archive_plugin.h @@ -71,8 +71,9 @@ struct archive_plugin { * @param error_r location to store the error occuring, or * NULL to ignore errors */ - bool (*open_stream)(struct archive_file *, struct input_stream *is, - const char *path, GError **error_r); + struct input_stream *(*open_stream)(struct archive_file *af, + const char *path, + GError **error_r); /** * closes archive file. @@ -99,8 +100,8 @@ archive_file_scan_reset(struct archive_file *file); char * archive_file_scan_next(struct archive_file *file); -bool -archive_file_open_stream(struct archive_file *file, struct input_stream *is, +struct input_stream * +archive_file_open_stream(struct archive_file *file, const char *path, GError **error_r); #endif diff --git a/src/decoder/wavpack_plugin.c b/src/decoder/wavpack_plugin.c index 3eb2b0e68..1615d70d0 100644 --- a/src/decoder/wavpack_plugin.c +++ b/src/decoder/wavpack_plugin.c @@ -464,13 +464,12 @@ wavpack_input_init(struct wavpack_input *isp, struct decoder *decoder, isp->last_byte = EOF; } -static bool -wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc, - struct wavpack_input *wpi) +static struct input_stream * +wavpack_open_wvc(struct decoder *decoder, struct wavpack_input *wpi) { + struct input_stream *is_wvc; char *utf8url; char *wvc_url = NULL; - bool ret; char first_byte; size_t nbytes; @@ -486,12 +485,11 @@ wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc, wvc_url = g_strconcat(utf8url, "c", NULL); g_free(utf8url); - ret = input_stream_open(is_wvc, wvc_url, NULL); + is_wvc = input_stream_open(wvc_url, NULL); g_free(wvc_url); - if (!ret) { - return false; - } + if (is_wvc == NULL) + return NULL; /* * And we try to buffer in order to get know @@ -502,13 +500,13 @@ wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc, ); if (nbytes == 0) { input_stream_close(is_wvc); - return false; + return NULL; } /* push it back */ wavpack_input_init(wpi, decoder, is_wvc); wpi->last_byte = first_byte; - return true; + return is_wvc; } /* @@ -519,14 +517,15 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is) { char error[ERRORLEN]; WavpackContext *wpc; - struct input_stream is_wvc; + struct input_stream *is_wvc; int open_flags = OPEN_NORMALIZE; struct wavpack_input isp, isp_wvc; bool can_seek = is->seekable; - if (wavpack_open_wvc(decoder, &is_wvc, &isp_wvc)) { + is_wvc = wavpack_open_wvc(decoder, &isp_wvc); + if (is_wvc != NULL) { open_flags |= OPEN_WVC; - can_seek &= is_wvc.seekable; + can_seek &= is_wvc->seekable; } if (!can_seek) { @@ -549,7 +548,7 @@ wavpack_streamdecode(struct decoder * decoder, struct input_stream *is) WavpackCloseFile(wpc); if (open_flags & OPEN_WVC) { - input_stream_close(&is_wvc); + input_stream_close(is_wvc); } } diff --git a/src/decoder_thread.c b/src/decoder_thread.c index 7e9c820d2..de095216a 100644 --- a/src/decoder_thread.c +++ b/src/decoder_thread.c @@ -56,22 +56,23 @@ decoder_lock_get_command(struct decoder_control *dc) * * Unlock the decoder before calling this function. * - * @return true on success of if #DECODE_COMMAND_STOP is received, - * false on error + * @return an input_stream on success or if #DECODE_COMMAND_STOP is + * received, NULL on error */ -static bool -decoder_input_stream_open(struct decoder_control *dc, - struct input_stream *is, const char *uri) +static struct input_stream * +decoder_input_stream_open(struct decoder_control *dc, const char *uri) { GError *error = NULL; + struct input_stream *is; - if (!input_stream_open(is, uri, &error)) { + is = input_stream_open(uri, &error); + if (is == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } - return false; + return NULL; } /* wait for the input stream to become ready; its metadata @@ -86,11 +87,11 @@ decoder_input_stream_open(struct decoder_control *dc, input_stream_close(is); g_warning("%s", error->message); g_error_free(error); - return false; + return NULL; } } - return true; + return is; } static bool @@ -215,12 +216,13 @@ static bool decoder_run_stream(struct decoder *decoder, const char *uri) { struct decoder_control *dc = decoder->dc; - struct input_stream input_stream; + struct input_stream *input_stream; bool success; decoder_unlock(dc); - if (!decoder_input_stream_open(dc, &input_stream, uri)) { + input_stream = decoder_input_stream_open(dc, uri); + if (input_stream == NULL) { decoder_lock(dc); return false; } @@ -229,15 +231,15 @@ decoder_run_stream(struct decoder *decoder, const char *uri) success = dc->command == DECODE_COMMAND_STOP || /* first we try mime types: */ - decoder_run_stream_mime_type(decoder, &input_stream) || + decoder_run_stream_mime_type(decoder, input_stream) || /* if that fails, try suffix matching the URL: */ - decoder_run_stream_suffix(decoder, &input_stream, uri) || + decoder_run_stream_suffix(decoder, input_stream, uri) || /* fallback to mp3: this is needed for bastard streams that don't have a suffix or set the mimeType */ - decoder_run_stream_fallback(decoder, &input_stream); + decoder_run_stream_fallback(decoder, input_stream); decoder_unlock(dc); - input_stream_close(&input_stream); + input_stream_close(input_stream); decoder_lock(dc); return success; @@ -267,21 +269,21 @@ decoder_run_file(struct decoder *decoder, const char *path_fs) decoder_unlock(dc); } else if (plugin->stream_decode != NULL) { - struct input_stream input_stream; + struct input_stream *input_stream; bool success; - if (!decoder_input_stream_open(dc, &input_stream, - path_fs)) + input_stream = decoder_input_stream_open(dc, path_fs); + if (input_stream == NULL) continue; decoder_lock(dc); success = decoder_stream_decode(plugin, decoder, - &input_stream); + input_stream); decoder_unlock(dc); - input_stream_close(&input_stream); + input_stream_close(input_stream); if (success) { decoder_lock(dc); diff --git a/src/input/archive_input_plugin.c b/src/input/archive_input_plugin.c index 9e3e79692..97e4836ff 100644 --- a/src/input/archive_input_plugin.c +++ b/src/input/archive_input_plugin.c @@ -33,24 +33,23 @@ * parent_stream so tar plugin fetches file data from gzip * plugin and gzip fetches file from disk */ -static bool -input_archive_open(struct input_stream *is, const char *pathname, - GError **error_r) +static struct input_stream * +input_archive_open(const char *pathname, GError **error_r) { const struct archive_plugin *arplug; struct archive_file *file; char *archive, *filename, *suffix, *pname; - bool opened; + struct input_stream *is; if (!g_path_is_absolute(pathname)) - return false; + return NULL; pname = g_strdup(pathname); // archive_lookup will modify pname when true is returned if (!archive_lookup(pname, &archive, &filename, &suffix)) { g_debug("not an archive, lookup %s failed\n", pname); g_free(pname); - return false; + return NULL; } //check which archive plugin to use (by ext) @@ -58,19 +57,19 @@ input_archive_open(struct input_stream *is, const char *pathname, if (!arplug) { g_warning("can't handle archive %s\n",archive); g_free(pname); - return false; + return NULL; } file = archive_file_open(arplug, archive, error_r); if (file == NULL) - return false; + return NULL; //setup fileops - opened = archive_file_open_stream(file, is, filename, error_r); + is = archive_file_open_stream(file, filename, error_r); archive_file_close(file); g_free(pname); - return opened; + return is; } const struct input_plugin input_plugin_archive = { diff --git a/src/input/curl_input_plugin.c b/src/input/curl_input_plugin.c index 53f2e0404..c54d994e8 100644 --- a/src/input/curl_input_plugin.c +++ b/src/input/curl_input_plugin.c @@ -57,6 +57,8 @@ struct buffer { }; struct input_curl { + struct input_stream base; + /* some buffers which were passed to libcurl, which we have too free */ char *url, *range; @@ -179,10 +181,8 @@ input_curl_easy_free(struct input_curl *c) * Frees this stream (but not the input_stream struct itself). */ static void -input_curl_free(struct input_stream *is) +input_curl_free(struct input_curl *c) { - struct input_curl *c = is->data; - if (c->tag != NULL) tag_free(c->tag); g_free(c->meta_name); @@ -201,7 +201,7 @@ input_curl_free(struct input_stream *is) static struct tag * input_curl_tag(struct input_stream *is) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; struct tag *tag = c->tag; c->tag = NULL; @@ -209,9 +209,8 @@ input_curl_tag(struct input_stream *is) } static bool -input_curl_multi_info_read(struct input_stream *is, GError **error_r) +input_curl_multi_info_read(struct input_curl *c, GError **error_r) { - struct input_curl *c = is->data; CURLMsg *msg; int msgs_in_queue; @@ -219,7 +218,7 @@ input_curl_multi_info_read(struct input_stream *is, GError **error_r) &msgs_in_queue)) != NULL) { if (msg->msg == CURLMSG_DONE) { c->eof = true; - is->ready = true; + c->base.ready = true; if (msg->data.result != CURLE_OK) { g_set_error(error_r, curl_quark(), @@ -279,7 +278,7 @@ input_curl_select(struct input_curl *c, GError **error_r) static bool fill_buffer(struct input_stream *is, GError **error_r) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; CURLMcode mcode = CURLM_CALL_MULTI_PERFORM; while (!c->eof && g_queue_is_empty(c->buffers)) { @@ -305,7 +304,7 @@ fill_buffer(struct input_stream *is, GError **error_r) return false; } - bret = input_curl_multi_info_read(is, error_r); + bret = input_curl_multi_info_read(c, error_r); if (!bret) return false; } @@ -407,7 +406,7 @@ static size_t input_curl_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; bool success; size_t nbytes = 0; char *dest = ptr; @@ -441,13 +440,15 @@ input_curl_read(struct input_stream *is, void *ptr, size_t size, static void input_curl_close(struct input_stream *is) { - input_curl_free(is); + struct input_curl *c = (struct input_curl *)is; + + input_curl_free(c); } static bool input_curl_eof(G_GNUC_UNUSED struct input_stream *is) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; return c->eof && g_queue_is_empty(c->buffers); } @@ -455,7 +456,7 @@ input_curl_eof(G_GNUC_UNUSED struct input_stream *is) static int input_curl_buffer(struct input_stream *is, GError **error_r) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; CURLMcode mcode; int running_handles; bool ret; @@ -483,7 +484,7 @@ input_curl_buffer(struct input_stream *is, GError **error_r) return -1; } - ret = input_curl_multi_info_read(is, error_r); + ret = input_curl_multi_info_read(c, error_r); if (!ret) return -1; @@ -494,8 +495,7 @@ input_curl_buffer(struct input_stream *is, GError **error_r) static size_t input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) { - struct input_stream *is = stream; - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)stream; const char *header = ptr, *end, *value; char name[64]; @@ -524,7 +524,7 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) if (g_ascii_strcasecmp(name, "accept-ranges") == 0) { /* a stream with icy-metadata is not seekable */ if (!icy_defined(&c->icy_metadata)) - is->seekable = true; + c->base.seekable = true; } else if (g_ascii_strcasecmp(name, "content-length") == 0) { char buffer[64]; @@ -534,10 +534,10 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) memcpy(buffer, value, end - value); buffer[end - value] = 0; - is->size = is->offset + g_ascii_strtoull(buffer, NULL, 10); + c->base.size = c->base.offset + g_ascii_strtoull(buffer, NULL, 10); } else if (g_ascii_strcasecmp(name, "content-type") == 0) { - g_free(is->mime); - is->mime = g_strndup(value, end - value); + g_free(c->base.mime); + c->base.mime = g_strndup(value, end - value); } else if (g_ascii_strcasecmp(name, "icy-name") == 0 || g_ascii_strcasecmp(name, "ice-name") == 0 || g_ascii_strcasecmp(name, "x-audiocast-name") == 0) { @@ -568,7 +568,7 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) /* a stream with icy-metadata is not seekable */ - is->seekable = false; + c->base.seekable = false; } } @@ -579,8 +579,7 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) static size_t input_curl_writefunction(void *ptr, size_t size, size_t nmemb, void *stream) { - struct input_stream *is = stream; - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)stream; struct buffer *buffer; size *= nmemb; @@ -594,15 +593,14 @@ input_curl_writefunction(void *ptr, size_t size, size_t nmemb, void *stream) g_queue_push_tail(c->buffers, buffer); c->buffered = true; - is->ready = true; + c->base.ready = true; return size; } static bool -input_curl_easy_init(struct input_stream *is, GError **error_r) +input_curl_easy_init(struct input_curl *c, GError **error_r) { - struct input_curl *c = is->data; CURLcode code; CURLMcode mcode; @@ -627,10 +625,10 @@ input_curl_easy_init(struct input_stream *is, GError **error_r) "Music Player Daemon " VERSION); curl_easy_setopt(c->easy, CURLOPT_HEADERFUNCTION, input_curl_headerfunction); - curl_easy_setopt(c->easy, CURLOPT_WRITEHEADER, is); + curl_easy_setopt(c->easy, CURLOPT_WRITEHEADER, c); curl_easy_setopt(c->easy, CURLOPT_WRITEFUNCTION, input_curl_writefunction); - curl_easy_setopt(c->easy, CURLOPT_WRITEDATA, is); + curl_easy_setopt(c->easy, CURLOPT_WRITEDATA, c); curl_easy_setopt(c->easy, CURLOPT_HTTP200ALIASES, http_200_aliases); curl_easy_setopt(c->easy, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(c->easy, CURLOPT_MAXREDIRS, 5); @@ -669,9 +667,9 @@ input_curl_easy_init(struct input_stream *is, GError **error_r) void input_curl_reinit(struct input_stream *is) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; - assert(is->plugin == &input_plugin_curl); + assert(c->base.plugin == &input_plugin_curl); assert(c->easy != NULL); curl_easy_setopt(c->easy, CURLOPT_WRITEHEADER, is); @@ -702,7 +700,7 @@ static bool input_curl_seek(struct input_stream *is, goffset offset, int whence, GError **error_r) { - struct input_curl *c = is->data; + struct input_curl *c = (struct input_curl *)is; bool ret; assert(is->ready); @@ -774,7 +772,7 @@ input_curl_seek(struct input_stream *is, goffset offset, int whence, return true; } - ret = input_curl_easy_init(is, error_r); + ret = input_curl_easy_init(c, error_r); if (!ret) return false; @@ -789,55 +787,54 @@ input_curl_seek(struct input_stream *is, goffset offset, int whence, if (!ret) return false; - return input_curl_multi_info_read(is, error_r); + return input_curl_multi_info_read(c, error_r); } -static bool -input_curl_open(struct input_stream *is, const char *url, GError **error_r) +static struct input_stream * +input_curl_open(const char *url, GError **error_r) { struct input_curl *c; bool ret; if (strncmp(url, "http://", 7) != 0) - return false; + return NULL; c = g_new0(struct input_curl, 1); + input_stream_init(&c->base, &input_plugin_curl); + c->url = g_strdup(url); c->buffers = g_queue_new(); - is->plugin = &input_plugin_curl; - is->data = c; - c->multi = curl_multi_init(); if (c->multi == NULL) { g_set_error(error_r, curl_quark(), 0, "curl_multi_init() failed"); - input_curl_free(is); - return false; + input_curl_free(c); + return NULL; } icy_clear(&c->icy_metadata); c->tag = NULL; - ret = input_curl_easy_init(is, error_r); + ret = input_curl_easy_init(c, error_r); if (!ret) { - input_curl_free(is); - return false; + input_curl_free(c); + return NULL; } ret = input_curl_send_request(c, error_r); if (!ret) { - input_curl_free(is); - return false; + input_curl_free(c); + return NULL; } - ret = input_curl_multi_info_read(is, error_r); + ret = input_curl_multi_info_read(c, error_r); if (!ret) { - input_curl_free(is); - return false; + input_curl_free(c); + return NULL; } - return true; + return &c->base; } const struct input_plugin input_plugin_curl = { diff --git a/src/input/file_input_plugin.c b/src/input/file_input_plugin.c index 92da42290..1c5813f88 100644 --- a/src/input/file_input_plugin.c +++ b/src/input/file_input_plugin.c @@ -32,18 +32,24 @@ #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "input_file" +struct file_input_stream { + struct input_stream base; + + int fd; +}; + static inline GQuark file_quark(void) { return g_quark_from_static_string("file"); } -static bool -input_file_open(struct input_stream *is, const char *filename, - GError **error_r) +static struct input_stream * +input_file_open(const char *filename, GError **error_r) { int fd, ret; struct stat st; + struct file_input_stream *fis; if (!g_path_is_absolute(filename)) return false; @@ -57,8 +63,6 @@ input_file_open(struct input_stream *is, const char *filename, return false; } - is->seekable = true; - ret = fstat(fd, &st); if (ret < 0) { g_set_error(error_r, file_quark(), errno, @@ -75,26 +79,29 @@ input_file_open(struct input_stream *is, const char *filename, return false; } - is->size = st.st_size; - #ifdef POSIX_FADV_SEQUENTIAL - posix_fadvise(fd, (off_t)0, is->size, POSIX_FADV_SEQUENTIAL); + posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL); #endif - is->plugin = &input_plugin_file; - is->data = GINT_TO_POINTER(fd); - is->ready = true; + fis = g_new(struct file_input_stream, 1); + input_stream_init(&fis->base, &input_plugin_file); - return true; + fis->base.size = st.st_size; + fis->base.seekable = true; + fis->base.ready = true; + + fis->fd = fd; + + return &fis->base; } static bool input_file_seek(struct input_stream *is, goffset offset, int whence, GError **error_r) { - int fd = GPOINTER_TO_INT(is->data); + struct file_input_stream *fis = (struct file_input_stream *)is; - offset = (goffset)lseek(fd, (off_t)offset, whence); + offset = (goffset)lseek(fis->fd, (off_t)offset, whence); if (offset < 0) { g_set_error(error_r, file_quark(), errno, "Failed to seek: %s", g_strerror(errno)); @@ -109,10 +116,10 @@ static size_t input_file_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - int fd = GPOINTER_TO_INT(is->data); + struct file_input_stream *fis = (struct file_input_stream *)is; ssize_t nbytes; - nbytes = read(fd, ptr, size); + nbytes = read(fis->fd, ptr, size); if (nbytes < 0) { g_set_error(error_r, file_quark(), errno, "Failed to read: %s", g_strerror(errno)); @@ -126,9 +133,10 @@ input_file_read(struct input_stream *is, void *ptr, size_t size, static void input_file_close(struct input_stream *is) { - int fd = GPOINTER_TO_INT(is->data); + struct file_input_stream *fis = (struct file_input_stream *)is; - close(fd); + close(fis->fd); + g_free(fis); } static bool diff --git a/src/input/mms_input_plugin.c b/src/input/mms_input_plugin.c index e7dc56bc8..5055eb05e 100644 --- a/src/input/mms_input_plugin.c +++ b/src/input/mms_input_plugin.c @@ -31,6 +31,8 @@ #define G_LOG_DOMAIN "input_mms" struct input_mms { + struct input_stream base; + mmsx_t *mms; bool eof; @@ -42,8 +44,8 @@ mms_quark(void) return g_quark_from_static_string("mms"); } -static bool -input_mms_open(struct input_stream *is, const char *url, GError **error_r) +static struct input_stream * +input_mms_open(const char *url, GError **error_r) { struct input_mms *m; @@ -51,30 +53,31 @@ input_mms_open(struct input_stream *is, const char *url, GError **error_r) !g_str_has_prefix(url, "mmsh://") && !g_str_has_prefix(url, "mmst://") && !g_str_has_prefix(url, "mmsu://")) - return false; + return NULL; m = g_new(struct input_mms, 1); + input_stream_init(&m->base, &input_plugin_mms); + m->mms = mmsx_connect(NULL, NULL, url, 128 * 1024); if (m->mms == NULL) { g_set_error(error_r, mms_quark(), 0, "mmsx_connect() failed"); - return false; + return NULL; } /* XX is this correct? at least this selects the ffmpeg decoder, which seems to work fine*/ - is->mime = g_strdup("audio/x-ms-wma"); + m->base.mime = g_strdup("audio/x-ms-wma"); + + m->base.ready = true; - is->plugin = &input_plugin_mms; - is->data = m; - is->ready = true; - return true; + return &m->base; } static size_t input_mms_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - struct input_mms *m = is->data; + struct input_mms *m = (struct input_mms *)is; int ret; ret = mmsx_read(NULL, m->mms, ptr, size); @@ -97,7 +100,7 @@ input_mms_read(struct input_stream *is, void *ptr, size_t size, static void input_mms_close(struct input_stream *is) { - struct input_mms *m = is->data; + struct input_mms *m = (struct input_mms *)is; mmsx_close(m->mms); g_free(m); @@ -106,7 +109,7 @@ input_mms_close(struct input_stream *is) static bool input_mms_eof(struct input_stream *is) { - struct input_mms *m = is->data; + struct input_mms *m = (struct input_mms *)is; return m->eof; } diff --git a/src/input/rewind_input_plugin.c b/src/input/rewind_input_plugin.c index 54efa75fb..68b3e8036 100644 --- a/src/input/rewind_input_plugin.c +++ b/src/input/rewind_input_plugin.c @@ -32,7 +32,9 @@ #define G_LOG_DOMAIN "input_rewind" struct input_rewind { - struct input_stream input; + struct input_stream base; + + struct input_stream *input; /** * The read position within the buffer. Undefined as long as @@ -61,11 +63,9 @@ struct input_rewind { * contain more data for the next read operation? */ static bool -reading_from_buffer(const struct input_stream *is) +reading_from_buffer(const struct input_rewind *r) { - const struct input_rewind *r = is->data; - - return r->tail > 0 && is->offset < r->input.offset; + return r->tail > 0 && r->base.offset < r->input->offset; } /** @@ -75,10 +75,10 @@ reading_from_buffer(const struct input_stream *is) * attributes. */ static void -copy_attributes(struct input_stream *dest) +copy_attributes(struct input_rewind *r) { - const struct input_rewind *r = dest->data; - const struct input_stream *src = &r->input; + struct input_stream *dest = &r->base; + const struct input_stream *src = r->input; dest->ready = src->ready; dest->seekable = src->seekable; @@ -94,9 +94,9 @@ copy_attributes(struct input_stream *dest) static void input_rewind_close(struct input_stream *is) { - struct input_rewind *r = is->data; + struct input_rewind *r = (struct input_rewind *)is; - input_stream_close(&r->input); + input_stream_close(r->input); g_free(r); } @@ -104,19 +104,19 @@ input_rewind_close(struct input_stream *is) static struct tag * input_rewind_tag(struct input_stream *is) { - struct input_rewind *r = is->data; + struct input_rewind *r = (struct input_rewind *)is; - return input_stream_tag(&r->input); + return input_stream_tag(r->input); } static int input_rewind_buffer(struct input_stream *is, GError **error_r) { - struct input_rewind *r = is->data; + struct input_rewind *r = (struct input_rewind *)is; - int ret = input_stream_buffer(&r->input, error_r); - if (ret < 0 || !reading_from_buffer(is)) - copy_attributes(is); + int ret = input_stream_buffer(r->input, error_r); + if (ret < 0 || !reading_from_buffer(r)) + copy_attributes(r); return ret; } @@ -125,13 +125,13 @@ static size_t input_rewind_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - struct input_rewind *r = is->data; + struct input_rewind *r = (struct input_rewind *)is; - if (reading_from_buffer(is)) { + if (reading_from_buffer(r)) { /* buffered read */ assert(r->head == (size_t)is->offset); - assert(r->tail == (size_t)r->input.offset); + assert(r->tail == (size_t)r->input->offset); if (size > r->tail - r->head) size = r->tail - r->head; @@ -144,9 +144,9 @@ input_rewind_read(struct input_stream *is, void *ptr, size_t size, } else { /* pass method call to underlying stream */ - size_t nbytes = input_stream_read(&r->input, ptr, size, error_r); + size_t nbytes = input_stream_read(r->input, ptr, size, error_r); - if (r->input.offset > (goffset)sizeof(r->buffer)) + if (r->input->offset > (goffset)sizeof(r->buffer)) /* disable buffering */ r->tail = 0; else if (r->tail == (size_t)is->offset) { @@ -155,46 +155,46 @@ input_rewind_read(struct input_stream *is, void *ptr, size_t size, memcpy(r->buffer + r->tail, ptr, nbytes); r->tail += nbytes; - assert(r->tail == (size_t)r->input.offset); + assert(r->tail == (size_t)r->input->offset); } - copy_attributes(is); + copy_attributes(r); return nbytes; } } static bool -input_rewind_eof(G_GNUC_UNUSED struct input_stream *is) +input_rewind_eof(struct input_stream *is) { - struct input_rewind *r = is->data; + struct input_rewind *r = (struct input_rewind *)is; - return !reading_from_buffer(is) && input_stream_eof(&r->input); + return !reading_from_buffer(r) && input_stream_eof(r->input); } static bool input_rewind_seek(struct input_stream *is, goffset offset, int whence, GError **error_r) { - struct input_rewind *r = is->data; + struct input_rewind *r = (struct input_rewind *)is; assert(is->ready); if (whence == SEEK_SET && r->tail > 0 && offset <= (goffset)r->tail) { /* buffered seek */ - assert(!reading_from_buffer(is) || + assert(!reading_from_buffer(r) || r->head == (size_t)is->offset); - assert(r->tail == (size_t)r->input.offset); + assert(r->tail == (size_t)r->input->offset); r->head = (size_t)offset; is->offset = offset; return true; } else { - bool success = input_stream_seek(&r->input, offset, whence, + bool success = input_stream_seek(r->input, offset, whence, error_r); - copy_attributes(is); + copy_attributes(r); /* disable the buffer, because r->input has left the buffered range now */ @@ -213,7 +213,7 @@ static const struct input_plugin rewind_input_plugin = { .seek = input_rewind_seek, }; -void +struct input_stream * input_rewind_open(struct input_stream *is) { struct input_rewind *c; @@ -224,17 +224,12 @@ input_rewind_open(struct input_stream *is) if (is->plugin != &input_plugin_curl) /* due to limitations in the input_plugin API, we only (explicitly) support the CURL input plugin */ - return; + return is; c = g_new(struct input_rewind, 1); + input_stream_init(&c->base, &rewind_input_plugin); c->tail = 0; + c->input = is; - /* move the CURL input stream to c->input */ - c->input = *is; - input_curl_reinit(&c->input); - - /* convert the existing input_stream pointer to a "rewind" - input stream */ - is->plugin = &rewind_input_plugin; - is->data = c; + return &c->base; } diff --git a/src/input/rewind_input_plugin.h b/src/input/rewind_input_plugin.h index 83152e588..27ad169b6 100644 --- a/src/input/rewind_input_plugin.h +++ b/src/input/rewind_input_plugin.h @@ -33,15 +33,15 @@ struct input_stream; #ifdef ENABLE_CURL -void +struct input_stream * input_rewind_open(struct input_stream *is); #else -static inline void +static inline struct input_stream * input_rewind_open(struct input_stream *is) { - (void)is; + return is; } #endif diff --git a/src/input_plugin.h b/src/input_plugin.h index bc48b9d4b..10be48dbb 100644 --- a/src/input_plugin.h +++ b/src/input_plugin.h @@ -48,8 +48,7 @@ struct input_plugin { */ void (*finish)(void); - bool (*open)(struct input_stream *is, const char *url, - GError **error_r); + struct input_stream *(*open)(const char *uri, GError **error_r); void (*close)(struct input_stream *is); struct tag *(*tag)(struct input_stream *is); diff --git a/src/input_stream.c b/src/input_stream.c index 0cf0558d6..96c692176 100644 --- a/src/input_stream.c +++ b/src/input_stream.c @@ -32,38 +32,34 @@ input_quark(void) return g_quark_from_static_string("input"); } -bool -input_stream_open(struct input_stream *is, const char *url, GError **error_r) +struct input_stream * +input_stream_open(const char *url, GError **error_r) { GError *error = NULL; assert(error_r == NULL || *error_r == NULL); - is->seekable = false; - is->ready = false; - is->offset = 0; - is->size = -1; - is->mime = NULL; - for (unsigned i = 0; input_plugins[i] != NULL; ++i) { const struct input_plugin *plugin = input_plugins[i]; + struct input_stream *is; if (!input_plugins_enabled[i]) continue; - if (plugin->open(is, url, &error)) { + is = plugin->open(url, &error); + if (is != NULL) { assert(is->plugin != NULL); assert(is->plugin->close != NULL); assert(is->plugin->read != NULL); assert(is->plugin->eof != NULL); assert(!is->seekable || is->plugin->seek != NULL); - input_rewind_open(is); + is = input_rewind_open(is); - return true; + return is; } else if (error != NULL) { g_propagate_error(error_r, error); - return false; + return NULL; } } @@ -103,9 +99,9 @@ input_stream_read(struct input_stream *is, void *ptr, size_t size, void input_stream_close(struct input_stream *is) { - is->plugin->close(is); - g_free(is->mime); + + is->plugin->close(is); } bool input_stream_eof(struct input_stream *is) diff --git a/src/input_stream.h b/src/input_stream.h index 069a9f581..e48f7eb26 100644 --- a/src/input_stream.h +++ b/src/input_stream.h @@ -38,11 +38,6 @@ struct input_stream { */ const struct input_plugin *plugin; - /** - * an opaque pointer managed by the plugin - */ - void *data; - /** * indicates whether the stream is ready for reading and * whether the other attributes in this struct are valid @@ -70,20 +65,28 @@ struct input_stream { char *mime; }; +static inline void +input_stream_init(struct input_stream *is, const struct input_plugin *plugin) +{ + is->plugin = plugin; + is->ready = false; + is->seekable = false; + is->size = -1; + is->offset = 0; + is->mime = NULL; +} + /** * Opens a new input stream. You may not access it until the "ready" * flag is set. * - * @param is the input_stream object allocated by the caller - * @return true on success + * @return an #input_stream object on success, NULL on error */ -bool -input_stream_open(struct input_stream *is, const char *url, GError **error_r); +struct input_stream * +input_stream_open(const char *uri, GError **error_r); /** - * Closes the input stream and free resources. This does not free the - * input_stream pointer itself, because it is assumed to be allocated - * by the caller. + * Close the input stream and free resources. */ void input_stream_close(struct input_stream *is); diff --git a/src/playlist/lastfm_playlist_plugin.c b/src/playlist/lastfm_playlist_plugin.c index 25e1adb1d..afb3979d9 100644 --- a/src/playlist/lastfm_playlist_plugin.c +++ b/src/playlist/lastfm_playlist_plugin.c @@ -35,7 +35,7 @@ struct lastfm_playlist { struct playlist_provider base; - struct input_stream is; + struct input_stream *is; struct playlist_provider *xspf; }; @@ -85,15 +85,14 @@ lastfm_finish(void) static char * lastfm_get(const char *url) { - struct input_stream input_stream; + struct input_stream *input_stream; GError *error = NULL; - bool success; int ret; char buffer[4096]; size_t length = 0, nbytes; - success = input_stream_open(&input_stream, url, &error); - if (!success) { + input_stream = input_stream_open(url, &error); + if (input_stream == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); @@ -102,10 +101,10 @@ lastfm_get(const char *url) return NULL; } - while (!input_stream.ready) { - ret = input_stream_buffer(&input_stream, &error); + while (!input_stream->ready) { + ret = input_stream_buffer(input_stream, &error); if (ret < 0) { - input_stream_close(&input_stream); + input_stream_close(input_stream); g_warning("%s", error->message); g_error_free(error); return NULL; @@ -113,7 +112,7 @@ lastfm_get(const char *url) } do { - nbytes = input_stream_read(&input_stream, buffer + length, + nbytes = input_stream_read(input_stream, buffer + length, sizeof(buffer) - length, &error); if (nbytes == 0) { if (error != NULL) { @@ -121,18 +120,18 @@ lastfm_get(const char *url) g_error_free(error); } - if (input_stream_eof(&input_stream)) + if (input_stream_eof(input_stream)) break; /* I/O error */ - input_stream_close(&input_stream); + input_stream_close(input_stream); return NULL; } length += nbytes; } while (length < sizeof(buffer)); - input_stream_close(&input_stream); + input_stream_close(input_stream); return g_strndup(buffer, length); } @@ -168,7 +167,6 @@ lastfm_open_uri(const char *uri) struct lastfm_playlist *playlist; GError *error = NULL; char *p, *q, *response, *session; - bool success; /* handshake */ @@ -231,10 +229,10 @@ lastfm_open_uri(const char *uri) NULL); g_free(session); - success = input_stream_open(&playlist->is, p, &error); + playlist->is = input_stream_open(p, &error); g_free(p); - if (!success) { + if (playlist->is == NULL) { if (error != NULL) { g_warning("Failed to load XSPF playlist: %s", error->message); @@ -245,10 +243,10 @@ lastfm_open_uri(const char *uri) return NULL; } - while (!playlist->is.ready) { - int ret = input_stream_buffer(&playlist->is, &error); + while (!playlist->is->ready) { + int ret = input_stream_buffer(playlist->is, &error); if (ret < 0) { - input_stream_close(&playlist->is); + input_stream_close(playlist->is); g_free(playlist); g_warning("%s", error->message); g_error_free(error); @@ -262,14 +260,14 @@ lastfm_open_uri(const char *uri) /* 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_free(playlist->is->mime); + playlist->is->mime = g_strdup("application/xspf+xml"); /* parse the XSPF playlist */ - playlist->xspf = playlist_list_open_stream(&playlist->is, NULL); + playlist->xspf = playlist_list_open_stream(playlist->is, NULL); if (playlist->xspf == NULL) { - input_stream_close(&playlist->is); + input_stream_close(playlist->is); g_free(playlist); g_warning("Failed to parse XSPF playlist"); return NULL; @@ -284,7 +282,7 @@ lastfm_close(struct playlist_provider *_playlist) struct lastfm_playlist *playlist = (struct lastfm_playlist *)_playlist; playlist_plugin_close(playlist->xspf); - input_stream_close(&playlist->is); + input_stream_close(playlist->is); g_free(playlist); } diff --git a/src/playlist_list.c b/src/playlist_list.c index 46fd238c1..d034f4c1e 100644 --- a/src/playlist_list.c +++ b/src/playlist_list.c @@ -293,10 +293,11 @@ playlist_suffix_supported(const char *suffix) } struct playlist_provider * -playlist_list_open_path(struct input_stream *is, const char *path_fs) +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); @@ -305,7 +306,8 @@ playlist_list_open_path(struct input_stream *is, const char *path_fs) if (suffix == NULL || !playlist_suffix_supported(suffix)) return NULL; - if (!input_stream_open(is, path_fs, &error)) { + is = input_stream_open(path_fs, &error); + if (is == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); diff --git a/src/playlist_list.h b/src/playlist_list.h index 84e179b4d..f19fa6579 100644 --- a/src/playlist_list.h +++ b/src/playlist_list.h @@ -54,12 +54,10 @@ playlist_list_open_stream(struct input_stream *is, const char *uri); /** * Opens a playlist from a local file. * - * @param is an uninitialized #input_stream object (must be closed - * with input_stream_close() if this function succeeds) * @param path_fs the path of the playlist file * @return a playlist, or NULL on error */ struct playlist_provider * -playlist_list_open_path(struct input_stream *is, const char *path_fs); +playlist_list_open_path(const char *path_fs); #endif diff --git a/src/playlist_queue.c b/src/playlist_queue.c index 5c000b148..327cdcacc 100644 --- a/src/playlist_queue.c +++ b/src/playlist_queue.c @@ -163,16 +163,15 @@ playlist_open_remote_into_queue(const char *uri, struct playlist *dest) { GError *error = NULL; struct playlist_provider *playlist; - bool stream = false; - struct input_stream is; + struct input_stream *is = NULL; enum playlist_result result; assert(uri_has_scheme(uri)); playlist = playlist_list_open_uri(uri); if (playlist == NULL) { - stream = input_stream_open(&is, uri, &error); - if (!stream) { + is = input_stream_open(uri, &error); + if (is == NULL) { if (error != NULL) { g_warning("Failed to open %s: %s", uri, error->message); @@ -182,9 +181,9 @@ playlist_open_remote_into_queue(const char *uri, struct playlist *dest) return PLAYLIST_RESULT_NO_SUCH_LIST; } - playlist = playlist_list_open_stream(&is, uri); + playlist = playlist_list_open_stream(is, uri); if (playlist == NULL) { - input_stream_close(&is); + input_stream_close(is); return PLAYLIST_RESULT_NO_SUCH_LIST; } } @@ -192,8 +191,8 @@ playlist_open_remote_into_queue(const char *uri, struct playlist *dest) result = playlist_load_into_queue(uri, playlist, dest); playlist_plugin_close(playlist); - if (stream) - input_stream_close(&is); + if (is != NULL) + input_stream_close(is); return result; } @@ -203,15 +202,13 @@ playlist_open_path_into_queue(const char *path_fs, const char *uri, struct playlist *dest) { struct playlist_provider *playlist; - struct input_stream is; enum playlist_result result; if ((playlist = playlist_list_open_uri(path_fs)) != NULL) result = playlist_load_into_queue(uri, playlist, dest); - else if ((playlist = playlist_list_open_path(&is, path_fs)) != NULL) { + else if ((playlist = playlist_list_open_path(path_fs)) != NULL) result = playlist_load_into_queue(uri, playlist, dest); - input_stream_close(&is); - } else + else return PLAYLIST_RESULT_NO_SUCH_LIST; playlist_plugin_close(playlist); diff --git a/src/song_update.c b/src/song_update.c index a264c75da..b418b600e 100644 --- a/src/song_update.c +++ b/src/song_update.c @@ -101,7 +101,7 @@ song_file_update(struct song *song) char *path_fs; const struct decoder_plugin *plugin; struct stat st; - struct input_stream is = { .plugin = NULL }; + struct input_stream *is = NULL; assert(song_is_file(song)); @@ -141,26 +141,25 @@ song_file_update(struct song *song) if (plugin->stream_tag != NULL) { /* open the input_stream (if not already open) */ - if (is.plugin == NULL && - !input_stream_open(&is, path_fs, NULL)) - is.plugin = NULL; + if (is == NULL) + is = input_stream_open(path_fs, NULL); /* now try the stream_tag() method */ - if (is.plugin != NULL) { + if (is != NULL) { song->tag = decoder_plugin_stream_tag(plugin, - &is); + is); if (song->tag != NULL) break; - input_stream_seek(&is, 0, SEEK_SET, NULL); + input_stream_seek(is, 0, SEEK_SET, NULL); } } plugin = decoder_plugin_from_suffix(suffix, plugin); } while (plugin != NULL); - if (is.plugin != NULL) - input_stream_close(&is); + if (is != NULL) + input_stream_close(is); if (song->tag != NULL && tag_is_empty(song->tag)) song->tag = tag_fallback(path_fs, song->tag); diff --git a/test/dump_playlist.c b/test/dump_playlist.c index 7be9b973f..95207e24d 100644 --- a/test/dump_playlist.c +++ b/test/dump_playlist.c @@ -44,8 +44,7 @@ my_log_func(const gchar *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, int main(int argc, char **argv) { const char *uri; - struct input_stream is; - bool stream_open = false; + struct input_stream *is = NULL; bool success; GError *error = NULL; struct playlist_provider *playlist; @@ -88,8 +87,8 @@ int main(int argc, char **argv) if (playlist == NULL) { /* open the stream and wait until it becomes ready */ - success = input_stream_open(&is, uri, &error); - if (!success) { + is = input_stream_open(uri, &error); + if (is == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); @@ -98,8 +97,8 @@ int main(int argc, char **argv) return 2; } - while (!is.ready) { - int ret = input_stream_buffer(&is, &error); + while (!is->ready) { + int ret = input_stream_buffer(is, &error); if (ret < 0) { /* error */ g_warning("%s", error->message); @@ -112,13 +111,11 @@ int main(int argc, char **argv) g_usleep(10000); } - stream_open = true; - /* open the playlist */ - playlist = playlist_list_open_stream(&is, uri); + playlist = playlist_list_open_stream(is, uri); if (playlist == NULL) { - input_stream_close(&is); + input_stream_close(is); g_printerr("Failed to open playlist\n"); return 2; } @@ -145,8 +142,8 @@ int main(int argc, char **argv) /* deinitialize everything */ playlist_plugin_close(playlist); - if (stream_open) - input_stream_close(&is); + if (is != NULL) + input_stream_close(is); playlist_list_global_finish(); input_stream_global_finish(); config_global_finish(); diff --git a/test/read_tags.c b/test/read_tags.c index a16b703f0..8138c187f 100644 --- a/test/read_tags.c +++ b/test/read_tags.c @@ -170,17 +170,17 @@ int main(int argc, char **argv) tag = decoder_plugin_tag_dup(plugin, path); if (tag == NULL && plugin->stream_tag != NULL) { - struct input_stream is; + struct input_stream *is = input_stream_open(path, &error); - if (!input_stream_open(&is, 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); + tag = decoder_plugin_stream_tag(plugin, is); + input_stream_close(is); } decoder_plugin_deinit_all(); diff --git a/test/run_decoder.c b/test/run_decoder.c index 9ec08af4d..5a41ef8f6 100644 --- a/test/run_decoder.c +++ b/test/run_decoder.c @@ -145,7 +145,6 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, int main(int argc, char **argv) { GError *error = NULL; - bool ret; const char *decoder_name; struct decoder decoder; @@ -179,10 +178,9 @@ int main(int argc, char **argv) decoder_plugin_file_decode(decoder.plugin, &decoder, decoder.uri); } else if (decoder.plugin->stream_decode != NULL) { - struct input_stream is; - - ret = input_stream_open(&is, decoder.uri, &error); - if (!ret) { + 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); @@ -192,9 +190,9 @@ int main(int argc, char **argv) return 1; } - decoder_plugin_stream_decode(decoder.plugin, &decoder, &is); + decoder_plugin_stream_decode(decoder.plugin, &decoder, is); - input_stream_close(&is); + input_stream_close(is); } else { g_printerr("Decoder plugin is not usable\n"); return 1; diff --git a/test/run_input.c b/test/run_input.c index 581b22dca..9a31019dd 100644 --- a/test/run_input.c +++ b/test/run_input.c @@ -103,7 +103,7 @@ dump_input_stream(struct input_stream *is) int main(int argc, char **argv) { GError *error = NULL; - struct input_stream is; + struct input_stream *is; int ret; if (argc != 2) { @@ -133,9 +133,10 @@ int main(int argc, char **argv) /* open the stream and dump it */ - if (input_stream_open(&is, argv[1], &error)) { - ret = dump_input_stream(&is); - input_stream_close(&is); + 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); -- cgit v1.2.3