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}