2018-01-17 19:10:46 +00:00
|
|
|
|
// /***************************************************************************
|
2020-02-27 12:31:25 +00:00
|
|
|
|
// Aaru Data Preservation Suite
|
2018-01-17 19:10:46 +00:00
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
//
|
|
|
|
|
|
// 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/>.
|
|
|
|
|
|
//
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2024-12-19 10:45:18 +00:00
|
|
|
|
// Copyright © 2011-2025 Natalia Portillo
|
2018-01-17 19:10:46 +00:00
|
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
2022-11-15 15:58:43 +00:00
|
|
|
|
namespace Aaru.Core;
|
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
/// <summary>Option parsing</summary>
|
|
|
|
|
|
public static class Options
|
2018-01-17 19:10:46 +00:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
/// <summary>Parses a string with options</summary>
|
|
|
|
|
|
/// <param name="options">Options string</param>
|
|
|
|
|
|
/// <returns>Options name-value dictionary</returns>
|
|
|
|
|
|
public static Dictionary<string, string> Parse(string options)
|
2018-01-17 19:10:46 +00:00
|
|
|
|
{
|
2022-11-15 15:58:43 +00:00
|
|
|
|
Dictionary<string, string> parsed = new();
|
2023-10-03 22:57:50 +01:00
|
|
|
|
var escaped = false;
|
|
|
|
|
|
var quoted = false;
|
|
|
|
|
|
var inValue = false;
|
2022-11-15 15:58:43 +00:00
|
|
|
|
string name = null;
|
|
|
|
|
|
string value;
|
|
|
|
|
|
var sb = new StringBuilder();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
|
if(options == null) return parsed;
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2023-10-03 22:57:50 +01:00
|
|
|
|
for(var index = 0; index < options.Length; index++)
|
2022-03-06 13:29:38 +00:00
|
|
|
|
{
|
|
|
|
|
|
char c = options[index];
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
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;
|
|
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
|
if(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) continue;
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
|
if(parsed.ContainsKey(name)) parsed.Remove(name);
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
parsed.Add(name, value);
|
|
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
if(escaped)
|
2023-10-03 22:57:50 +01:00
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2023-10-03 22:57:50 +01:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
else
|
2018-01-17 19:10:46 +00:00
|
|
|
|
sb.Append(c);
|
2020-02-29 18:03:35 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
break;
|
2018-01-17 19:10:46 +00:00
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
}
|
2018-01-17 19:10:46 +00:00
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
|
if(!inValue) return parsed;
|
2018-01-17 19:10:46 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
value = sb.ToString();
|
2018-01-17 19:10:46 +00:00
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
|
if(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) return parsed;
|
2018-01-17 19:10:46 +00:00
|
|
|
|
|
2024-05-01 04:05:22 +01:00
|
|
|
|
if(parsed.ContainsKey(name)) parsed.Remove(name);
|
2018-01-17 19:10:46 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
parsed.Add(name, value);
|
2018-01-17 19:10:46 +00:00
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
|
return parsed;
|
2018-01-17 19:10:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|