Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions Samples/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,23 @@
#pragma warning restore CA2000
}

case BuiltInType.ByteString:
{
byte[] bytes = value as byte[];
string hex = FormatByteString(bytes);

#pragma warning disable CA2000 // Justification: ownership is transferred to WinForms/control owner or existing sample lifetime is preserved.
string edited = new StringValueEditDlg().ShowDialog(hex);
#pragma warning restore CA2000

if (edited == null)
{
return null;
}

return ParseByteString(edited);
}

case BuiltInType.LocalizedText:
{
LocalizedText ltext = (LocalizedText)value;
Expand All @@ -569,6 +586,110 @@
#pragma warning restore CA2000
}

/// <summary>
/// Formats a byte array as a whitespace separated hex string for editing.
/// </summary>
private static string FormatByteString(byte[] bytes)
{
if (bytes == null)
{
return String.Empty;
}

var builder = new StringBuilder(bytes.Length * 3);

for (int ii = 0; ii < bytes.Length; ii++)
{
if (ii > 0)
{
builder.Append(' ');
}

builder.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0:X2}", bytes[ii]);
}

return builder.ToString();
}

/// <summary>
/// Parses an edited ByteString. Accepts hex (with optional whitespace, commas
/// or 0x prefixes) or, as a fallback, a base64 encoded string.
/// </summary>
private static byte[] ParseByteString(string text)
{
if (String.IsNullOrWhiteSpace(text))
{
return Array.Empty<byte>();
}

// Strip common separators and prefixes so both "0x0A, 0x0B" and "0A0B" work.
string cleaned = text

Check warning on line 626 in Samples/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'string.Replace(string, string?)' has a method overload that takes a 'StringComparison' parameter. Replace this call in 'Opc.Ua.Client.Controls.GuiUtils.ParseByteString(string)' with a call to 'string.Replace(string, string?, System.StringComparison)' for clarity of intent. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1307)

Check warning on line 626 in Samples/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'string.Replace(string, string?)' has a method overload that takes a 'StringComparison' parameter. Replace this call in 'Opc.Ua.Client.Controls.GuiUtils.ParseByteString(string)' with a call to 'string.Replace(string, string?, System.StringComparison)' for clarity of intent. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1307)

Check warning on line 626 in Samples/ClientControls.Net4/Configuration/Common (OLD)/GuiUtils.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

'string.Replace(string, string?)' has a method overload that takes a 'StringComparison' parameter. Replace this call in 'Opc.Ua.Client.Controls.GuiUtils.ParseByteString(string)' with a call to 'string.Replace(string, string?, System.StringComparison)' for clarity of intent. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1307)
.Replace("0x", String.Empty)
.Replace("0X", String.Empty)
.Replace(",", String.Empty)
.Replace("-", String.Empty);

var hexOnly = new StringBuilder(cleaned.Length);

foreach (char ch in cleaned)
{
if (Char.IsWhiteSpace(ch))
{
continue;
}

hexOnly.Append(ch);
}

string hex = hexOnly.ToString();

if (hex.Length > 0 &&
hex.Length % 2 == 0 &&
IsHexString(hex))
{
var bytes = new byte[hex.Length / 2];

for (int ii = 0; ii < bytes.Length; ii++)
{
bytes[ii] = Convert.ToByte(hex.Substring(ii * 2, 2), 16);
}

return bytes;
}

// Fall back to base64 if the text is not valid hex.
try
{
return Convert.FromBase64String(text.Trim());
}
catch (FormatException)
{
throw new FormatException(
"The value could not be interpreted as a ByteString. Enter the bytes as hex (e.g. '0A 1B 2C') or as a base64 string.");
}
}

/// <summary>
/// Returns true if every character in the string is a hexadecimal digit.
/// </summary>
private static bool IsHexString(string text)
{
foreach (char ch in text)
{
bool isHexDigit =
(ch >= '0' && ch <= '9') ||
(ch >= 'a' && ch <= 'f') ||
(ch >= 'A' && ch <= 'F');

if (!isHexDigit)
{
return false;
}
}

return true;
}

/// <summary>
/// Returns to display icon for the target of a reference.
/// </summary>
Expand Down
Loading