11using System ;
22using System . Collections . Generic ;
33using System . Runtime . InteropServices ;
4+ using System . Text ;
45using System . Text . RegularExpressions ;
56
67namespace OmniSharp . Extensions . LanguageServer . Protocol
@@ -98,11 +99,12 @@ private static string ReferenceResolution(string scheme, string path)
9899 {
99100 if ( string . IsNullOrWhiteSpace ( path ) )
100101 {
101- path = StrSlash ;
102+ return StrSlash ;
102103 }
103- else if ( path [ 0 ] != Slash )
104+
105+ if ( path [ 0 ] != Slash )
104106 {
105- path = Slash + path ;
107+ return Slash + path ;
106108 }
107109 }
108110
@@ -135,7 +137,7 @@ private static string ReferenceResolution(string scheme, string path)
135137
136138 private static string EncodeUriComponentFast ( string uriComponent , bool allowSlash )
137139 {
138- string res = null ;
140+ StringBuilder res = null ;
139141 var nativeEncodePos = - 1 ;
140142
141143 for ( var pos = 0 ; pos < uriComponent . Length ; pos ++ )
@@ -162,23 +164,25 @@ private static string EncodeUriComponentFast(string uriComponent, bool allowSlas
162164 // check if we are delaying native encode
163165 if ( nativeEncodePos != - 1 )
164166 {
165- res += Uri . EscapeDataString ( uriComponent . Substring ( nativeEncodePos , pos - nativeEncodePos ) ) ;
167+ res ??= new StringBuilder ( ) ;
168+ res . Append ( Uri . EscapeDataString ( uriComponent . Substring ( nativeEncodePos , pos - nativeEncodePos ) ) ) ;
166169 nativeEncodePos = - 1 ;
167170 }
168171
169172 // check if we write into a new string (by default we try to return the param)
170173 if ( res != null )
171174 {
172- res += uriComponent [ pos ] ;
175+ res ??= new StringBuilder ( ) ;
176+ res . Append ( uriComponent [ pos ] ) ;
173177 }
174178 }
175179 else
176180 {
177181 // encoding needed, we need to allocate a new string
178182 if ( res == null )
179-
180183 {
181- res = uriComponent . Substring ( 0 , pos ) ;
184+ res ??= new StringBuilder ( ) ;
185+ res . Append ( uriComponent . Substring ( 0 , pos ) ) ;
182186 }
183187
184188 // check with default table first
@@ -187,12 +191,12 @@ private static string EncodeUriComponentFast(string uriComponent, bool allowSlas
187191 // check if we are delaying native encode
188192 if ( nativeEncodePos != - 1 )
189193 {
190- res += Uri . EscapeDataString ( uriComponent . Substring ( nativeEncodePos , pos - nativeEncodePos ) ) ;
194+ res . Append ( Uri . EscapeDataString ( uriComponent . Substring ( nativeEncodePos , pos - nativeEncodePos ) ) ) ;
191195 nativeEncodePos = - 1 ;
192196 }
193197
194198 // append escaped variant to result
195- res += escaped ;
199+ res . Append ( escaped ) ;
196200 }
197201 else if ( nativeEncodePos == - 1 )
198202 {
@@ -204,37 +208,35 @@ private static string EncodeUriComponentFast(string uriComponent, bool allowSlas
204208
205209 if ( nativeEncodePos != - 1 )
206210 {
207- res += Uri . EscapeDataString ( uriComponent . Substring ( nativeEncodePos ) ) ;
211+ res ??= new StringBuilder ( ) ;
212+ res . Append ( Uri . EscapeDataString ( uriComponent . Substring ( nativeEncodePos ) ) ) ;
208213 }
209214
210- return ! string . IsNullOrWhiteSpace ( res ) ? res : uriComponent ;
215+ return res != null ? res . ToString ( ) : uriComponent ;
211216 }
212217
213218 private static string EncodeUriComponentMinimal ( string path )
214219 {
215- string res = null ;
220+ StringBuilder res = null ;
216221 for ( var pos = 0 ; pos < path . Length ; pos ++ )
217222 {
218223 var code = path [ pos ] ;
219224 if ( code == CharCode . Hash || code == CharCode . QuestionMark )
220225 {
221226 if ( res == null )
222227 {
223- res = path . Substring ( 0 , pos ) ;
228+ res = new StringBuilder ( path . Substring ( 0 , pos ) ) ;
224229 }
225230
226- res += EncodeTable [ code ] ;
231+ res . Append ( EncodeTable [ code ] ) ;
227232 }
228233 else
229234 {
230- if ( res != null )
231- {
232- res += path [ pos ] ;
233- }
235+ res ? . Append ( path [ pos ] ) ;
234236 }
235237 }
236238
237- return res ?? path ;
239+ return res != null ? res . ToString ( ) : path ;
238240 }
239241
240242 /// <summary>
@@ -290,18 +292,18 @@ string Encoder(string p, bool allowSlash)
290292 return ! skipEncoding ? EncodeUriComponentFast ( p , allowSlash ) : EncodeUriComponentMinimal ( p ) ;
291293 }
292294
293- var res = "" ;
295+ var res = new StringBuilder ( ) ;
294296 var ( scheme , authority , path , query , fragment ) = uri ;
295297 if ( ! string . IsNullOrWhiteSpace ( scheme ) )
296298 {
297- res += scheme ;
298- res += ":" ;
299+ res . Append ( scheme ) ;
300+ res . Append ( ":" ) ;
299301 }
300302
301303 if ( ! string . IsNullOrWhiteSpace ( authority ) || scheme == "file" )
302304 {
303- res += Slash ;
304- res += Slash ;
305+ res . Append ( Slash ) ;
306+ res . Append ( Slash ) ;
305307 }
306308
307309 if ( ! string . IsNullOrWhiteSpace ( authority ) )
@@ -315,70 +317,82 @@ string Encoder(string p, bool allowSlash)
315317 idx = userinfo . IndexOf ( ":" ) ;
316318 if ( idx == - 1 )
317319 {
318- res += Encoder ( userinfo , false ) ;
320+ res . Append ( Encoder ( userinfo , false ) ) ;
319321 }
320322 else
321323 {
322324 // <user>:<pass>@<auth>
323- res += Encoder ( userinfo . Substring ( 0 , idx ) , false ) ;
324- res += ":" ;
325- res += Encoder ( userinfo . Substring ( idx + 1 ) , false ) ;
325+ res . Append ( Encoder ( userinfo . Substring ( 0 , idx ) , false ) ) ;
326+ res . Append ( ":" ) ;
327+ res . Append ( Encoder ( userinfo . Substring ( idx + 1 ) , false ) ) ;
326328 }
327329
328- res += "@" ;
330+ res . Append ( "@" ) ;
329331 }
330332
331333 authority = authority . ToLowerInvariant ( ) ;
332334 idx = authority . IndexOf ( ":" , StringComparison . Ordinal ) ;
333335 if ( idx == - 1 )
334336 {
335- res += Encoder ( authority , false ) ;
337+ res . Append ( Encoder ( authority , false ) ) ;
336338 }
337339 else
338340 {
339341 // <auth>:<port>
340- res += Encoder ( authority . Substring ( 0 , idx ) , false ) ;
341- res += authority . Substring ( idx ) ;
342+ res . Append ( Encoder ( authority . Substring ( 0 , idx ) , false ) ) ;
343+ res . Append ( authority . Substring ( idx ) ) ;
342344 }
343345 }
344346
345347 if ( ! string . IsNullOrWhiteSpace ( path ) )
346348 {
349+ var appended = false ;
347350 // lower-case windows drive letters in /C:/fff or C:/fff
348351 if ( path . Length >= 3 && path [ 0 ] == CharCode . Slash && path [ 2 ] == CharCode . Colon )
349352 {
350353 var code = path [ 1 ] ;
351354 if ( code >= CharCode . A && code <= CharCode . Z )
352355 {
353- path = $ "/{ Convert . ToChar ( code + 32 ) } :{ path . Substring ( 3 ) } "; // "/c:".length == 3
356+ appended = true ;
357+ res . Append ( "/" ) ;
358+ res . Append ( Convert . ToChar ( code + 32 ) ) ;
359+ res . Append ( ":" ) ;
360+ res . Append ( Encoder ( path . Substring ( 3 ) , true ) ) ;
361+ // path = $"/{Convert.ToChar(code + 32)}:{path.Substring(3)}"; // "/c:".length == 3
354362 }
355363 }
356364 else if ( path . Length >= 2 && path [ 1 ] == CharCode . Colon )
357365 {
358366 var code = path [ 0 ] ;
359367 if ( code >= CharCode . A && code <= CharCode . Z )
360368 {
361- path = $ "{ Convert . ToChar ( code + 32 ) } :{ path . Substring ( 2 ) } "; // "/c:".length == 3
369+ appended = true ;
370+ res . Append ( Convert . ToChar ( code + 32 ) ) ;
371+ res . Append ( ":" ) ;
372+ res . Append ( Encoder ( path . Substring ( 2 ) , true ) ) ;
373+ // path = $"{Convert.ToChar(code + 32)}:{path.Substring(2)}"; // "/c:".length == 3
362374 }
363375 }
364376
365- // encode the rest of the path
366- res += Encoder ( path , true ) ;
377+ if ( ! appended )
378+ {
379+ res . Append ( Encoder ( path , true ) ) ;
380+ }
367381 }
368382
369383 if ( ! string . IsNullOrWhiteSpace ( query ) )
370384 {
371- res += "?" ;
372- res += Encoder ( query , false ) ;
385+ res . Append ( "?" ) ;
386+ res . Append ( Encoder ( query , false ) ) ;
373387 }
374388
375389 if ( ! string . IsNullOrWhiteSpace ( fragment ) )
376390 {
377- res += "#" ;
378- res += ! skipEncoding ? EncodeUriComponentFast ( fragment , false ) : fragment ;
391+ res . Append ( "#" ) ;
392+ res . Append ( ! skipEncoding ? EncodeUriComponentFast ( fragment , false ) : fragment ) ;
379393 }
380394
381- return res ;
395+ return res . ToString ( ) ;
382396 }
383397
384398 private static string DecodeUriComponentGraceful ( string str )
0 commit comments