1
0
mirror of https://github.com/ZetaKebab/MpcNET.git synced 2025-01-14 22:18:43 +00:00

Commands to Server are now Async

This commit is contained in:
glucaci 2016-11-30 23:24:46 +01:00
parent f9a6430f72
commit dd941b1f83
2 changed files with 163 additions and 208 deletions

View File

@ -6,34 +6,22 @@ using System.Threading.Tasks;
namespace LibMpc namespace LibMpc
{ {
public interface IMpc
{
bool IsConnected { get; }
Task<bool> ConnectAsync();
MpdOutput[] Outputs();
MpdStatistics Stats();
}
/// <summary> /// <summary>
/// The Mpc class implements all commands for the MPD. It takes care of command building /// The Mpc class implements all commands for the MPD. It takes care of command building
/// and parsing the response into .net objects. /// and parsing the response into .net objects.
/// </summary> /// </summary>
public class Mpc : IMpc public class Mpc
{ {
private static readonly Regex STATUS_AUDIO_REGEX = new Regex("^(?<sampleRate>[0-9]*):(?<bits>[0-9]*):(?<channels>[0-9]*)$"); private static readonly Regex STATUS_AUDIO_REGEX = new Regex("^(?<sampleRate>[0-9]*):(?<bits>[0-9]*):(?<channels>[0-9]*)$");
private readonly IPEndPoint _server;
private MpcConnection _connection; private MpcConnection _connection;
private IPEndPoint _server;
public Mpc(IPEndPoint server) public Mpc(IPEndPoint server)
{ {
_server = server; _server = server;
} }
/// <summary>
/// Connection status to MPD Server.
/// </summary>
public bool IsConnected => _connection?.IsConnected ?? false; public bool IsConnected => _connection?.IsConnected ?? false;
public async Task<bool> ConnectAsync() public async Task<bool> ConnectAsync()
@ -57,26 +45,30 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="id">The id of the output.</param> /// <param name="id">The id of the output.</param>
/// <returns>If the action was successful.</returns> /// <returns>If the action was successful.</returns>
public bool DisableOutput(int id) public async Task<bool> DisableOutputAsync(int id)
{ {
return !_connection.Exec("disableoutput", new string[] { id.ToString() }).IsError; var mpdResponse = await _connection.Exec("disableoutput", new string[] { id.ToString() });
return !mpdResponse.IsError;
} }
/// <summary> /// <summary>
/// Enables an MPD output. /// Enables an MPD output.
/// </summary> /// </summary>
/// <param name="id">The id of the output.</param> /// <param name="id">The id of the output.</param>
/// <returns>If the action was successful.</returns> /// <returns>If the action was successful.</returns>
public bool EnableOutput(int id) public async Task<bool> EnableOutputAsync(int id)
{ {
return !_connection.Exec("enableoutput", new string[] { id.ToString() }).IsError; var mpdResponse = await _connection.Exec("enableoutput", new string[] { id.ToString() });
return !mpdResponse.IsError;
} }
/// <summary> /// <summary>
/// Lists all outputs of the MPD. /// Lists all outputs of the MPD.
/// </summary> /// </summary>
/// <returns>The list of all MPD outputs.</returns> /// <returns>The list of all MPD outputs.</returns>
public MpdOutput[] Outputs() public async Task<MpdOutput[]> OutputsAsync()
{ {
MpdResponse response = _connection.Exec("outputs"); MpdResponse response = await _connection.Exec("outputs");
if (response.Message.Count % 3 != 0) if (response.Message.Count % 3 != 0)
throw new InvalidMpdResponseException(); throw new InvalidMpdResponseException();
@ -120,9 +112,9 @@ namespace LibMpc
/// Returns the list of tag types the MPD supports. /// Returns the list of tag types the MPD supports.
/// </summary> /// </summary>
/// <returns>The list of tag types the MPD supports.</returns> /// <returns>The list of tag types the MPD supports.</returns>
public string[] TagTypes() public async Task<string[]> TagTypesAsync()
{ {
MpdResponse response = _connection.Exec("tagtypes"); MpdResponse response = await _connection.Exec("tagtypes");
string[] ret = new string[response.Message.Count]; string[] ret = new string[response.Message.Count];
@ -140,9 +132,9 @@ namespace LibMpc
/// Starts an update of the MPD database. /// Starts an update of the MPD database.
/// </summary> /// </summary>
/// <returns>An sequential number of the update process.</returns> /// <returns>An sequential number of the update process.</returns>
public int Update() public async Task<int> UpdateAsync()
{ {
MpdResponse response = _connection.Exec("update"); MpdResponse response = await _connection.Exec("update");
if (response.Message.Count != 1) if (response.Message.Count != 1)
throw new InvalidMpdResponseException("Respose message has more than one line."); throw new InvalidMpdResponseException("Respose message has more than one line.");
@ -167,12 +159,12 @@ namespace LibMpc
/// <param name="scopeSpecifier">Specifies the attribute to search for.</param> /// <param name="scopeSpecifier">Specifies the attribute to search for.</param>
/// <param name="token">The value the files attribute must have to be included in the result.</param> /// <param name="token">The value the files attribute must have to be included in the result.</param>
/// <returns>All files in the database who's attribute matches the given token.</returns> /// <returns>All files in the database who's attribute matches the given token.</returns>
public List<MpdFile> Find(ScopeSpecifier scopeSpecifier, string token) public async Task<List<MpdFile>> FindAsync(ScopeSpecifier scopeSpecifier, string token)
{ {
if (token == null) if (token == null)
throw new ArgumentNullException("token"); throw new ArgumentNullException("token");
MpdResponse response = _connection.Exec("find", new string[] { TagConverter.ToTag(scopeSpecifier), token }); MpdResponse response = await _connection.Exec("find", new string[] { TagConverter.ToTag(scopeSpecifier), token });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -184,9 +176,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="scopeSpecifier">The attribute who's values are requested.</param> /// <param name="scopeSpecifier">The attribute who's values are requested.</param>
/// <returns>All values found in files of the MPD for the given attribute.</returns> /// <returns>All values found in files of the MPD for the given attribute.</returns>
public List<string> List(ScopeSpecifier scopeSpecifier) public async Task<List<string>> ListAsync(ScopeSpecifier scopeSpecifier)
{ {
MpdResponse response = _connection.Exec("list", new string[] { TagConverter.ToTag(scopeSpecifier) }); MpdResponse response = await _connection.Exec("list", new string[] { TagConverter.ToTag(scopeSpecifier) });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -200,12 +192,12 @@ namespace LibMpc
/// <param name="searchTag">The attribute whos value should match a given value for the file to be included in the result.</param> /// <param name="searchTag">The attribute whos value should match a given value for the file to be included in the result.</param>
/// <param name="searchValue">The value the searchTag attribute must match for the file to be included in the result.</param> /// <param name="searchValue">The value the searchTag attribute must match for the file to be included in the result.</param>
/// <returns>All values found in files of the MPD for the given attribute.</returns> /// <returns>All values found in files of the MPD for the given attribute.</returns>
public List<string> List(ScopeSpecifier resultTag, ScopeSpecifier searchTag, string searchValue) public async Task<List<string>> ListAsync(ScopeSpecifier resultTag, ScopeSpecifier searchTag, string searchValue)
{ {
if (searchValue == null) if (searchValue == null)
throw new ArgumentNullException("searchValue"); throw new ArgumentNullException("searchValue");
MpdResponse response = _connection.Exec("list", new string[] { TagConverter.ToTag(resultTag), TagConverter.ToTag(searchTag), searchValue }); MpdResponse response = await _connection.Exec("list", new string[] { TagConverter.ToTag(resultTag), TagConverter.ToTag(searchTag), searchValue });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -217,12 +209,12 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="path">The path whos subdirectories and their files are requested.</param> /// <param name="path">The path whos subdirectories and their files are requested.</param>
/// <returns>The names of all files and directory found under the given path.</returns> /// <returns>The names of all files and directory found under the given path.</returns>
public List<string> ListAll(string path) public async Task<List<string>> ListAllAsync(string path)
{ {
if (path == null) if (path == null)
throw new ArgumentNullException("path"); throw new ArgumentNullException("path");
MpdResponse response = _connection.Exec("listall", new string[] { path }); MpdResponse response = await _connection.Exec("listall", new string[] { path });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -234,12 +226,12 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="path">The path of which the file information is requested.</param> /// <param name="path">The path of which the file information is requested.</param>
/// <returns>The information of all files found in the given path and its subdirectories.</returns> /// <returns>The information of all files found in the given path and its subdirectories.</returns>
public List<MpdFile> ListAllInfo(string path) public async Task<List<MpdFile>> ListAllInfoAsync(string path)
{ {
if (path == null) if (path == null)
throw new ArgumentNullException("path"); throw new ArgumentNullException("path");
MpdResponse response = _connection.Exec("listallinfo", new string[] { path }); MpdResponse response = await _connection.Exec("listallinfo", new string[] { path });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -250,22 +242,22 @@ namespace LibMpc
/// Returns the directory listing of the root directory. /// Returns the directory listing of the root directory.
/// </summary> /// </summary>
/// <returns>The listing of the root directory.</returns> /// <returns>The listing of the root directory.</returns>
public MpdDirectoryListing LsInfo() public async Task<MpdDirectoryListing> LsInfoAsync()
{ {
return LsInfo(null); return await LsInfoAsync(null);
} }
/// <summary> /// <summary>
/// Returns the directory listing of the given path. /// Returns the directory listing of the given path.
/// </summary> /// </summary>
/// <param name="path">The path whos listing is requested.</param> /// <param name="path">The path whos listing is requested.</param>
/// <returns>The directory listing of the given path.</returns> /// <returns>The directory listing of the given path.</returns>
public MpdDirectoryListing LsInfo(string path) public async Task<MpdDirectoryListing> LsInfoAsync(string path)
{ {
MpdResponse response; MpdResponse response;
if (path == null) if (path == null)
response = _connection.Exec("lsinfo"); response = await _connection.Exec("lsinfo");
else else
response = _connection.Exec("lsinfo", new string[] { path }); response = await _connection.Exec("lsinfo", new string[] { path });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -281,12 +273,12 @@ namespace LibMpc
/// <param name="scopeSpecifier">Specifies the attribute to search for.</param> /// <param name="scopeSpecifier">Specifies the attribute to search for.</param>
/// <param name="token">The value the files attribute must have to be included in the result.</param> /// <param name="token">The value the files attribute must have to be included in the result.</param>
/// <returns>All files in the database who's attribute matches the given token.</returns> /// <returns>All files in the database who's attribute matches the given token.</returns>
public List<MpdFile> Search(ScopeSpecifier scopeSpecifier, string token) public async Task<List<MpdFile>> SearchAsync(ScopeSpecifier scopeSpecifier, string token)
{ {
if (token == null) if (token == null)
throw new ArgumentNullException("token"); throw new ArgumentNullException("token");
MpdResponse response = _connection.Exec("search", new string[] { TagConverter.ToTag(scopeSpecifier), token }); MpdResponse response = await _connection.Exec("search", new string[] { TagConverter.ToTag(scopeSpecifier), token });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -301,12 +293,12 @@ namespace LibMpc
/// Adds a file to the playlist. /// Adds a file to the playlist.
/// </summary> /// </summary>
/// <param name="filename">The name and path of the file to add.</param> /// <param name="filename">The name and path of the file to add.</param>
public void Add(string filename) public async Task AddAsync(string filename)
{ {
if (filename == null) if (filename == null)
throw new ArgumentNullException("filename"); throw new ArgumentNullException("filename");
MpdResponse response = _connection.Exec("add", new string[] { filename }); MpdResponse response = await _connection.Exec("add", new string[] { filename });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -316,12 +308,12 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="filename">The name and path of the file to add.</param> /// <param name="filename">The name and path of the file to add.</param>
/// <rereturns>The id of the file in the playlist.</rereturns> /// <rereturns>The id of the file in the playlist.</rereturns>
public int AddId(string filename) public async Task<int> AddIdAsync(string filename)
{ {
if (filename == null) if (filename == null)
throw new ArgumentNullException("filename"); throw new ArgumentNullException("filename");
MpdResponse response = _connection.Exec("add", new string[] { filename }); MpdResponse response = await _connection.Exec("add", new string[] { filename });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -341,9 +333,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Clears the playlist. /// Clears the playlist.
/// </summary> /// </summary>
public void Clear() public async Task ClearAsync()
{ {
MpdResponse response = _connection.Exec("clear"); MpdResponse response = await _connection.Exec("clear");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -352,9 +344,9 @@ namespace LibMpc
/// Returns the information of the current song. /// Returns the information of the current song.
/// </summary> /// </summary>
/// <returns>The information of the current song.</returns> /// <returns>The information of the current song.</returns>
public MpdFile CurrentSong() public async Task<MpdFile> CurrentSongAsync()
{ {
MpdResponse response = _connection.Exec("currentsong"); MpdResponse response = await _connection.Exec("currentsong");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -365,9 +357,9 @@ namespace LibMpc
/// Deletes the track with the given index from the current playlist. /// Deletes the track with the given index from the current playlist.
/// </summary> /// </summary>
/// <param name="nr">The index of the track to remove from the playlist.</param> /// <param name="nr">The index of the track to remove from the playlist.</param>
public void Delete(int nr) public async Task DeleteAsync(int nr)
{ {
MpdResponse response = _connection.Exec("delete", new string[] { nr.ToString() }); MpdResponse response = await _connection.Exec("delete", new string[] { nr.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -376,9 +368,9 @@ namespace LibMpc
/// Deletes the track with the given id from the current playlist. /// Deletes the track with the given id from the current playlist.
/// </summary> /// </summary>
/// <param name="id">The id of the track to remove from the playlist.</param> /// <param name="id">The id of the track to remove from the playlist.</param>
public void DeleteId(int id) public async Task DeleteIdAsync(int id)
{ {
MpdResponse response = _connection.Exec("deleteid", new string[] { id.ToString() }); MpdResponse response = await _connection.Exec("deleteid", new string[] { id.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -387,12 +379,12 @@ namespace LibMpc
/// Loads the playlist with the given name. /// Loads the playlist with the given name.
/// </summary> /// </summary>
/// <param name="name">The name of the playlist to load.</param> /// <param name="name">The name of the playlist to load.</param>
public void Load(string name) public async Task LoadAsync(string name)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("load", new string[] { name }); MpdResponse response = await _connection.Exec("load", new string[] { name });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -402,14 +394,14 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="oldName">The old name of the playlist.</param> /// <param name="oldName">The old name of the playlist.</param>
/// <param name="newName">The new name of the playlist.</param> /// <param name="newName">The new name of the playlist.</param>
public void Rename(string oldName, string newName) public async Task RenameAsync(string oldName, string newName)
{ {
if (oldName == null) if (oldName == null)
throw new ArgumentNullException("oldName"); throw new ArgumentNullException("oldName");
if (newName == null) if (newName == null)
throw new ArgumentNullException("newName"); throw new ArgumentNullException("newName");
MpdResponse response = _connection.Exec("rename", new string[] { oldName, newName }); MpdResponse response = await _connection.Exec("rename", new string[] { oldName, newName });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -419,9 +411,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="oldNr">The old index of the track in the playlist.</param> /// <param name="oldNr">The old index of the track in the playlist.</param>
/// <param name="newNr">The new index of the track in the playlist.</param> /// <param name="newNr">The new index of the track in the playlist.</param>
public void Move(int oldNr, int newNr) public async Task MoveAsync(int oldNr, int newNr)
{ {
MpdResponse response = _connection.Exec("move", new string[] { oldNr.ToString(), newNr.ToString() }); MpdResponse response = await _connection.Exec("move", new string[] { oldNr.ToString(), newNr.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -431,9 +423,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="id">The id of the track to move.</param> /// <param name="id">The id of the track to move.</param>
/// <param name="nr">The new index of the track in the playlist.</param> /// <param name="nr">The new index of the track in the playlist.</param>
public void MoveId(int id, int nr) public async Task MoveIdAsync(int id, int nr)
{ {
MpdResponse response = _connection.Exec("moveid", new string[] { id.ToString(), nr.ToString() }); MpdResponse response = await _connection.Exec("moveid", new string[] { id.ToString(), nr.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -442,9 +434,9 @@ namespace LibMpc
/// Returns the meta data of the items in the current playlist. /// Returns the meta data of the items in the current playlist.
/// </summary> /// </summary>
/// <returns>The meta data of the items in the current playlist.</returns> /// <returns>The meta data of the items in the current playlist.</returns>
public List<MpdFile> PlaylistInfo() public async Task<List<MpdFile>> PlaylistInfoAsync()
{ {
MpdResponse response = _connection.Exec("playlistinfo"); MpdResponse response = await _connection.Exec("playlistinfo");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -456,9 +448,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="nr">The index of the track in the playlist.</param> /// <param name="nr">The index of the track in the playlist.</param>
/// <returns>The meta data of the track in the current playlist.</returns> /// <returns>The meta data of the track in the current playlist.</returns>
public MpdFile PlaylistInfo(int nr) public async Task<MpdFile> PlaylistInfoAsync(int nr)
{ {
MpdResponse response = _connection.Exec("playlistinfo", new string[] { nr.ToString() }); MpdResponse response = await _connection.Exec("playlistinfo", new string[] { nr.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -469,9 +461,9 @@ namespace LibMpc
/// Returns the meta data of the items in the current playlist. /// Returns the meta data of the items in the current playlist.
/// </summary> /// </summary>
/// <returns>The meta data of the items in the current playlist.</returns> /// <returns>The meta data of the items in the current playlist.</returns>
public List<MpdFile> PlaylistId() public async Task<List<MpdFile>> PlaylistIdAsync()
{ {
MpdResponse response = _connection.Exec("playlistid"); MpdResponse response = await _connection.Exec("playlistid");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -483,9 +475,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="id">The id of the track in the playlist.</param> /// <param name="id">The id of the track in the playlist.</param>
/// <returns>The meta data of the track in the current playlist.</returns> /// <returns>The meta data of the track in the current playlist.</returns>
public MpdFile PlaylistId(int id) public async Task<MpdFile> PlaylistIdAsync(int id)
{ {
MpdResponse response = _connection.Exec("playlistid", new string[] { id.ToString() }); MpdResponse response = await _connection.Exec("playlistid", new string[] { id.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -497,9 +489,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="version">The version number.</param> /// <param name="version">The version number.</param>
/// <returns>All changed songs in the playlist since the given version.</returns> /// <returns>All changed songs in the playlist since the given version.</returns>
public List<MpdFile> Plchanges(int version) public async Task<List<MpdFile>> PlchangesAsync(int version)
{ {
MpdResponse response = _connection.Exec("plchanges", new string[] { version.ToString() }); MpdResponse response = await _connection.Exec("plchanges", new string[] { version.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -514,9 +506,9 @@ namespace LibMpc
/// The ids and positions of the changed tracks in the playlist since the given version as KeyValuePairs. /// The ids and positions of the changed tracks in the playlist since the given version as KeyValuePairs.
/// The key is the index and the id is the value. /// The key is the index and the id is the value.
/// </returns> /// </returns>
public List<KeyValuePair<int, int>> PlChangesPosId(int version) public async Task<List<KeyValuePair<int, int>>> PlChangesPosIdAsync(int version)
{ {
MpdResponse response = _connection.Exec("plchangesposid", new string[] { version.ToString() }); MpdResponse response = await _connection.Exec("plchangesposid", new string[] { version.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -558,12 +550,12 @@ namespace LibMpc
/// Removes the playlist with the given name. /// Removes the playlist with the given name.
/// </summary> /// </summary>
/// <param name="name">The name of the playlist to remove.</param> /// <param name="name">The name of the playlist to remove.</param>
public void Rm(string name) public async Task RmAsync(string name)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("rm", new string[] { name }); MpdResponse response = await _connection.Exec("rm", new string[] { name });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -572,12 +564,12 @@ namespace LibMpc
/// Saves the current playlist with the given name. /// Saves the current playlist with the given name.
/// </summary> /// </summary>
/// <param name="name">The name to the save the currenty playlist.</param> /// <param name="name">The name to the save the currenty playlist.</param>
public void Save(string name) public async Task SaveAsync(string name)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("save", new string[] { name }); MpdResponse response = await _connection.Exec("save", new string[] { name });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -585,9 +577,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Shuffles the current playlist. /// Shuffles the current playlist.
/// </summary> /// </summary>
public void Shuffle() public async Task ShuffleAsync()
{ {
MpdResponse response = _connection.Exec("shuffle"); MpdResponse response = await _connection.Exec("shuffle");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -597,9 +589,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="nr1">The index of the first track.</param> /// <param name="nr1">The index of the first track.</param>
/// <param name="nr2">The index of the second track.</param> /// <param name="nr2">The index of the second track.</param>
public void Swap(int nr1, int nr2) public async Task SwapAsync(int nr1, int nr2)
{ {
MpdResponse response = _connection.Exec("swap", new string[] { nr1.ToString(), nr2.ToString() }); MpdResponse response = await _connection.Exec("swap", new string[] { nr1.ToString(), nr2.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -609,9 +601,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="id1">The id of the first track.</param> /// <param name="id1">The id of the first track.</param>
/// <param name="id2">The id of the second track.</param> /// <param name="id2">The id of the second track.</param>
public void SwapId(int id1, int id2) public async Task SwapIdAsync(int id1, int id2)
{ {
MpdResponse response = _connection.Exec("swapid", new string[] { id1.ToString(), id2.ToString() }); MpdResponse response = await _connection.Exec("swapid", new string[] { id1.ToString(), id2.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -621,12 +613,12 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="name">The playlist whos filename are requested.</param> /// <param name="name">The playlist whos filename are requested.</param>
/// <returns>The filenames of the tracks in the given playlist.</returns> /// <returns>The filenames of the tracks in the given playlist.</returns>
public List<string> ListPlaylist(string name) public async Task<List<string>> ListPlaylistAsync(string name)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("listplaylist", new string[] { name }); MpdResponse response = await _connection.Exec("listplaylist", new string[] { name });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -638,12 +630,12 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="name">The playlist whos files meta data are requested.</param> /// <param name="name">The playlist whos files meta data are requested.</param>
/// <returns>The meta data of the tracks in the given playlist.</returns> /// <returns>The meta data of the tracks in the given playlist.</returns>
public List<MpdFile> ListPlaylistInfo(string name) public async Task<List<MpdFile>> ListPlaylistInfoAsync(string name)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("listplaylistinfo", new string[] { name }); MpdResponse response = await _connection.Exec("listplaylistinfo", new string[] { name });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -655,14 +647,14 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="name">The name of the playlist.</param> /// <param name="name">The name of the playlist.</param>
/// <param name="file">The path and name of the file to add.</param> /// <param name="file">The path and name of the file to add.</param>
public void PlaylistAdd(string name, string file) public async Task PlaylistAddAsync(string name, string file)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
if (file == null) if (file == null)
throw new ArgumentNullException("file"); throw new ArgumentNullException("file");
MpdResponse response = _connection.Exec("playlistadd", new string[] { name, file }); MpdResponse response = await _connection.Exec("playlistadd", new string[] { name, file });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -671,12 +663,12 @@ namespace LibMpc
/// Clears all tracks from a playlist. /// Clears all tracks from a playlist.
/// </summary> /// </summary>
/// <param name="name">The name of the playlist to clear.</param> /// <param name="name">The name of the playlist to clear.</param>
public void PlaylistClear(string name) public async Task PlaylistClearAsync(string name)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("playlistclear", new string[] { name }); MpdResponse response = await _connection.Exec("playlistclear", new string[] { name });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -686,12 +678,12 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="name">The name of the playlist</param> /// <param name="name">The name of the playlist</param>
/// <param name="id">The id of the track to delete.</param> /// <param name="id">The id of the track to delete.</param>
public void PlaylistDelete(string name, int id) public async Task PlaylistDeleteAsync(string name, int id)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("playlistdelete", new string[] { name, id.ToString() }); MpdResponse response = await _connection.Exec("playlistdelete", new string[] { name, id.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -702,12 +694,12 @@ namespace LibMpc
/// <param name="name">The name of the playlist.</param> /// <param name="name">The name of the playlist.</param>
/// <param name="id">The id of the track to move.</param> /// <param name="id">The id of the track to move.</param>
/// <param name="nr">The position to move the track to.</param> /// <param name="nr">The position to move the track to.</param>
public void PlaylistMove(string name, int id, int nr) public async Task PlaylistMoveAsync(string name, int id, int nr)
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("name"); throw new ArgumentNullException("name");
MpdResponse response = _connection.Exec("playlistmove", new string[] { id.ToString(), nr.ToString() }); MpdResponse response = await _connection.Exec("playlistmove", new string[] { id.ToString(), nr.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -718,12 +710,12 @@ namespace LibMpc
/// <param name="scopeSpecifier">The attribute to search for the given value.</param> /// <param name="scopeSpecifier">The attribute to search for the given value.</param>
/// <param name="token">The value to search for in the given attribute.</param> /// <param name="token">The value to search for in the given attribute.</param>
/// <returns>The meta data for all tracks in the current playlist whos attribute equals the given value.</returns> /// <returns>The meta data for all tracks in the current playlist whos attribute equals the given value.</returns>
public List<MpdFile> PlaylistFind(ScopeSpecifier scopeSpecifier, string token) public async Task<List<MpdFile>> PlaylistFindAsync(ScopeSpecifier scopeSpecifier, string token)
{ {
if (token == null) if (token == null)
throw new ArgumentNullException("token"); throw new ArgumentNullException("token");
MpdResponse response = _connection.Exec("playlistfind", new string[] { TagConverter.ToTag(scopeSpecifier), token }); MpdResponse response = await _connection.Exec("playlistfind", new string[] { TagConverter.ToTag(scopeSpecifier), token });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -736,12 +728,12 @@ namespace LibMpc
/// <param name="scopeSpecifier">The attribute to search for the given value.</param> /// <param name="scopeSpecifier">The attribute to search for the given value.</param>
/// <param name="token">The value to search for in the given attribute.</param> /// <param name="token">The value to search for in the given attribute.</param>
/// <returns>The meta data for all tracks in the current playlist whos attribute contains the given value.</returns> /// <returns>The meta data for all tracks in the current playlist whos attribute contains the given value.</returns>
public List<MpdFile> PlaylistSearch(ScopeSpecifier scopeSpecifier, string token) public async Task<List<MpdFile>> PlaylistSearchAsync(ScopeSpecifier scopeSpecifier, string token)
{ {
if (token == null) if (token == null)
throw new ArgumentNullException("token"); throw new ArgumentNullException("token");
MpdResponse response = _connection.Exec("playlistsearch", new string[] { TagConverter.ToTag(scopeSpecifier), token }); MpdResponse response = await _connection.Exec("playlistsearch", new string[] { TagConverter.ToTag(scopeSpecifier), token });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -755,9 +747,9 @@ namespace LibMpc
/// Sets the seconds to crossfade between songs. /// Sets the seconds to crossfade between songs.
/// </summary> /// </summary>
/// <param name="seconds">The seconds to crossfade between songs.</param> /// <param name="seconds">The seconds to crossfade between songs.</param>
public void Crossfade(int seconds) public async Task CrossfadeAsync(int seconds)
{ {
MpdResponse response = _connection.Exec("crossfade", new string[] { seconds.ToString() }); MpdResponse response = await _connection.Exec("crossfade", new string[] { seconds.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -765,9 +757,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Starts the playback of the next song in the playlist- /// Starts the playback of the next song in the playlist-
/// </summary> /// </summary>
public void Next() public async Task NextAsync()
{ {
MpdResponse response = _connection.Exec("next"); MpdResponse response = await _connection.Exec("next");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -776,9 +768,9 @@ namespace LibMpc
/// Sets the MPD to pause or resume the playback. /// Sets the MPD to pause or resume the playback.
/// </summary> /// </summary>
/// <param name="pause">If the playback should be paused or resumed.</param> /// <param name="pause">If the playback should be paused or resumed.</param>
public void Pause(bool pause) public async Task PauseAsync(bool pause)
{ {
MpdResponse response = _connection.Exec("pause", new string[] { pause ? "1" : "0" }); MpdResponse response = await _connection.Exec("pause", new string[] { pause ? "1" : "0" });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -786,9 +778,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Starts the playback of the current item in the playlist. /// Starts the playback of the current item in the playlist.
/// </summary> /// </summary>
public void Play() public async Task PlayAsync()
{ {
MpdResponse response = _connection.Exec("play"); MpdResponse response = await _connection.Exec("play");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -797,9 +789,9 @@ namespace LibMpc
/// Starts the playback of the item with the given index in the playlist. /// Starts the playback of the item with the given index in the playlist.
/// </summary> /// </summary>
/// <param name="nr">The index of the track in the playlist to start playing.</param> /// <param name="nr">The index of the track in the playlist to start playing.</param>
public void Play(int nr) public async Task PlayAsync(int nr)
{ {
MpdResponse response = _connection.Exec("play", new string[] { nr.ToString() }); MpdResponse response = await _connection.Exec("play", new string[] { nr.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -807,9 +799,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Starts the playback of the track in the playlist with the id 0. /// Starts the playback of the track in the playlist with the id 0.
/// </summary> /// </summary>
public void PlayId() public async Task PlayIdAsync()
{ {
MpdResponse response = _connection.Exec("playid"); MpdResponse response = await _connection.Exec("playid");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -818,9 +810,9 @@ namespace LibMpc
/// Starts the playback of the track in the playlist with the given id. /// Starts the playback of the track in the playlist with the given id.
/// </summary> /// </summary>
/// <param name="id">The id of the track to start playing.</param> /// <param name="id">The id of the track to start playing.</param>
public void PlayId(int id) public async Task PlayIdAsync(int id)
{ {
MpdResponse response = _connection.Exec("playid", new string[] { id.ToString() }); MpdResponse response = await _connection.Exec("playid", new string[] { id.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -828,9 +820,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Starts the playback of the previous track in the playlist. /// Starts the playback of the previous track in the playlist.
/// </summary> /// </summary>
public void Previous() public async Task PreviousAsync()
{ {
MpdResponse response = _connection.Exec("previous"); MpdResponse response = await _connection.Exec("previous");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -839,9 +831,9 @@ namespace LibMpc
/// Sets the MPD to random or sequential playback. /// Sets the MPD to random or sequential playback.
/// </summary> /// </summary>
/// <param name="random">If the MPD playlist should be played randomly.</param> /// <param name="random">If the MPD playlist should be played randomly.</param>
public void Random(bool random) public async Task RandomAsync(bool random)
{ {
MpdResponse response = _connection.Exec("random", new string[] { random ? "1" : "0" }); MpdResponse response = await _connection.Exec("random", new string[] { random ? "1" : "0" });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -850,9 +842,9 @@ namespace LibMpc
/// Sets if the MPD should repeat the playlist. /// Sets if the MPD should repeat the playlist.
/// </summary> /// </summary>
/// <param name="repeat">If the MPD should repeat the playlist.</param> /// <param name="repeat">If the MPD should repeat the playlist.</param>
public void Repeat(bool repeat) public async Task RepeatAsync(bool repeat)
{ {
MpdResponse response = _connection.Exec("repeat", new string[] { repeat ? "1" : "0" }); MpdResponse response = await _connection.Exec("repeat", new string[] { repeat ? "1" : "0" });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -862,9 +854,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="nr">The index of the song in the playlist.</param> /// <param name="nr">The index of the song in the playlist.</param>
/// <param name="time">The number of seconds to start playback on.</param> /// <param name="time">The number of seconds to start playback on.</param>
public void Seek(int nr, int time) public async Task SeekAsync(int nr, int time)
{ {
MpdResponse response = _connection.Exec("seek", new string[] { nr.ToString(), time.ToString() }); MpdResponse response = await _connection.Exec("seek", new string[] { nr.ToString(), time.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -874,9 +866,9 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="id">The id of the song in the playlist.</param> /// <param name="id">The id of the song in the playlist.</param>
/// <param name="time">The number of seconds to start playback on.</param> /// <param name="time">The number of seconds to start playback on.</param>
public void SeekId(int id, int time) public async Task SeekIdAsync(int id, int time)
{ {
MpdResponse response = _connection.Exec("seekid", new string[] { id.ToString(), time.ToString() }); MpdResponse response = await _connection.Exec("seekid", new string[] { id.ToString(), time.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -885,14 +877,14 @@ namespace LibMpc
/// Sets the output volume of the MPD. /// Sets the output volume of the MPD.
/// </summary> /// </summary>
/// <param name="vol">The output volume of the MPD between 0 and 100.</param> /// <param name="vol">The output volume of the MPD between 0 and 100.</param>
public void SetVol(int vol) public async Task SetVolAsync(int vol)
{ {
if (vol < 0) if (vol < 0)
throw new ArgumentException("vol < 0"); throw new ArgumentException("vol < 0");
if (vol > 100) if (vol > 100)
throw new ArgumentException("vol > 100"); throw new ArgumentException("vol > 100");
MpdResponse response = _connection.Exec("setvol", new string[] { vol.ToString() }); MpdResponse response = await _connection.Exec("setvol", new string[] { vol.ToString() });
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -900,9 +892,9 @@ namespace LibMpc
/// <summary> /// <summary>
/// Stops the playback of the MPD. /// Stops the playback of the MPD.
/// </summary> /// </summary>
public void Stop() public async Task StopAsync()
{ {
MpdResponse response = _connection.Exec("stop"); MpdResponse response = await _connection.Exec("stop");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -914,17 +906,17 @@ namespace LibMpc
/// <summary> /// <summary>
/// Clears the error message set in the MPD. /// Clears the error message set in the MPD.
/// </summary> /// </summary>
public void ClearError() public async Task ClearErrorAsync()
{ {
_connection.Exec("clearerror"); await _connection.Exec("clearerror");
} }
/// <summary> /// <summary>
/// Returns which commands the current user has access to. /// Returns which commands the current user has access to.
/// </summary> /// </summary>
/// <returns>The commands the current user has access to.</returns> /// <returns>The commands the current user has access to.</returns>
public List<string> Commands() public async Task<List<string>> CommandsAsync()
{ {
MpdResponse response = _connection.Exec("commands"); MpdResponse response = await _connection.Exec("commands");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -935,9 +927,9 @@ namespace LibMpc
/// Returns which commands the current user does has access to. /// Returns which commands the current user does has access to.
/// </summary> /// </summary>
/// <returns>The commands the current user does has access to.</returns> /// <returns>The commands the current user does has access to.</returns>
public List<string> NotCommands() public async Task<List<string>> NotCommandsAsync()
{ {
MpdResponse response = _connection.Exec("notcommands"); MpdResponse response = await _connection.Exec("notcommands");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -949,27 +941,28 @@ namespace LibMpc
/// </summary> /// </summary>
/// <param name="password">The password to authorize to the server.</param> /// <param name="password">The password to authorize to the server.</param>
/// <returns>If the password is valid.</returns> /// <returns>If the password is valid.</returns>
public bool Password(string password) public async Task<bool> PasswordAsync(string password)
{ {
if (password == null) if (password == null)
throw new ArgumentNullException("password"); throw new ArgumentNullException("password");
return _connection.Exec("password", new string[] { password }).IsError; var mpdResponse = await _connection.Exec("password", new string[] { password });
return mpdResponse.IsError;
} }
/// <summary> /// <summary>
/// Sends a ping command to the server and waits for the response. /// Sends a ping command to the server and waits for the response.
/// </summary> /// </summary>
public void Ping() public async Task PingAsync()
{ {
_connection.Exec("ping"); await _connection.Exec("ping");
} }
/// <summary> /// <summary>
/// Requests the current statistics from the MPD, /// Requests the current statistics from the MPD,
/// </summary> /// </summary>
/// <returns>The current statistics fromt the MPD.</returns> /// <returns>The current statistics fromt the MPD.</returns>
public MpdStatistics Stats() public async Task<MpdStatistics> StatsAsync()
{ {
MpdResponse response = _connection.Exec("stats"); MpdResponse response = await _connection.Exec("stats");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);
@ -1045,9 +1038,9 @@ namespace LibMpc
/// Returns the current status of the MPD. /// Returns the current status of the MPD.
/// </summary> /// </summary>
/// <returns>The current status of the MPD.</returns> /// <returns>The current status of the MPD.</returns>
public MpdStatus Status() public async Task<MpdStatus> StatusAsync()
{ {
MpdResponse response = _connection.Exec("status"); MpdResponse response = await _connection.Exec("status");
if (response.IsError) if (response.IsError)
throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); throw new MpdResponseException(response.ErrorCode, response.ErrorMessage);

View File

@ -24,68 +24,29 @@ namespace LibMpc
private static readonly Regex ACK_REGEX = new Regex("^ACK \\[(?<code>[0-9]*)@(?<nr>[0-9]*)] \\{(?<command>[a-z]*)} (?<message>.*)$"); private static readonly Regex ACK_REGEX = new Regex("^ACK \\[(?<code>[0-9]*)@(?<nr>[0-9]*)] \\{(?<command>[a-z]*)} (?<message>.*)$");
private IPEndPoint _ipEndPoint; private readonly IPEndPoint _server;
private TcpClient _tcpClient; private TcpClient _tcpClient;
private NetworkStream _networkStream; private NetworkStream _networkStream;
private StreamReader _reader; private StreamReader _reader;
private StreamWriter _writer; private StreamWriter _writer;
private string _version; private string _version;
/// <summary>
/// If the connection to the MPD is connected.
/// </summary>
public bool IsConnected { get { return (_tcpClient != null) && _tcpClient.Connected; } }
/// <summary>
/// The version of the MPD.
/// </summary>
public string Version { get { return _version; } }
private bool _autoConnect = false;
/// <summary>
/// If a connection should be established when a command is to be
/// executed in disconnected state.
/// </summary>
public bool AutoConnect
{
get{ return _autoConnect; }
set { _autoConnect = value; }
}
/// <summary>
/// Creates a new MpdConnection.
/// </summary>
/// <param name="server">The IPEndPoint of the MPD server.</param>
public MpcConnection(IPEndPoint server) public MpcConnection(IPEndPoint server)
{ {
Server = server; if (IsConnected) return;
}
/// <summary>
/// The IPEndPoint of the MPD server.
/// </summary>
/// <exception cref="AlreadyConnectedException">When a conenction to a MPD server is already established.</exception>
public IPEndPoint Server
{
get { return _ipEndPoint; }
set
{
if (IsConnected)
throw new AlreadyConnectedException();
_ipEndPoint = value;
ClearConnectionFields(); ClearConnectionFields();
} _server = server;
} }
/// <summary> public bool IsConnected => (_tcpClient != null) && _tcpClient.Connected;
/// Connects to the MPD server who's IPEndPoint was set in the Server property. public string Version => _version;
/// </summary>
/// <exception cref="InvalidOperationException">If no IPEndPoint was set to the Server property.</exception>
public async Task ConnectAsync() public async Task ConnectAsync()
{ {
if (_ipEndPoint == null) if (_server == null)
throw new InvalidOperationException("Server IPEndPoint not set."); throw new InvalidOperationException("Server IPEndPoint not set.");
if (IsConnected) if (IsConnected)
@ -93,7 +54,7 @@ namespace LibMpc
_tcpClient = new TcpClient(); _tcpClient = new TcpClient();
await _tcpClient.ConnectAsync(_ipEndPoint.Address, _ipEndPoint.Port); await _tcpClient.ConnectAsync(_server.Address, _server.Port);
_networkStream = _tcpClient.GetStream(); _networkStream = _tcpClient.GetStream();
@ -116,10 +77,12 @@ namespace LibMpc
/// <summary> /// <summary>
/// Disconnects from the current MPD server. /// Disconnects from the current MPD server.
/// </summary> /// </summary>
public Task Disconnect() private Task Disconnect()
{ {
if (_tcpClient == null) if (_tcpClient == null)
{
return Task.CompletedTask; return Task.CompletedTask;
}
_networkStream.Dispose(); _networkStream.Dispose();
ClearConnectionFields(); ClearConnectionFields();
@ -132,7 +95,7 @@ namespace LibMpc
/// <param name="command">The command to execute.</param> /// <param name="command">The command to execute.</param>
/// <returns>The MPD server response parsed into a basic object.</returns> /// <returns>The MPD server response parsed into a basic object.</returns>
/// <exception cref="ArgumentException">If the command contains a space of a newline charakter.</exception> /// <exception cref="ArgumentException">If the command contains a space of a newline charakter.</exception>
public MpdResponse Exec(string command) public async Task<MpdResponse> Exec(string command)
{ {
if (command == null) if (command == null)
throw new ArgumentNullException("command"); throw new ArgumentNullException("command");
@ -141,7 +104,8 @@ namespace LibMpc
if (command.Contains("\n")) if (command.Contains("\n"))
throw new ArgumentException("command contains newline"); throw new ArgumentException("command contains newline");
CheckConnected(); // TODO: Integrate connection status in MpdResponse
var connectionResult = await CheckConnectionAsync();
try try
{ {
@ -152,8 +116,7 @@ namespace LibMpc
} }
catch (Exception) catch (Exception)
{ {
try { Disconnect(); } try { await Disconnect(); } catch (Exception) { }
catch (Exception) { }
return null; // TODO: Create Null Object for MpdResponse return null; // TODO: Create Null Object for MpdResponse
} }
} }
@ -164,7 +127,7 @@ namespace LibMpc
/// <param name="argument">The arguments of the command.</param> /// <param name="argument">The arguments of the command.</param>
/// <returns>The MPD server response parsed into a basic object.</returns> /// <returns>The MPD server response parsed into a basic object.</returns>
/// <exception cref="ArgumentException">If the command contains a space of a newline charakter.</exception> /// <exception cref="ArgumentException">If the command contains a space of a newline charakter.</exception>
public MpdResponse Exec(string command, string[] argument) public async Task<MpdResponse> Exec(string command, string[] argument)
{ {
if (command == null) if (command == null)
throw new ArgumentNullException("command"); throw new ArgumentNullException("command");
@ -183,7 +146,8 @@ namespace LibMpc
throw new ArgumentException("argument[" + i + "] contains newline"); throw new ArgumentException("argument[" + i + "] contains newline");
} }
CheckConnected(); // TODO: Integrate connection status in MpdResponse
var connectionResult = await CheckConnectionAsync();
try try
{ {
@ -200,21 +164,19 @@ namespace LibMpc
} }
catch (Exception) catch (Exception)
{ {
try { Disconnect(); } catch (Exception) { } try { await Disconnect(); } catch (Exception) { }
throw; throw;
} }
} }
private void CheckConnected() private async Task<bool> CheckConnectionAsync()
{ {
if (!IsConnected) if (!IsConnected)
{ {
if (_autoConnect) await ConnectAsync();
ConnectAsync();
else
throw new NotConnectedException();
} }
return IsConnected;
} }
private void WriteToken(string token) private void WriteToken(string token)
@ -262,10 +224,10 @@ namespace LibMpc
private void ClearConnectionFields() private void ClearConnectionFields()
{ {
_tcpClient?.Dispose();
_networkStream?.Dispose();
_reader?.Dispose();
_writer?.Dispose(); _writer?.Dispose();
_reader?.Dispose();
_networkStream?.Dispose();
_tcpClient?.Dispose();
_version = string.Empty; _version = string.Empty;
} }
} }