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

Original code base

This commit is contained in:
Gabriel 2016-10-30 23:54:45 +01:00
parent d95448d4a4
commit dd938883e5
10 changed files with 3266 additions and 0 deletions

80
LibMpc/Enum.cs Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Libmpc
{
/// <summary>
/// The scope specifier for search commands.
/// </summary>
public enum ScopeSpecifier
{
/// <summary>
/// Any attribute of a file.
/// </summary>
Any,
/// <summary>
/// The path and name of the file.
/// </summary>
Filename,
/// <summary>
/// The artist of the track.
/// </summary>
Artist,
/// <summary>
/// The album the track appears on.
/// </summary>
Album,
/// <summary>
/// The title of the track.
/// </summary>
Title,
/// <summary>
/// The index of the track on its album.
/// </summary>
Track,
/// <summary>
/// The name of the track.
/// </summary>
Name,
/// <summary>
/// The genre of the song.
/// </summary>
Genre,
/// <summary>
/// The date the track was released.
/// </summary>
Date,
/// <summary>
/// The composer of the song.
/// </summary>
Composer,
/// <summary>
/// The performer of the song.
/// </summary>
Performer,
/// <summary>
/// A comment for the track.
/// </summary>
Comment,
/// <summary>
/// The disc of a multidisc album the track is on.
/// </summary>
Disc
}
}

