| 1 | using System;
|
|---|
| 2 | using System.Collections.Generic;
|
|---|
| 3 | using System.Text;
|
|---|
| 4 |
|
|---|
| 5 | namespace Common
|
|---|
| 6 | {
|
|---|
| 7 | public static class TextProcessing
|
|---|
| 8 | {
|
|---|
| 9 | private static readonly string[] SizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
|
|---|
| 10 |
|
|---|
| 11 | public static string SizeSuffix(long value, int digitsCount = 3)
|
|---|
| 12 | {
|
|---|
| 13 | if (value < 0)
|
|---|
| 14 | {
|
|---|
| 15 | throw new ArgumentException(@"Bytes should not be negative", nameof(value));
|
|---|
| 16 | }
|
|---|
| 17 | var magnitude = (int)Math.Max(0, Math.Log(value, 1024));
|
|---|
| 18 | var adjustedSize = value / Math.Pow(1024, magnitude);
|
|---|
| 19 | string result;
|
|---|
| 20 | if (adjustedSize != 0)
|
|---|
| 21 | {
|
|---|
| 22 | int digits = (int)Math.Log10(Math.Truncate(adjustedSize)) + 1;
|
|---|
| 23 | result = adjustedSize.ToString("N" + Math.Max(digitsCount - digits, 0));
|
|---|
| 24 | }
|
|---|
| 25 | else result = "0";
|
|---|
| 26 |
|
|---|
| 27 | return result + " " + SizeSuffixes[magnitude];
|
|---|
| 28 | }
|
|---|
| 29 |
|
|---|
| 30 | public static IEnumerable<string> SplitAndKeep(this string text, string[] separators)
|
|---|
| 31 | {
|
|---|
| 32 | int start = 0;
|
|---|
| 33 | int index;
|
|---|
| 34 | string lastSeparator = null;
|
|---|
| 35 |
|
|---|
| 36 | while ((index = text.IndexOfAny(separators, start, out string separator)) != -1)
|
|---|
| 37 | {
|
|---|
| 38 | if (start == 0)
|
|---|
| 39 | {
|
|---|
| 40 | yield return text.Substring(0, index);
|
|---|
| 41 | }
|
|---|
| 42 | else
|
|---|
| 43 | {
|
|---|
| 44 | yield return text.Substring(start - lastSeparator?.Length ?? 0,
|
|---|
| 45 | index - start - lastSeparator?.Length ?? 0);
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | start = index + separator.Length;
|
|---|
| 49 | lastSeparator = separator;
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | if (start < text.Length)
|
|---|
| 53 | {
|
|---|
| 54 | yield return text.Substring(start - lastSeparator?.Length ?? 0);
|
|---|
| 55 | }
|
|---|
| 56 | }
|
|---|
| 57 |
|
|---|
| 58 | public static int IndexOfAny(this string text, string[] anyOf, int startIndex, out string resultSeparator)
|
|---|
| 59 | {
|
|---|
| 60 | int result = -1;
|
|---|
| 61 | resultSeparator = null;
|
|---|
| 62 | foreach (var separator in anyOf)
|
|---|
| 63 | {
|
|---|
| 64 | int index = text.IndexOf(separator, startIndex, StringComparison.Ordinal);
|
|---|
| 65 | if (index >= startIndex && result < index)
|
|---|
| 66 | {
|
|---|
| 67 | result = index;
|
|---|
| 68 | resultSeparator = separator;
|
|---|
| 69 | }
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | return result;
|
|---|
| 73 | }
|
|---|
| 74 |
|
|---|
| 75 | public static bool StartsWith(this string text, string value, int start, StringComparison comparisonType)
|
|---|
| 76 | {
|
|---|
| 77 | // TODO: Can be possibly optimized without temporary string creation
|
|---|
| 78 | return text.Substring(start).StartsWith(value, comparisonType);
|
|---|
| 79 | }
|
|---|
| 80 |
|
|---|
| 81 | public static string Repeat(this string s, int n)
|
|---|
| 82 | => new StringBuilder(s.Length * n).Insert(0, s, n).ToString();
|
|---|
| 83 | }
|
|---|
| 84 | }
|
|---|