db/simple/Song: wrap in std::unique_ptr<>

This commit is contained in:
Max Kellermann 2019-05-21 22:46:34 +02:00
parent 02bb47dd08
commit bbdf2dcf1e
10 changed files with 65 additions and 41 deletions

View File

@ -41,18 +41,16 @@
#ifdef ENABLE_DATABASE #ifdef ENABLE_DATABASE
Song * SongPtr
Song::LoadFile(Storage &storage, const char *path_utf8, Song::LoadFile(Storage &storage, const char *path_utf8,
Directory &parent) noexcept Directory &parent) noexcept
{ {
assert(!uri_has_scheme(path_utf8)); assert(!uri_has_scheme(path_utf8));
assert(strchr(path_utf8, '\n') == nullptr); assert(strchr(path_utf8, '\n') == nullptr);
Song *song = NewFile(path_utf8, parent); auto song = NewFile(path_utf8, parent);
if (!song->UpdateFile(storage)) { if (!song->UpdateFile(storage))
song->Free();
return nullptr; return nullptr;
}
return song; return song;
} }
@ -102,19 +100,17 @@ Song::UpdateFile(Storage &storage) noexcept
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
Song * SongPtr
Song::LoadFromArchive(ArchiveFile &archive, const char *name_utf8, Song::LoadFromArchive(ArchiveFile &archive, const char *name_utf8,
Directory &parent) noexcept Directory &parent) noexcept
{ {
assert(!uri_has_scheme(name_utf8)); assert(!uri_has_scheme(name_utf8));
assert(strchr(name_utf8, '\n') == nullptr); assert(strchr(name_utf8, '\n') == nullptr);
Song *song = NewFile(name_utf8, parent); auto song = NewFile(name_utf8, parent);
if (!song->UpdateFileInArchive(archive)) { if (!song->UpdateFileInArchive(archive))
song->Free();
return nullptr; return nullptr;
}
return song; return song;
} }

View File

@ -164,13 +164,13 @@ Directory::LookupDirectory(const char *uri) noexcept
} }
void void
Directory::AddSong(Song *song) noexcept Directory::AddSong(SongPtr song) noexcept
{ {
assert(holding_db_lock()); assert(holding_db_lock());
assert(song != nullptr); assert(song != nullptr);
assert(song->parent == this); assert(song->parent == this);
songs.push_back(*song); songs.push_back(*song.release());
} }
void void

View File

