playlist/Plugin: pass InputStreamPtr&& to open_stream()
Obsolete class CloseSongEnumerator, which was a kludge.
This commit is contained in:
parent
cadc67ea40
commit
0705f42cf8
@ -1468,8 +1468,6 @@ endif
|
|||||||
libplaylist_plugins_a_SOURCES = \
|
libplaylist_plugins_a_SOURCES = \
|
||||||
src/playlist/PlaylistPlugin.hxx \
|
src/playlist/PlaylistPlugin.hxx \
|
||||||
src/playlist/SongEnumerator.hxx \
|
src/playlist/SongEnumerator.hxx \
|
||||||
src/playlist/CloseSongEnumerator.cxx \
|
|
||||||
src/playlist/CloseSongEnumerator.hxx \
|
|
||||||
src/playlist/MemorySongEnumerator.cxx \
|
src/playlist/MemorySongEnumerator.cxx \
|
||||||
src/playlist/MemorySongEnumerator.hxx \
|
src/playlist/MemorySongEnumerator.hxx \
|
||||||
src/playlist/plugins/ExtM3uPlaylistPlugin.cxx \
|
src/playlist/plugins/ExtM3uPlaylistPlugin.cxx \
|
||||||
|
@ -26,6 +26,11 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
TextInputStream::TextInputStream(InputStreamPtr &&_is)
|
||||||
|
:is(std::move(_is)) {}
|
||||||
|
|
||||||
|
TextInputStream::~TextInputStream() {}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
TextInputStream::ReadLine()
|
TextInputStream::ReadLine()
|
||||||
{
|
{
|
||||||
@ -54,7 +59,7 @@ TextInputStream::ReadLine()
|
|||||||
--dest.size;
|
--dest.size;
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
size_t nbytes = is.LockRead(dest.data, dest.size, error);
|
size_t nbytes = is->LockRead(dest.data, dest.size, error);
|
||||||
if (nbytes > 0)
|
if (nbytes > 0)
|
||||||
buffer.Append(nbytes);
|
buffer.Append(nbytes);
|
||||||
else if (error.IsDefined()) {
|
else if (error.IsDefined()) {
|
||||||
|
@ -20,12 +20,13 @@
|
|||||||
#ifndef MPD_TEXT_INPUT_STREAM_HXX
|
#ifndef MPD_TEXT_INPUT_STREAM_HXX
|
||||||
#define MPD_TEXT_INPUT_STREAM_HXX
|
#define MPD_TEXT_INPUT_STREAM_HXX
|
||||||
|
|
||||||
|
#include "input/Ptr.hxx"
|
||||||
#include "util/StaticFifoBuffer.hxx"
|
#include "util/StaticFifoBuffer.hxx"
|
||||||
|
|
||||||
class InputStream;
|
class InputStream;
|
||||||
|
|
||||||
class TextInputStream {
|
class TextInputStream {
|
||||||
InputStream &is;
|
InputStreamPtr is;
|
||||||
StaticFifoBuffer<char, 4096> buffer;
|
StaticFifoBuffer<char, 4096> buffer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -35,12 +36,16 @@ public:
|
|||||||
*
|
*
|
||||||
* @param _is an open #InputStream object
|
* @param _is an open #InputStream object
|
||||||
*/
|
*/
|
||||||
explicit TextInputStream(InputStream &_is)
|
explicit TextInputStream(InputStreamPtr &&_is);
|
||||||
:is(_is) {}
|
~TextInputStream();
|
||||||
|
|
||||||
TextInputStream(const TextInputStream &) = delete;
|
TextInputStream(const TextInputStream &) = delete;
|
||||||
TextInputStream& operator=(const TextInputStream &) = delete;
|
TextInputStream& operator=(const TextInputStream &) = delete;
|
||||||
|
|
||||||
|
InputStreamPtr &&StealInputStream() {
|
||||||
|
return std::move(is);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the next line from the stream with newline character stripped.
|
* Reads the next line from the stream with newline character stripped.
|
||||||
*
|
*
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2003-2015 The Music Player Daemon Project
|
|
||||||
* http://www.musicpd.org
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "CloseSongEnumerator.hxx"
|
|
||||||
#include "input/InputStream.hxx"
|
|
||||||
#include "DetachedSong.hxx"
|
|
||||||
|
|
||||||
CloseSongEnumerator::~CloseSongEnumerator()
|
|
||||||
{
|
|
||||||
delete other;
|
|
||||||
delete is;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<DetachedSong>
|
|
||||||
CloseSongEnumerator::NextSong()
|
|
||||||
{
|
|
||||||
return other->NextSong();
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2003-2015 The Music Player Daemon Project
|
|
||||||
* http://www.musicpd.org
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MPD_CLOSE_SONG_ENUMERATOR_HXX
|
|
||||||
#define MPD_CLOSE_SONG_ENUMERATOR_HXX
|
|
||||||
|
|
||||||
#include "SongEnumerator.hxx"
|
|
||||||
#include "Compiler.h"
|
|
||||||
|
|
||||||
class InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A #SongEnumerator wrapper that closes an #InputStream automatically
|
|
||||||
* after deleting the #SongEnumerator
|
|
||||||
*/
|
|
||||||
class CloseSongEnumerator final : public SongEnumerator {
|
|
||||||
SongEnumerator *const other;
|
|
||||||
|
|
||||||
InputStream *const is;
|
|
||||||
|
|
||||||
public:
|
|
||||||
gcc_nonnull_all
|
|
||||||
CloseSongEnumerator(SongEnumerator *_other, InputStream *const _is)
|
|
||||||
:other(_other), is(_is) {}
|
|
||||||
|
|
||||||
virtual ~CloseSongEnumerator();
|
|
||||||
|
|
||||||
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -20,8 +20,9 @@
|
|||||||
#ifndef MPD_PLAYLIST_PLUGIN_HXX
|
#ifndef MPD_PLAYLIST_PLUGIN_HXX
|
||||||
#define MPD_PLAYLIST_PLUGIN_HXX
|
#define MPD_PLAYLIST_PLUGIN_HXX
|
||||||
|
|
||||||
|
#include "input/Ptr.hxx"
|
||||||
|
|
||||||
struct ConfigBlock;
|
struct ConfigBlock;
|
||||||
class InputStream;
|
|
||||||
struct Tag;
|
struct Tag;
|
||||||
class Mutex;
|
class Mutex;
|
||||||
class Cond;
|
class Cond;
|
||||||
@ -57,8 +58,11 @@ struct playlist_plugin {
|
|||||||
* Opens the playlist in the specified input stream. It has
|
* Opens the playlist in the specified input stream. It has
|
||||||
* either matched one of the suffixes or one of the MIME
|
* either matched one of the suffixes or one of the MIME
|
||||||
* types.
|
* types.
|
||||||
|
*
|
||||||
|
* @parm is the input stream; the pointer will not be
|
||||||
|
* invalidated when the function returns nullptr
|
||||||
*/
|
*/
|
||||||
SongEnumerator *(*open_stream)(InputStream &is);
|
SongEnumerator *(*open_stream)(InputStreamPtr &&is);
|
||||||
|
|
||||||
const char *const*schemes;
|
const char *const*schemes;
|
||||||
const char *const*suffixes;
|
const char *const*suffixes;
|
||||||
@ -101,9 +105,9 @@ playlist_plugin_open_uri(const struct playlist_plugin *plugin, const char *uri,
|
|||||||
|
|
||||||
static inline SongEnumerator *
|
static inline SongEnumerator *
|
||||||
playlist_plugin_open_stream(const struct playlist_plugin *plugin,
|
playlist_plugin_open_stream(const struct playlist_plugin *plugin,
|
||||||
InputStream &is)
|
InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
return plugin->open_stream(is);
|
return plugin->open_stream(std::move(is));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -183,7 +183,7 @@ playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
playlist_list_open_stream_mime2(InputStream &is, const char *mime)
|
playlist_list_open_stream_mime2(InputStreamPtr &&is, const char *mime)
|
||||||
{
|
{
|
||||||
assert(mime != nullptr);
|
assert(mime != nullptr);
|
||||||
|
|
||||||
@ -193,10 +193,10 @@ playlist_list_open_stream_mime2(InputStream &is, const char *mime)
|
|||||||
string_array_contains(plugin->mime_types, mime)) {
|
string_array_contains(plugin->mime_types, mime)) {
|
||||||
/* rewind the stream, so each plugin gets a
|
/* rewind the stream, so each plugin gets a
|
||||||
fresh start */
|
fresh start */
|
||||||
is.Rewind(IgnoreError());
|
is->Rewind(IgnoreError());
|
||||||
|
|
||||||
auto playlist = playlist_plugin_open_stream(plugin,
|
auto playlist = playlist_plugin_open_stream(plugin,
|
||||||
is);
|
std::move(is));
|
||||||
if (playlist != nullptr)
|
if (playlist != nullptr)
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
@ -206,24 +206,25 @@ playlist_list_open_stream_mime2(InputStream &is, const char *mime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
playlist_list_open_stream_mime(InputStream &is, const char *full_mime)
|
playlist_list_open_stream_mime(InputStreamPtr &&is, const char *full_mime)
|
||||||
{
|
{
|
||||||
assert(full_mime != nullptr);
|
assert(full_mime != nullptr);
|
||||||
|
|
||||||
const char *semicolon = strchr(full_mime, ';');
|
const char *semicolon = strchr(full_mime, ';');
|
||||||
if (semicolon == nullptr)
|
if (semicolon == nullptr)
|
||||||
return playlist_list_open_stream_mime2(is, full_mime);
|
return playlist_list_open_stream_mime2(std::move(is),
|
||||||
|
full_mime);
|
||||||
|
|
||||||
if (semicolon == full_mime)
|
if (semicolon == full_mime)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
/* probe only the portion before the semicolon*/
|
/* probe only the portion before the semicolon*/
|
||||||
const std::string mime(full_mime, semicolon);
|
const std::string mime(full_mime, semicolon);
|
||||||
return playlist_list_open_stream_mime2(is, mime.c_str());
|
return playlist_list_open_stream_mime2(std::move(is), mime.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SongEnumerator *
|
SongEnumerator *
|
||||||
playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
playlist_list_open_stream_suffix(InputStreamPtr &&is, const char *suffix)
|
||||||
{
|
{
|
||||||
assert(suffix != nullptr);
|
assert(suffix != nullptr);
|
||||||
|
|
||||||
@ -233,9 +234,10 @@ playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
|||||||
string_array_contains(plugin->suffixes, suffix)) {
|
string_array_contains(plugin->suffixes, suffix)) {
|
||||||
/* rewind the stream, so each plugin gets a
|
/* rewind the stream, so each plugin gets a
|
||||||
fresh start */
|
fresh start */
|
||||||
is.Rewind(IgnoreError());
|
is->Rewind(IgnoreError());
|
||||||
|
|
||||||
auto playlist = playlist_plugin_open_stream(plugin, is);
|
auto playlist = playlist_plugin_open_stream(plugin,
|
||||||
|
std::move(is));
|
||||||
if (playlist != nullptr)
|
if (playlist != nullptr)
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
@ -245,13 +247,14 @@ playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SongEnumerator *
|
SongEnumerator *
|
||||||
playlist_list_open_stream(InputStream &is, const char *uri)
|
playlist_list_open_stream(InputStreamPtr &&is, const char *uri)
|
||||||
{
|
{
|
||||||
assert(is.IsReady());
|
assert(is->IsReady());
|
||||||
|
|
||||||
const char *const mime = is.GetMimeType();
|
const char *const mime = is->GetMimeType();
|
||||||
if (mime != nullptr) {
|
if (mime != nullptr) {
|
||||||
auto playlist = playlist_list_open_stream_mime(is, mime);
|
auto playlist = playlist_list_open_stream_mime(std::move(is),
|
||||||
|
mime);
|
||||||
if (playlist != nullptr)
|
if (playlist != nullptr)
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
@ -261,7 +264,8 @@ playlist_list_open_stream(InputStream &is, const char *uri)
|
|||||||
? uri_get_suffix(uri, suffix_buffer)
|
? uri_get_suffix(uri, suffix_buffer)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
if (suffix != nullptr) {
|
if (suffix != nullptr) {
|
||||||
auto playlist = playlist_list_open_stream_suffix(is, suffix);
|
auto playlist = playlist_list_open_stream_suffix(std::move(is),
|
||||||
|
suffix);
|
||||||
if (playlist != nullptr)
|
if (playlist != nullptr)
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,11 @@
|
|||||||
#ifndef MPD_PLAYLIST_REGISTRY_HXX
|
#ifndef MPD_PLAYLIST_REGISTRY_HXX
|
||||||
#define MPD_PLAYLIST_REGISTRY_HXX
|
#define MPD_PLAYLIST_REGISTRY_HXX
|
||||||
|
|
||||||
|
#include "input/Ptr.hxx"
|
||||||
|
|
||||||
class Mutex;
|
class Mutex;
|
||||||
class Cond;
|
class Cond;
|
||||||
class SongEnumerator;
|
class SongEnumerator;
|
||||||
class InputStream;
|
|
||||||
|
|
||||||
extern const struct playlist_plugin *const playlist_plugins[];
|
extern const struct playlist_plugin *const playlist_plugins[];
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ SongEnumerator *
|
|||||||
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond);
|
playlist_list_open_uri(const char *uri, Mutex &mutex, Cond &cond);
|
||||||
|
|
||||||
SongEnumerator *
|
SongEnumerator *
|
||||||
playlist_list_open_stream_suffix(InputStream &is, const char *suffix);
|
playlist_list_open_stream_suffix(InputStreamPtr &&is, const char *suffix);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a playlist from an input stream.
|
* Opens a playlist from an input stream.
|
||||||
@ -62,7 +63,7 @@ playlist_list_open_stream_suffix(InputStream &is, const char *suffix);
|
|||||||
* used to select the appropriate playlist plugin
|
* used to select the appropriate playlist plugin
|
||||||
*/
|
*/
|
||||||
SongEnumerator *
|
SongEnumerator *
|
||||||
playlist_list_open_stream(InputStream &is, const char *uri);
|
playlist_list_open_stream(InputStreamPtr &&is, const char *uri);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if there is a playlist plugin which can handle the
|
* Determines if there is a playlist plugin which can handle the
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "PlaylistStream.hxx"
|
#include "PlaylistStream.hxx"
|
||||||
#include "PlaylistRegistry.hxx"
|
#include "PlaylistRegistry.hxx"
|
||||||
#include "CloseSongEnumerator.hxx"
|
|
||||||
#include "util/UriUtil.hxx"
|
#include "util/UriUtil.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
@ -50,12 +49,8 @@ try {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto playlist = playlist_list_open_stream_suffix(*is,
|
return playlist_list_open_stream_suffix(std::move(is),
|
||||||
suffix_utf8.c_str());
|
suffix_utf8.c_str());
|
||||||
if (playlist != nullptr)
|
|
||||||
playlist = new CloseSongEnumerator(playlist, is.release());
|
|
||||||
|
|
||||||
return playlist;
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
LogError(e);
|
LogError(e);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -97,11 +92,7 @@ try {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist = playlist_list_open_stream(*is, uri);
|
return playlist_list_open_stream(std::move(is), uri);
|
||||||
if (playlist == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return new CloseSongEnumerator(playlist, is.release());
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
LogError(e);
|
LogError(e);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -144,7 +144,7 @@ asx_char_data(void *user_data, const XML_Char *s, int len)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
asx_open_stream(InputStream &is)
|
asx_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
AsxParser parser;
|
AsxParser parser;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ asx_open_stream(InputStream &is)
|
|||||||
expat.SetCharacterDataHandler(asx_char_data);
|
expat.SetCharacterDataHandler(asx_char_data);
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!expat.Parse(is, error)) {
|
if (!expat.Parse(*is, error)) {
|
||||||
LogError(error);
|
LogError(error);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -27,22 +27,21 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class CuePlaylist final : public SongEnumerator {
|
class CuePlaylist final : public SongEnumerator {
|
||||||
InputStream &is;
|
|
||||||
TextInputStream tis;
|
TextInputStream tis;
|
||||||
CueParser parser;
|
CueParser parser;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CuePlaylist(InputStream &_is)
|
CuePlaylist(InputStreamPtr &&is)
|
||||||
:is(_is), tis(is) {
|
:tis(std::move(is)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
cue_playlist_open_stream(InputStream &is)
|
cue_playlist_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
return new CuePlaylist(is);
|
return new CuePlaylist(std::move(is));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DetachedSong>
|
std::unique_ptr<DetachedSong>
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "input/TextInputStream.hxx"
|
#include "input/TextInputStream.hxx"
|
||||||
|
#include "input/InputStream.hxx"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -35,28 +36,36 @@ class ExtM3uPlaylist final : public SongEnumerator {
|
|||||||
TextInputStream tis;
|
TextInputStream tis;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExtM3uPlaylist(InputStream &is)
|
ExtM3uPlaylist(InputStreamPtr &&is)
|
||||||
:tis(is) {
|
:tis(std::move(is)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckFirstLine() {
|
/**
|
||||||
|
* @return nullptr if ExtM3U was recognized, or the original
|
||||||
|
* InputStream on error
|
||||||
|
*/
|
||||||
|
InputStreamPtr CheckFirstLine() {
|
||||||
char *line = tis.ReadLine();
|
char *line = tis.ReadLine();
|
||||||
if (line == nullptr)
|
if (line == nullptr)
|
||||||
return false;
|
return tis.StealInputStream();
|
||||||
|
|
||||||
StripRight(line);
|
StripRight(line);
|
||||||
return strcmp(line, "#EXTM3U") == 0;
|
if (strcmp(line, "#EXTM3U") != 0)
|
||||||
|
return tis.StealInputStream();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
extm3u_open_stream(InputStream &is)
|
extm3u_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
ExtM3uPlaylist *playlist = new ExtM3uPlaylist(is);
|
ExtM3uPlaylist *playlist = new ExtM3uPlaylist(std::move(is));
|
||||||
|
|
||||||
if (!playlist->CheckFirstLine()) {
|
is = playlist->CheckFirstLine();
|
||||||
|
if (is) {
|
||||||
/* no EXTM3U header: fall back to the plain m3u
|
/* no EXTM3U header: fall back to the plain m3u
|
||||||
plugin */
|
plugin */
|
||||||
delete playlist;
|
delete playlist;
|
||||||
|
@ -29,17 +29,17 @@ class M3uPlaylist final : public SongEnumerator {
|
|||||||
TextInputStream tis;
|
TextInputStream tis;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
M3uPlaylist(InputStream &is)
|
M3uPlaylist(InputStreamPtr &&is)
|
||||||
:tis(is) {
|
:tis(std::move(is)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
virtual std::unique_ptr<DetachedSong> NextSong() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
m3u_open_stream(InputStream &is)
|
m3u_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
return new M3uPlaylist(is);
|
return new M3uPlaylist(std::move(is));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<DetachedSong>
|
std::unique_ptr<DetachedSong>
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "../PlaylistPlugin.hxx"
|
#include "../PlaylistPlugin.hxx"
|
||||||
#include "../MemorySongEnumerator.hxx"
|
#include "../MemorySongEnumerator.hxx"
|
||||||
#include "input/TextInputStream.hxx"
|
#include "input/TextInputStream.hxx"
|
||||||
|
#include "input/InputStream.hxx"
|
||||||
#include "DetachedSong.hxx"
|
#include "DetachedSong.hxx"
|
||||||
#include "tag/TagBuilder.hxx"
|
#include "tag/TagBuilder.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
@ -142,17 +143,22 @@ ParsePls(TextInputStream &is, std::forward_list<DetachedSong> &songs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ParsePls(InputStream &is, std::forward_list<DetachedSong> &songs)
|
ParsePls(InputStreamPtr &&is, std::forward_list<DetachedSong> &songs)
|
||||||
{
|
{
|
||||||
TextInputStream tis(is);
|
TextInputStream tis(std::move(is));
|
||||||
return ParsePls(tis, songs);
|
if (!ParsePls(tis, songs)) {
|
||||||
|
is = tis.StealInputStream();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
pls_open_stream(InputStream &is)
|
pls_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
std::forward_list<DetachedSong> songs;
|
std::forward_list<DetachedSong> songs;
|
||||||
if (!ParsePls(is, songs))
|
if (!ParsePls(std::move(is), songs))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return new MemorySongEnumerator(std::move(songs));
|
return new MemorySongEnumerator(std::move(songs));
|
||||||
|
@ -142,7 +142,7 @@ rss_char_data(void *user_data, const XML_Char *s, int len)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
rss_open_stream(InputStream &is)
|
rss_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
RssParser parser;
|
RssParser parser;
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ rss_open_stream(InputStream &is)
|
|||||||
expat.SetCharacterDataHandler(rss_char_data);
|
expat.SetCharacterDataHandler(rss_char_data);
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!expat.Parse(is, error)) {
|
if (!expat.Parse(*is, error)) {
|
||||||
LogError(error);
|
LogError(error);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ xspf_char_data(void *user_data, const XML_Char *s, int len)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static SongEnumerator *
|
static SongEnumerator *
|
||||||
xspf_open_stream(InputStream &is)
|
xspf_open_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
XspfParser parser;
|
XspfParser parser;
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ xspf_open_stream(InputStream &is)
|
|||||||
expat.SetCharacterDataHandler(xspf_char_data);
|
expat.SetCharacterDataHandler(xspf_char_data);
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!expat.Parse(is, error)) {
|
if (!expat.Parse(*is, error)) {
|
||||||
LogError(error);
|
LogError(error);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ try {
|
|||||||
|
|
||||||
/* open the playlist */
|
/* open the playlist */
|
||||||
|
|
||||||
playlist = playlist_list_open_stream(*is, uri);
|
playlist = playlist_list_open_stream(std::move(is), uri);
|
||||||
if (playlist == NULL) {
|
if (playlist == NULL) {
|
||||||
fprintf(stderr, "Failed to open playlist\n");
|
fprintf(stderr, "Failed to open playlist\n");
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -44,23 +44,23 @@ dump_text_file(TextInputStream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_input_stream(InputStream &is)
|
dump_input_stream(InputStreamPtr &&is)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
TextInputStream tis(is);
|
TextInputStream tis(std::move(is));
|
||||||
dump_text_file(tis);
|
dump_text_file(tis);
|
||||||
}
|
}
|
||||||
|
|
||||||
is.Lock();
|
is->Lock();
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (!is.Check(error)) {
|
if (!is->Check(error)) {
|
||||||
LogError(error);
|
LogError(error);
|
||||||
is.Unlock();
|
is->Unlock();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
is.Unlock();
|
is->Unlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
auto is = InputStream::OpenReady(argv[1], mutex, cond, error);
|
auto is = InputStream::OpenReady(argv[1], mutex, cond, error);
|
||||||
if (is) {
|
if (is) {
|
||||||
ret = dump_input_stream(*is);
|
ret = dump_input_stream(std::move(is));
|
||||||
} else {
|
} else {
|
||||||
if (error.IsDefined())
|
if (error.IsDefined())
|
||||||
LogError(error);
|
LogError(error);
|
||||||
|
Loading…
Reference in New Issue
Block a user