|
|
|
@ -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
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 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.
|
|
|
|
|
/// </summary>
|
|
|
|
|
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<string, Dictionary<string, string>> Parse()
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, Dictionary<string, string>> result = new Dictionary<string, Dictionary<string, string>>();
|
|
|
|
|
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<string, string>();
|
|
|
|
|
}
|
|
|
|
|
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];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|