Skip to content

Commit d9d1cbe

Browse files
committed
Update FormatUtilities.cs
1 parent f73155d commit d9d1cbe

File tree

1 file changed

+42
-23
lines changed

1 file changed

+42
-23
lines changed

src/ImageSharp.Web/FormatUtilities.cs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ namespace SixLabors.ImageSharp.Web
1919
/// </summary>
2020
public sealed class FormatUtilities
2121
{
22-
private readonly IImageFormat[] imageFormats;
23-
private readonly Dictionary<IImageFormat, string[]> fileExtensions = new Dictionary<IImageFormat, string[]>();
22+
private readonly List<string> fileExtensions = new List<string>();
2423
private readonly Dictionary<string, string> fileExtension = new Dictionary<string, string>();
2524

2625
/// <summary>
@@ -33,12 +32,18 @@ public FormatUtilities(IOptions<ImageSharpMiddlewareOptions> options)
3332

3433
// The formats contained in the configuration are used a lot in hash generation
3534
// so we need them to be enumerated to remove allocations and allow indexing.
36-
this.imageFormats = options.Value.Configuration.ImageFormats.ToArray();
37-
for (int i = 0; i < this.imageFormats.Length; i++)
35+
IImageFormat[] imageFormats = options.Value.Configuration.ImageFormats.ToArray();
36+
37+
for (int i = 0; i < imageFormats.Length; i++)
3838
{
39-
string[] extensions = this.imageFormats[i].FileExtensions.ToArray();
40-
this.fileExtensions[this.imageFormats[i]] = extensions;
41-
this.fileExtension[this.imageFormats[i].DefaultMimeType] = extensions[0];
39+
string[] extensions = imageFormats[i].FileExtensions.ToArray();
40+
41+
foreach (string extension in extensions)
42+
{
43+
this.fileExtensions.Add(extension);
44+
}
45+
46+
this.fileExtension[imageFormats[i].DefaultMimeType] = extensions[0];
4247
}
4348
}
4449

@@ -50,32 +55,46 @@ public FormatUtilities(IOptions<ImageSharpMiddlewareOptions> options)
5055
[MethodImpl(MethodImplOptions.AggressiveInlining)]
5156
public string GetExtensionFromUri(string uri)
5257
{
53-
// TODO: Investigate using span to reduce allocations here.
54-
string[] parts = uri.Split('?');
55-
if (parts.Length > 1 && QueryHelpers.ParseQuery(parts[1]).TryGetValue(FormatWebProcessor.Format, out StringValues ext))
58+
int query = uri.IndexOf('?');
59+
ReadOnlySpan<char> path;
60+
61+
if (query > -1)
5662
{
57-
return ext;
63+
if (uri.Contains(FormatWebProcessor.Format, StringComparison.OrdinalIgnoreCase) && QueryHelpers.ParseQuery(uri.Substring(query)).TryGetValue(FormatWebProcessor.Format, out StringValues ext))
64+
{
65+
return ext;
66+
}
67+
68+
#if !NETCOREAPP3_1_OR_GREATER
69+
path = uri.ToLowerInvariant().AsSpan(0, query);
70+
#else
71+
path = uri.AsSpan(0, query);
72+
#endif
73+
}
74+
else
75+
{
76+
#if !NETCOREAPP3_1_OR_GREATER
77+
path = uri.ToLowerInvariant();
78+
#else
79+
path = uri;
80+
#endif
5881
}
5982

60-
string path = parts[0];
61-
string extension = null;
62-
int index = 0;
63-
for (int i = 0; i < this.imageFormats.Length; i++)
83+
int extensionIndex;
84+
if ((extensionIndex = path.LastIndexOf('.')) != -1)
6485
{
65-
for (int j = 0; j < this.fileExtensions[this.imageFormats[i]].Length; j++)
86+
ReadOnlySpan<char> extension = path.Slice(extensionIndex + 1);
87+
88+
foreach (string ext in this.fileExtensions)
6689
{
67-
int li = path.LastIndexOf($".{this.fileExtensions[this.imageFormats[i]][j]}", StringComparison.OrdinalIgnoreCase);
68-
if (li < index)
90+
if (extension.Equals(ext, StringComparison.OrdinalIgnoreCase))
6991
{
70-
continue;
92+
return ext;
7193
}
72-
73-
index = li;
74-
extension = this.fileExtensions[this.imageFormats[i]][j];
7594
}
7695
}
7796

78-
return extension;
97+
return null;
7998
}
8099

81100
/// <summary>

0 commit comments

Comments
 (0)