From ec2ab8f619ba72d50d656397a5b1321c93365ecc Mon Sep 17 00:00:00 2001 From: Me on Windows Date: Sat, 19 Jun 2021 08:53:27 +0000 Subject: [PATCH] Implement HTTP ini download, Ini parser. WIP. --- QuickPlay/Configuration.cs | 32 ++++++++++++++---- QuickPlay/IniParser.cs | 67 ++++++++++++++++++++++++++++++++++++++ QuickPlay/QuickPlay.csproj | 1 + QuickPlay/SongRecycler.cs | 1 - 4 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 QuickPlay/IniParser.cs diff --git a/QuickPlay/Configuration.cs b/QuickPlay/Configuration.cs index bc81adf..0e3c913 100644 --- a/QuickPlay/Configuration.cs +++ b/QuickPlay/Configuration.cs @@ -1,5 +1,8 @@ using System; +using System.Net.Http; using System.IO; +using System.Threading.Tasks; +using System.Collections.Generic; namespace QuickPlay { @@ -73,7 +76,7 @@ namespace QuickPlay public PlayerConfiguration GetPlayerConfig() { // TODO: decide sensibly - var cfgProvider = new CurlConfigurationProvider(playerConfigUrl); + var cfgProvider = new HttpConfigurationProvider(playerConfigUrl); return cfgProvider.GetConfiguration(); } @@ -97,9 +100,23 @@ namespace QuickPlay /// public class PlayerConfiguration { + List songs; + public static PlayerConfiguration FromFile(StreamReader reader) { - return null; // FIXME: Implement + var parser = new IniParser(reader); + var ini = parser.Parse(); + foreach (string key in ini.Keys) + { + // Two options: either general options, or song descriptions + if (key == "general") + { + + } else + { + // Song + } + } } public IPlayer GetPlayer() @@ -113,16 +130,19 @@ namespace QuickPlay PlayerConfiguration GetConfiguration(); } - sealed class CurlConfigurationProvider : IPlayerConfigurationProvider + sealed class HttpConfigurationProvider : IPlayerConfigurationProvider { readonly string configUrl; - public CurlConfigurationProvider(string url) + public HttpConfigurationProvider(string url) { configUrl = url; } - public PlayerConfiguration GetConfiguration() + public async Task GetConfiguration() { - throw new NotImplementedException(); + var client = new HttpClient() ; + var resp = await client.GetStreamAsync(configUrl); + var sr = new StreamReader(resp); + return PlayerConfiguration.FromFile(sr); } } diff --git a/QuickPlay/IniParser.cs b/QuickPlay/IniParser.cs new file mode 100644 index 0000000..4a20be6 --- /dev/null +++ b/QuickPlay/IniParser.cs @@ -0,0 +1,67 @@ +using Android.App; +using Android.Content; +using Android.OS; +using Android.Runtime; +using Android.Views; +using Android.Widget; +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; + +namespace QuickPlay +{ + /// + /// This class implements (yet another) INI-style parser. + /// + /// INI specification: everything is in sections, comments using both '#' + /// or ';', space around '=' is trimmed, last value assigned overrides + /// previous assignments, sections may not repeat. Section names may only + /// contain reasonable characters (at least [a-zA-Z0-9. ], not really + /// enforced). Everything is case-sensitive. + /// + /// Both CRLF and just LF should be supported as line ends. + /// + class IniParser + { + StreamReader reader; + string currentSection = null; + public IniParser(StreamReader sr) + { + reader = sr; + } + + // The return type is dictionary by sections, which in turn holds the section key-value dictionary + // Maybe the code is a bit more Pythonic than it should be... + public Dictionary> Parse() + { + Dictionary> result = new Dictionary>(); + while (!reader.EndOfStream) + { + var line = reader.ReadLine(); + line = StripComments(line).Trim(); + if (line.Length == 0) continue; + if (line.StartsWith('[')) + { + // This does not really do the right thing, but for QuickPlay's use it is good enough. + currentSection = line.Split(new char[] { '[', ']' })[1]; + if (result.ContainsKey(currentSection)) throw new InvalidOperationException("Multiple sections with same name"); + result[currentSection] = new Dictionary(); + } + else + { + // Other lines may only be assignments + int equalSignPosition = line.IndexOf('='); + string key = line.Substring(0, equalSignPosition).Trim(); + string value = line.Substring(equalSignPosition + 1).Trim(); + result[currentSection][key] = value; + } + } + return result; + } + string StripComments(string line) + { + return line.Split(new char[] { ';', '#' })[0]; + } + } +} \ No newline at end of file diff --git a/QuickPlay/QuickPlay.csproj b/QuickPlay/QuickPlay.csproj index cca639b..2d3d180 100644 --- a/QuickPlay/QuickPlay.csproj +++ b/QuickPlay/QuickPlay.csproj @@ -43,6 +43,7 @@ false false false + Xamarin.Android.Net.AndroidClientHandler True diff --git a/QuickPlay/SongRecycler.cs b/QuickPlay/SongRecycler.cs index ba21b74..48b3a87 100644 --- a/QuickPlay/SongRecycler.cs +++ b/QuickPlay/SongRecycler.cs @@ -7,7 +7,6 @@ using Android.Views; using Android.Widget; using System; using System.Collections.Generic; -using System.Linq; using System.Text; namespace QuickPlay