90
LibMpc/Exception.cs Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Libmpc
{
/// <summary>
/// Is thrown when a command is to be executed on a disconnected <see cref="MpcConnection"/>
/// where the <see cref="MpcConnection.AutoConnect"/> property is set to false.
/// </summary>
public class NotConnectedException : InvalidOperationException
{
/// <summary>
/// Creates a new NotConnectedException.
/// </summary>
public NotConnectedException() : base("Not connected.") {}
}
/// <summary>
/// Is thrown when the connect method is invoked on an already connected <see cref="MpcConnection"/>.
/// </summary>
public class AlreadyConnectedException : InvalidOperationException
{
/// <summary>
/// Creates a new AlreadyConnectedException.
/// </summary>
public AlreadyConnectedException() : base("Connected already established.") { }
}
/// <summary>
/// Is thrown if the response from a MPD server is not as expected. This should never happen when
/// working with a tested version of the MPD server.
/// </summary>
public class InvalidMpdResponseException : Exception
{
/// <summary>
/// Creates a new InvalidMpdResponseException.
/// </summary>
public InvalidMpdResponseException() : base( "Invalid Mpd Response." ) {}
/// <summary>
/// Creates a new InvalidMpdResponseException.
/// </summary>
/// <param name="message">A message describing the error.</param>
public InvalidMpdResponseException(string message) : base("Invalid Mpd Response: " + message) { }
}
/// <summary>
/// Is thrown when the MPD server returns an error to a command.
/// </summary>
public class MpdResponseException : Exception
{
private int errorCode;
private string errorMessage;
/// <summary>
/// The error code of the mpd server.
/// </summary>
public int ErrorCode { get { return this.errorCode; } }
/// <summary>
/// A message describing what went wrong.
/// </summary>
public string ErrorMessage { get { return this.errorMessage; } }
/// <summary>
/// Creates a new MpdResponseException.
/// </summary>
/// <param name="errorCode">The error code of the mpd server.</param>
/// <param name="errorMessage">A message describing what went wrong.</param>
public MpdResponseException(int errorCode, string errorMessage)
: base("MPD" + errorCode + " " + errorMessage)
{
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
}
}

1337
LibMpc/Mpc.cs Normal file

File diff suppressed because it is too large Load Diff

316
LibMpc/MpcConnection.cs Normal file
View File

@ -0,0 +1,316 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
namespace Libmpc
{
/// <summary>
/// The delegate for the <see cref="MpcConnection.OnConnected"/> and <see cref="MpcConnection.OnDisconnected"/> events.
/// </summary>
/// <param name="connection">The connection firing the event.</param>
public delegate void MpcConnectionEventDelegate( MpcConnection connection );
/// <summary>
/// Keeps the connection to the MPD server and handels the most basic structure of the
/// MPD protocol. The high level commands are handeled in the <see cref="Libmpc.Mpc"/>
/// class.
/// </summary>
public class MpcConnection
{
/// <summary>
/// Is fired when a connection to a MPD server is established.
/// </summary>
public event MpcConnectionEventDelegate OnConnected;
/// <summary>
/// Is fired when the connection to the MPD server is closed.
/// </summary>
public event MpcConnectionEventDelegate OnDisconnected;
private static readonly string FIRST_LINE_PREFIX = "OK MPD ";
private static readonly string OK = "OK";
private static readonly string ACK = "ACK";
private static readonly Regex ACK_REGEX = new Regex("^ACK \\[(?<code>[0-9]*)@(?<nr>[0-9]*)] \\{(?<command>[a-z]*)} (?<message>.*)$");
private IPEndPoint ipEndPoint = null;
private TcpClient tcpClient = null;
private NetworkStream networkStream = null;
private StreamReader reader;
private StreamWriter writer;
private string version;
/// <summary>
/// If the connection to the MPD is connected.
/// </summary>
public bool Connected { get { return (this.tcpClient != null) && this.tcpClient.Connected; } }
/// <summary>
/// The version of the MPD.
/// </summary>
public string Version { get { return this.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 this.autoConnect; }
set { this.autoConnect = value; }
}
/// <summary>
/// Creates a new MpdConnection.
/// </summary>
public MpcConnection() {}
/// <summary>
/// Creates a new MpdConnection.
/// </summary>
/// <param name="server">The IPEndPoint of the MPD server.</param>
public MpcConnection(IPEndPoint server) { this.Connect(server); }
/// <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 this.ipEndPoint; }
set
{
if (this.Connected)
throw new AlreadyConnectedException();
this.ipEndPoint = value;
this.ClearConnectionFields();
}
}
/// <summary>
/// Connects to a MPD server.
/// </summary>
/// <param name="server">The IPEndPoint of the server.</param>
public void Connect(IPEndPoint server)
{
this.Server = server;
this.Connect();
}
/// <summary>
/// Connects to the MPD server who's IPEndPoint was set in the Server property.
/// </summary>
/// <exception cref="InvalidOperationException">If no IPEndPoint was set to the Server property.</exception>
public void Connect()
{
if (this.ipEndPoint == null)
throw new InvalidOperationException("Server IPEndPoint not set.");
if (this.Connected)
throw new AlreadyConnectedException();
this.tcpClient = new TcpClient(
this.ipEndPoint.Address.ToString(),
this.ipEndPoint.Port);
this.networkStream = this.tcpClient.GetStream();
this.reader = new StreamReader(this.networkStream, Encoding.UTF8);
this.writer = new StreamWriter(this.networkStream, Encoding.UTF8);
this.writer.NewLine = "\n";
string firstLine = this.reader.ReadLine();
if( !firstLine.StartsWith( FIRST_LINE_PREFIX ) )
{
this.Disconnect();
throw new InvalidDataException("Response of mpd does not start with \"" + FIRST_LINE_PREFIX + "\"." );
}
this.version = firstLine.Substring(FIRST_LINE_PREFIX.Length);
this.writer.WriteLine();
this.writer.Flush();
this.readResponse();
if( this.OnConnected != null )
this.OnConnected.Invoke( this );
}
/// <summary>
/// Disconnects from the current MPD server.
/// </summary>
public void Disconnect()
{
if (this.tcpClient == null)
return;
this.networkStream.Close();
this.ClearConnectionFields();
if( this.OnDisconnected != null )
this.OnDisconnected.Invoke( this );
}
/// <summary>
/// Executes a simple command without arguments on the MPD server and returns the response.
/// </summary>
/// <param name="command">The command to execute.</param>
/// <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>
public MpdResponse Exec(string command)
{
if (command == null)
throw new ArgumentNullException("command");
if (command.Contains(" "))
throw new ArgumentException("command contains space");
if (command.Contains("\n"))
throw new ArgumentException("command contains newline");
this.CheckConnected();
try
{
this.writer.WriteLine(command);
this.writer.Flush();
return this.readResponse();
}
catch (Exception)
{
try { this.Disconnect(); }
catch (Exception) { }
throw;
}
}
/// <summary>
/// Executes a MPD command with arguments on the MPD server.
/// </summary>
/// <param name="command">The command to execute.</param>
/// <param name="argument">The arguments of the command.</param>
/// <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>
public MpdResponse Exec(string command, string[] argument)
{
if (command == null)
throw new ArgumentNullException("command");
if (command.Contains(" "))
throw new ArgumentException("command contains space");
if (command.Contains("\n"))
throw new ArgumentException("command contains newline");
if (argument == null)
throw new ArgumentNullException("argument");
for (int i = 0; i < argument.Length; i++)
{
if (argument[i] == null)
throw new ArgumentNullException("argument[" + i + "]");
if (argument[i].Contains("\n"))
throw new ArgumentException("argument[" + i + "] contains newline");
}
this.CheckConnected();
try
{
this.writer.Write(command);
foreach (string arg in argument)
{
this.writer.Write(' ');
this.WriteToken(arg);
}
this.writer.WriteLine();
this.writer.Flush();
return this.readResponse();
}
catch (Exception)
{
try { this.Disconnect(); } catch (Exception) { }
throw;
}
}
private void CheckConnected()
{
if (!this.Connected)
{
if (this.autoConnect)
this.Connect();
else
throw new NotConnectedException();
}
}
private void WriteToken(string token)
{
if (token.Contains(" "))
{
this.writer.Write("\"");
foreach (char chr in token)
if (chr == '"')
this.writer.Write("\\\"");
else
this.writer.Write(chr);
}
else
this.writer.Write(token);
}
private MpdResponse readResponse()
{
List<string> ret = new List<string>();
string line = this.reader.ReadLine();
while (!(line.Equals(OK) || line.StartsWith(ACK)))
{
ret.Add(line);
line = this.reader.ReadLine();
}
if (line.Equals(OK))
return new MpdResponse(new ReadOnlyCollection<string>(ret));
else
{
Match match = ACK_REGEX.Match(line);
if (match.Groups.Count != 5)
throw new InvalidDataException( "Error response not as expected" );
return new MpdResponse(
int.Parse( match.Result("${code}") ),
int.Parse( match.Result("${nr}") ),
match.Result("${command}"),
match.Result("${message}"),
new ReadOnlyCollection<string>(ret)
);
}
}
private void ClearConnectionFields()
{
this.tcpClient = null;
this.networkStream = null;
this.reader = null;
this.writer = null;
this.version = null;
}
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace Libmpc
{
/// <summary>
/// The MpdDirectoryListing class contains the response of a MPD server to a list command.
/// </summary>
public class MpdDirectoryListing
{
private readonly ReadOnlyCollection<MpdFile> file;
private readonly ReadOnlyCollection<string> directory;
private readonly ReadOnlyCollection<string> playlist;
/// <summary>
/// The list of files in the directory.
/// </summary>
public ReadOnlyCollection<MpdFile> FileList { get { return this.file; } }
/// <summary>
/// The list of subdirectories in the directory.
/// </summary>
public ReadOnlyCollection<string> DirectoryList { get { return this.directory; } }
/// <summary>
/// The list of playlists in the directory.
/// </summary>
public ReadOnlyCollection<string> PlaylistList { get { return this.playlist; } }
/// <summary>
/// Creates a new MpdDirectoryListing.
/// </summary>
/// <param name="file">The list of files in the directory.</param>
/// <param name="directory">The list of subdirectories in the directory.</param>
/// <param name="playlist">The list of playlists in the directory.</param>
public MpdDirectoryListing(List<MpdFile> file, List<string> directory, List<string> playlist)
{
if (file == null)
throw new ArgumentNullException("file");
if (directory == null)
throw new ArgumentNullException("directory");
if (playlist == null)
throw new ArgumentNullException("playlist");
this.file = new ReadOnlyCollection<MpdFile>(file);
this.directory = new ReadOnlyCollection<string>(directory);
this.playlist = new ReadOnlyCollection<string>(playlist);
}
/// <summary>
/// Creates a new MpdDirectoryListing.
/// </summary>
/// <param name="file">The list of files in the directory.</param>
/// <param name="directory">The list of subdirectories in the directory.</param>
/// <param name="playlist">The list of playlists in the directory.</param>
public MpdDirectoryListing(ReadOnlyCollection<MpdFile> file, ReadOnlyCollection<string> directory, ReadOnlyCollection<string> playlist)
{
if (file == null)
throw new ArgumentNullException("file");
if (directory == null)
throw new ArgumentNullException("directory");
if (playlist == null)
throw new ArgumentNullException("playlist");
this.file = file;
this.directory = directory;
this.playlist = playlist;
}
}
}

559
LibMpc/MpdFile.cs Normal file
View File

@ -0,0 +1,559 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Libmpc
{
/// <summary>
/// The MpdFile class contains all meta data for a file of the MPD.
/// </summary>
public class MpdFile
{
private const string TAG_FILE = "file";
private const string TAG_TIME = "Time";
private const string TAG_ARTIST = "Artist";
private const string TAG_ALBUM = "Album";
private const string TAG_TITLE = "Title";
private const string TAG_TRACK = "Track";
private const string TAG_NAME = "Name";
private const string TAG_GENRE = "Genre";
private const string TAG_DATE = "Date";
private const string TAG_COMPOSER = "Composer";
private const string TAG_PERFORMER = "Performer";
private const string TAG_COMMENT = "Comment";
private const string TAG_DISC = "Disc";
private const string TAG_POS = "Pos";
private const string TAG_ID = "Id";
private const int NO_TIME = -1;
private const string NO_ALBUM = null;
private const string NO_ARTIST = null;
private const string NO_TITLE = null;
private const string NO_TRACK = null;
private const string NO_NAME = null;
private const string NO_GENRE = null;
private const string NO_DATE = null;
private const string NO_COMPOSER = null;
private const string NO_PERFORMER = null;
private const string NO_COMMENT = null;
private const int NO_DISC = -1;
private const int NO_POS = -1;
private const int NO_ID = -1;
private readonly string file;
private readonly int time;
private readonly string album;
private readonly string artist;
private readonly string title;
private readonly string track;
private readonly string name;
private readonly string genre;
private readonly string date;
private readonly string composer;
private readonly string performer;
private readonly string comment;
private readonly int disc;
private readonly int pos;
private readonly int id;
/// <summary>
/// The name and path of the file.
/// </summary>
public string File { get { return this.file; } }
/// <summary>
/// The length of the file in seconds.
/// </summary>
public int Time { get { return this.time; } }
/// <summary>
/// The album of the file.
/// </summary>
public string Album { get { return this.album; } }
/// <summary>
/// The artist of the file.
/// </summary>
public string Artist { get { return this.artist; } }
/// <summary>
/// The title of the file.
/// </summary>
public string Title { get { return this.title; } }
/// <summary>
/// The value of the track property of the file.
/// </summary>
public string Track { get { return this.track; } }
/// <summary>
/// The name of the song.
/// </summary>
public string Name { get { return this.name; } }
/// <summary>
/// The genre of the song.
/// </summary>
public string Genre { get { return this.genre; } }
/// <summary>
/// The date the song was released.
/// </summary>
public string Date { get { return this.date; } }
/// <summary>
/// The composer of the song.
/// </summary>
public string Composer { get { return this.composer; } }
/// <summary>
/// The performer of the song.
/// </summary>
public string Performer { get { return this.performer; } }
/// <summary>
/// A comment to the file.
/// </summary>
public string Comment { get { return this.comment; } }
/// <summary>
/// The number of the disc on a multidisc album.
/// </summary>
public int Disc { get { return this.disc; } }
/// <summary>
/// The index of the file in a playlist.
/// </summary>
public int Pos { get { return this.pos; } }
/// <summary>
/// The id of the file in a playlist.
/// </summary>
public int Id { get { return this.id; } }
/// <summary>
/// If the MpdFile has the <see cref="Time"/> property set.
/// </summary>
public bool HasTime { get { return this.time != NO_TIME; } }
/// <summary>
/// If the MpdFile has the <see cref="Album"/> property set.
/// </summary>
public bool HasAlbum { get { return this.album != NO_ALBUM; } }
/// <summary>
/// If the MpdFile has the <see cref="Artist"/> property set.
/// </summary>
public bool HasArtist { get { return this.artist != NO_ARTIST; } }
/// <summary>
/// If the MpdFile has the <see cref="Title"/> property set.
/// </summary>
public bool HasTitle { get { return this.title != NO_TITLE; } }
/// <summary>
/// If the MpdFile has the <see cref="Track"/> property set.
/// </summary>
public bool HasTrack { get { return this.track != NO_TRACK; } }
/// <summary>
/// If the MpdFile has the <see cref="Name"/> property set.
/// </summary>
public bool HasName { get { return this.name != NO_NAME; } }
/// <summary>
/// If the MpdFile has the <see cref="Genre"/> property set.
/// </summary>
public bool HasGenre { get { return this.genre != NO_GENRE; } }
/// <summary>
/// If the MpdFile has the <see cref="Date"/> property set.
/// </summary>
public bool HasDate { get { return this.date != NO_DATE; } }
/// <summary>
/// If the MpdFile has the <see cref="Composer"/> property set.
/// </summary>
public bool HasComposer { get { return this.composer != NO_COMPOSER; } }
/// <summary>
/// If the MpdFile has the <see cref="Performer"/> property set.
/// </summary>
public bool HasPerformer { get { return this.performer != NO_PERFORMER; } }
/// <summary>
/// If the MpdFile has the <see cref="Comment"/> property set.
/// </summary>
public bool HasComment { get { return this.comment != NO_COMMENT; } }
/// <summary>
/// If the MpdFile has the <see cref="Disc"/> property set.
/// </summary>
public bool HasDisc { get { return this.disc != NO_DISC; } }
/// <summary>
/// If the MpdFile has the <see cref="Pos"/> property set.
/// </summary>
public bool HasPos { get { return this.pos != NO_POS; } }
/// <summary>
/// If the MpdFile has the <see cref="Id"/> property set.
/// </summary>
public bool HasId { get { return this.id != NO_ID; } }
/// <summary>
/// Creates a new MpdFile.
/// </summary>
/// <param name="file">The name and path of the file.</param>
/// <param name="time">The length of the file in seconds.</param>
/// <param name="album">The album of the file.</param>
/// <param name="artist">The artist of the file.</param>
/// <param name="title">The title of the file.</param>
/// <param name="track">The value of the track property of the file.</param>
/// <param name="name">The name of the song.</param>
/// <param name="genre">The genre of the song.</param>
/// <param name="date">The date the song was released.</param>
/// <param name="composer">The composer of the song.</param>
/// <param name="performer">The performer of the song.</param>
/// <param name="comment">A comment to the file.</param>
/// <param name="disc">The number of the disc on a multidisc album.</param>
/// <param name="pos">The index of the file in a playlist.</param>
/// <param name="id">The id of the file in a playlist.</param>
public MpdFile(string file,
int time,
string album,
string artist,
string title,
string track,
string name,
string genre,
string date,
string composer,
string performer,
string comment,
int disc,
int pos,
int id)
{
if (file == null)
throw new ArgumentNullException("file");
this.file = file;
this.time = time;
this.album = album;
this.artist = artist;
this.title = title;
this.track = track;
this.name = name;
this.genre = genre;
this.date = date;
this.composer = composer;
this.performer = performer;
this.comment = comment;
this.disc = disc;
this.pos = pos;
this.id = id;
}
/// <summary>
/// A string containing all the properties of the file.
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
appendString(builder, TAG_FILE, this.file);
if (this.HasTime)
appendInt(builder, TAG_TIME, this.time);
if (this.HasAlbum)
appendString(builder, TAG_ALBUM, this.album);
if (this.HasArtist)
appendString(builder, TAG_ARTIST, this.artist);
if (this.HasTitle)
appendString(builder, TAG_TITLE, this.title);
if (this.HasTrack)
appendString(builder, TAG_TRACK, this.track);
if (this.HasName)
appendString(builder, TAG_NAME, this.name);
if (this.HasGenre)
appendString(builder, TAG_GENRE, this.genre);
if (this.HasDate)
appendString(builder, TAG_DATE, this.date);
if (this.HasComposer)
appendString(builder, TAG_COMPOSER, this.composer);
if (this.HasPerformer)
appendString(builder, TAG_PERFORMER, this.performer);
if (this.HasComment)
appendString(builder, TAG_COMMENT, this.comment);
if (this.HasDisc)
appendInt(builder, TAG_DISC, this.disc);
if (this.HasPos)
appendInt(builder, TAG_POS, this.pos);
if (this.HasId)
appendInt(builder, TAG_ID, this.id);
return builder.ToString();
}
private static void appendString(StringBuilder builder, string name, string value)
{
builder.Append(name);
builder.Append(": ");
builder.Append(value);
builder.AppendLine();
}
private static void appendInt(StringBuilder builder, string name, int value)
{
builder.Append(name);
builder.Append(": ");
builder.Append(value);
builder.AppendLine();
}
/// <summary>
/// Returns a MpdFile object from a MpdResponse object.
/// </summary>
/// <param name="response">The response of the MPD server.</param>
/// <returns>A new MpdFile object build from the MpdResponse object.</returns>
public static MpdFile build(MpdResponse response)
{
if (response == null)
throw new ArgumentNullException("response");
string file = null;
int time = NO_TIME;
string album = NO_ALBUM;
string artist = NO_ARTIST;
string title = NO_TITLE;
string track = NO_TRACK;
string name = NO_NAME;
string genre = NO_GENRE;
string date = NO_DATE;
string composer = NO_COMPOSER;
string performer = NO_PERFORMER;
string comment = NO_COMMENT;
int disc = NO_DISC;
int pos = NO_POS;
int id = NO_ID;
foreach (KeyValuePair<string, string> line in response)
{
if( line.Key != null )
switch (line.Key)
{
case TAG_FILE:
file = line.Value;
break;
case TAG_TIME:
int tryTime;
if( int.TryParse( line.Value, out tryTime ) )
time = tryTime;
break;
case TAG_ALBUM:
album = line.Value;
break;
case TAG_ARTIST:
artist = line.Value;
break;
case TAG_TITLE:
title = line.Value;
break;
case TAG_TRACK:
track = line.Value;
break;
case TAG_NAME:
name = line.Value;
break;
case TAG_GENRE:
genre = line.Value;
break;
case TAG_DATE:
date = line.Value;
break;
case TAG_COMPOSER:
composer = line.Value;
break;
case TAG_PERFORMER:
performer = line.Value;
break;
case TAG_COMMENT:
comment = line.Value;
break;
case TAG_DISC:
int tryDisc;
if (int.TryParse(line.Value, out tryDisc))
disc = tryDisc;
break;
case TAG_POS:
int tryPos;
if (int.TryParse(line.Value, out tryPos))
pos = tryPos;
break;
case TAG_ID:
int tryId;
if (int.TryParse(line.Value, out tryId))
id = tryId;
break;
}
}
if (file == null)
return null;
else
return new MpdFile(
file,
time,
album,
artist,
title,
track,
name,
genre,
date,
composer,
performer,
comment,
disc,
pos,
id);
}
/// <summary>
/// Builds a list of MpdFile objects from a MpdResponse object.
/// </summary>
/// <param name="response">The MpdResponse object to build the list of MpdFiles from.</param>
/// <returns>A list ob MpdFiles built from the MpdResponse object.</returns>
public static List<MpdFile> buildList(MpdResponse response)
{
if (response == null)
throw new ArgumentNullException("response");
List<MpdFile> ret = new List<MpdFile>();
string file = null;
int time = NO_TIME;
string album = NO_ALBUM;
string artist = NO_ARTIST;
string title = NO_TITLE;
string track = NO_TRACK;
string name = NO_NAME;
string genre = NO_GENRE;
string date = NO_DATE;
string composer = NO_COMPOSER;
string performer = NO_PERFORMER;
string comment = NO_COMMENT;
int disc = NO_DISC;
int pos = NO_POS;
int id = NO_ID;
foreach (KeyValuePair<string, string> line in response)
{
if( line.Key != null )
switch (line.Key)
{
case TAG_FILE:
if( file != null )
ret.Add( new MpdFile(
file,
time,
album,
artist,
title,
track,
name,
genre,
date,
composer,
performer,
comment,
disc,
pos,
id ) );
file = line.Value;
time = NO_TIME;
album = NO_ALBUM;
artist = NO_ARTIST;
title = NO_TITLE;
track = NO_TRACK;
name = NO_NAME;
genre = NO_GENRE;
date = NO_DATE;
composer = NO_COMPOSER;
performer = NO_PERFORMER;
comment = NO_COMMENT;
disc = NO_DISC;
pos = NO_POS;
id = NO_ID;
break;
case TAG_TIME:
int tryTime;
if( int.TryParse( line.Value, out tryTime ) )
time = tryTime;
break;
case TAG_ALBUM:
album = line.Value;
break;
case TAG_ARTIST:
artist = line.Value;
break;
case TAG_TITLE:
title = line.Value;
break;
case TAG_TRACK:
track = line.Value;
/*
int tryTrack;
if (int.TryParse(line.Value, out tryTrack))
track = tryTrack;
*/
break;
case TAG_NAME:
name = line.Value;
break;
case TAG_GENRE:
genre = line.Value;
break;
case TAG_DATE:
date = line.Value;
break;
case TAG_COMPOSER:
composer = line.Value;
break;
case TAG_PERFORMER:
performer = line.Value;
break;
case TAG_COMMENT:
comment = line.Value;
break;
case TAG_DISC:
int tryDisc;
if (int.TryParse(line.Value, out tryDisc))
disc = tryDisc;
break;
case TAG_POS:
int tryPos;
if (int.TryParse(line.Value, out tryPos))
pos = tryPos;
break;
case TAG_ID:
int tryId;
if (int.TryParse(line.Value, out tryId))
id = tryId;
break;
}
}
if (file != null)
ret.Add(new MpdFile(
file,
time,
album,
artist,
title,
track,
name,
genre,
date,
composer,
performer,
comment,
disc,
pos,
id ));
return ret;
}
}
}

69
LibMpc/MpdOutput.cs Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Libmpc
{
/// <summary>
/// The MpdOutput class contains all attributes of an output device of the MPD.
/// </summary>
public class MpdOutput
{
private readonly int id;
private readonly string name;
private readonly bool enabled;
/// <summary>
/// The id of the output.
/// </summary>
public int Id { get { return this.id; } }
/// <summary>
/// The name of the output.
/// </summary>
public string Name { get { return this.name; } }
/// <summary>
/// If the output is enabled.
/// </summary>
public bool IsEnabled { get { return this.enabled; } }
/// <summary>
/// Creates a new MpdOutput object.
/// </summary>
/// <param name="id">The id of the output.</param>
/// <param name="name">The name of the output.</param>
/// <param name="enabled">If the output is enabled.</param>
public MpdOutput(int id, string name, bool enabled)
{
if (name == null)
throw new ArgumentNullException("name");
this.id = id;
this.name = name;
this.enabled = enabled;
}
/// <summary>
/// Returns a string representation of the object mainly for debuging purpose.
/// </summary>
/// <returns>A string representation of the object.</returns>
public override string ToString()
{
return this.id + "::" + this.name + "::" + this.enabled;
}
}
}

326
LibMpc/MpdResponse.cs Normal file
View File

@ -0,0 +1,326 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.RegularExpressions;
namespace Libmpc
{
/// <summary>
/// The MpdResponse class parses the response to an MPD command in it's most
/// basic structure.
/// </summary>
public class MpdResponse : IEnumerable<KeyValuePair<string, string>>
{
private const string OK = "OK";
private const string ACK = "ACK";
private static readonly Regex LINE_REGEX = new Regex("^(?<key>[A-Za-z]*):[ ]{0,1}(?<value>.*)$");
private readonly bool isError;
private readonly int errorCode;
private readonly int commandListNum;
private readonly string currentCommand;
private readonly string errorMessage;
private readonly ReadOnlyCollection<string> message;
private Dictionary<string, string> dictionary = null;
/// <summary>
/// If the response denotes an error in the last command.
/// </summary>
public bool IsError { get { return this.isError; } }
/// <summary>
/// The error code if an error occured.
/// </summary>
public int ErrorCode { get { return this.errorCode; } }
/// <summary>
/// If an error occured the index of the invalid command in a command list.
/// </summary>
public int CommandListNum { get { return this.commandListNum; } }
/// <summary>
/// The command executed.
/// </summary>
public string CurrentCommand { get { return this.currentCommand; } }
/// <summary>
/// The description of the error, if occured.
/// </summary>
public string ErrorMessage { get { return this.errorMessage; } }
/// <summary>
/// The lines of the response message.
/// </summary>
public ReadOnlyCollection<string> Message { get { return this.message; } }
/// <summary>
/// The value of an attribute in the MPD response.
/// </summary>
/// <param name="key">The name of the attribute.</param>
/// <returns>The value of the attribute</returns>
public string this[string key]
{
get
{
if (this.dictionary == null)
{
this.dictionary = new Dictionary<string,string>();
foreach (string line in this.message)
{
Match match = LINE_REGEX.Match(line);
if (match.Success)
this.dictionary[match.Result("$key")] = match.Result("$value");
}
}
return this.dictionary[key];
}
}
/// <summary>
/// The number of lines in the response message.
/// </summary>
public int Count { get { return this.message.Count; } }
/// <summary>
/// A line in the MPD response as KeyValuePair. If the message cannot be separated
/// into key and value according to the MPD protocol spec, a KeyValuePair is returned
/// with the key null and the value the whole text of the line.
/// </summary>
/// <param name="line">The index of the line.</param>
/// <returns>The requested line as KeyValuePair.</returns>
public KeyValuePair<string, string> this[int line]
{
get
{
Match match = LINE_REGEX.Match(this.message[line]);
if (match.Success)
return new KeyValuePair<string, string>(match.Result("${key}"), match.Result("${value}"));
else
return new KeyValuePair<string,string>(null, this.message[line]);
}
}
/// <summary>
/// Creates a new MpdResponse from a list of lines in case no error occured.
/// </summary>
/// <param name="message">The response to an MPD command.</param>
public MpdResponse( ReadOnlyCollection<string> message )
{
if (message == null)
throw new ArgumentNullException("message");
this.isError = false;
this.errorCode = -1;
this.commandListNum = 0;
this.currentCommand = null;
this.errorMessage = null;
this.message = message;
}
/// <summary>
/// Creates a new MpdResponse in case an error occured.
/// </summary>
/// <param name="errorCode">The code of the error.</param>
/// <param name="commandListNum">The index of the command which raised the error.</param>
/// <param name="currentCommand">The command that raised the error.</param>
/// <param name="errorMessage">The message describing the error.</param>
/// <param name="message">The text of the standard MPD response.</param>
public MpdResponse( int errorCode, int commandListNum, string currentCommand, string errorMessage, ReadOnlyCollection<string> message)
{
if (currentCommand == null)
throw new ArgumentNullException("currentCommand");
if (errorMessage == null)
throw new ArgumentNullException("errorMessage");
if (message == null)
throw new ArgumentNullException("message");
this.isError = true;
this.errorCode = errorCode;
this.commandListNum = commandListNum;
this.currentCommand = currentCommand;
this.errorMessage = errorMessage;
this.message = message;
}
/// <summary>
/// Returns the values in all lines with the given attribute.
/// </summary>
/// <param name="attribute">The attribute who's values are reguested.</param>
/// <returns>The values in all lines with the given attribute.</returns>
public List<string> getAttributeValueList(string attribute)
{
List<string> ret = new List<string>();
foreach (string line in this.message)
{
Match match = LINE_REGEX.Match(line);
if (match.Success)
{
string key = match.Result("${key}");
if( ( key != null ) && key.Equals( attribute ) )
{
string value = match.Result("${value}");
if( value != null )
ret.Add( value );
}
}
}
return ret;
}
/// <summary>
/// Returns only the value parts in all key/value pairs in the response.
/// </summary>
/// <returns>The list of values in all key/value pairs in the response.</returns>
public List<string> getValueList()
{
List<string> ret = new List<string>();
foreach (string line in this.message)
{
Match match = LINE_REGEX.Match(line);
if (match.Success)
{
string value = match.Result("${value}");
if (value != null)
ret.Add(value);
}
}
return ret;
}
/// <summary>
/// Builds the response text of the MPD server from the object.
/// </summary>
/// <returns>The response text of the MPD server from the object.</returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
foreach (string line in this.message)
builder.AppendLine(line);
if (this.isError)
{
builder.Append(ACK);
builder.Append(" [");
builder.Append(this.errorMessage);
builder.Append('@');
builder.Append(this.commandListNum);
builder.Append("] {");
builder.Append(this.currentCommand);
builder.Append("} ");
builder.Append(this.errorMessage);
//ACK [50@1] {play} song doesn't exist: "10240"
}
else
builder.Append(OK);
return builder.ToString();
}
#region IEnumerable<KeyValuePair<string,string>> Members
/// <summary>
/// Returns an enumerator for all KeyValuePairs in the MPD response.
/// </summary>
/// <returns>An enumerator for all KeyValuePairs in the MPD response.</returns>
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
{
return new MpdResponseEnumerator(this);
}
#endregion
#region IEnumerable Members
/// <summary>
/// Returns an enumerator for all KeyValuePairs in the MPD response.
/// </summary>
/// <returns>An enumerator for all KeyValuePairs in the MPD response.</returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return new MpdResponseEnumerator(this);
}
#endregion
}
/// <summary>
/// A class for enumerating over the KeyValuePairs in the response.
/// </summary>
public class MpdResponseEnumerator :IEnumerator<KeyValuePair<string, string>>
{
private readonly MpdResponse response;
private int position = -1;
private KeyValuePair<string, string> current;
/// <summary>
/// Creates a new MpdResponseEnumerator.
/// </summary>
/// <param name="response">The response to enumerate over.</param>
protected internal MpdResponseEnumerator(MpdResponse response)
{
this.response = response;
}
#region IEnumerator<KeyValuePair<string,string>> Members
/// <summary>
/// Returns the current element of the enumerator.
/// </summary>
KeyValuePair<string, string> IEnumerator<KeyValuePair<string, string>>.Current
{
get { return this.current; }
}
#endregion
#region IDisposable Members
void IDisposable.Dispose()
{
this.position = -1;
}
#endregion
#region IEnumerator Members
/// <summary>
/// Returns the current element of the enumerator.
/// </summary>
object System.Collections.IEnumerator.Current
{
get { return this.current; }
}
/// <summary>
/// Moves the enumerator to the next KeyValuePair in the MPD response.
/// </summary>
/// <returns>If the enumerator has any values left.</returns>
bool System.Collections.IEnumerator.MoveNext()
{
this.position++;
if (this.position < this.response.Count)
{
this.current = this.response[this.position];
return true;
}
else
return false;
}
/// <summary>
/// Sets the enumerator to it's initial state.
/// </summary>
void System.Collections.IEnumerator.Reset()
{
this.position = -1;
}
#endregion
}
}

