change internal storing of Song info (much less memory consumption)
This commit is contained in:
@@ -326,7 +326,8 @@ void MPDConnection::GetPlaylistChanges(long long id, SongList &v) const
|
|||||||
{
|
{
|
||||||
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
||||||
{
|
{
|
||||||
Song *s = new Song(item->info.song);
|
Song *s = new Song(item->info.song, 1);
|
||||||
|
item->info.song = 0;
|
||||||
v.push_back(s);
|
v.push_back(s);
|
||||||
}
|
}
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
@@ -343,6 +344,7 @@ Song MPDConnection::GetSong(const string &path) const
|
|||||||
mpd_InfoEntity *item = NULL;
|
mpd_InfoEntity *item = NULL;
|
||||||
item = mpd_getNextInfoEntity(itsConnection);
|
item = mpd_getNextInfoEntity(itsConnection);
|
||||||
Song result = item->info.song;
|
Song result = item->info.song;
|
||||||
|
item->info.song = 0;
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
mpd_finishCommand(itsConnection);
|
mpd_finishCommand(itsConnection);
|
||||||
return result;
|
return result;
|
||||||
@@ -364,6 +366,7 @@ Song MPDConnection::GetCurrentSong() const
|
|||||||
mpd_InfoEntity *item = NULL;
|
mpd_InfoEntity *item = NULL;
|
||||||
item = mpd_getNextInfoEntity(itsConnection);
|
item = mpd_getNextInfoEntity(itsConnection);
|
||||||
Song result = item->info.song;
|
Song result = item->info.song;
|
||||||
|
item->info.song = 0;
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
mpd_finishCommand(itsConnection);
|
mpd_finishCommand(itsConnection);
|
||||||
return result;
|
return result;
|
||||||
@@ -383,6 +386,7 @@ void MPDConnection::GetPlaylistContent(const string &path, SongList &v) const
|
|||||||
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
||||||
{
|
{
|
||||||
Song *s = new Song(item->info.song);
|
Song *s = new Song(item->info.song);
|
||||||
|
item->info.song = 0;
|
||||||
v.push_back(s);
|
v.push_back(s);
|
||||||
}
|
}
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
@@ -686,6 +690,7 @@ void MPDConnection::CommitSearch(SongList &v) const
|
|||||||
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
||||||
{
|
{
|
||||||
Song *s = new Song(item->info.song);
|
Song *s = new Song(item->info.song);
|
||||||
|
item->info.song = 0;
|
||||||
v.push_back(s);
|
v.push_back(s);
|
||||||
}
|
}
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
@@ -728,6 +733,7 @@ void MPDConnection::GetDirectory(const string &path, ItemList &v) const
|
|||||||
break;
|
break;
|
||||||
case MPD_INFO_ENTITY_TYPE_SONG:
|
case MPD_INFO_ENTITY_TYPE_SONG:
|
||||||
i.song = new Song(item->info.song);
|
i.song = new Song(item->info.song);
|
||||||
|
item->info.song = 0;
|
||||||
i.type = itSong;
|
i.type = itSong;
|
||||||
break;
|
break;
|
||||||
case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE:
|
case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE:
|
||||||
@@ -753,6 +759,7 @@ void MPDConnection::GetDirectoryRecursive(const string &path, SongList &v) const
|
|||||||
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
||||||
{
|
{
|
||||||
Song *s = new Song(item->info.song);
|
Song *s = new Song(item->info.song);
|
||||||
|
item->info.song = 0;
|
||||||
v.push_back(s);
|
v.push_back(s);
|
||||||
}
|
}
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
@@ -772,6 +779,7 @@ void MPDConnection::GetSongs(const string &path, SongList &v) const
|
|||||||
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG)
|
||||||
{
|
{
|
||||||
Song *s = new Song(item->info.song);
|
Song *s = new Song(item->info.song);
|
||||||
|
item->info.song = 0;
|
||||||
v.push_back(s);
|
v.push_back(s);
|
||||||
}
|
}
|
||||||
mpd_freeInfoEntity(item);
|
mpd_freeInfoEntity(item);
|
||||||
|
|||||||
@@ -1056,10 +1056,10 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Filename:[/b] ", 1);
|
wFooter->WriteXY(0, Config.statusbar_visibility, "[.b]Filename:[/b] ", 1);
|
||||||
if (s.GetShortFilename() == EMPTY_TAG)
|
if (s.GetShortFilename() == EMPTY_TAG)
|
||||||
s.SetShortFilename(wFooter->GetString());
|
s.SetFile(wFooter->GetString());
|
||||||
else
|
else
|
||||||
s.SetShortFilename(wFooter->GetString(s.GetShortFilename()));
|
s.SetFile(wFooter->GetString(s.GetFile()));
|
||||||
mSearcher->Current().first = "[.b]Filename:[/b] " + s.GetShortFilename();
|
mSearcher->Current().first = "[.b]Filename:[/b] " + s.GetFile();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ void Search(Song &s)
|
|||||||
if (!search_case_sensitive)
|
if (!search_case_sensitive)
|
||||||
{
|
{
|
||||||
string t;
|
string t;
|
||||||
t = s.GetShortFilename();
|
t = s.GetFile();
|
||||||
transform(t.begin(), t.end(), t.begin(), tolower);
|
transform(t.begin(), t.end(), t.begin(), tolower);
|
||||||
s.SetShortFilename(t);
|
s.SetFile(t);
|
||||||
|
|
||||||
t = s.GetTitle();
|
t = s.GetTitle();
|
||||||
transform(t.begin(), t.end(), t.begin(), tolower);
|
transform(t.begin(), t.end(), t.begin(), tolower);
|
||||||
@@ -123,7 +123,7 @@ void Search(Song &s)
|
|||||||
string t;
|
string t;
|
||||||
t = copy.GetShortFilename();
|
t = copy.GetShortFilename();
|
||||||
transform(t.begin(), t.end(), t.begin(), tolower);
|
transform(t.begin(), t.end(), t.begin(), tolower);
|
||||||
copy.SetShortFilename(t);
|
copy.SetFile(t);
|
||||||
|
|
||||||
t = copy.GetTitle();
|
t = copy.GetTitle();
|
||||||
transform(t.begin(), t.end(), t.begin(), tolower);
|
transform(t.begin(), t.end(), t.begin(), tolower);
|
||||||
@@ -145,11 +145,13 @@ void Search(Song &s)
|
|||||||
transform(t.begin(), t.end(), t.begin(), tolower);
|
transform(t.begin(), t.end(), t.begin(), tolower);
|
||||||
copy.SetComment(t);
|
copy.SetComment(t);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
copy.SetFile(copy.GetShortFilename());
|
||||||
|
|
||||||
if (search_match_to_pattern)
|
if (search_match_to_pattern)
|
||||||
{
|
{
|
||||||
if (found && !s.GetShortFilename().empty())
|
if (found && !s.GetFile().empty())
|
||||||
found = copy.GetShortFilename().find(s.GetShortFilename()) != string::npos;
|
found = copy.GetFile().find(s.GetFile()) != string::npos;
|
||||||
if (found && !s.GetTitle().empty())
|
if (found && !s.GetTitle().empty())
|
||||||
found = copy.GetTitle().find(s.GetTitle()) != string::npos;
|
found = copy.GetTitle().find(s.GetTitle()) != string::npos;
|
||||||
if (found && !s.GetArtist().empty())
|
if (found && !s.GetArtist().empty())
|
||||||
@@ -167,8 +169,8 @@ void Search(Song &s)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (found && !s.GetShortFilename().empty())
|
if (found && !s.GetFile().empty())
|
||||||
found = copy.GetShortFilename() == s.GetShortFilename();
|
found = copy.GetFile() == s.GetFile();
|
||||||
if (found && !s.GetTitle().empty())
|
if (found && !s.GetTitle().empty())
|
||||||
found = copy.GetTitle() == s.GetTitle();
|
found = copy.GetTitle() == s.GetTitle();
|
||||||
if (found && !s.GetArtist().empty())
|
if (found && !s.GetArtist().empty())
|
||||||
|
|||||||
251
src/song.cpp
251
src/song.cpp
@@ -47,152 +47,263 @@ void DefineEmptyTags()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Song::Song(mpd_Song *s) : itsHash(0),
|
Song::Song(mpd_Song *s, bool copy_ptr) : itsSong(s),
|
||||||
itsLength(s->time),
|
isStream(0),
|
||||||
itsPosition(s->pos),
|
itsHash(0),
|
||||||
itsID(s->id),
|
copyPtr(copy_ptr),
|
||||||
itsGetEmptyFields(0)
|
itsGetEmptyFields(0)
|
||||||
{
|
{
|
||||||
s->file ? itsFile = s->file : itsFile = "";
|
string itsFile = itsSong->file ? itsSong->file : "";
|
||||||
s->artist ? itsArtist = s->artist : itsArtist = "";
|
|
||||||
s->title ? itsTitle = s->title : itsTitle = "";
|
|
||||||
s->album ? itsAlbum = s->album : itsAlbum = "";
|
|
||||||
s->track ? itsTrack = IntoStr(atoi(s->track)) : itsTrack = "";
|
|
||||||
//s->name ? itsName = s->name : itsName = "";
|
|
||||||
s->date ? itsYear = s->date : itsYear = "";
|
|
||||||
s->genre ? itsGenre = s->genre : itsGenre = "";
|
|
||||||
s->composer ? itsComposer = s->composer : itsComposer = "";
|
|
||||||
s->performer ? itsPerformer = s->performer : itsPerformer = "";
|
|
||||||
s->disc ? itsDisc = s->disc : itsDisc = "";
|
|
||||||
s->comment ? itsComment = s->comment : itsComment = "";
|
|
||||||
|
|
||||||
int i = itsFile.find_last_of("/");
|
itsSlash = itsFile.find_last_of("/");
|
||||||
|
|
||||||
if (itsFile.substr(0, 7) == "http://")
|
if (itsFile.substr(0, 7) == "http://")
|
||||||
{
|
isStream = 1;
|
||||||
itsShortName = itsFile;
|
|
||||||
}
|
|
||||||
else if (i != string::npos)
|
|
||||||
{
|
|
||||||
itsDirectory = itsFile.substr(0, i);
|
|
||||||
itsShortName = itsFile.substr(i+1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
itsDirectory = "/";
|
|
||||||
itsShortName = itsFile;
|
|
||||||
}
|
|
||||||
// generate pseudo-hash
|
// generate pseudo-hash
|
||||||
i = 0;
|
for (int i = 0; i < strlen(itsSong->file); i++)
|
||||||
for (string::const_iterator it = itsFile.begin(); it != itsFile.end(); it++, i++)
|
|
||||||
{
|
{
|
||||||
itsHash += *it;
|
itsHash += itsSong->file[i];
|
||||||
if (i%2)
|
if (i%2)
|
||||||
itsHash *= *it;
|
itsHash *= itsSong->file[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Song::Song(const Song &s) : itsSong(0),
|
||||||
|
itsNewName(s.itsNewName),
|
||||||
|
itsSlash(s.itsSlash),
|
||||||
|
itsHash(s.itsHash),
|
||||||
|
copyPtr(s.copyPtr),
|
||||||
|
isStream(s.isStream),
|
||||||
|
itsGetEmptyFields(s.itsGetEmptyFields)
|
||||||
|
{
|
||||||
|
itsSong = s.copyPtr ? s.itsSong : mpd_songDup(s.itsSong);
|
||||||
|
}
|
||||||
|
|
||||||
|
Song::~Song()
|
||||||
|
{
|
||||||
|
if (itsSong)
|
||||||
|
mpd_freeSong(itsSong);
|
||||||
|
}
|
||||||
|
|
||||||
string Song::GetLength() const
|
string Song::GetLength() const
|
||||||
{
|
{
|
||||||
if (!itsLength)
|
if (!itsSong->time)
|
||||||
return "-:--";
|
return "-:--";
|
||||||
return ShowTime(itsLength);
|
return ShowTime(itsSong->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Song::Clear()
|
void Song::Clear()
|
||||||
{
|
{
|
||||||
itsFile.clear();
|
if (itsSong)
|
||||||
itsShortName.clear();
|
mpd_freeSong(itsSong);
|
||||||
itsDirectory.clear();
|
itsSong = mpd_newSong();
|
||||||
itsArtist.clear();
|
itsNewName.clear();
|
||||||
itsTitle.clear();
|
itsSlash = 0;
|
||||||
itsAlbum.clear();
|
itsHash = 0;
|
||||||
itsTrack.clear();
|
copyPtr = 0;
|
||||||
//itsName.clear();
|
itsGetEmptyFields = 0;
|
||||||
itsYear.clear();
|
|
||||||
itsGenre.clear();
|
|
||||||
itsComposer.clear();
|
|
||||||
itsPerformer.clear();
|
|
||||||
itsDisc.clear();
|
|
||||||
itsComment.clear();
|
|
||||||
itsLength = 0;
|
|
||||||
itsPosition = 0;
|
|
||||||
itsID = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Song::Empty() const
|
bool Song::Empty() const
|
||||||
{
|
{
|
||||||
return itsFile.empty() && itsShortName.empty() && itsArtist.empty() && itsTitle.empty() && itsAlbum.empty() && itsTrack.empty() && itsYear.empty() && itsGenre.empty() && itsComposer.empty() && itsPerformer.empty() && itsDisc.empty() && itsComment.empty();
|
return !itsSong || (!itsSong->file && !itsSong->title && !itsSong->artist && !itsSong->album && !itsSong->date && !itsSong->track && !itsSong->genre && !itsSong->composer && !itsSong->performer && !itsSong->disc && !itsSong->comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetFile() const
|
string Song::GetFile() const
|
||||||
{
|
{
|
||||||
return itsFile.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsFile;
|
return !itsSong->file ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->file;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetShortFilename() const
|
string Song::GetShortFilename() const
|
||||||
{
|
{
|
||||||
return itsShortName.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsShortName;
|
return !itsSong->file ? (itsGetEmptyFields ? "" : EMPTY_TAG) : (itsSlash != string::npos && !isStream ? string(itsSong->file).substr(itsSlash+1) : itsSong->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetDirectory() const
|
string Song::GetDirectory() const
|
||||||
{
|
{
|
||||||
return itsDirectory.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsDirectory;
|
return !itsSong->file || isStream ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSlash != string::npos ? string(itsSong->file).substr(0, itsSlash) : "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetArtist() const
|
string Song::GetArtist() const
|
||||||
{
|
{
|
||||||
return itsArtist.empty() ? (itsGetEmptyFields ? "" : UNKNOWN_ARTIST) : itsArtist;
|
return !itsSong->artist ? (itsGetEmptyFields ? "" : UNKNOWN_ARTIST) : itsSong->artist;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetTitle() const
|
string Song::GetTitle() const
|
||||||
{
|
{
|
||||||
return itsTitle.empty() ? (itsGetEmptyFields ? "" : UNKNOWN_TITLE) : itsTitle;
|
return !itsSong->title ? (itsGetEmptyFields ? "" : UNKNOWN_TITLE) : itsSong->title;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetAlbum() const
|
string Song::GetAlbum() const
|
||||||
{
|
{
|
||||||
return itsAlbum.empty() ? (itsGetEmptyFields ? "" : UNKNOWN_ALBUM) : itsAlbum;
|
return !itsSong->album ? (itsGetEmptyFields ? "" : UNKNOWN_ALBUM) : itsSong->album;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetTrack() const
|
string Song::GetTrack() const
|
||||||
{
|
{
|
||||||
return itsTrack.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : (StrToInt(itsTrack) < 10 && itsTrack[0] != '0' ? "0"+itsTrack : itsTrack);
|
return !itsSong->track ? (itsGetEmptyFields ? "" : EMPTY_TAG) : (StrToInt(itsSong->track) < 10 && itsSong->track[0] != '0' ? "0"+string(itsSong->track) : itsSong->track);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetYear() const
|
string Song::GetYear() const
|
||||||
{
|
{
|
||||||
return itsYear.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsYear;
|
return !itsSong->date ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->date;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetGenre() const
|
string Song::GetGenre() const
|
||||||
{
|
{
|
||||||
return itsGenre.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsGenre;
|
return !itsSong->genre ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->genre;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetComposer() const
|
string Song::GetComposer() const
|
||||||
{
|
{
|
||||||
return itsComposer.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsComposer;
|
return !itsSong->composer ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->composer;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetPerformer() const
|
string Song::GetPerformer() const
|
||||||
{
|
{
|
||||||
return itsPerformer.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsPerformer;
|
return !itsSong->performer ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->performer;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetDisc() const
|
string Song::GetDisc() const
|
||||||
{
|
{
|
||||||
return itsDisc.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsDisc;
|
return !itsSong->disc ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->disc;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::GetComment() const
|
string Song::GetComment() const
|
||||||
{
|
{
|
||||||
return itsComment.empty() ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsComment;
|
return !itsSong->comment ? (itsGetEmptyFields ? "" : EMPTY_TAG) : itsSong->comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetFile(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->file)
|
||||||
|
str_pool_put(itsSong->file);
|
||||||
|
itsSong->file = str.empty() ? 0 : str_pool_dup(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetArtist(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->artist)
|
||||||
|
str_pool_put(itsSong->artist);
|
||||||
|
itsSong->artist = str.empty() ? 0 : str_pool_dup(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetTitle(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->title)
|
||||||
|
str_pool_put(itsSong->title);
|
||||||
|
itsSong->title = str.empty() ? 0 : str_pool_dup(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetAlbum(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->album)
|
||||||
|
str_pool_put(itsSong->album);
|
||||||
|
itsSong->album = str.empty() ? 0 : str_pool_dup(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetTrack(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->track)
|
||||||
|
str_pool_put(itsSong->track);
|
||||||
|
itsSong->track = str.empty() ? 0 : str_pool_dup(IntoStr(StrToInt(str)).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetTrack(int track)
|
||||||
|
{
|
||||||
|
if (itsSong->track)
|
||||||
|
str_pool_put(itsSong->track);
|
||||||
|
itsSong->track = str_pool_dup(IntoStr(track).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetYear(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->date)
|
||||||
|
str_pool_put(itsSong->date);
|
||||||
|
itsSong->date = str.empty() ? 0 : str_pool_dup(IntoStr(StrToInt(str)).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetYear(int year)
|
||||||
|
{
|
||||||
|
if (itsSong->date)
|
||||||
|
str_pool_put(itsSong->date);
|
||||||
|
itsSong->date = str_pool_dup(IntoStr(year).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetGenre(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->genre)
|
||||||
|
str_pool_put(itsSong->genre);
|
||||||
|
itsSong->genre = str.empty() ? 0 : str_pool_dup(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetComment(const string &str)
|
||||||
|
{
|
||||||
|
if (itsSong->comment)
|
||||||
|
str_pool_put(itsSong->comment);
|
||||||
|
itsSong->comment = str.empty() ? 0 : str_pool_dup(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Song::SetPosition(int pos)
|
||||||
|
{
|
||||||
|
itsSong->pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Song & Song::operator=(const Song &s)
|
||||||
|
{
|
||||||
|
if (this == &s)
|
||||||
|
return *this;
|
||||||
|
if (itsSong)
|
||||||
|
mpd_freeSong(itsSong);
|
||||||
|
itsSong = s.copyPtr ? s.itsSong : mpd_songDup(s.itsSong);
|
||||||
|
itsNewName = s.itsNewName;
|
||||||
|
itsSlash = s.itsSlash;
|
||||||
|
itsHash = s.itsHash;
|
||||||
|
copyPtr = s.copyPtr;
|
||||||
|
isStream = s.isStream;
|
||||||
|
itsGetEmptyFields = s.itsGetEmptyFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Song::operator==(const Song &s) const
|
bool Song::operator==(const Song &s) const
|
||||||
{
|
{
|
||||||
return itsFile == s.itsFile && itsArtist == s.itsArtist && itsTitle == s.itsTitle && itsAlbum == s.itsAlbum && itsTrack == s.itsTrack && itsYear == s.itsYear && itsGenre == s.itsGenre && itsComposer == s.itsComposer && itsPerformer == s.itsPerformer && itsDisc == s.itsDisc && itsComment == s.itsComment && itsHash == s.itsHash && itsLength && s.itsLength && itsPosition == s.itsPosition && itsID == s.itsID;
|
return (itsSong->file && s.itsSong->file
|
||||||
|
? strcmp(itsSong->file, s.itsSong->file) == 0
|
||||||
|
: !(itsSong->file || s.itsSong->file))
|
||||||
|
&& (itsSong->title && s.itsSong->title
|
||||||
|
? strcmp(itsSong->title, s.itsSong->title) == 0
|
||||||
|
: !(itsSong->title || s.itsSong->title))
|
||||||
|
&& (itsSong->artist && s.itsSong->artist
|
||||||
|
? strcmp(itsSong->artist, s.itsSong->artist) == 0
|
||||||
|
: !(itsSong->artist || s.itsSong->artist))
|
||||||
|
&& (itsSong->album && s.itsSong->album
|
||||||
|
? strcmp(itsSong->album, s.itsSong->album) == 0
|
||||||
|
: !(itsSong->album || s.itsSong->album))
|
||||||
|
&& (itsSong->track && s.itsSong->track
|
||||||
|
? strcmp(itsSong->track, s.itsSong->track) == 0
|
||||||
|
: !(itsSong->track || s.itsSong->track))
|
||||||
|
&& (itsSong->date && s.itsSong->date
|
||||||
|
? strcmp(itsSong->date, s.itsSong->date) == 0
|
||||||
|
: !(itsSong->date || s.itsSong->date))
|
||||||
|
&& (itsSong->genre && s.itsSong->genre
|
||||||
|
? strcmp(itsSong->genre, s.itsSong->genre) == 0
|
||||||
|
: !(itsSong->genre || s.itsSong->genre))
|
||||||
|
&& (itsSong->composer && s.itsSong->composer
|
||||||
|
? strcmp(itsSong->composer, s.itsSong->composer) == 0
|
||||||
|
: !(itsSong->composer || s.itsSong->composer))
|
||||||
|
&& (itsSong->performer && s.itsSong->performer
|
||||||
|
? strcmp(itsSong->performer, s.itsSong->performer) == 0
|
||||||
|
: !(itsSong->performer || s.itsSong->performer))
|
||||||
|
&& (itsSong->disc && s.itsSong->disc
|
||||||
|
? strcmp(itsSong->disc, s.itsSong->disc) == 0
|
||||||
|
: !(itsSong->disc || s.itsSong->disc))
|
||||||
|
&& (itsSong->comment && s.itsSong->comment
|
||||||
|
? strcmp(itsSong->comment, s.itsSong->comment) == 0
|
||||||
|
: !(itsSong->comment || s.itsSong->comment))
|
||||||
|
&& itsSong->time == s.itsSong->time
|
||||||
|
&& itsSong->pos == s.itsSong->pos
|
||||||
|
&& itsSong->id == s.itsSong->id
|
||||||
|
&& itsHash == itsHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Song::operator!=(const Song &s) const
|
bool Song::operator!=(const Song &s) const
|
||||||
@@ -202,7 +313,7 @@ bool Song::operator!=(const Song &s) const
|
|||||||
|
|
||||||
bool Song::operator<(const Song &s) const
|
bool Song::operator<(const Song &s) const
|
||||||
{
|
{
|
||||||
return itsPosition < s.itsPosition;
|
return itsSong->pos < s.itsSong->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Song::ShowTime(int length)
|
string Song::ShowTime(int length)
|
||||||
|
|||||||
63
src/song.h
63
src/song.h
@@ -36,9 +36,10 @@ void DefineEmptyTags();
|
|||||||
class Song
|
class Song
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Song() : itsHash(0), itsLength(0), itsPosition(0), itsID(0), itsGetEmptyFields(0) { }
|
Song() : itsHash(0), copyPtr(0), isStream(0), itsGetEmptyFields(0) { itsSong = mpd_newSong(); }
|
||||||
Song(mpd_Song *);
|
Song(mpd_Song *, bool = 0);
|
||||||
~Song() {};
|
Song(const Song &);
|
||||||
|
~Song();
|
||||||
|
|
||||||
string GetFile() const;
|
string GetFile() const;
|
||||||
string GetShortFilename() const;
|
string GetShortFilename() const;
|
||||||
@@ -56,55 +57,45 @@ class Song
|
|||||||
string GetComment() const;
|
string GetComment() const;
|
||||||
string GetLength() const;
|
string GetLength() const;
|
||||||
long long GetHash() const { return itsHash; }
|
long long GetHash() const { return itsHash; }
|
||||||
int GetTotalLength() const { return itsLength < 0 ? 0 : itsLength; }
|
int GetTotalLength() const { return itsSong->time < 0 ? 0 : itsSong->time; }
|
||||||
int GetPosition() const { return itsPosition; }
|
int GetPosition() const { return itsSong->pos; }
|
||||||
int GetID() const { return itsID; }
|
int GetID() const { return itsSong->id; }
|
||||||
|
|
||||||
void SetFile(const string &str) { itsFile = str; }
|
void SetFile(const string &str);
|
||||||
void SetShortFilename(const string &str) { itsShortName = str; }
|
void SetArtist(const string &str);
|
||||||
void SetArtist(const string &str) { itsArtist = str; }
|
void SetTitle(const string &str);
|
||||||
void SetTitle(const string &str) { itsTitle = str; }
|
void SetAlbum(const string &str);
|
||||||
void SetAlbum(const string &str) { itsAlbum = str; }
|
void SetTrack(const string &str);
|
||||||
void SetTrack(const string &str) { itsTrack = str.empty() ? "" : IntoStr(StrToInt(str)); }
|
void SetTrack(int track);
|
||||||
void SetTrack(int track) { itsTrack = IntoStr(track); }
|
void SetYear(const string &str);
|
||||||
void SetYear(const string &str) { itsYear = str.empty() ? "" : IntoStr(StrToInt(str)); }
|
void SetYear(int year);
|
||||||
void SetYear(int year) { itsYear = IntoStr(year); }
|
void SetGenre(const string &str);
|
||||||
void SetGenre(const string &str) { itsGenre = str; }
|
void SetComment(const string &str);
|
||||||
void SetComment(const string &str) { itsComment = str; }
|
void SetPosition(int pos);
|
||||||
void SetPosition(int pos) { itsPosition = pos; }
|
|
||||||
|
|
||||||
void SetNewName(string name) { itsNewName = name == itsShortName ? "" : name; }
|
void SetNewName(string name) { itsNewName = name == GetShortFilename() ? "" : name; }
|
||||||
string GetNewName() const { return itsNewName; }
|
string GetNewName() const { return itsNewName; }
|
||||||
|
|
||||||
|
void NullMe() { itsSong = 0; }
|
||||||
|
void CopyPtr(bool copy) { copyPtr = copy; }
|
||||||
|
|
||||||
void GetEmptyFields(bool get) { itsGetEmptyFields = get; }
|
void GetEmptyFields(bool get) { itsGetEmptyFields = get; }
|
||||||
void Clear();
|
void Clear();
|
||||||
bool Empty() const;
|
bool Empty() const;
|
||||||
|
|
||||||
|
Song & operator=(const Song &);
|
||||||
bool operator==(const Song &) const;
|
bool operator==(const Song &) const;
|
||||||
bool operator!=(const Song &) const;
|
bool operator!=(const Song &) const;
|
||||||
bool operator<(const Song &rhs) const;
|
bool operator<(const Song &rhs) const;
|
||||||
|
|
||||||
static string ShowTime(int);
|
static string ShowTime(int);
|
||||||
private:
|
private:
|
||||||
string itsFile;
|
mpd_Song *itsSong;
|
||||||
string itsShortName;
|
|
||||||
string itsNewName;
|
string itsNewName;
|
||||||
string itsDirectory;
|
unsigned itsSlash;
|
||||||
string itsArtist;
|
|
||||||
string itsTitle;
|
|
||||||
string itsAlbum;
|
|
||||||
string itsTrack;
|
|
||||||
//string itsName;
|
|
||||||
string itsYear;
|
|
||||||
string itsGenre;
|
|
||||||
string itsComposer;
|
|
||||||
string itsPerformer;
|
|
||||||
string itsDisc;
|
|
||||||
string itsComment;
|
|
||||||
long long itsHash;
|
long long itsHash;
|
||||||
int itsLength;
|
bool copyPtr;
|
||||||
int itsPosition;
|
bool isStream;
|
||||||
int itsID;
|
|
||||||
bool itsGetEmptyFields;
|
bool itsGetEmptyFields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -181,7 +181,11 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
|
|||||||
Mpd->GetPlaylistChanges(playlist_old_id, list);
|
Mpd->GetPlaylistChanges(playlist_old_id, list);
|
||||||
|
|
||||||
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||||
|
{
|
||||||
mPlaylist->AddOption(**it, now_playing == (*it)->GetPosition());
|
mPlaylist->AddOption(**it, now_playing == (*it)->GetPosition());
|
||||||
|
mPlaylist->Back().CopyPtr(0);
|
||||||
|
(*it)->NullMe();
|
||||||
|
}
|
||||||
|
|
||||||
if (current_screen == csPlaylist)
|
if (current_screen == csPlaylist)
|
||||||
{
|
{
|
||||||
@@ -197,7 +201,11 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
|
|||||||
for (int i = 0; i < mPlaylist->Size(); i++)
|
for (int i = 0; i < mPlaylist->Size(); i++)
|
||||||
{
|
{
|
||||||
if (*list[i] != mPlaylist->at(i))
|
if (*list[i] != mPlaylist->at(i))
|
||||||
|
{
|
||||||
mPlaylist->UpdateOption(i, *list[i]);
|
mPlaylist->UpdateOption(i, *list[i]);
|
||||||
|
mPlaylist->at(i).CopyPtr(0);
|
||||||
|
list[i]->NullMe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FreeSongList(list);
|
FreeSongList(list);
|
||||||
@@ -315,7 +323,7 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
|
|||||||
int elapsed = Mpd->GetElapsedTime();
|
int elapsed = Mpd->GetElapsedTime();
|
||||||
|
|
||||||
// 'repeat one' mode check - be sure that we deal with item with known length
|
// 'repeat one' mode check - be sure that we deal with item with known length
|
||||||
if (Mpd->GetCurrentSong().GetTotalLength() && elapsed == Mpd->GetCurrentSong().GetTotalLength()-1)
|
if (s.GetTotalLength() && elapsed == s.GetTotalLength()-1)
|
||||||
repeat_one_allowed = 1;
|
repeat_one_allowed = 1;
|
||||||
|
|
||||||
if (!block_statusbar_update && Config.statusbar_visibility)
|
if (!block_statusbar_update && Config.statusbar_visibility)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ calc_hash(const char *p)
|
|||||||
{
|
{
|
||||||
unsigned hash = 5381;
|
unsigned hash = 5381;
|
||||||
|
|
||||||
assert(p != NULL);
|
//assert(p != NULL);
|
||||||
|
|
||||||
while (*p != 0)
|
while (*p != 0)
|
||||||
hash = (hash << 5) + hash + *p++;
|
hash = (hash << 5) + hash + *p++;
|
||||||
@@ -47,7 +47,7 @@ calc_hash(const char *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline struct slot *
|
static inline struct slot *
|
||||||
value_to_slot(char *value)
|
value_to_slot(const char *value)
|
||||||
{
|
{
|
||||||
return (struct slot*)(value - offsetof(struct slot, value));
|
return (struct slot*)(value - offsetof(struct slot, value));
|
||||||
}
|
}
|
||||||
@@ -72,7 +72,7 @@ char *str_pool_get(const char *value)
|
|||||||
slot_p = &slots[calc_hash(value) % NUM_SLOTS];
|
slot_p = &slots[calc_hash(value) % NUM_SLOTS];
|
||||||
for (slot = *slot_p; slot != NULL; slot = slot->next) {
|
for (slot = *slot_p; slot != NULL; slot = slot->next) {
|
||||||
if (strcmp(value, slot->value) == 0 && slot->ref < 0xff) {
|
if (strcmp(value, slot->value) == 0 && slot->ref < 0xff) {
|
||||||
assert(slot->ref > 0);
|
//assert(slot->ref > 0);
|
||||||
++slot->ref;
|
++slot->ref;
|
||||||
return slot->value;
|
return slot->value;
|
||||||
}
|
}
|
||||||
@@ -83,15 +83,15 @@ char *str_pool_get(const char *value)
|
|||||||
return slot->value;
|
return slot->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *str_pool_dup(char *value)
|
char *str_pool_dup(const char *value)
|
||||||
{
|
{
|
||||||
struct slot *slot = value_to_slot(value);
|
struct slot *slot = value_to_slot(value);
|
||||||
|
|
||||||
assert(slot->ref > 0);
|
//assert(slot->ref > 0);
|
||||||
|
|
||||||
if (slot->ref < 0xff) {
|
if (slot->ref < 0xff) {
|
||||||
++slot->ref;
|
++slot->ref;
|
||||||
return value;
|
return (char *) value;
|
||||||
} else {
|
} else {
|
||||||
/* the reference counter overflows above 0xff;
|
/* the reference counter overflows above 0xff;
|
||||||
duplicate the value, and start with 1 */
|
duplicate the value, and start with 1 */
|
||||||
@@ -103,12 +103,12 @@ char *str_pool_dup(char *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void str_pool_put(char *value)
|
void str_pool_put(const char *value)
|
||||||
{
|
{
|
||||||
struct slot **slot_p, *slot;
|
struct slot **slot_p, *slot;
|
||||||
|
|
||||||
slot = value_to_slot(value);
|
slot = value_to_slot(value);
|
||||||
assert(slot->ref > 0);
|
//assert(slot->ref > 0);
|
||||||
--slot->ref;
|
--slot->ref;
|
||||||
|
|
||||||
if (slot->ref > 0)
|
if (slot->ref > 0)
|
||||||
@@ -117,7 +117,7 @@ void str_pool_put(char *value)
|
|||||||
for (slot_p = &slots[calc_hash(value) % NUM_SLOTS];
|
for (slot_p = &slots[calc_hash(value) % NUM_SLOTS];
|
||||||
*slot_p != slot;
|
*slot_p != slot;
|
||||||
slot_p = &(*slot_p)->next) {
|
slot_p = &(*slot_p)->next) {
|
||||||
assert(*slot_p != NULL);
|
//assert(*slot_p != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
*slot_p = slot->next;
|
*slot_p = slot->next;
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ extern "C" {
|
|||||||
|
|
||||||
char *str_pool_get(const char *value);
|
char *str_pool_get(const char *value);
|
||||||
|
|
||||||
char *str_pool_dup(char *value);
|
char *str_pool_dup(const char *value);
|
||||||
|
|
||||||
void str_pool_put(char *value);
|
void str_pool_put(const char *value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user