Skip to content

Commit 681b415

Browse files
committed
Cleanup
1 parent 7d97a48 commit 681b415

File tree

4 files changed

+286
-224
lines changed

4 files changed

+286
-224
lines changed

src/StaticWebAssetsSdk/Tasks/Data/ContentTypeProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ private bool TryGetMapping(StaticWebAssetGlobMatcher.MatchContext context, TaskL
475475
#if NET9_0_OR_GREATER
476476
private static ReadOnlySpan<char> ResolvePathWithoutCompressedExtension(ReadOnlySpan<char> fileName, out bool hasCompressedExtension)
477477
#else
478-
private string ResolvePathWithoutCompressedExtension(string fileName, out bool hasCompressedExtension)
478+
private static string ResolvePathWithoutCompressedExtension(string fileName, out bool hasCompressedExtension)
479479
#endif
480480
{
481481
var extension = Path.GetExtension(fileName);

src/StaticWebAssetsSdk/Tasks/Data/StaticWebAssetPathPattern.cs

Lines changed: 76 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ namespace Microsoft.AspNetCore.StaticWebAssets.Tasks;
1111
internal sealed class StaticWebAssetPathPattern : IEquatable<StaticWebAssetPathPattern>
1212
#else
1313
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
14+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0057:Use range operator", Justification = "Can't use range syntax in full framework")]
1415
public sealed class StaticWebAssetPathPattern : IEquatable<StaticWebAssetPathPattern>
1516
#endif
1617
{
17-
private const string FingerprintStart = "#[";
18-
private const string FingerprintEnd = "]";
19-
private const char FingerprintOptional = '?';
20-
private const char FingerprintPreferred = '!';
21-
private const char FingerprintValueSeparator = '=';
22-
private const char FingerprintParameterStart = '{';
23-
private const char FingerprintParameterEnd = '}';
18+
private const string PatternStart = "#[";
19+
private const char PatternEnd = ']';
20+
private const char PatternOptional = '?';
21+
private const char PatternPreferred = '!';
22+
private const char PatternValueSeparator = '=';
23+
private const char PatternParameterStart = '{';
24+
private const char PatternParameterEnd = '}';
2425

2526
public StaticWebAssetPathPattern(string path) : this(path.AsMemory()) { }
2627

@@ -71,7 +72,7 @@ public static StaticWebAssetPathPattern Parse(ReadOnlyMemory<char> rawPathMemory
7172
{
7273
var pattern = new StaticWebAssetPathPattern(rawPathMemory);
7374
var current = rawPathMemory;
74-
var nextToken = MemoryExtensions.IndexOf(current.Span, FingerprintStart.AsSpan(), StringComparison.OrdinalIgnoreCase);
75+
var nextToken = MemoryExtensions.IndexOf(current.Span, PatternStart.AsSpan(), StringComparison.OrdinalIgnoreCase);
7576
if (nextToken == -1)
7677
{
7778
var literalSegment = new StaticWebAssetPathSegment();
@@ -90,7 +91,7 @@ public static StaticWebAssetPathPattern Parse(ReadOnlyMemory<char> rawPathMemory
9091
while (nextToken != -1)
9192
{
9293
current = current.Slice(nextToken);
93-
var tokenEnd = MemoryExtensions.IndexOf(current.Span, FingerprintEnd.AsSpan(), StringComparison.Ordinal);
94+
var tokenEnd = MemoryExtensions.IndexOf(current.Span, PatternEnd);
9495
if (tokenEnd == -1)
9596
{
9697
if (assetIdentity != null)
@@ -112,17 +113,18 @@ public static StaticWebAssetPathPattern Parse(ReadOnlyMemory<char> rawPathMemory
112113

113114
// Check if the segment is optional (ends with ? or !)
114115
if (tokenEnd < current.Length - 1 &&
115-
(current.Span[tokenEnd + 1] == FingerprintOptional || current.Span[tokenEnd + 1] == FingerprintPreferred))
116+
(current.Span[tokenEnd + 1] == PatternOptional || current.Span[tokenEnd + 1] == PatternPreferred))
116117
{
117118
token.IsOptional = true;
118-
if (current.Span[tokenEnd + 1] == FingerprintPreferred)
119+
if (current.Span[tokenEnd + 1] == PatternPreferred)
119120
{
120121
token.IsPreferred = true;
121122
}
122123
tokenEnd++;
123124
}
125+
124126
current = current.Slice(tokenEnd + 1);
125-
nextToken = MemoryExtensions.IndexOf(current.Span, FingerprintStart.AsSpan(), StringComparison.OrdinalIgnoreCase);
127+
nextToken = MemoryExtensions.IndexOf(current.Span, PatternStart.AsSpan(), StringComparison.OrdinalIgnoreCase);
126128

127129
if (nextToken == -1 && current.Length > 0)
128130
{
@@ -141,6 +143,61 @@ public static StaticWebAssetPathPattern Parse(ReadOnlyMemory<char> rawPathMemory
141143
return pattern;
142144
}
143145

146+
// Iterate over the token expression and add the parts to the token segment
147+
// Some examples are '.{fingerprint}', '{fingerprint}.', '{fingerprint}{fingerprint}', {fingerprint}.{fingerprint}
148+
// The '.' represents sample literal content.
149+
// The value within the {} represents token variables.
150+
private static void AddTokenSegmentParts(ReadOnlyMemory<char> tokenExpression, StaticWebAssetPathSegment token)
151+
{
152+
var current = tokenExpression;
153+
var nextToken = MemoryExtensions.IndexOf(current.Span, PatternParameterStart);
154+
if (nextToken is not (-1) and > 0)
155+
{
156+
var literalPart = new StaticWebAssetSegmentPart { Name = current.Slice(0, nextToken), IsLiteral = true };
157+
token.Parts.Add(literalPart);
158+
}
159+
160+
while (nextToken != -1)
161+
{
162+
current = current.Slice(nextToken);
163+
var tokenEnd = MemoryExtensions.IndexOf(current.Span, PatternParameterEnd);
164+
if (tokenEnd == -1)
165+
{
166+
throw new InvalidOperationException($"Invalid token expression '{tokenExpression}'. Missing '}}' token.");
167+
}
168+
169+
var embeddedValue = MemoryExtensions.IndexOf(current.Span, PatternValueSeparator);
170+
if (embeddedValue != -1)
171+
{
172+
var tokenPart = new StaticWebAssetSegmentPart
173+
{
174+
Name = current.Slice(1, embeddedValue - 1),
175+
IsLiteral = false,
176+
Value = current.Slice(embeddedValue + 1, tokenEnd - embeddedValue - 1)
177+
};
178+
token.Parts.Add(tokenPart);
179+
}
180+
else
181+
{
182+
var tokenPart = new StaticWebAssetSegmentPart { Name = current.Slice(1, tokenEnd - 1), IsLiteral = false };
183+
token.Parts.Add(tokenPart);
184+
}
185+
186+
current = current.Slice(tokenEnd + 1);
187+
nextToken = MemoryExtensions.IndexOf(current.Span, PatternParameterStart);
188+
if (nextToken == -1 && current.Length > 0)
189+
{
190+
var literalPart = new StaticWebAssetSegmentPart { Name = current, IsLiteral = true };
191+
token.Parts.Add(literalPart);
192+
}
193+
else if (nextToken > 0)
194+
{
195+
var literalPart = new StaticWebAssetSegmentPart { Name = current.Slice(0, nextToken), IsLiteral = true };
196+
token.Parts.Add(literalPart);
197+
}
198+
}
199+
}
200+
144201
public static StaticWebAssetPathPattern Parse(string rawPath, string assetIdentity = null)
145202
{
146203
return Parse(rawPath.AsMemory(), assetIdentity);
@@ -246,7 +303,6 @@ public IEnumerable<StaticWebAssetPathPattern> ExpandPatternExpression()
246303
// - asset.css produces a single pattern (asset.css).
247304
// - other#[.{fingerprint}].js produces a single pattern asset#[.{fingerprint}].js
248305
// - last#[.{fingerprint}]?.txt produces two patterns last#[.{fingerprint}]?.txt and last.txt
249-
250306
var hasOptionalSegments = false;
251307
foreach (var segment in Segments)
252308
{
@@ -376,61 +432,6 @@ internal void EmbedTokens(StaticWebAsset staticWebAsset, StaticWebAssetTokenReso
376432
RawPattern = GetRawPattern(Segments);
377433
}
378434

379-
// Iterate over the token expression and add the parts to the token segment
380-
// Some examples are '.{fingerprint}', '{fingerprint}.', '{fingerprint}{fingerprint}', {fingerprint}.{fingerprint}
381-
// The '.' represents sample literal content.
382-
// The value within the {} represents token variables.
383-
private static void AddTokenSegmentParts(ReadOnlyMemory<char> tokenExpression, StaticWebAssetPathSegment token)
384-
{
385-
var current = tokenExpression;
386-
var nextToken = MemoryExtensions.IndexOf(current.Span, FingerprintParameterStart);
387-
if (nextToken is not (-1) and > 0)
388-
{
389-
var literalPart = new StaticWebAssetSegmentPart { Name = current.Slice(0, nextToken), IsLiteral = true };
390-
token.Parts.Add(literalPart);
391-
}
392-
393-
while (nextToken != -1)
394-
{
395-
current = current.Slice(nextToken);
396-
var tokenEnd = MemoryExtensions.IndexOf(current.Span, FingerprintParameterEnd);
397-
if (tokenEnd == -1)
398-
{
399-
throw new InvalidOperationException($"Invalid token expression '{tokenExpression}'. Missing '}}' token.");
400-
}
401-
402-
var embeddedValue = MemoryExtensions.IndexOf(current.Span, FingerprintValueSeparator);
403-
if (embeddedValue != -1)
404-
{
405-
var tokenPart = new StaticWebAssetSegmentPart
406-
{
407-
Name = current.Slice(1, embeddedValue - 1),
408-
IsLiteral = false,
409-
Value = current.Slice(embeddedValue + 1, tokenEnd - embeddedValue - 1)
410-
};
411-
token.Parts.Add(tokenPart);
412-
}
413-
else
414-
{
415-
var tokenPart = new StaticWebAssetSegmentPart { Name = current.Slice(1, tokenEnd - 1), IsLiteral = false };
416-
token.Parts.Add(tokenPart);
417-
}
418-
419-
current = current.Slice(tokenEnd + 1);
420-
nextToken = MemoryExtensions.IndexOf(current.Span, FingerprintParameterStart);
421-
if (nextToken == -1 && current.Length > 0)
422-
{
423-
var literalPart = new StaticWebAssetSegmentPart { Name = current, IsLiteral = true };
424-
token.Parts.Add(literalPart);
425-
}
426-
else if (nextToken > 0)
427-
{
428-
var literalPart = new StaticWebAssetSegmentPart { Name = current.Slice(0, nextToken), IsLiteral = true };
429-
token.Parts.Add(literalPart);
430-
}
431-
}
432-
}
433-
434435
private static ReadOnlyMemory<char> GetRawPattern(IList<StaticWebAssetPathSegment> segments)
435436
{
436437
var stringBuilder = new StringBuilder();
@@ -440,25 +441,25 @@ private static ReadOnlyMemory<char> GetRawPattern(IList<StaticWebAssetPathSegmen
440441
var isLiteral = IsLiteralSegment(segment);
441442
if (!isLiteral)
442443
{
443-
stringBuilder.Append("#[");
444+
stringBuilder.Append(PatternStart);
444445
}
445446
for (var j = 0; j < segment.Parts.Count; j++)
446447
{
447448
var part = segment.Parts[j];
448-
stringBuilder.Append(part.IsLiteral ? part.Name : $$"""{{{(!part.Value.IsEmpty ? $"""{part.Name}={part.Value}""" : part.Name)}}}""");
449+
stringBuilder.Append(part.IsLiteral ? part.Name : $$"""{{{(!part.Value.IsEmpty ? $"""{part.Name}{PatternValueSeparator}{part.Value}""" : part.Name)}}}""");
449450
}
450451
if (!isLiteral)
451452
{
452-
stringBuilder.Append(']');
453+
stringBuilder.Append(PatternEnd);
453454
if (segment.IsOptional)
454455
{
455456
if (segment.IsPreferred)
456457
{
457-
stringBuilder.Append('!');
458+
stringBuilder.Append(PatternPreferred);
458459
}
459460
else
460461
{
461-
stringBuilder.Append('?');
462+
stringBuilder.Append(PatternOptional);
462463
}
463464
}
464465
}
@@ -496,10 +497,12 @@ public override int GetHashCode()
496497
#endif
497498

498499
public static bool operator ==(StaticWebAssetPathPattern left, StaticWebAssetPathPattern right) => EqualityComparer<StaticWebAssetPathPattern>.Default.Equals(left, right);
500+
499501
public static bool operator !=(StaticWebAssetPathPattern left, StaticWebAssetPathPattern right) => !(left == right);
500502

501503
private string GetDebuggerDisplay() => string.Concat(Segments.Select(s => s.GetDebuggerDisplay()));
502504

503505
private static bool IsLiteralSegment(StaticWebAssetPathSegment segment) => segment.Parts.Count == 1 && segment.Parts[0].IsLiteral;
506+
504507
internal static string PathWithoutTokens(string path) => Parse(path).ComputePatternLabel();
505508
}

src/StaticWebAssetsSdk/Tasks/Data/StaticWebAssetSegmentPart.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,23 @@ public bool Equals(StaticWebAssetSegmentPart other) => other is not null &&
2525
public override int GetHashCode()
2626
{
2727
var hashCode = -62096114;
28-
hashCode = (hashCode * -1521134295) + EqualityComparer<ReadOnlyMemory<char>>.Default.GetHashCode(Name);
29-
hashCode = (hashCode * -1521134295) + EqualityComparer<ReadOnlyMemory<char>>.Default.GetHashCode(Value);
28+
hashCode = (hashCode * -1521134295) + GetSpanHashCode(Name);
29+
hashCode = (hashCode * -1521134295) + GetSpanHashCode(Value);
3030
hashCode = (hashCode * -1521134295) + IsLiteral.GetHashCode();
3131
return hashCode;
3232
}
33+
34+
private int GetSpanHashCode(ReadOnlyMemory<char> memory)
35+
{
36+
var hashCode = -62096114;
37+
var span = memory.Span;
38+
for ( var i = 0; i < span.Length; i++)
39+
{
40+
hashCode = (hashCode * -1521134295) + span[i].GetHashCode();
41+
}
42+
43+
return hashCode;
44+
}
3345
#else
3446
public override int GetHashCode() => HashCode.Combine(Name, Value, IsLiteral);
3547
#endif

0 commit comments

Comments
 (0)