mirror of
https://github.com/ZetaKebab/MpcNET.git
synced 2025-01-14 22:18:43 +00:00
MpdResponse refactored (partial)
This commit is contained in:
parent
ec24b3f01a
commit
9212021be6
13
LibMpc/Constants.cs
Normal file
13
LibMpc/Constants.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LibMpc
|
||||||
|
{
|
||||||
|
public class Constants
|
||||||
|
{
|
||||||
|
public static readonly string Ok = "OK";
|
||||||
|
public static readonly string Ack = "ACK";
|
||||||
|
|
||||||
|
public static readonly string FirstLinePrefix = "OK MPD ";
|
||||||
|
}
|
||||||
|
}
|
24
LibMpc/Message/MpdMessage.cs
Normal file
24
LibMpc/Message/MpdMessage.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
namespace LibMpc
|
||||||
|
{
|
||||||
|
public interface IMpdMessage
|
||||||
|
{
|
||||||
|
IMpdRequest Request { get; }
|
||||||
|
IMpdResponse Response { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MpdMessage : IMpdMessage
|
||||||
|
{
|
||||||
|
public MpdMessage(IMpcCommand command)
|
||||||
|
{
|
||||||
|
Request = new MpdRequest(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddResponse(IMpdResponse response)
|
||||||
|
{
|
||||||
|
Response = response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMpdRequest Request { get; }
|
||||||
|
public IMpdResponse Response { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
17
LibMpc/Message/MpdRequest.cs
Normal file
17
LibMpc/Message/MpdRequest.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace LibMpc
|
||||||
|
{
|
||||||
|
public interface IMpdRequest
|
||||||
|
{
|
||||||
|
IMpcCommand Command { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MpdRequest : IMpdRequest
|
||||||
|
{
|
||||||
|
public MpdRequest(IMpcCommand command)
|
||||||
|
{
|
||||||
|
Command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMpcCommand Command { get; }
|
||||||
|
}
|
||||||
|
}
|
73
LibMpc/Message/MpdResponse.cs
Normal file
73
LibMpc/Message/MpdResponse.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace LibMpc
|
||||||
|
{
|
||||||
|
public interface IMpdResponse
|
||||||
|
{
|
||||||
|
IEnumerable<string> Response { get; }
|
||||||
|
IReadOnlyDictionary<string, string> Values { get; }
|
||||||
|
IMpdResponseState State { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MpdResponse : IMpdResponse
|
||||||
|
{
|
||||||
|
private static readonly Regex LinePattern = new Regex("^(?<key>[A-Za-z]*):[ ]{0,1}(?<value>.*)$");
|
||||||
|
|
||||||
|
public MpdResponse(ICollection<string> response)
|
||||||
|
{
|
||||||
|
response.CheckNotNull();
|
||||||
|
|
||||||
|
var endLine = response.Take(response.Count - 2).Single();
|
||||||
|
|
||||||
|
Response = response.Take(response.Count - 2).ToList();
|
||||||
|
State = new MpdResponseState(endLine);
|
||||||
|
Values = GetValuesFromResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMpdResponseState State { get; }
|
||||||
|
|
||||||
|
public IEnumerable<string> Response { get; }
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<string, string> Values { get; }
|
||||||
|
|
||||||
|
|
||||||
|
private IReadOnlyDictionary<string, string> GetValuesFromResponse()
|
||||||
|
{
|
||||||
|
var result = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
foreach (var line in Response)
|
||||||
|
{
|
||||||
|
var match = LinePattern.Match(line);
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
var mpdKey = match.Result("${key}");
|
||||||
|
if (!string.IsNullOrEmpty(mpdKey))
|
||||||
|
{
|
||||||
|
var mpdValue = match.Result("${value}");
|
||||||
|
if (string.IsNullOrEmpty(mpdValue))
|
||||||
|
{
|
||||||
|
result.Add(mpdKey, mpdValue);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CheckNotNullExtension
|
||||||
|
{
|
||||||
|
public static void CheckNotNull(this object toBeChecked)
|
||||||
|
{
|
||||||
|
if (toBeChecked == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(toBeChecked));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
LibMpc/Message/MpdResponseState.cs
Normal file
63
LibMpc/Message/MpdResponseState.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace LibMpc
|
||||||
|
{
|
||||||
|
public interface IMpdResponseState
|
||||||
|
{
|
||||||
|
string Status { get; }
|
||||||
|
string ErrorMessage { get; }
|
||||||
|
string MpdError { get; }
|
||||||
|
bool IsError { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MpdResponseState : IMpdResponseState
|
||||||
|
{
|
||||||
|
private static readonly Regex ErrorPattern = new Regex("^ACK \\[(?<code>[0-9]*)@(?<nr>[0-9]*)] \\{(?<command>[a-z]*)} (?<message>.*)$");
|
||||||
|
|
||||||
|
private readonly string _endLine;
|
||||||
|
|
||||||
|
public MpdResponseState(string endLine)
|
||||||
|
{
|
||||||
|
_endLine = endLine;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_endLine))
|
||||||
|
{
|
||||||
|
if (_endLine.Equals(Constants.Ok))
|
||||||
|
{
|
||||||
|
Status = _endLine;
|
||||||
|
IsError = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ParseErrorResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsError { get; private set; } = true;
|
||||||
|
public string Status { get; private set; } = "UNKNOWN";
|
||||||
|
public string ErrorMessage { get; private set; } = string.Empty;
|
||||||
|
public string MpdError { get; private set; } = string.Empty;
|
||||||
|
|
||||||
|
private void ParseErrorResponse()
|
||||||
|
{
|
||||||
|
Status = "ERROR";
|
||||||
|
MpdError = _endLine;
|
||||||
|
|
||||||
|
var match = ErrorPattern.Match(_endLine);
|
||||||
|
|
||||||
|
if (match.Groups.Count != 5)
|
||||||
|
{
|
||||||
|
ErrorMessage = "Unexpected response from server.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var errorCode = match.Result("${code}");
|
||||||
|
var commandListItem = match.Result("${nr}");
|
||||||
|
var commandFailed = match.Result("${command}");
|
||||||
|
var errorMessage = match.Result("${message}");
|
||||||
|
ErrorMessage = $"ErrorCode: { errorCode }, CommandListItem: { commandListItem }, CommandFailed: { commandFailed }, ErrorMessage: { errorMessage }";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace LibMpc
|
namespace LibMpc
|
||||||
@ -17,12 +15,6 @@ namespace LibMpc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class MpcConnection
|
public class MpcConnection
|
||||||
{
|
{
|
||||||
private static readonly string FIRST_LINE_PREFIX = "OK MPD ";
|
|
||||||
|
|
||||||
private static readonly string OK = "OK";
|
|
||||||
private static readonly string ACK = "ACK";
|
|
||||||
|
|
||||||
|
|
||||||
private readonly IPEndPoint _server;
|
private readonly IPEndPoint _server;
|
||||||
|
|
||||||
private TcpClient _tcpClient;
|
private TcpClient _tcpClient;
|
||||||
@ -61,12 +53,12 @@ namespace LibMpc
|
|||||||
_writer = new StreamWriter(_networkStream, Encoding.UTF8) { NewLine = "\n" };
|
_writer = new StreamWriter(_networkStream, Encoding.UTF8) { NewLine = "\n" };
|
||||||
|
|
||||||
var firstLine = _reader.ReadLine();
|
var firstLine = _reader.ReadLine();
|
||||||
if (!firstLine.StartsWith(FIRST_LINE_PREFIX))
|
if (!firstLine.StartsWith(Constants.FirstLinePrefix))
|
||||||
{
|
{
|
||||||
await DisconnectAsync();
|
await DisconnectAsync();
|
||||||
throw new InvalidDataException("Response of mpd does not start with \"" + FIRST_LINE_PREFIX + "\"." );
|
throw new InvalidDataException("Response of mpd does not start with \"" + Constants.FirstLinePrefix + "\"." );
|
||||||
}
|
}
|
||||||
_version = firstLine.Substring(FIRST_LINE_PREFIX.Length);
|
_version = firstLine.Substring(Constants.FirstLinePrefix.Length);
|
||||||
|
|
||||||
await _writer.WriteLineAsync();
|
await _writer.WriteLineAsync();
|
||||||
_writer.Flush();
|
_writer.Flush();
|
||||||
@ -194,23 +186,16 @@ namespace LibMpc
|
|||||||
private async Task<MpdResponse> ReadResponseAsync()
|
private async Task<MpdResponse> ReadResponseAsync()
|
||||||
{
|
{
|
||||||
var response = new List<string>();
|
var response = new List<string>();
|
||||||
var currentLine = _reader.ReadLine();
|
|
||||||
|
|
||||||
// Read response untli reach end token (OK or ACK)
|
// Read response untli reach end token (OK or ACK)
|
||||||
while (!(currentLine.Equals(OK) || currentLine.StartsWith(ACK)))
|
string responseLine;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
response.Add(currentLine);
|
responseLine = await _reader.ReadLineAsync();
|
||||||
currentLine = await _reader.ReadLineAsync();
|
response.Add(responseLine);
|
||||||
}
|
} while (!(responseLine.Equals(Constants.Ok) || responseLine.StartsWith(Constants.Ack) || string.IsNullOrEmpty(responseLine)));
|
||||||
|
|
||||||
if (currentLine.Equals(OK))
|
return new MpdResponse(response);
|
||||||
{
|
|
||||||
return new MpdResponse(new ReadOnlyCollection<string>(response));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return AcknowledgeResponse.Parse(currentLine, response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearConnectionFields()
|
private void ClearConnectionFields()
|
||||||
@ -222,24 +207,4 @@ namespace LibMpc
|
|||||||
_version = string.Empty;
|
_version = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AcknowledgeResponse
|
|
||||||
{
|
|
||||||
private static readonly Regex AcknowledgePattern = new Regex("^ACK \\[(?<code>[0-9]*)@(?<nr>[0-9]*)] \\{(?<command>[a-z]*)} (?<message>.*)$");
|
|
||||||
|
|
||||||
public static MpdResponse Parse(string acknowledgeResponse, IList<string> payload)
|
|
||||||
{
|
|
||||||
var match = AcknowledgePattern.Match(acknowledgeResponse);
|
|
||||||
|
|
||||||
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>(payload));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,308 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user