Files
Aaru/Aaru.Core/Options.cs

204 lines
7.3 KiB
C#
Raw Normal View History

// /***************************************************************************
2020-02-27 12:31:25 +00:00
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
// 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/>.
//
// ----------------------------------------------------------------------------
2022-02-18 10:02:53 +00:00
// Copyright © 2011-2022 Natalia Portillo
// ****************************************************************************/
using System.Collections.Generic;
using System.Globalization;
using System.Text;
2020-02-27 00:33:26 +00:00
namespace Aaru.Core
{
2021-08-17 21:23:10 +01:00
/// <summary>Option parsing</summary>
public static class Options
{
2021-08-17 21:23:10 +01:00
/// <summary>Parses a string with options</summary>
2021-08-17 13:56:05 +01:00
/// <param name="options">Options string</param>
/// <returns>Options name-value dictionary</returns>
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;
2020-02-29 18:03:35 +00:00
var sb = new StringBuilder();
2020-02-29 18:03:35 +00:00
if(options == null)
return parsed;
for(int index = 0; index < options.Length; index++)
{
char c = options[index];
switch(c)
{
case '\\' when !escaped:
escaped = true;
2020-02-29 18:03:35 +00:00
break;
case '"' when !escaped:
quoted = !quoted;
2020-02-29 18:03:35 +00:00
break;
case '=' when quoted:
sb.Append(c);
2020-02-29 18:03:35 +00:00
break;
case '=':
name = sb.ToString().ToLower(CultureInfo.CurrentCulture);
sb = new StringBuilder();
inValue = true;
2020-02-29 18:03:35 +00:00
break;
case ',' when quoted:
sb.Append(c);
2020-02-29 18:03:35 +00:00
break;
case ',' when inValue:
value = sb.ToString();
sb = new StringBuilder();
inValue = false;
2020-02-29 18:03:35 +00:00
if(string.IsNullOrEmpty(name) ||
string.IsNullOrEmpty(value))
continue;
2020-02-29 18:03:35 +00:00
if(parsed.ContainsKey(name))
parsed.Remove(name);
parsed.Add(name, value);
2020-02-29 18:03:35 +00:00
break;
default:
if(escaped)
switch(c)
{
case 'a':
sb.Append('\a');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 'b':
sb.Append('\b');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 'f':
sb.Append('\f');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 'n':
sb.Append('\n');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 'r':
sb.Append('\r');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 't':
sb.Append('\t');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 'v':
sb.Append('\v');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case '\\':
sb.Append('\\');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case '\'':
sb.Append('\'');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case '"':
sb.Append('"');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case '0':
sb.Append('\0');
escaped = false;
2020-02-29 18:03:35 +00:00
break;
case 'u':
string unicode = options.Substring(index + 1, 4);
sb.Append((char)int.Parse(unicode, NumberStyles.HexNumber));
escaped = false;
index += 4;
2020-02-29 18:03:35 +00:00
break;
case 'U':
string longUnicode = options.Substring(index + 1, 8);
sb.Append((char)int.Parse(longUnicode, NumberStyles.HexNumber));
escaped = false;
index += 8;
2020-02-29 18:03:35 +00:00
break;
default:
sb.Append(c);
escaped = false;
2020-02-29 18:03:35 +00:00
break;
}
2020-02-29 18:03:35 +00:00
else
sb.Append(c);
break;
}
}
2020-02-29 18:03:35 +00:00
if(!inValue)
return parsed;
value = sb.ToString();
2020-02-29 18:03:35 +00:00
if(string.IsNullOrEmpty(name) ||
string.IsNullOrEmpty(value))
return parsed;
2020-02-29 18:03:35 +00:00
if(parsed.ContainsKey(name))
parsed.Remove(name);
parsed.Add(name, value);
return parsed;
}
}
}