* Remove McpServerConfig and have McpClientFactory accept IClientTransport instances directly. * Address feedback and use lists when representing stdio arguments. * Use "Name" for transport descriptors and "EndpointName" for MCP clients and servers. * Update code samples. * Fix source file naming
101 lines
No EOL
3.6 KiB
C#
101 lines
No EOL
3.6 KiB
C#
// Licensed to the .NET Foundation under one or more agreements.
|
|
// The .NET Foundation licenses this file to you under the MIT license.
|
|
|
|
// Copied from:
|
|
// https://github.com/dotnet/runtime/blob/d2650b6ae7023a2d9d2c74c56116f1f18472ab04/src/libraries/System.Private.CoreLib/src/System/PasteArguments.cs
|
|
// and changed from using ValueStringBuilder to StringBuilder.
|
|
|
|
using System.Text;
|
|
|
|
namespace System;
|
|
|
|
internal static partial class PasteArguments
|
|
{
|
|
internal static void AppendArgument(StringBuilder stringBuilder, string argument)
|
|
{
|
|
if (stringBuilder.Length != 0)
|
|
{
|
|
stringBuilder.Append(' ');
|
|
}
|
|
|
|
// Parsing rules for non-argv[0] arguments:
|
|
// - Backslash is a normal character except followed by a quote.
|
|
// - 2N backslashes followed by a quote ==> N literal backslashes followed by unescaped quote
|
|
// - 2N+1 backslashes followed by a quote ==> N literal backslashes followed by a literal quote
|
|
// - Parsing stops at first whitespace outside of quoted region.
|
|
// - (post 2008 rule): A closing quote followed by another quote ==> literal quote, and parsing remains in quoting mode.
|
|
if (argument.Length != 0 && ContainsNoWhitespaceOrQuotes(argument))
|
|
{
|
|
// Simple case - no quoting or changes needed.
|
|
stringBuilder.Append(argument);
|
|
}
|
|
else
|
|
{
|
|
stringBuilder.Append(Quote);
|
|
int idx = 0;
|
|
while (idx < argument.Length)
|
|
{
|
|
char c = argument[idx++];
|
|
if (c == Backslash)
|
|
{
|
|
int numBackSlash = 1;
|
|
while (idx < argument.Length && argument[idx] == Backslash)
|
|
{
|
|
idx++;
|
|
numBackSlash++;
|
|
}
|
|
|
|
if (idx == argument.Length)
|
|
{
|
|
// We'll emit an end quote after this so must double the number of backslashes.
|
|
stringBuilder.Append(Backslash, numBackSlash * 2);
|
|
}
|
|
else if (argument[idx] == Quote)
|
|
{
|
|
// Backslashes will be followed by a quote. Must double the number of backslashes.
|
|
stringBuilder.Append(Backslash, numBackSlash * 2 + 1);
|
|
stringBuilder.Append(Quote);
|
|
idx++;
|
|
}
|
|
else
|
|
{
|
|
// Backslash will not be followed by a quote, so emit as normal characters.
|
|
stringBuilder.Append(Backslash, numBackSlash);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
if (c == Quote)
|
|
{
|
|
// Escape the quote so it appears as a literal. This also guarantees that we won't end up generating a closing quote followed
|
|
// by another quote (which parses differently pre-2008 vs. post-2008.)
|
|
stringBuilder.Append(Backslash);
|
|
stringBuilder.Append(Quote);
|
|
continue;
|
|
}
|
|
|
|
stringBuilder.Append(c);
|
|
}
|
|
|
|
stringBuilder.Append(Quote);
|
|
}
|
|
}
|
|
|
|
private static bool ContainsNoWhitespaceOrQuotes(string s)
|
|
{
|
|
for (int i = 0; i < s.Length; i++)
|
|
{
|
|
char c = s[i];
|
|
if (char.IsWhiteSpace(c) || c == Quote)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private const char Quote = '\"';
|
|
private const char Backslash = '\\';
|
|
} |