*Save, *State: use the OutputStream API instead of FILE*
This commit is contained in:
parent
0d0ccacdf3
commit
9fb351a139
@ -21,6 +21,7 @@
|
|||||||
#include "PlaylistDatabase.hxx"
|
#include "PlaylistDatabase.hxx"
|
||||||
#include "db/PlaylistVector.hxx"
|
#include "db/PlaylistVector.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
@ -31,10 +32,10 @@
|
|||||||
static constexpr Domain playlist_database_domain("playlist_database");
|
static constexpr Domain playlist_database_domain("playlist_database");
|
||||||
|
|
||||||
void
|
void
|
||||||
playlist_vector_save(FILE *fp, const PlaylistVector &pv)
|
playlist_vector_save(BufferedOutputStream &os, const PlaylistVector &pv)
|
||||||
{
|
{
|
||||||
for (const PlaylistInfo &pi : pv)
|
for (const PlaylistInfo &pi : pv)
|
||||||
fprintf(fp, PLAYLIST_META_BEGIN "%s\n"
|
os.Format(PLAYLIST_META_BEGIN "%s\n"
|
||||||
"mtime: %li\n"
|
"mtime: %li\n"
|
||||||
"playlist_end\n",
|
"playlist_end\n",
|
||||||
pi.name.c_str(), (long)pi.mtime);
|
pi.name.c_str(), (long)pi.mtime);
|
||||||
|
@ -22,16 +22,15 @@
|
|||||||
|
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define PLAYLIST_META_BEGIN "playlist_begin: "
|
#define PLAYLIST_META_BEGIN "playlist_begin: "
|
||||||
|
|
||||||
class PlaylistVector;
|
class PlaylistVector;
|
||||||
|
class BufferedOutputStream;
|
||||||
class TextFile;
|
class TextFile;
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
void
|
void
|
||||||
playlist_vector_save(FILE *fp, const PlaylistVector &pv);
|
playlist_vector_save(BufferedOutputStream &os, const PlaylistVector &pv);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name,
|
playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name,
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "DetachedSong.hxx"
|
#include "DetachedSong.hxx"
|
||||||
#include "TagSave.hxx"
|
#include "TagSave.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "tag/TagBuilder.hxx"
|
#include "tag/TagBuilder.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
@ -38,38 +39,38 @@
|
|||||||
static constexpr Domain song_save_domain("song_save");
|
static constexpr Domain song_save_domain("song_save");
|
||||||
|
|
||||||
static void
|
static void
|
||||||
range_save(FILE *file, unsigned start_ms, unsigned end_ms)
|
range_save(BufferedOutputStream &os, unsigned start_ms, unsigned end_ms)
|
||||||
{
|
{
|
||||||
if (end_ms > 0)
|
if (end_ms > 0)
|
||||||
fprintf(file, "Range: %u-%u\n", start_ms, end_ms);
|
os.Format("Range: %u-%u\n", start_ms, end_ms);
|
||||||
else if (start_ms > 0)
|
else if (start_ms > 0)
|
||||||
fprintf(file, "Range: %u-\n", start_ms);
|
os.Format("Range: %u-\n", start_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
song_save(FILE *fp, const Song &song)
|
song_save(BufferedOutputStream &os, const Song &song)
|
||||||
{
|
{
|
||||||
fprintf(fp, SONG_BEGIN "%s\n", song.uri);
|
os.Format(SONG_BEGIN "%s\n", song.uri);
|
||||||
|
|
||||||
range_save(fp, song.start_ms, song.end_ms);
|
range_save(os, song.start_ms, song.end_ms);
|
||||||
|
|
||||||
tag_save(fp, song.tag);
|
tag_save(os, song.tag);
|
||||||
|
|
||||||
fprintf(fp, SONG_MTIME ": %li\n", (long)song.mtime);
|
os.Format(SONG_MTIME ": %li\n", (long)song.mtime);
|
||||||
fprintf(fp, SONG_END "\n");
|
os.Format(SONG_END "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
song_save(FILE *fp, const DetachedSong &song)
|
song_save(BufferedOutputStream &os, const DetachedSong &song)
|
||||||
{
|
{
|
||||||
fprintf(fp, SONG_BEGIN "%s\n", song.GetURI());
|
os.Format(SONG_BEGIN "%s\n", song.GetURI());
|
||||||
|
|
||||||
range_save(fp, song.GetStartMS(), song.GetEndMS());
|
range_save(os, song.GetStartMS(), song.GetEndMS());
|
||||||
|
|
||||||
tag_save(fp, song.GetTag());
|
tag_save(os, song.GetTag());
|
||||||
|
|
||||||
fprintf(fp, SONG_MTIME ": %li\n", (long)song.GetLastModified());
|
os.Format(SONG_MTIME ": %li\n", (long)song.GetLastModified());
|
||||||
fprintf(fp, SONG_END "\n");
|
os.Format(SONG_END "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedSong *
|
DetachedSong *
|
||||||
|
@ -20,21 +20,20 @@
|
|||||||
#ifndef MPD_SONG_SAVE_HXX
|
#ifndef MPD_SONG_SAVE_HXX
|
||||||
#define MPD_SONG_SAVE_HXX
|
#define MPD_SONG_SAVE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define SONG_BEGIN "song_begin: "
|
#define SONG_BEGIN "song_begin: "
|
||||||
|
|
||||||
struct Song;
|
struct Song;
|
||||||
struct Directory;
|
struct Directory;
|
||||||
class DetachedSong;
|
class DetachedSong;
|
||||||
|
class BufferedOutputStream;
|
||||||
class TextFile;
|
class TextFile;
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
void
|
void
|
||||||
song_save(FILE *fp, const Song &song);
|
song_save(BufferedOutputStream &os, const Song &song);
|
||||||
|
|
||||||
void
|
void
|
||||||
song_save(FILE *fp, const DetachedSong &song);
|
song_save(BufferedOutputStream &os, const DetachedSong &song);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a song from the input file. Reading stops after the
|
* Loads a song from the input file. Reading stops after the
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "output/OutputState.hxx"
|
#include "output/OutputState.hxx"
|
||||||
#include "queue/PlaylistState.hxx"
|
#include "queue/PlaylistState.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/FileOutputStream.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "Partition.hxx"
|
#include "Partition.hxx"
|
||||||
#include "Instance.hxx"
|
#include "Instance.hxx"
|
||||||
#include "mixer/Volume.hxx"
|
#include "mixer/Volume.hxx"
|
||||||
@ -62,25 +64,35 @@ StateFile::IsModified() const
|
|||||||
partition.pc);
|
partition.pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
StateFile::Write(BufferedOutputStream &os)
|
||||||
|
{
|
||||||
|
save_sw_volume_state(os);
|
||||||
|
audio_output_state_save(os, partition.outputs);
|
||||||
|
playlist_state_save(os, partition.playlist, partition.pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
StateFile::Write(OutputStream &os, Error &error)
|
||||||
|
{
|
||||||
|
BufferedOutputStream bos(os);
|
||||||
|
Write(bos);
|
||||||
|
return bos.Flush(error);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StateFile::Write()
|
StateFile::Write()
|
||||||
{
|
{
|
||||||
FormatDebug(state_file_domain,
|
FormatDebug(state_file_domain,
|
||||||
"Saving state file %s", path_utf8.c_str());
|
"Saving state file %s", path_utf8.c_str());
|
||||||
|
|
||||||
FILE *fp = FOpen(path, FOpenMode::WriteText);
|
Error error;
|
||||||
if (gcc_unlikely(!fp)) {
|
FileOutputStream fos(path, error);
|
||||||
FormatErrno(state_file_domain, "failed to create %s",
|
if (!fos.IsDefined() || !Write(fos, error) || !fos.Commit(error)) {
|
||||||
path_utf8.c_str());
|
LogError(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_sw_volume_state(fp);
|
|
||||||
audio_output_state_save(fp, partition.outputs);
|
|
||||||
playlist_state_save(fp, partition.playlist, partition.pc);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
RememberVersions();
|
RememberVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct Partition;
|
struct Partition;
|
||||||
|
class OutputStream;
|
||||||
|
class BufferedOutputStream;
|
||||||
|
|
||||||
class StateFile final : private TimeoutMonitor {
|
class StateFile final : private TimeoutMonitor {
|
||||||
AllocatedPath path;
|
AllocatedPath path;
|
||||||
@ -53,6 +55,9 @@ public:
|
|||||||
void CheckModified();
|
void CheckModified();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool Write(OutputStream &os, Error &error);
|
||||||
|
void Write(BufferedOutputStream &os);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current state versions for use with IsModified().
|
* Save the current state versions for use with IsModified().
|
||||||
*/
|
*/
|
||||||
|
@ -20,19 +20,19 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "TagSave.hxx"
|
#include "TagSave.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
|
|
||||||
#define SONG_TIME "Time: "
|
#define SONG_TIME "Time: "
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_save(FILE *file, const Tag &tag)
|
tag_save(BufferedOutputStream &os, const Tag &tag)
|
||||||
{
|
{
|
||||||
if (tag.time >= 0)
|
if (tag.time >= 0)
|
||||||
fprintf(file, SONG_TIME "%i\n", tag.time);
|
os.Format(SONG_TIME "%i\n", tag.time);
|
||||||
|
|
||||||
if (tag.has_playlist)
|
if (tag.has_playlist)
|
||||||
fprintf(file, "Playlist: yes\n");
|
os.Format("Playlist: yes\n");
|
||||||
|
|
||||||
for (const auto &i : tag)
|
for (const auto &i : tag)
|
||||||
fprintf(file, "%s: %s\n",
|
os.Format("%s: %s\n", tag_item_names[i.type], i.value);
|
||||||
tag_item_names[i.type], i.value);
|
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,10 @@
|
|||||||
#ifndef MPD_TAG_SAVE_HXX
|
#ifndef MPD_TAG_SAVE_HXX
|
||||||
#define MPD_TAG_SAVE_HXX
|
#define MPD_TAG_SAVE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
class BufferedOutputStream;
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_save(FILE *file, const Tag &tag);
|
tag_save(BufferedOutputStream &os, const Tag &tag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "db/DatabaseError.hxx"
|
#include "db/DatabaseError.hxx"
|
||||||
#include "Directory.hxx"
|
#include "Directory.hxx"
|
||||||
#include "DirectorySave.hxx"
|
#include "DirectorySave.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "tag/TagSettings.h"
|
#include "tag/TagSettings.h"
|
||||||
@ -49,20 +50,20 @@ static constexpr unsigned DB_FORMAT = 2;
|
|||||||
static constexpr unsigned OLDEST_DB_FORMAT = 1;
|
static constexpr unsigned OLDEST_DB_FORMAT = 1;
|
||||||
|
|
||||||
void
|
void
|
||||||
db_save_internal(FILE *fp, const Directory &music_root)
|
db_save_internal(BufferedOutputStream &os, const Directory &music_root)
|
||||||
{
|
{
|
||||||
fprintf(fp, "%s\n", DIRECTORY_INFO_BEGIN);
|
os.Format("%s\n", DIRECTORY_INFO_BEGIN);
|
||||||
fprintf(fp, DB_FORMAT_PREFIX "%u\n", DB_FORMAT);
|
os.Format(DB_FORMAT_PREFIX "%u\n", DB_FORMAT);
|
||||||
fprintf(fp, "%s%s\n", DIRECTORY_MPD_VERSION, VERSION);
|
os.Format("%s%s\n", DIRECTORY_MPD_VERSION, VERSION);
|
||||||
fprintf(fp, "%s%s\n", DIRECTORY_FS_CHARSET, GetFSCharset());
|
os.Format("%s%s\n", DIRECTORY_FS_CHARSET, GetFSCharset());
|
||||||
|
|
||||||
for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i)
|
for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i)
|
||||||
if (!ignore_tag_items[i])
|
if (!ignore_tag_items[i])
|
||||||
fprintf(fp, DB_TAG_PREFIX "%s\n", tag_item_names[i]);
|
os.Format(DB_TAG_PREFIX "%s\n", tag_item_names[i]);
|
||||||
|
|
||||||
fprintf(fp, "%s\n", DIRECTORY_INFO_END);
|
os.Format("%s\n", DIRECTORY_INFO_END);
|
||||||
|
|
||||||
directory_save(fp, music_root);
|
directory_save(os, music_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -20,14 +20,13 @@
|
|||||||
#ifndef MPD_DATABASE_SAVE_HXX
|
#ifndef MPD_DATABASE_SAVE_HXX
|
||||||
#define MPD_DATABASE_SAVE_HXX
|
#define MPD_DATABASE_SAVE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct Directory;
|
struct Directory;
|
||||||
|
class BufferedOutputStream;
|
||||||
class TextFile;
|
class TextFile;
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
void
|
void
|
||||||
db_save_internal(FILE *file, const Directory &root);
|
db_save_internal(BufferedOutputStream &os, const Directory &root);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
db_load_internal(TextFile &file, Directory &root, Error &error);
|
db_load_internal(TextFile &file, Directory &root, Error &error);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "DetachedSong.hxx"
|
#include "DetachedSong.hxx"
|
||||||
#include "PlaylistDatabase.hxx"
|
#include "PlaylistDatabase.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/NumberParser.hxx"
|
#include "util/NumberParser.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
@ -70,37 +71,37 @@ ParseTypeString(const char *type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_save(FILE *fp, const Directory &directory)
|
directory_save(BufferedOutputStream &os, const Directory &directory)
|
||||||
{
|
{
|
||||||
if (!directory.IsRoot()) {
|
if (!directory.IsRoot()) {
|
||||||
const char *type = DeviceToTypeString(directory.device);
|
const char *type = DeviceToTypeString(directory.device);
|
||||||
if (type != nullptr)
|
if (type != nullptr)
|
||||||
fprintf(fp, DIRECTORY_TYPE "%s\n", type);
|
os.Format(DIRECTORY_TYPE "%s\n", type);
|
||||||
|
|
||||||
if (directory.mtime != 0)
|
if (directory.mtime != 0)
|
||||||
fprintf(fp, DIRECTORY_MTIME "%lu\n",
|
os.Format(DIRECTORY_MTIME "%lu\n",
|
||||||
(unsigned long)directory.mtime);
|
(unsigned long)directory.mtime);
|
||||||
|
|
||||||
fprintf(fp, "%s%s\n", DIRECTORY_BEGIN, directory.GetPath());
|
os.Format("%s%s\n", DIRECTORY_BEGIN, directory.GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &child : directory.children) {
|
for (const auto &child : directory.children) {
|
||||||
fprintf(fp, DIRECTORY_DIR "%s\n", child.GetName());
|
os.Format(DIRECTORY_DIR "%s\n", child.GetName());
|
||||||
|
|
||||||
if (!child.IsMount())
|
if (!child.IsMount())
|
||||||
directory_save(fp, child);
|
directory_save(os, child);
|
||||||
|
|
||||||
if (ferror(fp))
|
if (!os.Check())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &song : directory.songs)
|
for (const auto &song : directory.songs)
|
||||||
song_save(fp, song);
|
song_save(os, song);
|
||||||
|
|
||||||
playlist_vector_save(fp, directory.playlists);
|
playlist_vector_save(os, directory.playlists);
|
||||||
|
|
||||||
if (!directory.IsRoot())
|
if (!directory.IsRoot())
|
||||||
fprintf(fp, DIRECTORY_END "%s\n", directory.GetPath());
|
os.Format(DIRECTORY_END "%s\n", directory.GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -20,14 +20,13 @@
|
|||||||
#ifndef MPD_DIRECTORY_SAVE_HXX
|
#ifndef MPD_DIRECTORY_SAVE_HXX
|
||||||
#define MPD_DIRECTORY_SAVE_HXX
|
#define MPD_DIRECTORY_SAVE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct Directory;
|
struct Directory;
|
||||||
class TextFile;
|
class TextFile;
|
||||||
|
class BufferedOutputStream;
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_save(FILE *fp, const Directory &directory);
|
directory_save(BufferedOutputStream &os, const Directory &directory);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
directory_load(TextFile &file, Directory &directory, Error &error);
|
directory_load(TextFile &file, Directory &directory, Error &error);
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include "db/DatabaseLock.hxx"
|
#include "db/DatabaseLock.hxx"
|
||||||
#include "db/DatabaseError.hxx"
|
#include "db/DatabaseError.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
|
#include "fs/output/FileOutputStream.hxx"
|
||||||
#include "config/ConfigData.hxx"
|
#include "config/ConfigData.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
#include "util/CharUtil.hxx"
|
#include "util/CharUtil.hxx"
|
||||||
@ -366,22 +368,16 @@ SimpleDatabase::Save(Error &error)
|
|||||||
|
|
||||||
LogDebug(simple_db_domain, "writing DB");
|
LogDebug(simple_db_domain, "writing DB");
|
||||||
|
|
||||||
FILE *fp = FOpen(path, FOpenMode::WriteText);
|
FileOutputStream fos(path, error);
|
||||||
if (!fp) {
|
if (!fos.IsDefined())
|
||||||
error.FormatErrno("unable to write to db file \"%s\"",
|
|
||||||
path_utf8.c_str());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
db_save_internal(fp, *root);
|
BufferedOutputStream bos(fos);
|
||||||
|
|
||||||
if (ferror(fp)) {
|
db_save_internal(bos, *root);
|
||||||
error.SetErrno("Failed to write to database file");
|
|
||||||
fclose(fp);
|
if (!bos.Flush(error) || !fos.Commit(error))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (StatFile(path, st))
|
if (StatFile(path, st))
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "system/PeriodClock.hxx"
|
#include "system/PeriodClock.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -110,9 +111,10 @@ read_sw_volume_state(const char *line, MultipleOutputs &outputs)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_sw_volume_state(FILE *fp)
|
void
|
||||||
|
save_sw_volume_state(BufferedOutputStream &os)
|
||||||
{
|
{
|
||||||
fprintf(fp, SW_VOLUME_STATE "%u\n", volume_software_set);
|
os.Format(SW_VOLUME_STATE "%u\n", volume_software_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
|
@ -22,9 +22,8 @@
|
|||||||
|
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class MultipleOutputs;
|
class MultipleOutputs;
|
||||||
|
class BufferedOutputStream;
|
||||||
|
|
||||||
void
|
void
|
||||||
InvalidateHardwareVolume();
|
InvalidateHardwareVolume();
|
||||||
@ -39,7 +38,8 @@ volume_level_change(MultipleOutputs &outputs, unsigned volume);
|
|||||||
bool
|
bool
|
||||||
read_sw_volume_state(const char *line, MultipleOutputs &outputs);
|
read_sw_volume_state(const char *line, MultipleOutputs &outputs);
|
||||||
|
|
||||||
void save_sw_volume_state(FILE *fp);
|
void
|
||||||
|
save_sw_volume_state(BufferedOutputStream &os);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a hash number for the current state of the software
|
* Generates a hash number for the current state of the software
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "Internal.hxx"
|
#include "Internal.hxx"
|
||||||
#include "Domain.hxx"
|
#include "Domain.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -38,13 +39,13 @@
|
|||||||
unsigned audio_output_state_version;
|
unsigned audio_output_state_version;
|
||||||
|
|
||||||
void
|
void
|
||||||
audio_output_state_save(FILE *fp, const MultipleOutputs &outputs)
|
audio_output_state_save(BufferedOutputStream &os,
|
||||||
|
const MultipleOutputs &outputs)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0, n = outputs.Size(); i != n; ++i) {
|
for (unsigned i = 0, n = outputs.Size(); i != n; ++i) {
|
||||||
const AudioOutput &ao = outputs.Get(i);
|
const AudioOutput &ao = outputs.Get(i);
|
||||||
|
|
||||||
fprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n",
|
os.Format(AUDIO_DEVICE_STATE "%d:%s\n", ao.enabled, ao.name);
|
||||||
ao.enabled, ao.name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,15 +25,15 @@
|
|||||||
#ifndef MPD_OUTPUT_STATE_HXX
|
#ifndef MPD_OUTPUT_STATE_HXX
|
||||||
#define MPD_OUTPUT_STATE_HXX
|
#define MPD_OUTPUT_STATE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
class MultipleOutputs;
|
class MultipleOutputs;
|
||||||
|
class BufferedOutputStream;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
audio_output_state_read(const char *line, MultipleOutputs &outputs);
|
audio_output_state_read(const char *line, MultipleOutputs &outputs);
|
||||||
|
|
||||||
void
|
void
|
||||||
audio_output_state_save(FILE *fp, const MultipleOutputs &outputs);
|
audio_output_state_save(BufferedOutputStream &os,
|
||||||
|
const MultipleOutputs &outputs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a version number for the current state of the audio
|
* Generates a version number for the current state of the audio
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "Playlist.hxx"
|
#include "Playlist.hxx"
|
||||||
#include "queue/QueueSave.hxx"
|
#include "queue/QueueSave.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "PlayerControl.hxx"
|
#include "PlayerControl.hxx"
|
||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/ConfigOption.hxx"
|
#include "config/ConfigOption.hxx"
|
||||||
@ -59,47 +60,45 @@
|
|||||||
#define PLAYLIST_BUFFER_SIZE 2*MPD_PATH_MAX
|
#define PLAYLIST_BUFFER_SIZE 2*MPD_PATH_MAX
|
||||||
|
|
||||||
void
|
void
|
||||||
playlist_state_save(FILE *fp, const struct playlist &playlist,
|
playlist_state_save(BufferedOutputStream &os, const struct playlist &playlist,
|
||||||
PlayerControl &pc)
|
PlayerControl &pc)
|
||||||
{
|
{
|
||||||
const auto player_status = pc.GetStatus();
|
const auto player_status = pc.GetStatus();
|
||||||
|
|
||||||
fputs(PLAYLIST_STATE_FILE_STATE, fp);
|
os.Write(PLAYLIST_STATE_FILE_STATE);
|
||||||
|
|
||||||
if (playlist.playing) {
|
if (playlist.playing) {
|
||||||
switch (player_status.state) {
|
switch (player_status.state) {
|
||||||
case PlayerState::PAUSE:
|
case PlayerState::PAUSE:
|
||||||
fputs(PLAYLIST_STATE_FILE_STATE_PAUSE "\n", fp);
|
os.Write(PLAYLIST_STATE_FILE_STATE_PAUSE "\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fputs(PLAYLIST_STATE_FILE_STATE_PLAY "\n", fp);
|
os.Write(PLAYLIST_STATE_FILE_STATE_PLAY "\n");
|
||||||
}
|
}
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_CURRENT "%i\n",
|
os.Format(PLAYLIST_STATE_FILE_CURRENT "%i\n",
|
||||||
playlist.queue.OrderToPosition(playlist.current));
|
playlist.queue.OrderToPosition(playlist.current));
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_TIME "%i\n",
|
os.Format(PLAYLIST_STATE_FILE_TIME "%i\n",
|
||||||
(int)player_status.elapsed_time);
|
(int)player_status.elapsed_time);
|
||||||
} else {
|
} else {
|
||||||
fputs(PLAYLIST_STATE_FILE_STATE_STOP "\n", fp);
|
os.Write(PLAYLIST_STATE_FILE_STATE_STOP "\n");
|
||||||
|
|
||||||
if (playlist.current >= 0)
|
if (playlist.current >= 0)
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_CURRENT "%i\n",
|
os.Format(PLAYLIST_STATE_FILE_CURRENT "%i\n",
|
||||||
playlist.queue.OrderToPosition(playlist.current));
|
playlist.queue.OrderToPosition(playlist.current));
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_RANDOM "%i\n", playlist.queue.random);
|
os.Format(PLAYLIST_STATE_FILE_RANDOM "%i\n", playlist.queue.random);
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_REPEAT "%i\n", playlist.queue.repeat);
|
os.Format(PLAYLIST_STATE_FILE_REPEAT "%i\n", playlist.queue.repeat);
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_SINGLE "%i\n", playlist.queue.single);
|
os.Format(PLAYLIST_STATE_FILE_SINGLE "%i\n", playlist.queue.single);
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_CONSUME "%i\n",
|
os.Format(PLAYLIST_STATE_FILE_CONSUME "%i\n", playlist.queue.consume);
|
||||||
playlist.queue.consume);
|
os.Format(PLAYLIST_STATE_FILE_CROSSFADE "%i\n",
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_CROSSFADE "%i\n",
|
|
||||||
(int)pc.GetCrossFade());
|
(int)pc.GetCrossFade());
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_MIXRAMPDB "%f\n",
|
os.Format(PLAYLIST_STATE_FILE_MIXRAMPDB "%f\n", pc.GetMixRampDb());
|
||||||
pc.GetMixRampDb());
|
os.Format(PLAYLIST_STATE_FILE_MIXRAMPDELAY "%f\n",
|
||||||
fprintf(fp, PLAYLIST_STATE_FILE_MIXRAMPDELAY "%f\n",
|
|
||||||
pc.GetMixRampDelay());
|
pc.GetMixRampDelay());
|
||||||
fputs(PLAYLIST_STATE_FILE_PLAYLIST_BEGIN "\n", fp);
|
os.Write(PLAYLIST_STATE_FILE_PLAYLIST_BEGIN "\n");
|
||||||
queue_save(fp, playlist.queue);
|
queue_save(os, playlist.queue);
|
||||||
fputs(PLAYLIST_STATE_FILE_PLAYLIST_END "\n", fp);
|
os.Write(PLAYLIST_STATE_FILE_PLAYLIST_END "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -25,15 +25,14 @@
|
|||||||
#ifndef MPD_PLAYLIST_STATE_HXX
|
#ifndef MPD_PLAYLIST_STATE_HXX
|
||||||
#define MPD_PLAYLIST_STATE_HXX
|
#define MPD_PLAYLIST_STATE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct playlist;
|
struct playlist;
|
||||||
struct PlayerControl;
|
struct PlayerControl;
|
||||||
class TextFile;
|
class TextFile;
|
||||||
|
class BufferedOutputStream;
|
||||||
class SongLoader;
|
class SongLoader;
|
||||||
|
|
||||||
void
|
void
|
||||||
playlist_state_save(FILE *fp, const playlist &playlist,
|
playlist_state_save(BufferedOutputStream &os, const playlist &playlist,
|
||||||
PlayerControl &pc);
|
PlayerControl &pc);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "SongLoader.hxx"
|
#include "SongLoader.hxx"
|
||||||
#include "playlist/PlaylistSong.hxx"
|
#include "playlist/PlaylistSong.hxx"
|
||||||
#include "fs/TextFile.hxx"
|
#include "fs/TextFile.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
#include "util/StringUtil.hxx"
|
#include "util/StringUtil.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "fs/Traits.hxx"
|
#include "fs/Traits.hxx"
|
||||||
@ -36,40 +37,41 @@
|
|||||||
#define PRIO_LABEL "Prio: "
|
#define PRIO_LABEL "Prio: "
|
||||||
|
|
||||||
static void
|
static void
|
||||||
queue_save_database_song(FILE *fp, int idx, const DetachedSong &song)
|
queue_save_database_song(BufferedOutputStream &os,
|
||||||
|
int idx, const DetachedSong &song)
|
||||||
{
|
{
|
||||||
fprintf(fp, "%i:%s\n", idx, song.GetURI());
|
os.Format("%i:%s\n", idx, song.GetURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
queue_save_full_song(FILE *fp, const DetachedSong &song)
|
queue_save_full_song(BufferedOutputStream &os, const DetachedSong &song)
|
||||||
{
|
{
|
||||||
song_save(fp, song);
|
song_save(os, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
queue_save_song(FILE *fp, int idx, const DetachedSong &song)
|
queue_save_song(BufferedOutputStream &os, int idx, const DetachedSong &song)
|
||||||
{
|
{
|
||||||
if (song.IsInDatabase() &&
|
if (song.IsInDatabase() &&
|
||||||
song.GetStartMS() == 0 && song.GetEndMS() == 0)
|
song.GetStartMS() == 0 && song.GetEndMS() == 0)
|
||||||
/* use the brief format (just the URI) for "full"
|
/* use the brief format (just the URI) for "full"
|
||||||
database songs */
|
database songs */
|
||||||
queue_save_database_song(fp, idx, song);
|
queue_save_database_song(os, idx, song);
|
||||||
else
|
else
|
||||||
/* use the long format (URI, range, tags) for the
|
/* use the long format (URI, range, tags) for the
|
||||||
rest, so all metadata survives a MPD restart */
|
rest, so all metadata survives a MPD restart */
|
||||||
queue_save_full_song(fp, song);
|
queue_save_full_song(os, song);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
queue_save(FILE *fp, const Queue &queue)
|
queue_save(BufferedOutputStream &os, const Queue &queue)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < queue.GetLength(); i++) {
|
for (unsigned i = 0; i < queue.GetLength(); i++) {
|
||||||
uint8_t prio = queue.GetPriorityAtPosition(i);
|
uint8_t prio = queue.GetPriorityAtPosition(i);
|
||||||
if (prio != 0)
|
if (prio != 0)
|
||||||
fprintf(fp, PRIO_LABEL "%u\n", prio);
|
os.Format(PRIO_LABEL "%u\n", prio);
|
||||||
|
|
||||||
queue_save_song(fp, i, queue.Get(i));
|
queue_save_song(os, i, queue.Get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,14 +25,13 @@
|
|||||||
#ifndef MPD_QUEUE_SAVE_HXX
|
#ifndef MPD_QUEUE_SAVE_HXX
|
||||||
#define MPD_QUEUE_SAVE_HXX
|
#define MPD_QUEUE_SAVE_HXX
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct Queue;
|
struct Queue;
|
||||||
|
class BufferedOutputStream;
|
||||||
class TextFile;
|
class TextFile;
|
||||||
class SongLoader;
|
class SongLoader;
|
||||||
|
|
||||||
void
|
void
|
||||||
queue_save(FILE *fp, const Queue &queue);
|
queue_save(BufferedOutputStream &os, const Queue &queue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads one song from the state file and appends it to the queue.
|
* Loads one song from the state file and appends it to the queue.
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include "playlist/PlaylistRegistry.hxx"
|
#include "playlist/PlaylistRegistry.hxx"
|
||||||
#include "playlist/PlaylistPlugin.hxx"
|
#include "playlist/PlaylistPlugin.hxx"
|
||||||
#include "fs/Path.hxx"
|
#include "fs/Path.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
|
#include "fs/output/StdioOutputStream.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
@ -40,6 +42,15 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
tag_save(FILE *file, const Tag &tag)
|
||||||
|
{
|
||||||
|
StdioOutputStream sos(file);
|
||||||
|
BufferedOutputStream bos(sos);
|
||||||
|
tag_save(bos, tag);
|
||||||
|
bos.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *uri;
|
const char *uri;
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "thread/Cond.hxx"
|
#include "thread/Cond.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
#include "fs/output/BufferedOutputStream.hxx"
|
||||||
|
#include "fs/output/StdioOutputStream.hxx"
|
||||||
|
|
||||||
#ifdef ENABLE_ARCHIVE
|
#ifdef ENABLE_ARCHIVE
|
||||||
#include "archive/ArchiveList.hxx"
|
#include "archive/ArchiveList.hxx"
|
||||||
@ -40,6 +42,15 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
tag_save(FILE *file, const Tag &tag)
|
||||||
|
{
|
||||||
|
StdioOutputStream sos(file);
|
||||||
|
BufferedOutputStream bos(sos);
|
||||||
|
tag_save(bos, tag);
|
||||||
|
bos.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_input_stream(InputStream *is)
|
dump_input_stream(InputStream *is)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user