A game about forced loneliness, made by TACStudios
1using System; 2 3namespace UnityEngine.InputSystem.Utilities 4{ 5 // Work with substrings without actually allocating strings. 6 internal struct Substring : IComparable<Substring>, IEquatable<Substring> 7 { 8 private readonly string m_String; 9 private readonly int m_Index; 10 private readonly int m_Length; 11 12 public bool isEmpty => m_Length == 0; 13 14 public Substring(string str) 15 { 16 m_String = str; 17 m_Index = 0; 18 if (str != null) 19 m_Length = str.Length; 20 else 21 m_Length = 0; 22 } 23 24 public Substring(string str, int index, int length) 25 { 26 Debug.Assert(str == null || index < str.Length); 27 Debug.Assert(str != null || length == 0); 28 29 m_String = str; 30 m_Index = index; 31 m_Length = length; 32 } 33 34 public Substring(string str, int index) 35 { 36 Debug.Assert(str == null || index < str.Length); 37 38 m_String = str; 39 m_Index = index; 40 m_Length = str.Length - index; 41 } 42 43 public override bool Equals(object obj) 44 { 45 if (obj is Substring other) 46 return Equals(other); 47 48 if (obj is string str) 49 return Equals(str); 50 51 return false; 52 } 53 54 public bool Equals(string other) 55 { 56 if (string.IsNullOrEmpty(other)) 57 return m_Length == 0; 58 59 if (other.Length != m_Length) 60 return false; 61 62 for (var i = 0; i < m_Length; ++i) 63 if (other[i] != m_String[m_Index + i]) 64 return false; 65 66 return true; 67 } 68 69 public bool Equals(Substring other) 70 { 71 return CompareTo(other) == 0; 72 } 73 74 public bool Equals(InternedString other) 75 { 76 if (length != other.length) 77 return false; 78 79 return string.Compare(m_String, m_Index, other.ToString(), 0, length, 80 StringComparison.OrdinalIgnoreCase) == 0; 81 } 82 83 public int CompareTo(Substring other) 84 { 85 return Compare(this, other, StringComparison.CurrentCulture); 86 } 87 88 public static int Compare(Substring left, Substring right, StringComparison comparison) 89 { 90 if (left.m_Length != right.m_Length) 91 { 92 if (left.m_Length < right.m_Length) 93 return -1; 94 return 1; 95 } 96 97 return string.Compare(left.m_String, left.m_Index, right.m_String, right.m_Index, left.m_Length, 98 comparison); 99 } 100 101 public bool StartsWith(string str) 102 { 103 if (str.Length > length) 104 return false; 105 for (var i = 0; i < str.Length; ++i) 106 if (m_String[m_Index + i] != str[i]) 107 return false; 108 return true; 109 } 110 111 public string Substr(int index = 0, int length = -1) 112 { 113 if (length < 0) 114 length = this.length - index; 115 return m_String.Substring(m_Index + index, length); 116 } 117 118 public override string ToString() 119 { 120 if (m_String == null) 121 return string.Empty; 122 123 return m_String.Substring(m_Index, m_Length); 124 } 125 126 public override int GetHashCode() 127 { 128 if (m_String == null) 129 return 0; 130 131 if (m_Index == 0 && m_Length == m_String.Length) 132 return m_String.GetHashCode(); 133 134 ////FIXME: this is bad... shouldn't allocate 135 return ToString().GetHashCode(); 136 } 137 138 public static bool operator==(Substring a, Substring b) 139 { 140 return a.Equals(b); 141 } 142 143 public static bool operator!=(Substring a, Substring b) 144 { 145 return !a.Equals(b); 146 } 147 148 public static bool operator==(Substring a, InternedString b) 149 { 150 return a.Equals(b); 151 } 152 153 public static bool operator!=(Substring a, InternedString b) 154 { 155 return !a.Equals(b); 156 } 157 158 public static bool operator==(InternedString a, Substring b) 159 { 160 return b.Equals(a); 161 } 162 163 public static bool operator!=(InternedString a, Substring b) 164 { 165 return !b.Equals(a); 166 } 167 168 public static implicit operator Substring(string s) 169 { 170 return new Substring(s); 171 } 172 173 public int length => m_Length; 174 175 public int index => m_Index; 176 177 public char this[int index] 178 { 179 get 180 { 181 if (index < 0 || index >= m_Length) 182 throw new ArgumentOutOfRangeException(nameof(index)); 183 return m_String[m_Index + index]; 184 } 185 } 186 } 187}