You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
842 lines
19 KiB
842 lines
19 KiB
/*************************************************************************** |
|
* Copyright (C) 2008-2009 by Andrzej Rybczak * |
|
* electricityispower@gmail.com * |
|
* * |
|
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * |
|
***************************************************************************/ |
|
|
|
#include "charset.h" |
|
#include "mpdpp.h" |
|
|
|
using namespace MPD; |
|
|
|
using std::string; |
|
|
|
const char *MPD::Message::PartOfSongsAdded = "Only part of requested songs' list added to playlist!"; |
|
const char *MPD::Message::FullPlaylist = "Playlist is full!"; |
|
const char *MPD::Message::FunctionDisabledFilteringEnabled = "Function disabled due to enabled filtering in playlist"; |
|
|
|
Connection::Connection() : itsConnection(0), |
|
isConnected(0), |
|
isCommandsListEnabled(0), |
|
itsErrorCode(0), |
|
itsMaxPlaylistLength(-1), |
|
itsHost("localhost"), |
|
itsPort(6600), |
|
itsTimeout(15), |
|
itsCurrentStatus(0), |
|
itsOldStatus(0), |
|
itsUpdater(0), |
|
itsErrorHandler(0) |
|
{ |
|
} |
|
|
|
Connection::~Connection() |
|
{ |
|
if (itsConnection) |
|
mpd_closeConnection(itsConnection); |
|
if (itsOldStatus) |
|
mpd_freeStatus(itsOldStatus); |
|
if (itsCurrentStatus) |
|
mpd_freeStatus(itsCurrentStatus); |
|
} |
|
|
|
bool Connection::Connect() |
|
{ |
|
if (!isConnected && !itsConnection) |
|
{ |
|
itsConnection = mpd_newConnection(itsHost.c_str(), itsPort, itsTimeout); |
|
isConnected = 1; |
|
if (CheckForErrors()) |
|
return false; |
|
if (!itsPassword.empty()) |
|
SendPassword(); |
|
return !CheckForErrors(); |
|
} |
|
else |
|
return true; |
|
} |
|
|
|
bool Connection::Connected() const |
|
{ |
|
return isConnected; |
|
} |
|
|
|
void Connection::Disconnect() |
|
{ |
|
if (itsConnection) |
|
mpd_closeConnection(itsConnection); |
|
if (itsOldStatus) |
|
mpd_freeStatus(itsOldStatus); |
|
if (itsCurrentStatus) |
|
mpd_freeStatus(itsCurrentStatus); |
|
itsConnection = 0; |
|
itsCurrentStatus = 0; |
|
itsOldStatus = 0; |
|
isConnected = 0; |
|
isCommandsListEnabled = 0; |
|
itsMaxPlaylistLength = -1; |
|
} |
|
|
|
float Connection::Version() const |
|
{ |
|
return itsConnection ? itsConnection->version[1] + itsConnection->version[2]*0.1 : 0; |
|
} |
|
|
|
void Connection::SetHostname(const string &host) |
|
{ |
|
size_t at = host.find("@"); |
|
if (at != string::npos) |
|
{ |
|
itsPassword = host.substr(0, at); |
|
itsHost = host.substr(at+1); |
|
} |
|
else |
|
itsHost = host; |
|
} |
|
|
|
void Connection::SendPassword() const |
|
{ |
|
mpd_sendPasswordCommand(itsConnection, itsPassword.c_str()); |
|
mpd_finishCommand(itsConnection); |
|
} |
|
|
|
void Connection::SetStatusUpdater(StatusUpdater updater, void *data) |
|
{ |
|
itsUpdater = updater; |
|
itsStatusUpdaterUserdata = data; |
|
} |
|
|
|
void Connection::SetErrorHandler(ErrorHandler handler, void *data) |
|
{ |
|
itsErrorHandler = handler; |
|
itsErrorHandlerUserdata = data; |
|
} |
|
|
|
void Connection::UpdateStatus() |
|
{ |
|
if (!itsConnection) |
|
return; |
|
|
|
CheckForErrors(); |
|
|
|
if (!itsConnection) |
|
return; |
|
|
|
if (itsOldStatus) |
|
mpd_freeStatus(itsOldStatus); |
|
|
|
itsOldStatus = itsCurrentStatus; |
|
itsCurrentStatus = 0; |
|
|
|
mpd_sendStatusCommand(itsConnection); |
|
itsCurrentStatus = mpd_getStatus(itsConnection); |
|
|
|
if (!itsMaxPlaylistLength) |
|
itsMaxPlaylistLength = GetPlaylistLength(); |
|
|
|
if (CheckForErrors()) |
|
return; |
|
|
|
if (itsCurrentStatus && itsUpdater) |
|
{ |
|
if (!itsOldStatus) |
|
{ |
|
itsChanges.Playlist = 1; |
|
itsChanges.SongID = 1; |
|
itsChanges.Database = 1; |
|
itsChanges.DBUpdating = 1; |
|
itsChanges.Volume = 1; |
|
itsChanges.ElapsedTime = 1; |
|
itsChanges.Crossfade = 1; |
|
itsChanges.Random = 1; |
|
itsChanges.Repeat = 1; |
|
itsChanges.PlayerState = 1; |
|
itsChanges.StatusFlags = 1; |
|
} |
|
else |
|
{ |
|
itsChanges.Playlist = itsOldStatus->playlist != itsCurrentStatus->playlist; |
|
itsChanges.SongID = itsOldStatus->songid != itsCurrentStatus->songid; |
|
itsChanges.Database = itsOldStatus->updatingDb && !itsCurrentStatus->updatingDb; |
|
itsChanges.DBUpdating = itsOldStatus->updatingDb != itsCurrentStatus->updatingDb; |
|
itsChanges.Volume = itsOldStatus->volume != itsCurrentStatus->volume; |
|
itsChanges.ElapsedTime = itsOldStatus->elapsedTime != itsCurrentStatus->elapsedTime; |
|
itsChanges.Crossfade = itsOldStatus->crossfade != itsCurrentStatus->crossfade; |
|
itsChanges.Random = itsOldStatus->random != itsCurrentStatus->random; |
|
itsChanges.Repeat = itsOldStatus->repeat != itsCurrentStatus->repeat; |
|
itsChanges.PlayerState = itsOldStatus->state != itsCurrentStatus->state; |
|
itsChanges.StatusFlags = itsChanges.Repeat || itsChanges.Random || itsChanges.Crossfade || itsChanges.DBUpdating; |
|
} |
|
itsUpdater(this, itsChanges, itsErrorHandlerUserdata); |
|
} |
|
} |
|
|
|
void Connection::UpdateDirectory(const string &path) |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendUpdateCommand(itsConnection, path.c_str()); |
|
mpd_finishCommand(itsConnection); |
|
if (!itsConnection->error && itsUpdater) |
|
{ |
|
itsCurrentStatus->updatingDb = 1; |
|
StatusChanges ch; |
|
ch.DBUpdating = 1; |
|
itsUpdater(this, ch, itsErrorHandlerUserdata); |
|
} |
|
} |
|
} |
|
|
|
void Connection::Execute(const string &command) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_executeCommand(itsConnection, command.c_str()); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Play() const |
|
{ |
|
if (isConnected) |
|
PlayID(-1); |
|
} |
|
|
|
void Connection::Play(int pos) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPlayCommand(itsConnection, pos); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::PlayID(int id) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPlayIdCommand(itsConnection, id); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Pause() const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPauseCommand(itsConnection, itsCurrentStatus->state != psPause); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Stop() const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendStopCommand(itsConnection); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Next() const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendNextCommand(itsConnection); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Prev() const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPrevCommand(itsConnection); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Move(int from, int to) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendMoveCommand(itsConnection, from, to); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Swap(int from, int to) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendSwapCommand(itsConnection, from, to); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Seek(int where) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendSeekCommand(itsConnection, itsCurrentStatus->song, where); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Shuffle() const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendShuffleCommand(itsConnection); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::ClearPlaylist() const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendClearCommand(itsConnection); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::ClearPlaylist(const string &playlist) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPlaylistClearCommand(itsConnection, playlist.c_str()); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::AddToPlaylist(const string &path, const Song &s) const |
|
{ |
|
if (!s.Empty()) |
|
AddToPlaylist(path, s.GetFile()); |
|
} |
|
|
|
void Connection::AddToPlaylist(const string &path, const string &file) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPlaylistAddCommand(itsConnection, path.c_str(), file.c_str()); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Move(const string &path, int from, int to) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPlaylistMoveCommand(itsConnection, path.c_str(), from, to); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Rename(const string &from, const string &to) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendRenameCommand(itsConnection, from.c_str(), to.c_str()); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::GetPlaylistChanges(long long id, SongList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
if (id < 0) |
|
{ |
|
id = 0; |
|
v.reserve(GetPlaylistLength()); |
|
} |
|
mpd_sendPlChangesCommand(itsConnection, id); |
|
mpd_InfoEntity *item = NULL; |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG) |
|
{ |
|
Song *s = new Song(item->info.song, 1); |
|
item->info.song = 0; |
|
v.push_back(s); |
|
} |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
Song Connection::GetSong(const string &path) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendListallInfoCommand(itsConnection, path.c_str()); |
|
mpd_InfoEntity *item = NULL; |
|
item = mpd_getNextInfoEntity(itsConnection); |
|
Song result = item->info.song; |
|
item->info.song = 0; |
|
mpd_freeInfoEntity(item); |
|
mpd_finishCommand(itsConnection); |
|
return result; |
|
} |
|
else |
|
return Song(); |
|
} |
|
|
|
int Connection::GetCurrentSongPos() const |
|
{ |
|
return isConnected && itsCurrentStatus ? (itsCurrentStatus->state == psPlay || itsCurrentStatus->state == psPause ? itsCurrentStatus->song : -1) : -1; |
|
} |
|
|
|
Song Connection::GetCurrentSong() const |
|
{ |
|
if (isConnected && (GetState() == psPlay || GetState() == psPause)) |
|
{ |
|
mpd_sendCurrentSongCommand(itsConnection); |
|
mpd_InfoEntity *item = NULL; |
|
item = mpd_getNextInfoEntity(itsConnection); |
|
if (item) |
|
{ |
|
Song result = item->info.song; |
|
item->info.song = 0; |
|
mpd_freeInfoEntity(item); |
|
return result; |
|
} |
|
else |
|
return Song(); |
|
mpd_finishCommand(itsConnection); |
|
} |
|
else |
|
return Song(); |
|
} |
|
|
|
void Connection::GetPlaylistContent(const string &path, SongList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendListPlaylistInfoCommand(itsConnection, path.c_str()); |
|
mpd_InfoEntity *item = NULL; |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG) |
|
{ |
|
Song *s = new Song(item->info.song); |
|
item->info.song = 0; |
|
v.push_back(s); |
|
} |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::SetRepeat(bool mode) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendRepeatCommand(itsConnection, mode); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::SetRandom(bool mode) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendRandomCommand(itsConnection, mode); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::SetVolume(int vol) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendSetvolCommand(itsConnection, vol); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::SetCrossfade(int crossfade) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendCrossfadeCommand(itsConnection, crossfade); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
int Connection::AddSong(const string &path) |
|
{ |
|
int id = -1; |
|
if (isConnected) |
|
{ |
|
if (GetPlaylistLength() < itsMaxPlaylistLength) |
|
{ |
|
id = mpd_sendAddIdCommand(itsConnection, path.c_str()); |
|
if (!isCommandsListEnabled) |
|
{ |
|
mpd_finishCommand(itsConnection); |
|
UpdateStatus(); |
|
} |
|
else |
|
id = 0; |
|
} |
|
else if (itsErrorHandler) |
|
itsErrorHandler(this, MPD_ACK_ERROR_PLAYLIST_MAX, Message::FullPlaylist, NULL); |
|
} |
|
return id; |
|
} |
|
|
|
int Connection::AddSong(const Song &s) |
|
{ |
|
return !s.Empty() ? (AddSong((!s.IsFromDB() ? "file://" : "") + (s.Localized() ? locale_to_utf_cpy(s.GetFile()) : s.GetFile()))) : -1; |
|
} |
|
|
|
void Connection::Delete(int pos) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendDeleteCommand(itsConnection, pos); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::DeleteID(int id) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendDeleteIdCommand(itsConnection, id); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::Delete(const string &playlist, int pos) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendPlaylistDeleteCommand(itsConnection, playlist.c_str(), pos); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::StartCommandsList() |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendCommandListBegin(itsConnection); |
|
isCommandsListEnabled = 1; |
|
} |
|
|
|
} |
|
|
|
void Connection::CommitCommandsList() |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendCommandListEnd(itsConnection); |
|
mpd_finishCommand(itsConnection); |
|
UpdateStatus(); |
|
if (GetPlaylistLength() == itsMaxPlaylistLength && itsErrorHandler) |
|
itsErrorHandler(this, MPD_ACK_ERROR_PLAYLIST_MAX, Message::FullPlaylist, NULL); |
|
isCommandsListEnabled = 0; |
|
} |
|
} |
|
|
|
void Connection::DeletePlaylist(const string &name) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendRmCommand(itsConnection, name.c_str()); |
|
if (!isCommandsListEnabled) |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
bool Connection::SavePlaylist(const string &name) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendSaveCommand(itsConnection, name.c_str()); |
|
mpd_finishCommand(itsConnection); |
|
return !(itsConnection->error == MPD_ERROR_ACK && itsConnection->errorCode == MPD_ACK_ERROR_EXIST); |
|
} |
|
else |
|
return false; |
|
} |
|
|
|
void Connection::GetPlaylists(TagList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
ItemList list; |
|
GetDirectory("/", list); |
|
for (ItemList::const_iterator it = list.begin(); it != list.end(); it++) |
|
{ |
|
if (it->type == itPlaylist) |
|
v.push_back(it->name); |
|
} |
|
FreeItemList(list); |
|
} |
|
} |
|
|
|
void Connection::GetList(TagList &v, mpd_TagItems type) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendListCommand(itsConnection, type, NULL); |
|
char *item; |
|
while ((item = mpd_getNextTag(itsConnection, type)) != NULL) |
|
{ |
|
if (item[0] != 0) // do not push empty item |
|
v.push_back(item); |
|
delete [] item; |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::GetAlbums(const string &artist, TagList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_sendListCommand(itsConnection, MPD_TABLE_ALBUM, artist.empty() ? NULL : artist.c_str()); |
|
char *item; |
|
while ((item = mpd_getNextAlbum(itsConnection)) != NULL) |
|
{ |
|
if (item[0] != 0) // do not push empty item |
|
v.push_back(item); |
|
delete [] item; |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::StartSearch(bool exact_match) const |
|
{ |
|
if (isConnected) |
|
mpd_startSearch(itsConnection, exact_match); |
|
} |
|
|
|
void Connection::StartFieldSearch(mpd_TagItems item) |
|
{ |
|
if (isConnected) |
|
{ |
|
itsSearchedField = item; |
|
mpd_startFieldSearch(itsConnection, item); |
|
} |
|
} |
|
|
|
void Connection::AddSearch(mpd_TagItems item, const string &str) const |
|
{ |
|
if (isConnected) |
|
mpd_addConstraintSearch(itsConnection, item, str.c_str()); |
|
} |
|
|
|
void Connection::CommitSearch(SongList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_commitSearch(itsConnection); |
|
mpd_InfoEntity *item = NULL; |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG) |
|
{ |
|
Song *s = new Song(item->info.song); |
|
item->info.song = 0; |
|
v.push_back(s); |
|
} |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::CommitSearch(TagList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_commitSearch(itsConnection); |
|
char *tag = NULL; |
|
while ((tag = mpd_getNextTag(itsConnection, itsSearchedField)) != NULL) |
|
{ |
|
if (tag[0] != 0) // do not push empty item |
|
v.push_back(tag); |
|
delete [] tag; |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::GetDirectory(const string &path, ItemList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_InfoEntity *item = NULL; |
|
mpd_sendLsInfoCommand(itsConnection, path.c_str()); |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
Item i; |
|
switch (item->type) |
|
{ |
|
case MPD_INFO_ENTITY_TYPE_DIRECTORY: |
|
i.name = item->info.directory->path; |
|
i.type = itDirectory; |
|
break; |
|
case MPD_INFO_ENTITY_TYPE_SONG: |
|
i.song = new Song(item->info.song); |
|
item->info.song = 0; |
|
i.type = itSong; |
|
break; |
|
case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE: |
|
i.name = item->info.playlistFile->path; |
|
i.type = itPlaylist; |
|
break; |
|
} |
|
v.push_back(i); |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::GetDirectoryRecursive(const string &path, SongList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_InfoEntity *item = NULL; |
|
mpd_sendListallInfoCommand(itsConnection, path.c_str()); |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG) |
|
{ |
|
Song *s = new Song(item->info.song); |
|
item->info.song = 0; |
|
v.push_back(s); |
|
} |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::GetSongs(const string &path, SongList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_InfoEntity *item = NULL; |
|
mpd_sendLsInfoCommand(itsConnection, path.c_str()); |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
if (item->type == MPD_INFO_ENTITY_TYPE_SONG) |
|
{ |
|
Song *s = new Song(item->info.song); |
|
item->info.song = 0; |
|
v.push_back(s); |
|
} |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
void Connection::GetDirectories(const string &path, TagList &v) const |
|
{ |
|
if (isConnected) |
|
{ |
|
mpd_InfoEntity *item = NULL; |
|
mpd_sendLsInfoCommand(itsConnection, path.c_str()); |
|
while ((item = mpd_getNextInfoEntity(itsConnection)) != NULL) |
|
{ |
|
if (item->type == MPD_INFO_ENTITY_TYPE_DIRECTORY) |
|
v.push_back(item->info.directory->path); |
|
mpd_freeInfoEntity(item); |
|
} |
|
mpd_finishCommand(itsConnection); |
|
} |
|
} |
|
|
|
int Connection::CheckForErrors() |
|
{ |
|
itsErrorCode = 0; |
|
if (itsConnection->error) |
|
{ |
|
itsErrorMessage = itsConnection->errorStr; |
|
if (itsConnection->error == MPD_ERROR_ACK) |
|
{ |
|
// this is to avoid setting too small max size as we check it before fetching current status |
|
// setting real max playlist length is in UpdateStatus() |
|
if (itsConnection->errorCode == MPD_ACK_ERROR_PLAYLIST_MAX && itsMaxPlaylistLength == size_t(-1)) |
|
itsMaxPlaylistLength = 0; |
|
|
|
if (itsErrorHandler) |
|
itsErrorHandler(this, itsConnection->errorCode, itsConnection->errorStr, itsErrorHandlerUserdata); |
|
itsErrorCode = itsConnection->errorCode; |
|
} |
|
else |
|
{ |
|
if (itsErrorHandler) |
|
itsErrorHandler(this, itsConnection->error, itsConnection->errorStr, itsErrorHandlerUserdata); |
|
itsErrorCode = itsConnection->error; |
|
Disconnect(); // the rest of errors are fatal to connection |
|
} |
|
if (itsConnection) |
|
mpd_clearError(itsConnection); |
|
} |
|
return itsErrorCode; |
|
} |
|
|
|
void MPD::FreeSongList(SongList &l) |
|
{ |
|
for (SongList::iterator i = l.begin(); i != l.end(); i++) |
|
delete *i; |
|
l.clear(); |
|
} |
|
|
|
void MPD::FreeItemList(ItemList &l) |
|
{ |
|
for (ItemList::iterator i = l.begin(); i != l.end(); i++) |
|
delete i->song; |
|
l.clear(); |
|
} |
|
|
|
|