Playlist*: use the BufferedOutputStream API instead of FILE*

This commit is contained in:
Max Kellermann 2015-03-24 20:32:23 +01:00
parent f9e0f0d257
commit 69ad5671ed
3 changed files with 38 additions and 40 deletions

View File

@ -20,12 +20,15 @@
#include "config.h" #include "config.h"
#include "PlaylistFile.hxx" #include "PlaylistFile.hxx"
#include "PlaylistSave.hxx" #include "PlaylistSave.hxx"
#include "PlaylistError.hxx"
#include "db/PlaylistInfo.hxx" #include "db/PlaylistInfo.hxx"
#include "db/PlaylistVector.hxx" #include "db/PlaylistVector.hxx"
#include "DetachedSong.hxx" #include "DetachedSong.hxx"
#include "SongLoader.hxx" #include "SongLoader.hxx"
#include "Mapper.hxx" #include "Mapper.hxx"
#include "fs/io/TextFile.hxx" #include "fs/io/TextFile.hxx"
#include "fs/io/FileOutputStream.hxx"
#include "fs/io/BufferedOutputStream.hxx"
#include "config/ConfigGlobal.hxx" #include "config/ConfigGlobal.hxx"
#include "config/ConfigOption.hxx" #include "config/ConfigOption.hxx"
#include "config/ConfigDefaults.hxx" #include "config/ConfigDefaults.hxx"
@ -229,17 +232,18 @@ SavePlaylistFile(const PlaylistFileContents &contents, const char *utf8path,
if (path_fs.IsNull()) if (path_fs.IsNull())
return false; return false;
FILE *file = FOpen(path_fs, FOpenMode::WriteText); FileOutputStream fos(path_fs, error);
if (file == nullptr) { if (!fos.IsDefined()) {
playlist_errno(error); TranslatePlaylistError(error);
return false; return false;
} }
for (const auto &uri_utf8 : contents) BufferedOutputStream bos(fos);
playlist_print_uri(file, uri_utf8.c_str());
fclose(file); for (const auto &uri_utf8 : contents)
return true; playlist_print_uri(bos, uri_utf8.c_str());
return bos.Flush(error) && fos.Commit(error);
} }
PlaylistFileContents PlaylistFileContents
@ -399,29 +403,24 @@ spl_append_song(const char *utf8path, const DetachedSong &song, Error &error)
if (path_fs.IsNull()) if (path_fs.IsNull())
return false; return false;
FILE *file = FOpen(path_fs, FOpenMode::AppendText); AppendFileOutputStream fos(path_fs, error);
if (file == nullptr) { if (!fos.IsDefined()) {
playlist_errno(error); TranslatePlaylistError(error);
return false; return false;
} }
struct stat st; if (fos.Tell() / (MPD_PATH_MAX + 1) >= playlist_max_length) {
if (fstat(fileno(file), &st) < 0) {
playlist_errno(error);
fclose(file);
return false;
}
if (st.st_size / off_t(MPD_PATH_MAX + 1) >= (off_t)playlist_max_length) {
fclose(file);
error.Set(playlist_domain, int(PlaylistResult::TOO_LARGE), error.Set(playlist_domain, int(PlaylistResult::TOO_LARGE),
"Stored playlist is too large"); "Stored playlist is too large");
return false; return false;
} }
playlist_print_song(file, song); BufferedOutputStream bos(fos);
fclose(file); playlist_print_song(bos, song);
if (!bos.Flush(error) || !fos.Commit(error))
return false;
idle_add(IDLE_STORED_PLAYLIST); idle_add(IDLE_STORED_PLAYLIST);
return true; return true;

View File

@ -30,6 +30,8 @@
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "fs/FileSystem.hxx" #include "fs/FileSystem.hxx"
#include "fs/NarrowPath.hxx" #include "fs/NarrowPath.hxx"
#include "fs/io/FileOutputStream.hxx"
#include "fs/io/BufferedOutputStream.hxx"
#include "util/Alloc.hxx" #include "util/Alloc.hxx"
#include "util/UriUtil.hxx" #include "util/UriUtil.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
@ -38,7 +40,7 @@
#include <string.h> #include <string.h>
void void
playlist_print_song(FILE *file, const DetachedSong &song) playlist_print_song(BufferedOutputStream &os, const DetachedSong &song)
{ {
const char *uri_utf8 = playlist_saveAbsolutePaths const char *uri_utf8 = playlist_saveAbsolutePaths
? song.GetRealURI() ? song.GetRealURI()
@ -46,11 +48,11 @@ playlist_print_song(FILE *file, const DetachedSong &song)
const auto uri_fs = AllocatedPath::FromUTF8(uri_utf8); const auto uri_fs = AllocatedPath::FromUTF8(uri_utf8);
if (!uri_fs.IsNull()) if (!uri_fs.IsNull())
fprintf(file, "%s\n", NarrowPath(uri_fs).c_str()); os.Format("%s\n", NarrowPath(uri_fs).c_str());
} }
void void
playlist_print_uri(FILE *file, const char *uri) playlist_print_uri(BufferedOutputStream &os, const char *uri)
{ {
auto path = auto path =
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
@ -62,7 +64,7 @@ playlist_print_uri(FILE *file, const char *uri)
AllocatedPath::FromUTF8(uri); AllocatedPath::FromUTF8(uri);
if (!path.IsNull()) if (!path.IsNull())
fprintf(file, "%s\n", NarrowPath(path).c_str()); os.Format("%s\n", NarrowPath(path).c_str());
} }
bool bool
@ -78,18 +80,19 @@ spl_save_queue(const char *name_utf8, const Queue &queue, Error &error)
return false; return false;
} }
FILE *file = FOpen(path_fs, FOpenMode::WriteText); FileOutputStream fos(path_fs, error);
if (!fos.IsDefined()) {
if (file == nullptr) { TranslatePlaylistError(error);
error.FormatErrno("Failed to open %s",
path_fs.ToUTF8().c_str());
return false; return false;
} }
for (unsigned i = 0; i < queue.GetLength(); i++) BufferedOutputStream bos(fos);
playlist_print_song(file, queue.Get(i));
fclose(file); for (unsigned i = 0; i < queue.GetLength(); i++)
playlist_print_song(bos, queue.Get(i));
if (!bos.Flush(error) || !fos.Commit(error))
return false;
idle_add(IDLE_STORED_PLAYLIST); idle_add(IDLE_STORED_PLAYLIST);
return true; return true;

View File

@ -20,21 +20,17 @@
#ifndef MPD_PLAYLIST_SAVE_H #ifndef MPD_PLAYLIST_SAVE_H
#define MPD_PLAYLIST_SAVE_H #define MPD_PLAYLIST_SAVE_H
#include "PlaylistError.hxx"
#include <stdio.h>
struct Queue; struct Queue;
struct playlist; struct playlist;
struct PlayerControl; class BufferedOutputStream;
class DetachedSong; class DetachedSong;
class Error; class Error;
void void
playlist_print_song(FILE *file, const DetachedSong &song); playlist_print_song(BufferedOutputStream &os, const DetachedSong &song);
void void
playlist_print_uri(FILE *fp, const char *uri); playlist_print_uri(BufferedOutputStream &os, const char *uri);
/** /**
* Saves a queue object into a stored playlist file. * Saves a queue object into a stored playlist file.