@@ -12,6 +12,11 @@ namespace Confuser.Core {
1212 public static class Utils {
1313 static readonly char [ ] hexCharset = "0123456789abcdef" . ToCharArray ( ) ;
1414
15+ // Use not thread safe buffers since app is not multithreaded
16+ static readonly StringBuilder Buffer = new StringBuilder ( ) ;
17+ static readonly SHA1Managed Sha1Managed = new SHA1Managed ( ) ;
18+ static readonly SHA256Managed Sha256Managed = new SHA256Managed ( ) ;
19+
1520 /// <summary>
1621 /// Gets the value associated with the specified key, or default value if the key does not exists.
1722 /// </summary>
@@ -24,9 +29,8 @@ public static class Utils {
2429 public static TValue GetValueOrDefault < TKey , TValue > (
2530 this Dictionary < TKey , TValue > dictionary ,
2631 TKey key ,
27- TValue defValue = default ( TValue ) ) {
28- TValue ret ;
29- if ( dictionary . TryGetValue ( key , out ret ) )
32+ TValue defValue = default ) {
33+ if ( dictionary . TryGetValue ( key , out var ret ) )
3034 return ret ;
3135 return defValue ;
3236 }
@@ -44,8 +48,7 @@ public static TValue GetValueOrDefaultLazy<TKey, TValue>(
4448 this Dictionary < TKey , TValue > dictionary ,
4549 TKey key ,
4650 Func < TKey , TValue > defValueFactory ) {
47- TValue ret ;
48- if ( dictionary . TryGetValue ( key , out ret ) )
51+ if ( dictionary . TryGetValue ( key , out var ret ) )
4952 return ret ;
5053 return defValueFactory ( key ) ;
5154 }
@@ -62,8 +65,7 @@ public static TValue GetValueOrDefaultLazy<TKey, TValue>(
6265 public static void AddListEntry < TKey , TValue > ( this IDictionary < TKey , List < TValue > > self , TKey key , TValue value ) {
6366 if ( key == null )
6467 throw new ArgumentNullException ( "key" ) ;
65- List < TValue > list ;
66- if ( ! self . TryGetValue ( key , out list ) )
68+ if ( ! self . TryGetValue ( key , out var list ) )
6769 list = self [ key ] = new List < TValue > ( ) ;
6870 list . Add ( value ) ;
6971 }
@@ -102,36 +104,14 @@ public static string NullIfEmpty(this string val) {
102104 /// </summary>
103105 /// <param name="buffer">The input buffer.</param>
104106 /// <returns>The SHA1 hash of the input buffer.</returns>
105- public static byte [ ] SHA1 ( byte [ ] buffer ) {
106- var sha = new SHA1Managed ( ) ;
107- return sha . ComputeHash ( buffer ) ;
108- }
109-
110- /// <summary>
111- /// Xor the values in the two buffer together.
112- /// </summary>
113- /// <param name="buffer1">The input buffer 1.</param>
114- /// <param name="buffer2">The input buffer 2.</param>
115- /// <returns>The result buffer.</returns>
116- /// <exception cref="System.ArgumentException">Length of the two buffers are not equal.</exception>
117- public static byte [ ] Xor ( byte [ ] buffer1 , byte [ ] buffer2 ) {
118- if ( buffer1 . Length != buffer2 . Length )
119- throw new ArgumentException ( "Length mismatched." ) ;
120- var ret = new byte [ buffer1 . Length ] ;
121- for ( int i = 0 ; i < ret . Length ; i ++ )
122- ret [ i ] = ( byte ) ( buffer1 [ i ] ^ buffer2 [ i ] ) ;
123- return ret ;
124- }
107+ public static byte [ ] SHA1 ( byte [ ] buffer ) => Sha1Managed . ComputeHash ( buffer ) ;
125108
126109 /// <summary>
127110 /// Compute the SHA256 hash of the input buffer.
128111 /// </summary>
129112 /// <param name="buffer">The input buffer.</param>
130113 /// <returns>The SHA256 hash of the input buffer.</returns>
131- public static byte [ ] SHA256 ( byte [ ] buffer ) {
132- var sha = new SHA256Managed ( ) ;
133- return sha . ComputeHash ( buffer ) ;
134- }
114+ public static byte [ ] SHA256 ( byte [ ] buffer ) => Sha256Managed . ComputeHash ( buffer ) ;
135115
136116 /// <summary>
137117 /// Encoding the buffer to a string using specified charset.
@@ -140,65 +120,32 @@ public static byte[] SHA256(byte[] buffer) {
140120 /// <param name="charset">The charset.</param>
141121 /// <returns>The encoded string.</returns>
142122 public static string EncodeString ( byte [ ] buff , char [ ] charset ) {
123+ Buffer . Clear ( ) ;
143124 int current = buff [ 0 ] ;
144- var ret = new StringBuilder ( ) ;
145125 for ( int i = 1 ; i < buff . Length ; i ++ ) {
146126 current = ( current << 8 ) + buff [ i ] ;
147127 while ( current >= charset . Length ) {
148- ret . Append ( charset [ current % charset . Length ] ) ;
149- current /= charset . Length ;
128+ current = Math . DivRem ( current , charset . Length , out int remainder ) ;
129+ Buffer . Append ( charset [ remainder ] ) ;
150130 }
151131 }
152132 if ( current != 0 )
153- ret . Append ( charset [ current % charset . Length ] ) ;
154- return ret . ToString ( ) ;
155- }
156-
157- /// <summary>
158- /// Returns a new string in which all occurrences of a specified string in
159- /// <paramref name="str" /> are replaced with another specified string.
160- /// </summary>
161- /// <returns>
162- /// A <see cref="string" /> equivalent to <paramref name="str" /> but with all instances of
163- /// <paramref name="oldValue" />
164- /// replaced with <paramref name="newValue" />.
165- /// </returns>
166- /// <param name="str">A string to do the replace in. </param>
167- /// <param name="oldValue">A string to be replaced. </param>
168- /// <param name="newValue">A string to replace all occurrences of <paramref name="oldValue" />. </param>
169- /// <param name="comparison">One of the <see cref="StringComparison" /> values. </param>
170- /// <remarks>Adopted from http://stackoverflow.com/a/244933 </remarks>
171- public static string Replace ( this string str , string oldValue , string newValue , StringComparison comparison ) {
172- StringBuilder sb = new StringBuilder ( ) ;
173-
174- int previousIndex = 0 ;
175- int index = str . IndexOf ( oldValue , comparison ) ;
176- while ( index != - 1 ) {
177- sb . Append ( str . Substring ( previousIndex , index - previousIndex ) ) ;
178- sb . Append ( newValue ) ;
179- index += oldValue . Length ;
180- previousIndex = index ;
181- index = str . IndexOf ( oldValue , index , comparison ) ;
182- }
183- sb . Append ( str . Substring ( previousIndex ) ) ;
184-
185- return sb . ToString ( ) ;
133+ Buffer . Append ( charset [ current % charset . Length ] ) ;
134+ return Buffer . ToString ( ) ;
186135 }
187136
188-
189137 /// <summary>
190138 /// Encode the buffer to a hexadecimal string.
191139 /// </summary>
192140 /// <param name="buff">The input buffer.</param>
193141 /// <returns>A hexadecimal representation of input buffer.</returns>
194142 public static string ToHexString ( byte [ ] buff ) {
195- var ret = new char [ buff . Length * 2 ] ;
196- int i = 0 ;
143+ Buffer . Clear ( ) ;
197144 foreach ( byte val in buff ) {
198- ret [ i ++ ] = hexCharset [ val >> 4 ] ;
199- ret [ i ++ ] = hexCharset [ val & 0xf ] ;
145+ Buffer . Append ( hexCharset [ val >> 4 ] ) ;
146+ Buffer . Append ( hexCharset [ val & 0xf ] ) ;
200147 }
201- return new string ( ret ) ;
148+ return Buffer . ToString ( ) ;
202149 }
203150
204151 /// <summary>
@@ -208,12 +155,17 @@ public static string ToHexString(byte[] buff) {
208155 /// <param name="self">The list to remove from.</param>
209156 /// <param name="match">The predicate that defines the conditions of the elements to remove.</param>
210157 /// <returns><paramref name="self" /> for method chaining.</returns>
211- public static IList < T > RemoveWhere < T > ( this IList < T > self , Predicate < T > match ) {
158+ public static void RemoveWhere < T > ( this IList < T > self , Predicate < T > match ) {
159+ if ( self is List < T > list ) {
160+ list . RemoveAll ( match ) ;
161+ return ;
162+ }
163+
164+ // Switch to slow algorithm
212165 for ( int i = self . Count - 1 ; i >= 0 ; i -- ) {
213166 if ( match ( self [ i ] ) )
214167 self . RemoveAt ( i ) ;
215168 }
216- return self ;
217169 }
218170
219171 /// <summary>
0 commit comments