diff options
| -rw-r--r-- | Emby.Server.Implementations/Data/SqliteItemRepository.cs | 14 | ||||
| -rw-r--r-- | MediaBrowser.Common/Extensions/SplitStringExtensions.cs (renamed from MediaBrowser.Common/Extensions/SplitLinesStringExtensions.cs) | 16 | ||||
| -rw-r--r-- | tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs | 31 |
3 files changed, 43 insertions, 18 deletions
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 292ff48fa..4b9b0bed0 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1082,7 +1082,7 @@ namespace Emby.Server.Implementations.Data } } - private ItemImageInfo ItemImageInfoFromValueString(ReadOnlySpan<char> value) + internal ItemImageInfo ItemImageInfoFromValueString(ReadOnlySpan<char> value) { var nextSegment = value.IndexOf('*'); if (nextSegment == -1) @@ -1103,7 +1103,7 @@ namespace Emby.Server.Implementations.Data nextSegment = value.IndexOf('*'); if (nextSegment == -1) { - return null; + nextSegment = value.Length; } ReadOnlySpan<char> imageType = value[..nextSegment]; @@ -1128,13 +1128,18 @@ namespace Emby.Server.Implementations.Data { value = value[(nextSegment + 1)..]; nextSegment = value.IndexOf('*'); + if (nextSegment == -1 || nextSegment == value.Length) + { + return image; + } + ReadOnlySpan<char> widthSpan = value[..nextSegment]; value = value[(nextSegment + 1)..]; nextSegment = value.IndexOf('*'); if (nextSegment == -1) { - return image; + nextSegment = value.Length; } ReadOnlySpan<char> heightSpan = value[..nextSegment]; @@ -1146,10 +1151,9 @@ namespace Emby.Server.Implementations.Data image.Height = height; } - nextSegment += 1; if (nextSegment < value.Length - 1) { - value = value[nextSegment..]; + value = value[(nextSegment + 1)..]; var length = value.Length; Span<char> blurHashSpan = stackalloc char[length]; diff --git a/MediaBrowser.Common/Extensions/SplitLinesStringExtensions.cs b/MediaBrowser.Common/Extensions/SplitStringExtensions.cs index 5332aba9f..6c1c45013 100644 --- a/MediaBrowser.Common/Extensions/SplitLinesStringExtensions.cs +++ b/MediaBrowser.Common/Extensions/SplitStringExtensions.cs @@ -33,33 +33,33 @@ namespace MediaBrowser.Common.Extensions /// <summary> /// Extension class for splitting lines without unnecessary allocations. /// </summary> - public static class SplitLinesStringExtensions + public static class SplitStringExtensions { /// <summary> - /// Creates a new line split enumerator. + /// Creates a new string split enumerator. /// </summary> /// <param name="str">The string to split.</param> /// <param name="separator">The separator to split on.</param> /// <returns>The enumerator struct.</returns> [Pure] - public static LineSplitEnumerator SpanSplit(this string str, char separator) => new (str.AsSpan(), separator); + public static SplitEnumerator SpanSplit(this string str, char separator) => new (str.AsSpan(), separator); /// <summary> - /// Creates a new line split enumerator. + /// Creates a new span split enumerator. /// </summary> /// <param name="str">The span to split.</param> /// <param name="separator">The separator to split on.</param> /// <returns>The enumerator struct.</returns> [Pure] - public static LineSplitEnumerator Split(this ReadOnlySpan<char> str, char separator) => new (str, separator); + public static SplitEnumerator Split(this ReadOnlySpan<char> str, char separator) => new (str, separator); [StructLayout(LayoutKind.Auto)] - public ref struct LineSplitEnumerator + public ref struct SplitEnumerator { private readonly char _separator; private ReadOnlySpan<char> _str; - public LineSplitEnumerator(ReadOnlySpan<char> str, char separator) + public SplitEnumerator(ReadOnlySpan<char> str, char separator) { _str = str; _separator = separator; @@ -68,7 +68,7 @@ namespace MediaBrowser.Common.Extensions public ReadOnlySpan<char> Current { get; private set; } - public readonly LineSplitEnumerator GetEnumerator() => this; + public readonly SplitEnumerator GetEnumerator() => this; public bool MoveNext() { diff --git a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs index af6ec3245..c0f34afa7 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs @@ -37,7 +37,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data yield return new object[] { "/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg*637452096478512963*Primary*1920*1080*WjQbtJtSO8nhNZ%L_Io#R/oaS6o}-;adXAoIn7j[%hW9s:WGw[nN", - new ItemImageInfo() + new ItemImageInfo { Path = "/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg", Type = ImageType.Primary, @@ -51,7 +51,27 @@ namespace Jellyfin.Server.Implementations.Tests.Data yield return new object[] { "https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg*0*Primary*0*0", - new ItemImageInfo() + new ItemImageInfo + { + Path = "https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg", + Type = ImageType.Primary, + } + }; + + yield return new object[] + { + "https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg*0*Primary", + new ItemImageInfo + { + Path = "https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg", + Type = ImageType.Primary, + } + }; + + yield return new object[] + { + "https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg*0*Primary*600", + new ItemImageInfo { Path = "https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg", Type = ImageType.Primary, @@ -61,7 +81,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data yield return new object[] { "%MetadataPath%/library/68/68578562b96c80a7ebd530848801f645/poster.jpg*637264380567586027*Primary*600*336", - new ItemImageInfo() + new ItemImageInfo { Path = "/meta/data/path/library/68/68578562b96c80a7ebd530848801f645/poster.jpg", Type = ImageType.Primary, @@ -76,7 +96,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data [MemberData(nameof(ItemImageInfoFromValueString_Valid_TestData))] public void ItemImageInfoFromValueString_Valid_Success(string value, ItemImageInfo expected) { - var result = _sqliteItemRepository.ItemImageInfoFromValueString(value); + var result = _sqliteItemRepository.ItemImageInfoFromValueString(value.AsSpan()); Assert.Equal(expected.Path, result.Path); Assert.Equal(expected.Type, result.Type); Assert.Equal(expected.DateModified, result.DateModified); @@ -88,9 +108,10 @@ namespace Jellyfin.Server.Implementations.Tests.Data [Theory] [InlineData("")] [InlineData("*")] + [InlineData("https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg*0")] public void ItemImageInfoFromValueString_Invalid_Null(string value) { - Assert.Null(_sqliteItemRepository.ItemImageInfoFromValueString(value)); + Assert.Null(_sqliteItemRepository.ItemImageInfoFromValueString(value.AsSpan())); } public static IEnumerable<object[]> DeserializeImages_Valid_TestData() |