134
LibMpc/MpdStatistics.cs Normal file
View File

@ -0,0 +1,134 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Libmpc
{
/// <summary>
/// The MpdStatistics class contains statistics of the MPD file database.
/// </summary>
public class MpdStatistics
{
private readonly int artists;
private readonly int albums;
private readonly int songs;
private readonly int uptime;
private readonly int playtime;
private readonly int db_playtime;
private readonly long db_update;
/// <summary>
/// The number of artists in the MPD database.
/// </summary>
public int Artists { get { return this.artists; } }
/// <summary>
/// The number of albums in the MPD database.
/// </summary>
public int Albums { get { return this.albums; } }
/// <summary>
/// The number of songs in the MPD database.
/// </summary>
public int Songs { get { return this.songs; } }
/// <summary>
/// The time the MPD server is running in seconds.
/// </summary>
public int Uptime { get { return this.uptime; } }
/// <summary>
/// The number of seconds the MPD played so far.
/// </summary>
public int Playtime { get { return this.playtime; } }
/// <summary>
/// The total playtime of all songs in the MPD database.
/// </summary>
public int DbPlaytime { get { return this.db_playtime; } }
/// <summary>
/// The timestamp of the last MPD database update.
/// </summary>
public long DbUpdate { get { return this.db_update; } }
/// <summary>
/// Creates a new MpdStatistics object.
/// </summary>
/// <param name="artists">The number of artists in the MPD database.</param>
/// <param name="albums">The number of albums in the MPD database.</param>
/// <param name="songs">The number of songs in the MPD database.</param>
/// <param name="uptime">The time the MPD server is running in seconds.</param>
/// <param name="playtime">The number of seconds the MPD played so far.</param>
/// <param name="db_playtime">The total playtime of all songs in the MPD database.</param>
/// <param name="db_update">The timestamp of the last MPD database update.</param>
public MpdStatistics(
int artists,
int albums,
int songs,
int uptime,
int playtime,
int db_playtime,
long db_update
)
{
this.artists = artists;
this.albums = albums;
this.songs = songs;
this.uptime = uptime;
this.playtime = playtime;
this.db_playtime = db_playtime;
this.db_update = db_update;
}
/// <summary>
/// Returns a string representation of the object mainly for debugging purpuse.
/// </summary>
/// <returns>A string representation of the object.</returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
appendInt(builder, "artists", this.artists);
appendInt(builder, "songs", this.songs);
appendInt(builder, "uptime", this.uptime);
appendInt(builder, "playtime", this.playtime);
appendInt(builder, "db_playtime", this.db_playtime);
appendLong(builder, "db_update", this.db_update);
return builder.ToString();
}
private static void appendInt(StringBuilder builder, string name, int value)
{
if (value < 0)
return;
builder.Append(name);
builder.Append(": ");
builder.Append(value);
builder.AppendLine();
}
private static void appendLong(StringBuilder builder, string name, long value)
{
if (value < 0)
return;
builder.Append(name);
builder.Append(": ");
builder.Append(value);
builder.AppendLine();
}
}
}

