Files
Aaru/DiscImageChef.Core/Options.cs

170 lines
6.9 KiB
C#
Raw Normal View History

// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Partitions.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Core algorithms.
//
// --[ Description ] ----------------------------------------------------------
//
// Logic to handle name=value option pairs.
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
2020-01-03 17:51:30 +00:00
// Copyright © 2011-2020 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.Globalization;
using System.Text;
namespace DiscImageChef.Core
{
public static class Options
{
public static Dictionary<string, string> Parse(string options)
{
Dictionary<string, string> parsed = new Dictionary<string, string>();
bool escaped = false;
bool quoted = false;
bool inValue = false;
string name = null;
2018-06-20 22:22:21 +01:00
string value;
2018-06-22 08:08:38 +01:00
StringBuilder sb = new StringBuilder();
if(options == null) return parsed;
for(int index = 0; index < options.Length; index++)
{
char c = options[index];
switch(c)
{
case '\\' when !escaped:
escaped = true;
break;
case '"' when !escaped:
quoted = !quoted;
break;
case '=' when quoted:
sb.Append(c);
break;
case '=':
name = sb.ToString().ToLower(CultureInfo.CurrentCulture);
sb = new StringBuilder();
inValue = true;
break;
case ',' when quoted:
sb.Append(c);
break;
case ',' when inValue:
value = sb.ToString();
sb = new StringBuilder();
inValue = false;
if(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) continue;
if(parsed.ContainsKey(name)) parsed.Remove(name);
parsed.Add(name, value);
break;
default:
if(escaped)
switch(c)
{
case 'a':
sb.Append('\a');
escaped = false;
break;
case 'b':
sb.Append('\b');
escaped = false;
break;
case 'f':
sb.Append('\f');
escaped = false;
break;
case 'n':
sb.Append('\n');
escaped = false;
break;
case 'r':
sb.Append('\r');
escaped = false;
break;
case 't':
sb.Append('\t');
escaped = false;
break;
case 'v':
sb.Append('\v');
escaped = false;
break;
case '\\':
sb.Append('\\');
escaped = false;
break;
case '\'':
sb.Append('\'');
escaped = false;
break;
case '"':
sb.Append('"');
escaped = false;
break;
case '0':
sb.Append('\0');
escaped = false;
break;
case 'u':
string unicode = options.Substring(index + 1, 4);
sb.Append((char)int.Parse(unicode, NumberStyles.HexNumber));
escaped = false;
index += 4;
break;
case 'U':
string longUnicode = options.Substring(index + 1, 8);
sb.Append((char)int.Parse(longUnicode, NumberStyles.HexNumber));
escaped = false;
index += 8;
break;
default:
sb.Append(c);
escaped = false;
break;
}
else sb.Append(c);
break;
}
}
if(!inValue) return parsed;
value = sb.ToString();
if(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) return parsed;
if(parsed.ContainsKey(name)) parsed.Remove(name);
parsed.Add(name, value);
return parsed;
}
}
}