// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tools.DotNETCommon { public static class StringUtils { /// /// Indents a string by a given indent /// /// The text to indent /// The indent to add to each line /// The indented string public static string Indent(string Text, string Indent) { string Result = ""; if(Text.Length > 0) { Result = Indent + Text.Replace("\n", "\n" + Indent); } return Result; } /// /// Extension method to allow formatting a string to a stringbuilder and appending a newline /// /// The string builder /// Format string, as used for StringBuilder.AppendFormat /// Arguments for the format string public static void AppendLine(this StringBuilder Builder, string Format, params object[] Args) { Builder.AppendFormat(Format, Args); Builder.AppendLine(); } /// /// Formats a list of strings in the style "1, 2, 3 and 4" /// /// List of strings to format /// Formatted list of strings public static string FormatList(string[] Arguments) { StringBuilder Result = new StringBuilder(); if(Arguments.Length > 0) { Result.Append(Arguments[0]); for(int Idx = 1; Idx < Arguments.Length; Idx++) { if(Idx == Arguments.Length - 1) { Result.Append(" and "); } else { Result.Append(", "); } Result.Append(Arguments[Idx]); } } return Result.ToString(); } /// /// Formats a list of strings in the style "1, 2, 3 and 4" /// /// List of strings to format /// Formatted list of strings public static string FormatList(IEnumerable Arguments) { return FormatList(Arguments.ToArray()); } /// /// Parses a hexadecimal digit /// /// Character to parse /// Value of this digit public static bool TryParseHexDigit(char Character, out int Value) { if(Character >= '0' && Character <= '9') { Value = Character - '0'; return true; } else if(Character >= 'a' && Character <= 'f') { Value = 10 + (Character - 'a'); return true; } else if(Character >= 'A' && Character <= 'F') { Value = 10 + (Character - 'A'); return true; } else { Value = 0; return false; } } /// /// Parses a hexadecimal string into an array of bytes /// /// Text to parse /// public static bool TryParseHexString(string Text, out byte[] OutBytes) { byte[] Bytes = new byte[Text.Length / 2]; for(int Idx = 0; Idx < Text.Length; Idx++) { int A, B; if(!TryParseHexDigit(Text[Idx], out A) || !TryParseHexDigit(Text[Idx + 1], out B)) { OutBytes = null; return false; } Bytes[Idx / 2] = (byte)((A << 4) | B); } OutBytes = Bytes; return true; } /// /// Formats an array of bytes as a hexadecimal string /// /// An array of bytes /// String representation of the array public static string FormatHexString(byte[] Bytes) { const string HexDigits = "0123456789abcdef"; char[] Characters = new char[Bytes.Length * 2]; for(int Idx = 0; Idx < Bytes.Length; Idx++) { Characters[Idx * 2 + 0] = HexDigits[Bytes[Idx] >> 4]; Characters[Idx * 2 + 1] = HexDigits[Bytes[Idx] & 15]; } return new string(Characters); } } }