271
LibMpc/MpdStatus.cs Normal file
View File

@ -0,0 +1,271 @@
/*
* Copyright 2008 Matthias Sessler
*
* This file is part of LibMpc.net.
*
* LibMpc.net is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* LibMpc.net 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMpc.net. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Libmpc
{
/// <summary>
/// The possible states of the MPD.
/// </summary>
public enum MpdState
{
/// <summary>
/// The state of the MPD could not be translated into this enumeration.
/// </summary>
Unknown,
/// <summary>
/// The MPD is playing a track.
/// </summary>
Play,
/// <summary>
/// The MPD is not playing a track.
/// </summary>
Stop,
/// <summary>
/// The playback of the MPD is currently paused.
/// </summary>
Pause
}
/// <summary>
/// The MpdStatus class contains all values describing the current status of the MPD.
/// </summary>
public class MpdStatus
{
private int volume;
private bool repeat;
private bool random;
private int playlist;
private int playlistLength;
private int xFade;
private MpdState state;
private int song;
private int songId;
private int timeElapsed;
private int timeTotal;
private int bitrate;
private int audioSampleRate;
private int audioBits;
private int audioChannels;
private int updatingDb;
private string error;
/// <summary>
/// The current volume of the output.
/// </summary>
public int Volume { get { return this.volume; } }
/// <summary>
/// If the playlist is repeated after finish.
/// </summary>
public bool Repeat { get { return this.repeat; } }
/// <summary>
/// If the playlist is played in random order.
/// </summary>
public bool Random { get { return this.random; } }
/// <summary>
/// The version number of the playlist.
/// </summary>
public int Playlist { get { return this.playlist; } }
/// <summary>
/// The length of the playlist.
/// </summary>
public int PlaylistLength { get { return this.playlistLength; } }
/// <summary>
/// The number of seconds crossfaded between song changes.
/// </summary>
public int XFade { get { return this.xFade; } }
/// <summary>
/// The state of the MPD.
/// </summary>
public MpdState State { get { return this.state; } }
/// <summary>
/// The index of the currently played song in the playlist.
/// </summary>
public int Song { get { return this.song; } }
/// <summary>
/// The id of the song currently played.
/// </summary>
public int SongId { get { return this.songId; } }
/// <summary>
/// The number of seconds already played of the current song.
/// </summary>
public int TimeElapsed { get { return this.timeElapsed; } }
/// <summary>
/// The length of the current song in seconds.
/// </summary>
public int TimeTotal { get { return this.timeTotal; } }
/// <summary>
/// The bitrate of the current song.
/// </summary>
public int Bitrate { get { return this.bitrate; } }
/// <summary>
/// The audio sample rate of the current song.
/// </summary>
public int AudioSampleRate { get { return this.audioSampleRate; } }
/// <summary>
/// The audio bits of the current song.
/// </summary>
public int AudioBits { get { return this.audioBits; } }
/// <summary>
/// The number of audio channels of the current song.
/// </summary>
public int AudioChannels { get { return this.audioChannels; } }
/// <summary>
/// The number of the update on the MPD database currently running.
/// </summary>
public int UpdatingDb { get { return this.updatingDb; } }
/// <summary>
/// An error message, if there is an error.
/// </summary>
public string Error { get { return this.error; } }
/// <summary>
/// Creates a new MpdStatus object.
/// </summary>
/// <param name="volume">The current volume of the output.</param>
/// <param name="repeat">If the playlist is repeated after finish.</param>
/// <param name="random">If the playlist is played in random order.</param>
/// <param name="playlist">The version number of the playlist.</param>
/// <param name="playlistLength">The length of the playlist.</param>
/// <param name="xFade">The number of seconds crossfaded between song changes.</param>
/// <param name="state">The state of the MPD.</param>
/// <param name="song">The index of the currently played song in the playlist.</param>
/// <param name="songId">The id of the song currently played.</param>
/// <param name="timeElapsed">The number of seconds already played of the current song.</param>
/// <param name="timeTotal">The length of the current song in seconds.</param>
/// <param name="bitrate">The bitrate of the current song.</param>
/// <param name="audioSampleRate">The audio sample rate of the current song.</param>
/// <param name="audioBits">The audio bits of the current song.</param>
/// <param name="audioChannels">The number of audio channels of the current song.</param>
/// <param name="updatingDb">The number of the update on the MPD database currently running.</param>
/// <param name="error">An error message, if there is an error.</param>
public MpdStatus(
int volume,
bool repeat,
bool random,
int playlist,
int playlistLength,
int xFade,
MpdState state,
int song,
int songId,
int timeElapsed,
int timeTotal,
int bitrate,
int audioSampleRate,
int audioBits,
int audioChannels,
int updatingDb,
string error
)
{
this.volume = volume;
this.repeat = repeat;
this.random = random;
this.playlist = playlist;
this.playlistLength = playlistLength;
this.xFade = xFade;
this.state = state;
this.song = song;
this.songId = songId;
this.timeElapsed = timeElapsed;
this.timeTotal = timeTotal;
this.bitrate = bitrate;
this.audioSampleRate = audioSampleRate;
this.audioBits = audioBits;
this.audioChannels = audioChannels;
this.updatingDb = updatingDb;
this.error = error;
}
/// <summary>
/// Returns a string representation of the object maily for debugging purpuses.
/// </summary>
/// <returns>A string representation of the object.</returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
appendInt(builder, "volume", this.volume);
appendBool(builder, "repeat", this.repeat);
appendBool(builder, "random", this.random);
appendInt(builder, "playlist", this.playlist);
appendInt(builder, "playlistlength", this.playlistLength);
appendInt(builder, "xfade", this.xFade);
switch (this.state)
{
case MpdState.Play:
builder.AppendLine("state: play");
break;
case MpdState.Pause:
builder.AppendLine("state: pause");
break;
case MpdState.Stop:
builder.AppendLine("state: stop");
break;
}
appendInt(builder, "song", this.song);
appendInt(builder, "songid", this.songId);
if ((this.timeElapsed >= 0) || (this.timeTotal >= 0))
{
builder.Append("time: ");
builder.Append(this.timeElapsed);
builder.Append(":");
builder.Append(this.timeTotal);
builder.AppendLine();
}
appendInt(builder, "bitrate", this.bitrate);
if ((this.audioSampleRate >= 0) || (this.audioBits >= 0) || (this.audioChannels >= 0))
{
builder.Append("audio: ");
builder.Append(this.audioSampleRate);
builder.Append(":");
builder.Append(this.audioBits);
builder.Append(":");
builder.Append(this.audioChannels);
builder.AppendLine();
}
appendInt(builder, "updating_db", this.updatingDb);
if (this.error != null)
{
builder.Append("error: ");
builder.AppendLine(this.error);
}
return builder.ToString();
}
private static void appendInt(StringBuilder builder, string name, int value)
{
if (value < 0)
return;
builder.Append(name);
builder.Append(": ");
builder.Append(value);
builder.AppendLine();
}
private static void appendBool(StringBuilder builder, string name, bool value)
{
builder.Append(name);
builder.Append(": ");
builder.Append(value ? '1' : '0');
builder.AppendLine();
}
}
}