@ -20,6 +20,7 @@
#ifndef MPD_DIRECTORY_HXX #ifndef MPD_DIRECTORY_HXX
#define MPD_DIRECTORY_HXX #define MPD_DIRECTORY_HXX
#include "Ptr.hxx"
#include "util/Compiler.h" #include "util/Compiler.h"
#include "db/Visitor.hxx" #include "db/Visitor.hxx"
#include "db/PlaylistVector.hxx" #include "db/PlaylistVector.hxx"
@ -242,7 +243,7 @@ public:
* Add a song object to this directory. Its "parent" attribute must * Add a song object to this directory. Its "parent" attribute must
* be set already. * be set already.
*/ */
void AddSong(Song *song) noexcept; void AddSong(SongPtr song) noexcept;
/** /**
* Remove a song object from this directory (which effectively * Remove a song object from this directory (which effectively

View File

@ -168,7 +168,7 @@ directory_load(TextFile &file, Directory &directory)
directory); directory);
song->audio_format = audio_format; song->audio_format = audio_format;
directory.AddSong(song); directory.AddSong(std::move(song));
} else if ((p = StringAfterPrefix(line, PLAYLIST_META_BEGIN))) { } else if ((p = StringAfterPrefix(line, PLAYLIST_META_BEGIN))) {
const char *name = p; const char *name = p;
playlist_metadata_load(file, directory.playlists, name); playlist_metadata_load(file, directory.playlists, name);

View File

@ -0,0 +1,29 @@
/*
* Copyright 2003-2019 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_SONG_PTR_HXX
#define MPD_SONG_PTR_HXX
#include "Disposer.hxx"
#include <memory>
using SongPtr = std::unique_ptr<Song, SongDisposer>;
#endif

View File

@ -40,7 +40,7 @@ Song::~Song() noexcept
{ {
} }
static Song * static SongPtr
song_alloc(const char *uri, Directory &parent) noexcept song_alloc(const char *uri, Directory &parent) noexcept
{ {
size_t uri_length; size_t uri_length;
@ -49,15 +49,16 @@ song_alloc(const char *uri, Directory &parent) noexcept
uri_length = strlen(uri); uri_length = strlen(uri);
assert(uri_length); assert(uri_length);
return NewVarSize<Song>(sizeof(Song::uri), auto *song = NewVarSize<Song>(sizeof(Song::uri),
uri_length + 1, uri_length + 1,
uri, uri_length, parent); uri, uri_length, parent);
return SongPtr(song);
} }
Song * SongPtr
Song::NewFrom(DetachedSong &&other, Directory &parent) noexcept Song::NewFrom(DetachedSong &&other, Directory &parent) noexcept
{ {
Song *song = song_alloc(other.GetURI(), parent); SongPtr song(song_alloc(other.GetURI(), parent));
song->tag = std::move(other.WritableTag()); song->tag = std::move(other.WritableTag());
song->mtime = other.GetLastModified(); song->mtime = other.GetLastModified();
song->start_time = other.GetStartTime(); song->start_time = other.GetStartTime();
@ -65,10 +66,10 @@ Song::NewFrom(DetachedSong &&other, Directory &parent) noexcept
return song; return song;
} }
Song * SongPtr
Song::NewFile(const char *path, Directory &parent) noexcept Song::NewFile(const char *path, Directory &parent) noexcept
{ {
return song_alloc(path, parent); return SongPtr(song_alloc(path, parent));
} }
void void

View File

@ -20,6 +20,7 @@
#ifndef MPD_SONG_HXX #ifndef MPD_SONG_HXX
#define MPD_SONG_HXX #define MPD_SONG_HXX
#include "Ptr.hxx"
#include "Chrono.hxx" #include "Chrono.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
@ -95,20 +96,17 @@ struct Song {
Song(const char *_uri, size_t uri_length, Directory &parent) noexcept; Song(const char *_uri, size_t uri_length, Directory &parent) noexcept;
~Song() noexcept; ~Song() noexcept;
gcc_malloc gcc_returns_nonnull static SongPtr NewFrom(DetachedSong &&other, Directory &parent) noexcept;
static Song *NewFrom(DetachedSong &&other, Directory &parent) noexcept;
/** allocate a new song with a local file name */ /** allocate a new song with a local file name */
gcc_malloc gcc_returns_nonnull static SongPtr NewFile(const char *path_utf8, Directory &parent) noexcept;
static Song *NewFile(const char *path_utf8, Directory &parent) noexcept;
/** /**
* allocate a new song structure with a local file name and attempt to * allocate a new song structure with a local file name and attempt to
* load its metadata. If all decoder plugin fail to read its meta * load its metadata. If all decoder plugin fail to read its meta
* data, nullptr is returned. * data, nullptr is returned.
*/ */
gcc_malloc static SongPtr LoadFile(Storage &storage, const char *name_utf8,
static Song *LoadFile(Storage &storage, const char *name_utf8,
Directory &parent) noexcept; Directory &parent) noexcept;
void Free() noexcept; void Free() noexcept;
@ -116,7 +114,7 @@ struct Song {
bool UpdateFile(Storage &storage) noexcept; bool UpdateFile(Storage &storage) noexcept;
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
static Song *LoadFromArchive(ArchiveFile &archive, static SongPtr LoadFromArchive(ArchiveFile &archive,
const char *name_utf8, const char *name_utf8,
Directory &parent) noexcept; Directory &parent) noexcept;
bool UpdateFileInArchive(ArchiveFile &archive) noexcept; bool UpdateFileInArchive(ArchiveFile &archive) noexcept;

View File

@ -82,11 +82,11 @@ UpdateWalk::UpdateArchiveTree(ArchiveFile &archive, Directory &directory,
//add file //add file
Song *song = LockFindSong(directory, name); Song *song = LockFindSong(directory, name);
if (song == nullptr) { if (song == nullptr) {
song = Song::LoadFromArchive(archive, name, directory); auto new_song = Song::LoadFromArchive(archive, name, directory);
if (song != nullptr) { if (!new_song) {
{ {
const ScopeDatabaseLock protect; const ScopeDatabaseLock protect;
directory.AddSong(song); directory.AddSong(std::move(new_song));
} }
modified = true; modified = true;

View File

@ -102,8 +102,7 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
} }
for (auto &vtrack : v) { for (auto &vtrack : v) {
Song *song = Song::NewFrom(std::move(vtrack), auto song = Song::NewFrom(std::move(vtrack), *contdir);
*contdir);
// shouldn't be necessary but it's there.. // shouldn't be necessary but it's there..
song->mtime = info.mtime; song->mtime = info.mtime;
@ -113,7 +112,7 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
{ {
const ScopeDatabaseLock protect; const ScopeDatabaseLock protect;
contdir->AddSong(song); contdir->AddSong(std::move(song));
} }
modified = true; modified = true;

View File

@ -61,8 +61,8 @@ UpdateWalk::UpdateSongFile2(Directory &directory,
if (song == nullptr) { if (song == nullptr) {
FormatDebug(update_domain, "reading %s/%s", FormatDebug(update_domain, "reading %s/%s",
directory.GetPath(), name); directory.GetPath(), name);
song = Song::LoadFile(storage, name, directory); auto new_song = Song::LoadFile(storage, name, directory);
if (song == nullptr) { if (!new_song) {
FormatDebug(update_domain, FormatDebug(update_domain,
"ignoring unrecognized file %s/%s", "ignoring unrecognized file %s/%s",
directory.GetPath(), name); directory.GetPath(), name);
@ -71,7 +71,7 @@ UpdateWalk::UpdateSongFile2(Directory &directory,
{ {
const ScopeDatabaseLock protect; const ScopeDatabaseLock protect;
directory.AddSong(song); directory.AddSong(std::move(new_song));
} }
modified = true; modified = true;