feat: initial project commit
All checks were successful
default / default (8.0) (push) Successful in 39s
All checks were successful
default / default (8.0) (push) Successful in 39s
This commit is contained in:
commit
833bc2bd9c
52 changed files with 3783 additions and 0 deletions
137
src/Process/Builders/ArgumentsBuilder.cs
Normal file
137
src/Process/Builders/ArgumentsBuilder.cs
Normal file
|
@ -0,0 +1,137 @@
|
|||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace Geekeey.Extensions.Process;
|
||||
|
||||
/// <summary>
|
||||
/// Builder that helps format command-line arguments into a string.
|
||||
/// </summary>
|
||||
public sealed partial class ArgumentsBuilder
|
||||
{
|
||||
private static readonly IFormatProvider DefaultFormatProvider = CultureInfo.InvariantCulture;
|
||||
|
||||
private readonly StringBuilder _buffer = new();
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified value to the list of arguments.
|
||||
/// </summary>
|
||||
public ArgumentsBuilder Add(string value, bool escape = true)
|
||||
{
|
||||
if (_buffer.Length > 0)
|
||||
_buffer.Append(' ');
|
||||
|
||||
_buffer.Append(escape ? Escape(value) : value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified values to the list of arguments.
|
||||
/// </summary>
|
||||
public ArgumentsBuilder Add(IEnumerable<string> values, bool escape = true)
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
Add(value, escape);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified value to the list of arguments.
|
||||
/// </summary>
|
||||
public ArgumentsBuilder Add(IFormattable value, IFormatProvider formatProvider, bool escape = true)
|
||||
=> Add(value.ToString(null, formatProvider), escape);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified value to the list of arguments.
|
||||
/// The value is converted to string using invariant culture.
|
||||
/// </summary>
|
||||
public ArgumentsBuilder Add(IFormattable value, bool escape = true)
|
||||
=> Add(value, DefaultFormatProvider, escape);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified values to the list of arguments.
|
||||
/// </summary>
|
||||
public ArgumentsBuilder Add(IEnumerable<IFormattable> values, IFormatProvider formatProvider, bool escape = true)
|
||||
{
|
||||
foreach (var value in values)
|
||||
{
|
||||
Add(value, formatProvider, escape);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified values to the list of arguments.
|
||||
/// The values are converted to string using invariant culture.
|
||||
/// </summary>
|
||||
public ArgumentsBuilder Add(IEnumerable<IFormattable> values, bool escape = true)
|
||||
=> Add(values, DefaultFormatProvider, escape);
|
||||
|
||||
/// <summary>
|
||||
/// Builds the resulting arguments string.
|
||||
/// </summary>
|
||||
public string Build() => _buffer.ToString();
|
||||
}
|
||||
|
||||
public partial class ArgumentsBuilder
|
||||
{
|
||||
private static string Escape(string argument)
|
||||
{
|
||||
// Short circuit if the argument is clean and doesn't need escaping
|
||||
if (argument.Length > 0 && argument.All(c => !char.IsWhiteSpace(c) && c is not '"'))
|
||||
return argument;
|
||||
|
||||
var buffer = new StringBuilder();
|
||||
|
||||
buffer.Append('"');
|
||||
|
||||
for (var i = 0; i < argument.Length;)
|
||||
{
|
||||
var c = argument[i++];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\\':
|
||||
{
|
||||
var backslashCount = 1;
|
||||
while (i < argument.Length && argument[i] == '\\')
|
||||
{
|
||||
backslashCount++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == argument.Length)
|
||||
{
|
||||
buffer.Append('\\', backslashCount * 2);
|
||||
}
|
||||
else if (argument[i] == '"')
|
||||
{
|
||||
buffer.Append('\\', backslashCount * 2 + 1).Append('"');
|
||||
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.Append('\\', backslashCount);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case '"':
|
||||
buffer.Append('\\').Append('"');
|
||||
break;
|
||||
default:
|
||||
buffer.Append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer.Append('"');
|
||||
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue