diff --git a/Emby.Naming/Audio/AudioFileParser.cs b/Emby.Naming/Audio/AudioFileParser.cs
index 8b47dd12e4..af4aa0059f 100644
--- a/Emby.Naming/Audio/AudioFileParser.cs
+++ b/Emby.Naming/Audio/AudioFileParser.cs
@@ -1,7 +1,7 @@
using System;
using System.IO;
-using System.Linq;
using Emby.Naming.Common;
+using MediaBrowser.Common.Extensions;
namespace Emby.Naming.Audio
{
@@ -18,8 +18,8 @@ namespace Emby.Naming.Audio
/// True if file at path is audio file.
public static bool IsAudioFile(string path, NamingOptions options)
{
- var extension = Path.GetExtension(path);
- return options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
+ var extension = Path.GetExtension(path.AsSpan());
+ return options.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase);
}
}
}
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index 63116f3680..3224ff4129 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/Emby.Naming/Emby.Naming.csproj
@@ -23,11 +23,12 @@
-
+
-
+
+
diff --git a/Emby.Naming/Video/ExtraResolver.cs b/Emby.Naming/Video/ExtraResolver.cs
index 1d3b36a1ad..f9d06c09be 100644
--- a/Emby.Naming/Video/ExtraResolver.cs
+++ b/Emby.Naming/Video/ExtraResolver.cs
@@ -29,70 +29,73 @@ namespace Emby.Naming.Video
/// Path to file.
/// Returns object.
public ExtraResult GetExtraInfo(string path)
- {
- return _options.VideoExtraRules
- .Select(i => GetExtraInfo(path, i))
- .FirstOrDefault(i => i.ExtraType != null) ?? new ExtraResult();
- }
-
- private ExtraResult GetExtraInfo(string path, ExtraRule rule)
{
var result = new ExtraResult();
- if (rule.MediaType == MediaType.Audio)
+ for (var i = 0; i < _options.VideoExtraRules.Length; i++)
{
- if (!AudioFileParser.IsAudioFile(path, _options))
+ var rule = _options.VideoExtraRules[i];
+ if (rule.MediaType == MediaType.Audio)
{
- return result;
+ if (!AudioFileParser.IsAudioFile(path, _options))
+ {
+ continue;
+ }
}
- }
- else if (rule.MediaType == MediaType.Video)
- {
- if (!new VideoResolver(_options).IsVideoFile(path))
+ else if (rule.MediaType == MediaType.Video)
{
- return result;
+ if (!new VideoResolver(_options).IsVideoFile(path))
+ {
+ continue;
+ }
}
- }
-
- if (rule.RuleType == ExtraRuleType.Filename)
- {
- var filename = Path.GetFileNameWithoutExtension(path);
- if (string.Equals(filename, rule.Token, StringComparison.OrdinalIgnoreCase))
+ var pathSpan = path.AsSpan();
+ if (rule.RuleType == ExtraRuleType.Filename)
{
- result.ExtraType = rule.ExtraType;
- result.Rule = rule;
- }
- }
- else if (rule.RuleType == ExtraRuleType.Suffix)
- {
- var filename = Path.GetFileNameWithoutExtension(path);
+ var filename = Path.GetFileNameWithoutExtension(pathSpan);
- if (filename.IndexOf(rule.Token, StringComparison.OrdinalIgnoreCase) > 0)
+ if (filename.Equals(rule.Token, StringComparison.OrdinalIgnoreCase))
+ {
+ result.ExtraType = rule.ExtraType;
+ result.Rule = rule;
+ }
+ }
+ else if (rule.RuleType == ExtraRuleType.Suffix)
{
- result.ExtraType = rule.ExtraType;
- result.Rule = rule;
+ var filename = Path.GetFileNameWithoutExtension(pathSpan);
+
+ if (filename.Contains(rule.Token, StringComparison.OrdinalIgnoreCase))
+ {
+ result.ExtraType = rule.ExtraType;
+ result.Rule = rule;
+ }
}
- }
- else if (rule.RuleType == ExtraRuleType.Regex)
- {
- var filename = Path.GetFileName(path);
+ else if (rule.RuleType == ExtraRuleType.Regex)
+ {
+ var filename = Path.GetFileName(path);
- var regex = new Regex(rule.Token, RegexOptions.IgnoreCase);
+ var regex = new Regex(rule.Token, RegexOptions.IgnoreCase);
- if (regex.IsMatch(filename))
+ if (regex.IsMatch(filename))
+ {
+ result.ExtraType = rule.ExtraType;
+ result.Rule = rule;
+ }
+ }
+ else if (rule.RuleType == ExtraRuleType.DirectoryName)
{
- result.ExtraType = rule.ExtraType;
- result.Rule = rule;
+ var directoryName = Path.GetFileName(Path.GetDirectoryName(pathSpan));
+ if (directoryName.Equals(rule.Token, StringComparison.OrdinalIgnoreCase))
+ {
+ result.ExtraType = rule.ExtraType;
+ result.Rule = rule;
+ }
}
- }
- else if (rule.RuleType == ExtraRuleType.DirectoryName)
- {
- var directoryName = Path.GetFileName(Path.GetDirectoryName(path));
- if (string.Equals(directoryName, rule.Token, StringComparison.OrdinalIgnoreCase))
+
+ if (result.ExtraType != null)
{
- result.ExtraType = rule.ExtraType;
- result.Rule = rule;
+ return result;
}
}
diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs
index 79a6da8f7b..27e73208c6 100644
--- a/Emby.Naming/Video/VideoResolver.cs
+++ b/Emby.Naming/Video/VideoResolver.cs
@@ -1,8 +1,8 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
-using System.Linq;
using Emby.Naming.Common;
+using MediaBrowser.Common.Extensions;
namespace Emby.Naming.Video
{
@@ -59,15 +59,15 @@ namespace Emby.Naming.Video
}
bool isStub = false;
- string? container = null;
+ ReadOnlySpan container = ReadOnlySpan.Empty;
string? stubType = null;
if (!isDirectory)
{
- var extension = Path.GetExtension(path);
+ var extension = Path.GetExtension(path.AsSpan());
// Check supported extensions
- if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
+ if (!_options.VideoFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
{
// It's not supported. Check stub extensions
if (!StubResolver.TryResolveFile(path, _options, out stubType))
@@ -86,9 +86,7 @@ namespace Emby.Naming.Video
var extraResult = new ExtraResolver(_options).GetExtraInfo(path);
- var name = isDirectory
- ? Path.GetFileName(path)
- : Path.GetFileNameWithoutExtension(path);
+ var name = Path.GetFileNameWithoutExtension(path);
int? year = null;
@@ -107,7 +105,7 @@ namespace Emby.Naming.Video
return new VideoFileInfo(
path: path,
- container: container,
+ container: container.IsEmpty ? null : container.ToString(),
isStub: isStub,
name: name,
year: year,
@@ -126,8 +124,8 @@ namespace Emby.Naming.Video
/// True if is video file.
public bool IsVideoFile(string path)
{
- var extension = Path.GetExtension(path);
- return _options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
+ var extension = Path.GetExtension(path.AsSpan());
+ return _options.VideoFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase);
}
///
@@ -137,8 +135,8 @@ namespace Emby.Naming.Video
/// True if is video file stub.
public bool IsStubFile(string path)
{
- var extension = Path.GetExtension(path);
- return _options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
+ var extension = Path.GetExtension(path.AsSpan());
+ return _options.StubFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase);
}
///
diff --git a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
index 8c756a7f4c..c331a61124 100644
--- a/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
+++ b/Emby.Server.Implementations/Data/BaseSqliteRepository.cs
@@ -181,11 +181,9 @@ namespace Emby.Server.Implementations.Data
foreach (var row in connection.Query("PRAGMA table_info(" + table + ")"))
{
- if (row[1].SQLiteType != SQLiteType.Null)
+ if (row.TryGetString(1, out var columnName))
{
- var name = row[1].ToString();
-
- columnNames.Add(name);
+ columnNames.Add(columnName);
}
}
diff --git a/Emby.Server.Implementations/Data/SqliteExtensions.cs b/Emby.Server.Implementations/Data/SqliteExtensions.cs
index a04d630887..a8f3feb589 100644
--- a/Emby.Server.Implementations/Data/SqliteExtensions.cs
+++ b/Emby.Server.Implementations/Data/SqliteExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using SQLitePCL.pretty;
@@ -96,21 +97,43 @@ namespace Emby.Server.Implementations.Data
DateTimeStyles.None).ToUniversalTime();
}
- public static DateTime? TryReadDateTime(this IResultSetValue result)
+ public static bool TryReadDateTime(this IReadOnlyList reader, int index, out DateTime result)
{
- var dateText = result.ToString();
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
+ }
+
+ var dateText = item.ToString();
if (DateTime.TryParseExact(dateText, _datetimeFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out var dateTimeResult))
{
- return dateTimeResult.ToUniversalTime();
+ result = dateTimeResult.ToUniversalTime();
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ public static bool TryGetGuid(this IReadOnlyList reader, int index, out Guid result)
+ {
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
}
- return null;
+ result = item.ReadGuidFromBlob();
+ return true;
}
- public static bool IsDBNull(this IReadOnlyList result, int index)
+ public static bool IsDbNull(this IResultSetValue result)
{
- return result[index].SQLiteType == SQLiteType.Null;
+ return result.SQLiteType == SQLiteType.Null;
}
public static string GetString(this IReadOnlyList result, int index)
@@ -118,14 +141,48 @@ namespace Emby.Server.Implementations.Data
return result[index].ToString();
}
+ public static bool TryGetString(this IReadOnlyList reader, int index, out string result)
+ {
+ result = null;
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ return false;
+ }
+
+ result = item.ToString();
+ return true;
+ }
+
public static bool GetBoolean(this IReadOnlyList result, int index)
{
return result[index].ToBool();
}
- public static int GetInt32(this IReadOnlyList result, int index)
+ public static bool TryGetBoolean(this IReadOnlyList reader, int index, out bool result)
+ {
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
+ }
+
+ result = item.ToBool();
+ return true;
+ }
+
+ public static bool TryGetInt32(this IReadOnlyList reader, int index, out int result)
{
- return result[index].ToInt();
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
+ }
+
+ result = item.ToInt();
+ return true;
}
public static long GetInt64(this IReadOnlyList result, int index)
@@ -133,9 +190,43 @@ namespace Emby.Server.Implementations.Data
return result[index].ToInt64();
}
- public static float GetFloat(this IReadOnlyList result, int index)
+ public static bool TryGetInt64(this IReadOnlyList reader, int index, out long result)
+ {
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
+ }
+
+ result = item.ToInt64();
+ return true;
+ }
+
+ public static bool TryGetSingle(this IReadOnlyList reader, int index, out float result)
+ {
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
+ }
+
+ result = item.ToFloat();
+ return true;
+ }
+
+ public static bool TryGetDouble(this IReadOnlyList reader, int index, out double result)
{
- return result[index].ToFloat();
+ var item = reader[index];
+ if (item.IsDbNull())
+ {
+ result = default;
+ return false;
+ }
+
+ result = item.ToDouble();
+ return true;
}
public static Guid GetGuid(this IReadOnlyList result, int index)
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 4ae7a842c6..b3d8860a9e 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -1332,27 +1332,23 @@ namespace Emby.Server.Implementations.Data
if (queryHasStartDate)
{
- if (!reader.IsDBNull(index))
+ if (item is IHasStartDate hasStartDate && reader.TryReadDateTime(index, out var startDate))
{
- if (item is IHasStartDate hasStartDate)
- {
- hasStartDate.StartDate = reader[index].ReadDateTime();
- }
+ hasStartDate.StartDate = startDate;
}
index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryReadDateTime(index++, out var endDate))
{
- item.EndDate = reader[index].TryReadDateTime();
+ item.EndDate = endDate;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ var channelId = reader[index];
+ if (!channelId.IsDbNull())
{
- if (!Utf8Parser.TryParse(reader[index].ToBlob(), out Guid value, out _, standardFormat: 'N'))
+ if (!Utf8Parser.TryParse(channelId.ToBlob(), out Guid value, out _, standardFormat: 'N'))
{
var str = reader.GetString(index);
Logger.LogWarning("{ChannelId} isn't in the expected format", str);
@@ -1368,33 +1364,25 @@ namespace Emby.Server.Implementations.Data
{
if (item is IHasProgramAttributes hasProgramAttributes)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetBoolean(index++, out var isMovie))
{
- hasProgramAttributes.IsMovie = reader.GetBoolean(index);
+ hasProgramAttributes.IsMovie = isMovie;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetBoolean(index++, out var isSeries))
{
- hasProgramAttributes.IsSeries = reader.GetBoolean(index);
+ hasProgramAttributes.IsSeries = isSeries;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var episodeTitle))
{
- hasProgramAttributes.EpisodeTitle = reader.GetString(index);
+ hasProgramAttributes.EpisodeTitle = episodeTitle;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetBoolean(index++, out var isRepeat))
{
- hasProgramAttributes.IsRepeat = reader.GetBoolean(index);
+ hasProgramAttributes.IsRepeat = isRepeat;
}
-
- index++;
}
else
{
@@ -1402,242 +1390,190 @@ namespace Emby.Server.Implementations.Data
}
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetSingle(index++, out var communityRating))
{
- item.CommunityRating = reader.GetFloat(index);
+ item.CommunityRating = communityRating;
}
- index++;
-
if (HasField(query, ItemFields.CustomRating))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var customRating))
{
- item.CustomRating = reader.GetString(index);
+ item.CustomRating = customRating;
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var indexNumber))
{
- item.IndexNumber = reader.GetInt32(index);
+ item.IndexNumber = indexNumber;
}
- index++;
-
if (HasField(query, ItemFields.Settings))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetBoolean(index++, out var isLocked))
{
- item.IsLocked = reader.GetBoolean(index);
+ item.IsLocked = isLocked;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var preferredMetadataLanguage))
{
- item.PreferredMetadataLanguage = reader.GetString(index);
+ item.PreferredMetadataLanguage = preferredMetadataLanguage;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var preferredMetadataCountryCode))
{
- item.PreferredMetadataCountryCode = reader.GetString(index);
+ item.PreferredMetadataCountryCode = preferredMetadataCountryCode;
}
-
- index++;
}
if (HasField(query, ItemFields.Width))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var width))
{
- item.Width = reader.GetInt32(index);
+ item.Width = width;
}
-
- index++;
}
if (HasField(query, ItemFields.Height))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var height))
{
- item.Height = reader.GetInt32(index);
+ item.Height = height;
}
-
- index++;
}
if (HasField(query, ItemFields.DateLastRefreshed))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryReadDateTime(index++, out var dateLastRefreshed))
{
- item.DateLastRefreshed = reader[index].ReadDateTime();
+ item.DateLastRefreshed = dateLastRefreshed;
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var name))
{
- item.Name = reader.GetString(index);
+ item.Name = name;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var restorePath))
{
- item.Path = RestorePath(reader.GetString(index));
+ item.Path = RestorePath(restorePath);
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryReadDateTime(index++, out var premiereDate))
{
- item.PremiereDate = reader[index].TryReadDateTime();
+ item.PremiereDate = premiereDate;
}
- index++;
-
if (HasField(query, ItemFields.Overview))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var overview))
{
- item.Overview = reader.GetString(index);
+ item.Overview = overview;
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var parentIndexNumber))
{
- item.ParentIndexNumber = reader.GetInt32(index);
+ item.ParentIndexNumber = parentIndexNumber;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var productionYear))
{
- item.ProductionYear = reader.GetInt32(index);
+ item.ProductionYear = productionYear;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var officialRating))
{
- item.OfficialRating = reader.GetString(index);
+ item.OfficialRating = officialRating;
}
- index++;
-
if (HasField(query, ItemFields.SortName))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var forcedSortName))
{
- item.ForcedSortName = reader.GetString(index);
+ item.ForcedSortName = forcedSortName;
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt64(index++, out var runTimeTicks))
{
- item.RunTimeTicks = reader.GetInt64(index);
+ item.RunTimeTicks = runTimeTicks;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt64(index++, out var size))
{
- item.Size = reader.GetInt64(index);
+ item.Size = size;
}
- index++;
-
if (HasField(query, ItemFields.DateCreated))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryReadDateTime(index++, out var dateCreated))
{
- item.DateCreated = reader[index].ReadDateTime();
+ item.DateCreated = dateCreated;
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryReadDateTime(index++, out var dateModified))
{
- item.DateModified = reader[index].ReadDateTime();
+ item.DateModified = dateModified;
}
- index++;
-
- item.Id = reader.GetGuid(index);
- index++;
+ item.Id = reader.GetGuid(index++);
if (HasField(query, ItemFields.Genres))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var genres))
{
- item.Genres = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
+ item.Genres = genres.Split('|', StringSplitOptions.RemoveEmptyEntries);
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetGuid(index++, out var parentId))
{
- item.ParentId = reader.GetGuid(index);
+ item.ParentId = parentId;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var audioString))
{
- if (Enum.TryParse(reader.GetString(index), true, out ProgramAudio audio))
+ // TODO Span overload coming in the future https://github.com/dotnet/runtime/issues/1916
+ if (Enum.TryParse(audioString, true, out ProgramAudio audio))
{
item.Audio = audio;
}
}
- index++;
-
// TODO: Even if not needed by apps, the server needs it internally
// But get this excluded from contexts where it is not needed
if (hasServiceName)
{
if (item is LiveTvChannel liveTvChannel)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index, out var serviceName))
{
- liveTvChannel.ServiceName = reader.GetString(index);
+ liveTvChannel.ServiceName = serviceName;
}
}
index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetBoolean(index++, out var isInMixedFolder))
{
- item.IsInMixedFolder = reader.GetBoolean(index);
+ item.IsInMixedFolder = isInMixedFolder;
}
- index++;
-
if (HasField(query, ItemFields.DateLastSaved))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryReadDateTime(index++, out var dateLastSaved))
{
- item.DateLastSaved = reader[index].ReadDateTime();
+ item.DateLastSaved = dateLastSaved;
}
-
- index++;
}
if (HasField(query, ItemFields.Settings))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var lockedFields))
{
IEnumerable GetLockedFields(string s)
{
@@ -1650,37 +1586,31 @@ namespace Emby.Server.Implementations.Data
}
}
- item.LockedFields = GetLockedFields(reader.GetString(index)).ToArray();
+ item.LockedFields = GetLockedFields(lockedFields).ToArray();
}
-
- index++;
}
if (HasField(query, ItemFields.Studios))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var studios))
{
- item.Studios = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
+ item.Studios = studios.Split('|', StringSplitOptions.RemoveEmptyEntries);
}
-
- index++;
}
if (HasField(query, ItemFields.Tags))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var tags))
{
- item.Tags = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
+ item.Tags = tags.Split('|', StringSplitOptions.RemoveEmptyEntries);
}
-
- index++;
}
if (hasTrailerTypes)
{
if (item is Trailer trailer)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index, out var trailerTypes))
{
IEnumerable GetTrailerTypes(string s)
{
@@ -1693,7 +1623,7 @@ namespace Emby.Server.Implementations.Data
}
}
- trailer.TrailerTypes = GetTrailerTypes(reader.GetString(index)).ToArray();
+ trailer.TrailerTypes = GetTrailerTypes(trailerTypes).ToArray();
}
}
@@ -1702,19 +1632,17 @@ namespace Emby.Server.Implementations.Data
if (HasField(query, ItemFields.OriginalTitle))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var originalTitle))
{
- item.OriginalTitle = reader.GetString(index);
+ item.OriginalTitle = originalTitle;
}
-
- index++;
}
if (item is Video video)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index, out var primaryVersionId))
{
- video.PrimaryVersionId = reader.GetString(index);
+ video.PrimaryVersionId = primaryVersionId;
}
}
@@ -1722,40 +1650,34 @@ namespace Emby.Server.Implementations.Data
if (HasField(query, ItemFields.DateLastMediaAdded))
{
- if (item is Folder folder && !reader.IsDBNull(index))
+ if (item is Folder folder && reader.TryReadDateTime(index, out var dateLastMediaAdded))
{
- folder.DateLastMediaAdded = reader[index].TryReadDateTime();
+ folder.DateLastMediaAdded = dateLastMediaAdded;
}
index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var album))
{
- item.Album = reader.GetString(index);
+ item.Album = album;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetSingle(index++, out var criticRating))
{
- item.CriticRating = reader.GetFloat(index);
+ item.CriticRating = criticRating;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetBoolean(index++, out var isVirtualItem))
{
- item.IsVirtualItem = reader.GetBoolean(index);
+ item.IsVirtualItem = isVirtualItem;
}
- index++;
-
if (item is IHasSeries hasSeriesName)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index, out var seriesName))
{
- hasSeriesName.SeriesName = reader.GetString(index);
+ hasSeriesName.SeriesName = seriesName;
}
}
@@ -1765,15 +1687,15 @@ namespace Emby.Server.Implementations.Data
{
if (item is Episode episode)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index, out var seasonName))
{
- episode.SeasonName = reader.GetString(index);
+ episode.SeasonName = seasonName;
}
index++;
- if (!reader.IsDBNull(index))
+ if (reader.TryGetGuid(index, out var seasonId))
{
- episode.SeasonId = reader.GetGuid(index);
+ episode.SeasonId = seasonId;
}
}
else
@@ -1789,9 +1711,9 @@ namespace Emby.Server.Implementations.Data
{
if (hasSeries != null)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetGuid(index, out var seriesId))
{
- hasSeries.SeriesId = reader.GetGuid(index);
+ hasSeries.SeriesId = seriesId;
}
}
@@ -1800,56 +1722,48 @@ namespace Emby.Server.Implementations.Data
if (HasField(query, ItemFields.PresentationUniqueKey))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var presentationUniqueKey))
{
- item.PresentationUniqueKey = reader.GetString(index);
+ item.PresentationUniqueKey = presentationUniqueKey;
}
-
- index++;
}
if (HasField(query, ItemFields.InheritedParentalRatingValue))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var parentalRating))
{
- item.InheritedParentalRatingValue = reader.GetInt32(index);
+ item.InheritedParentalRatingValue = parentalRating;
}
-
- index++;
}
if (HasField(query, ItemFields.ExternalSeriesId))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var externalSeriesId))
{
- item.ExternalSeriesId = reader.GetString(index);
+ item.ExternalSeriesId = externalSeriesId;
}
-
- index++;
}
if (HasField(query, ItemFields.Taglines))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var tagLine))
{
- item.Tagline = reader.GetString(index);
+ item.Tagline = tagLine;
}
-
- index++;
}
- if (item.ProviderIds.Count == 0 && !reader.IsDBNull(index))
+ if (item.ProviderIds.Count == 0 && reader.TryGetString(index, out var providerIds))
{
- DeserializeProviderIds(reader.GetString(index), item);
+ DeserializeProviderIds(providerIds, item);
}
index++;
if (query.DtoOptions.EnableImages)
{
- if (item.ImageInfos.Length == 0 && !reader.IsDBNull(index))
+ if (item.ImageInfos.Length == 0 && reader.TryGetString(index, out var imageInfos))
{
- item.ImageInfos = DeserializeImages(reader.GetString(index));
+ item.ImageInfos = DeserializeImages(imageInfos);
}
index++;
@@ -1857,72 +1771,62 @@ namespace Emby.Server.Implementations.Data
if (HasField(query, ItemFields.ProductionLocations))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var productionLocations))
{
- item.ProductionLocations = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries).ToArray();
+ item.ProductionLocations = productionLocations.Split('|', StringSplitOptions.RemoveEmptyEntries);
}
-
- index++;
}
if (HasField(query, ItemFields.ExtraIds))
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var extraIds))
{
- item.ExtraIds = SplitToGuids(reader.GetString(index));
+ item.ExtraIds = SplitToGuids(extraIds);
}
-
- index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetInt32(index++, out var totalBitrate))
{
- item.TotalBitrate = reader.GetInt32(index);
+ item.TotalBitrate = totalBitrate;
}
- index++;
-
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var extraTypeString))
{
- if (Enum.TryParse(reader.GetString(index), true, out ExtraType extraType))
+ if (Enum.TryParse(extraTypeString, true, out ExtraType extraType))
{
item.ExtraType = extraType;
}
}
- index++;
-
if (hasArtistFields)
{
- if (item is IHasArtist hasArtists && !reader.IsDBNull(index))
+ if (item is IHasArtist hasArtists && reader.TryGetString(index, out var artists))
{
- hasArtists.Artists = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
+ hasArtists.Artists = artists.Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
- if (item is IHasAlbumArtist hasAlbumArtists && !reader.IsDBNull(index))
+ if (item is IHasAlbumArtist hasAlbumArtists && reader.TryGetString(index, out var albumArtists))
{
- hasAlbumArtists.AlbumArtists = reader.GetString(index).Split('|', StringSplitOptions.RemoveEmptyEntries);
+ hasAlbumArtists.AlbumArtists = albumArtists.Split('|', StringSplitOptions.RemoveEmptyEntries);
}
index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index++, out var externalId))
{
- item.ExternalId = reader.GetString(index);
+ item.ExternalId = externalId;
}
- index++;
-
if (HasField(query, ItemFields.SeriesPresentationUniqueKey))
{
if (hasSeries != null)
{
- if (!reader.IsDBNull(index))
+ if (reader.TryGetString(index, out var seriesPresentationUniqueKey))
{
- hasSeries.SeriesPresentationUniqueKey = reader.GetString(index);
+ hasSeries.SeriesPresentationUniqueKey = seriesPresentationUniqueKey;
}
}
@@ -1931,21 +1835,19 @@ namespace Emby.Server.Implementations.Data
if (enableProgramAttributes)
{
- if (item is LiveTvProgram program && !reader.IsDBNull(index))
+ if (item is LiveTvProgram program && reader.TryGetString(index, out var showId))
{
- program.ShowId = reader.GetString(index);
+ program.ShowId = showId;
}
index++;
}
- if (!reader.IsDBNull(index))
+ if (reader.TryGetGuid(index, out var ownerId))
{
- item.OwnerId = reader.GetGuid(index);
+ item.OwnerId = ownerId;
}
- index++;
-
return item;
}
@@ -2032,14 +1934,14 @@ namespace Emby.Server.Implementations.Data
StartPositionTicks = reader.GetInt64(0)
};
- if (!reader.IsDBNull(1))
+ if (reader.TryGetString(1, out var chapterName))
{
- chapter.Name = reader.GetString(1);
+ chapter.Name = chapterName;
}
- if (!reader.IsDBNull(2))
+ if (reader.TryGetString(2, out var imagePath))
{
- chapter.ImagePath = reader.GetString(2);
+ chapter.ImagePath = imagePath;
if (!string.IsNullOrEmpty(chapter.ImagePath))
{
@@ -2054,9 +1956,9 @@ namespace Emby.Server.Implementations.Data
}
}
- if (!reader.IsDBNull(3))
+ if (reader.TryReadDateTime(3, out var imageDateModified))
{
- chapter.ImageDateModified = reader[3].ReadDateTime();
+ chapter.ImageDateModified = imageDateModified;
}
return chapter;
@@ -3228,12 +3130,8 @@ namespace Emby.Server.Implementations.Data
foreach (var row in statement.ExecuteQuery())
{
var id = row.GetGuid(0);
- string path = null;
- if (!row.IsDBNull(1))
- {
- path = row.GetString(1);
- }
+ row.TryGetString(1, out var path);
list.Add(new Tuple(id, path));
}
@@ -5327,9 +5225,9 @@ AND Type = @InternalPersonType)");
{
foreach (var row in statement.ExecuteQuery())
{
- if (!row.IsDBNull(0))
+ if (row.TryGetString(0, out var result))
{
- list.Add(row.GetString(0));
+ list.Add(result);
}
}
}
@@ -5603,7 +5501,7 @@ AND Type = @InternalPersonType)");
return result;
}
- private ItemCounts GetItemCounts(IReadOnlyList reader, int countStartColumn, string[] typesToCount)
+ private static ItemCounts GetItemCounts(IReadOnlyList reader, int countStartColumn, string[] typesToCount)
{
var counts = new ItemCounts();
@@ -5612,51 +5510,43 @@ AND Type = @InternalPersonType)");
return counts;
}
- var typeString = reader.IsDBNull(countStartColumn) ? null : reader.GetString(countStartColumn);
-
- if (string.IsNullOrWhiteSpace(typeString))
+ if (!reader.TryGetString(countStartColumn, out var typeString))
{
return counts;
}
- var allTypes = typeString.Split('|', StringSplitOptions.RemoveEmptyEntries)
- .ToLookup(x => x);
-
- foreach (var type in allTypes)
+ foreach (var typeName in typeString.AsSpan().Split('|'))
{
- var value = type.Count();
- var typeName = type.Key;
-
- if (string.Equals(typeName, typeof(Series).FullName, StringComparison.OrdinalIgnoreCase))
+ if (typeName.Equals(typeof(Series).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.SeriesCount = value;
+ counts.SeriesCount++;
}
- else if (string.Equals(typeName, typeof(Episode).FullName, StringComparison.OrdinalIgnoreCase))
+ else if (typeName.Equals(typeof(Episode).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.EpisodeCount = value;
+ counts.EpisodeCount++;
}
- else if (string.Equals(typeName, typeof(Movie).FullName, StringComparison.OrdinalIgnoreCase))
+ else if (typeName.Equals(typeof(Movie).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.MovieCount = value;
+ counts.MovieCount++;
}
- else if (string.Equals(typeName, typeof(MusicAlbum).FullName, StringComparison.OrdinalIgnoreCase))
+ else if (typeName.Equals(typeof(MusicAlbum).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.AlbumCount = value;
+ counts.AlbumCount++;
}
- else if (string.Equals(typeName, typeof(MusicArtist).FullName, StringComparison.OrdinalIgnoreCase))
+ else if (typeName.Equals(typeof(MusicArtist).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.ArtistCount = value;
+ counts.ArtistCount++;
}
- else if (string.Equals(typeName, typeof(Audio).FullName, StringComparison.OrdinalIgnoreCase))
+ else if (typeName.Equals(typeof(Audio).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.SongCount = value;
+ counts.SongCount++;
}
- else if (string.Equals(typeName, typeof(Trailer).FullName, StringComparison.OrdinalIgnoreCase))
+ else if (typeName.Equals(typeof(Trailer).FullName, StringComparison.OrdinalIgnoreCase))
{
- counts.TrailerCount = value;
+ counts.TrailerCount++;
}
- counts.ItemCount += value;
+ counts.ItemCount++;
}
return counts;
@@ -5850,19 +5740,19 @@ AND Type = @InternalPersonType)");
Name = reader.GetString(1)
};
- if (!reader.IsDBNull(2))
+ if (reader.TryGetString(2, out var role))
{
- item.Role = reader.GetString(2);
+ item.Role = role;
}
- if (!reader.IsDBNull(3))
+ if (reader.TryGetString(3, out var type))
{
- item.Type = reader.GetString(3);
+ item.Type = type;
}
- if (!reader.IsDBNull(4))
+ if (reader.TryGetInt32(4, out var sortOrder))
{
- item.SortOrder = reader.GetInt32(4);
+ item.SortOrder = sortOrder;
}
return item;
@@ -6058,150 +5948,150 @@ AND Type = @InternalPersonType)");
item.Type = Enum.Parse(reader[2].ToString(), true);
- if (reader[3].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(3, out var codec))
{
- item.Codec = reader[3].ToString();
+ item.Codec = codec;
}
- if (reader[4].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(4, out var language))
{
- item.Language = reader[4].ToString();
+ item.Language = language;
}
- if (reader[5].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(5, out var channelLayout))
{
- item.ChannelLayout = reader[5].ToString();
+ item.ChannelLayout = channelLayout;
}
- if (reader[6].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(6, out var profile))
{
- item.Profile = reader[6].ToString();
+ item.Profile = profile;
}
- if (reader[7].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(7, out var aspectRatio))
{
- item.AspectRatio = reader[7].ToString();
+ item.AspectRatio = aspectRatio;
}
- if (reader[8].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(8, out var path))
{
- item.Path = RestorePath(reader[8].ToString());
+ item.Path = RestorePath(path);
}
item.IsInterlaced = reader.GetBoolean(9);
- if (reader[10].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(10, out var bitrate))
{
- item.BitRate = reader.GetInt32(10);
+ item.BitRate = bitrate;
}
- if (reader[11].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(11, out var channels))
{
- item.Channels = reader.GetInt32(11);
+ item.Channels = channels;
}
- if (reader[12].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(12, out var sampleRate))
{
- item.SampleRate = reader.GetInt32(12);
+ item.SampleRate = sampleRate;
}
item.IsDefault = reader.GetBoolean(13);
item.IsForced = reader.GetBoolean(14);
item.IsExternal = reader.GetBoolean(15);
- if (reader[16].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(16, out var width))
{
- item.Width = reader.GetInt32(16);
+ item.Width = width;
}
- if (reader[17].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(17, out var height))
{
- item.Height = reader.GetInt32(17);
+ item.Height = height;
}
- if (reader[18].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetSingle(18, out var averageFrameRate))
{
- item.AverageFrameRate = reader.GetFloat(18);
+ item.AverageFrameRate = averageFrameRate;
}
- if (reader[19].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetSingle(19, out var realFrameRate))
{
- item.RealFrameRate = reader.GetFloat(19);
+ item.RealFrameRate = realFrameRate;
}
- if (reader[20].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetSingle(20, out var level))
{
- item.Level = reader.GetFloat(20);
+ item.Level = level;
}
- if (reader[21].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(21, out var pixelFormat))
{
- item.PixelFormat = reader[21].ToString();
+ item.PixelFormat = pixelFormat;
}
- if (reader[22].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(22, out var bitDepth))
{
- item.BitDepth = reader.GetInt32(22);
+ item.BitDepth = bitDepth;
}
- if (reader[23].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetBoolean(23, out var isAnamorphic))
{
- item.IsAnamorphic = reader.GetBoolean(23);
+ item.IsAnamorphic = isAnamorphic;
}
- if (reader[24].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(24, out var refFrames))
{
- item.RefFrames = reader.GetInt32(24);
+ item.RefFrames = refFrames;
}
- if (reader[25].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(25, out var codecTag))
{
- item.CodecTag = reader.GetString(25);
+ item.CodecTag = codecTag;
}
- if (reader[26].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(26, out var comment))
{
- item.Comment = reader.GetString(26);
+ item.Comment = comment;
}
- if (reader[27].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(27, out var nalLengthSize))
{
- item.NalLengthSize = reader.GetString(27);
+ item.NalLengthSize = nalLengthSize;
}
- if (reader[28].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetBoolean(28, out var isAVC))
{
- item.IsAVC = reader[28].ToBool();
+ item.IsAVC = isAVC;
}
- if (reader[29].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(29, out var title))
{
- item.Title = reader[29].ToString();
+ item.Title = title;
}
- if (reader[30].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(30, out var timeBase))
{
- item.TimeBase = reader[30].ToString();
+ item.TimeBase = timeBase;
}
- if (reader[31].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(31, out var codecTimeBase))
{
- item.CodecTimeBase = reader[31].ToString();
+ item.CodecTimeBase = codecTimeBase;
}
- if (reader[32].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(32, out var colorPrimaries))
{
- item.ColorPrimaries = reader[32].ToString();
+ item.ColorPrimaries = colorPrimaries;
}
- if (reader[33].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(33, out var colorSpace))
{
- item.ColorSpace = reader[33].ToString();
+ item.ColorSpace = colorSpace;
}
- if (reader[34].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(34, out var colorTransfer))
{
- item.ColorTransfer = reader[34].ToString();
+ item.ColorTransfer = colorTransfer;
}
if (item.Type == MediaStreamType.Subtitle)
@@ -6357,29 +6247,29 @@ AND Type = @InternalPersonType)");
Index = reader[1].ToInt()
};
- if (reader[2].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(2, out var codec))
{
- item.Codec = reader[2].ToString();
+ item.Codec = codec;
}
- if (reader[2].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(3, out var codecTag))
{
- item.CodecTag = reader[3].ToString();
+ item.CodecTag = codecTag;
}
- if (reader[4].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(4, out var comment))
{
- item.Comment = reader[4].ToString();
+ item.Comment = comment;
}
- if (reader[6].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(5, out var fileName))
{
- item.FileName = reader[5].ToString();
+ item.FileName = fileName;
}
- if (reader[6].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(6, out var mimeType))
{
- item.MimeType = reader[6].ToString();
+ item.MimeType = mimeType;
}
return item;
diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
index 6574db6078..e0ebd0a6cf 100644
--- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
@@ -355,9 +355,9 @@ namespace Emby.Server.Implementations.Data
userData.Key = reader[0].ToString();
// userData.UserId = reader[1].ReadGuidFromBlob();
- if (reader[2].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetDouble(2, out var rating))
{
- userData.Rating = reader[2].ToDouble();
+ userData.Rating = rating;
}
userData.Played = reader[3].ToBool();
@@ -365,19 +365,19 @@ namespace Emby.Server.Implementations.Data
userData.IsFavorite = reader[5].ToBool();
userData.PlaybackPositionTicks = reader[6].ToInt64();
- if (reader[7].SQLiteType != SQLiteType.Null)
+ if (reader.TryReadDateTime(7, out var lastPlayedDate))
{
- userData.LastPlayedDate = reader[7].TryReadDateTime();
+ userData.LastPlayedDate = lastPlayedDate;
}
- if (reader[8].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(8, out var audioStreamIndex))
{
- userData.AudioStreamIndex = reader[8].ToInt();
+ userData.AudioStreamIndex = audioStreamIndex;
}
- if (reader[9].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetInt32(9, out var subtitleStreamIndex))
{
- userData.SubtitleStreamIndex = reader[9].ToInt();
+ userData.SubtitleStreamIndex = subtitleStreamIndex;
}
return userData;
diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
index 024404ceb0..fbf9254d16 100644
--- a/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
+++ b/Emby.Server.Implementations/HttpServer/Security/AuthorizationContext.cs
@@ -2,8 +2,8 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Net;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
@@ -215,7 +215,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
auth = httpReq.Request.Headers[HeaderNames.Authorization];
}
- return GetAuthorization(auth);
+ return GetAuthorization(auth.Count > 0 ? auth[0] : null);
}
///
@@ -232,7 +232,7 @@ namespace Emby.Server.Implementations.HttpServer.Security
auth = httpReq.Headers[HeaderNames.Authorization];
}
- return GetAuthorization(auth);
+ return GetAuthorization(auth.Count > 0 ? auth[0] : null);
}
///
@@ -240,43 +240,43 @@ namespace Emby.Server.Implementations.HttpServer.Security
///
/// The authorization header.
/// Dictionary{System.StringSystem.String}.
- private Dictionary GetAuthorization(string authorizationHeader)
+ private Dictionary GetAuthorization(ReadOnlySpan authorizationHeader)
{
if (authorizationHeader == null)
{
return null;
}
- var parts = authorizationHeader.Split(' ', 2);
+ var firstSpace = authorizationHeader.IndexOf(' ');
- // There should be at least to parts
- if (parts.Length != 2)
+ // There should be at least two parts
+ if (firstSpace == -1)
{
return null;
}
- var acceptedNames = new[] { "MediaBrowser", "Emby" };
+ var name = authorizationHeader[..firstSpace];
- // It has to be a digest request
- if (!acceptedNames.Contains(parts[0], StringComparer.OrdinalIgnoreCase))
+ if (!name.Equals("MediaBrowser", StringComparison.OrdinalIgnoreCase)
+ && !name.Equals("Emby", StringComparison.OrdinalIgnoreCase))
{
return null;
}
- // Remove uptil the first space
- authorizationHeader = parts[1];
- parts = authorizationHeader.Split(',');
+ authorizationHeader = authorizationHeader[(firstSpace + 1)..];
var result = new Dictionary(StringComparer.OrdinalIgnoreCase);
- foreach (var item in parts)
+ foreach (var item in authorizationHeader.Split(','))
{
- var param = item.Trim().Split('=', 2);
+ var trimmedItem = item.Trim();
+ var firstEqualsSign = trimmedItem.IndexOf('=');
- if (param.Length == 2)
+ if (firstEqualsSign > 0)
{
- var value = NormalizeValue(param[1].Trim('"'));
- result[param[0]] = value;
+ var key = trimmedItem[..firstEqualsSign].ToString();
+ var value = NormalizeValue(trimmedItem[(firstEqualsSign + 1)..].Trim('"').ToString());
+ result[key] = value;
}
}
diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index 6e688693be..16050185fb 100644
--- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -165,13 +165,13 @@ namespace Emby.Server.Implementations.Library.Resolvers
protected void SetVideoType(Video video, VideoFileInfo videoInfo)
{
- var extension = Path.GetExtension(video.Path);
- video.VideoType = string.Equals(extension, ".iso", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(extension, ".img", StringComparison.OrdinalIgnoreCase) ?
- VideoType.Iso :
- VideoType.VideoFile;
+ var extension = Path.GetExtension(video.Path.AsSpan());
+ video.VideoType = extension.Equals(".iso", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".img", StringComparison.OrdinalIgnoreCase)
+ ? VideoType.Iso
+ : VideoType.VideoFile;
- video.IsShortcut = string.Equals(extension, ".strm", StringComparison.OrdinalIgnoreCase);
+ video.IsShortcut = extension.Equals(".strm", StringComparison.OrdinalIgnoreCase);
video.IsPlaceHolder = videoInfo.IsStub;
if (videoInfo.IsStub)
@@ -193,11 +193,11 @@ namespace Emby.Server.Implementations.Library.Resolvers
{
if (video.VideoType == VideoType.Iso)
{
- if (video.Path.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1)
+ if (video.Path.Contains("dvd", StringComparison.OrdinalIgnoreCase))
{
video.IsoType = IsoType.Dvd;
}
- else if (video.Path.IndexOf("bluray", StringComparison.OrdinalIgnoreCase) != -1)
+ else if (video.Path.Contains("bluray", StringComparison.OrdinalIgnoreCase))
{
video.IsoType = IsoType.BluRay;
}
diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs
index 4bc12f44a4..76f863c951 100644
--- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs
+++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs
@@ -297,50 +297,49 @@ namespace Emby.Server.Implementations.Security
AccessToken = reader[1].ToString()
};
- if (reader[2].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(2, out var deviceId))
{
- info.DeviceId = reader[2].ToString();
+ info.DeviceId = deviceId;
}
- if (reader[3].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(3, out var appName))
{
- info.AppName = reader[3].ToString();
+ info.AppName = appName;
}
- if (reader[4].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(4, out var appVersion))
{
- info.AppVersion = reader[4].ToString();
+ info.AppVersion = appVersion;
}
- if (reader[5].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(6, out var userId))
{
- info.DeviceName = reader[5].ToString();
+ info.UserId = new Guid(userId);
}
- if (reader[6].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(7, out var userName))
{
- info.UserId = new Guid(reader[6].ToString());
- }
-
- if (reader[7].SQLiteType != SQLiteType.Null)
- {
- info.UserName = reader[7].ToString();
+ info.UserName = userName;
}
info.DateCreated = reader[8].ReadDateTime();
- if (reader[9].SQLiteType != SQLiteType.Null)
+ if (reader.TryReadDateTime(9, out var dateLastActivity))
{
- info.DateLastActivity = reader[9].ReadDateTime();
+ info.DateLastActivity = dateLastActivity;
}
else
{
info.DateLastActivity = info.DateCreated;
}
- if (reader[10].SQLiteType != SQLiteType.Null)
+ if (reader.TryGetString(10, out var customName))
+ {
+ info.DeviceName = customName;
+ }
+ else if (reader.TryGetString(5, out var deviceName))
{
- info.DeviceName = reader[10].ToString();
+ info.DeviceName = deviceName;
}
return info;
@@ -361,9 +360,9 @@ namespace Emby.Server.Implementations.Security
foreach (var row in statement.ExecuteQuery())
{
- if (row[0].SQLiteType != SQLiteType.Null)
+ if (row.TryGetString(0, out var customName))
{
- result.CustomName = row[0].ToString();
+ result.CustomName = customName;
}
}
diff --git a/Jellyfin.sln b/Jellyfin.sln
index 8626a4b1ba..9fbd9d266e 100644
--- a/Jellyfin.sln
+++ b/Jellyfin.sln
@@ -81,6 +81,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Tests", "te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Integration.Tests", "tests\Jellyfin.Server.Integration.Tests\Jellyfin.Server.Integration.Tests.csproj", "{68B0B823-A5AC-4E8B-82EA-965AAC7BF76E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Providers.Tests", "tests\Jellyfin.Providers.Tests\Jellyfin.Providers.Tests.csproj", "{A964008C-2136-4716-B6CB-B3426C22320A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -223,6 +225,10 @@ Global
{68B0B823-A5AC-4E8B-82EA-965AAC7BF76E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68B0B823-A5AC-4E8B-82EA-965AAC7BF76E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68B0B823-A5AC-4E8B-82EA-965AAC7BF76E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A964008C-2136-4716-B6CB-B3426C22320A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A964008C-2136-4716-B6CB-B3426C22320A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A964008C-2136-4716-B6CB-B3426C22320A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A964008C-2136-4716-B6CB-B3426C22320A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -240,6 +246,7 @@ Global
{42816EA8-4511-4CBF-A9C7-7791D5DDDAE6} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
{3ADBCD8C-C0F2-4956-8FDC-35D686B74CF9} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
{68B0B823-A5AC-4E8B-82EA-965AAC7BF76E} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
+ {A964008C-2136-4716-B6CB-B3426C22320A} = {FBBB5129-006E-4AD7-BAD5-8B7CA1D10ED6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3448830C-EBDC-426C-85CD-7BBB9651A7FE}
diff --git a/MediaBrowser.Common/Extensions/EnumerableExtensions.cs b/MediaBrowser.Common/Extensions/EnumerableExtensions.cs
new file mode 100644
index 0000000000..2b8a6c395b
--- /dev/null
+++ b/MediaBrowser.Common/Extensions/EnumerableExtensions.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Common.Extensions
+{
+ ///
+ /// Static extensions for the interface.
+ ///
+ public static class EnumerableExtensions
+ {
+ ///
+ /// Determines whether the value is contained in the source collection.
+ ///
+ /// An instance of the interface.
+ /// The value to look for in the collection.
+ /// The string comparison.
+ /// A value indicating whether the value is contained in the collection.
+ /// The source is null.
+ public static bool Contains(this IEnumerable source, ReadOnlySpan value, StringComparison stringComparison)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ if (source is IList list)
+ {
+ int len = list.Count;
+ for (int i = 0; i < len; i++)
+ {
+ if (value.Equals(list[i], stringComparison))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ foreach (string element in source)
+ {
+ if (value.Equals(element, stringComparison))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
index 7ad8c24e89..31475e22f4 100644
--- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
+++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
@@ -466,7 +466,7 @@ namespace MediaBrowser.LocalMetadata.Images
return added;
}
- private bool AddImage(IEnumerable files, List images, string name, ImageType type)
+ private bool AddImage(List files, List images, string name, ImageType type)
{
var image = GetImage(files, name);
@@ -484,9 +484,20 @@ namespace MediaBrowser.LocalMetadata.Images
return false;
}
- private FileSystemMetadata? GetImage(IEnumerable files, string name)
+ private static FileSystemMetadata? GetImage(IReadOnlyList files, string name)
{
- return files.FirstOrDefault(i => !i.IsDirectory && string.Equals(name, _fileSystem.GetFileNameWithoutExtension(i), StringComparison.OrdinalIgnoreCase) && i.Length > 0);
+ for (var i = 0; i < files.Count; i++)
+ {
+ var file = files[i];
+ if (!file.IsDirectory
+ && file.Length > 0
+ && Path.GetFileNameWithoutExtension(file.FullName.AsSpan()).Equals(name, StringComparison.OrdinalIgnoreCase))
+ {
+ return file;
+ }
+ }
+
+ return null;
}
}
}
diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
index e9f999c6d0..b086ef07bb 100644
--- a/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
+++ b/MediaBrowser.Providers/MediaInfo/SubtitleResolver.cs
@@ -15,17 +15,6 @@ namespace MediaBrowser.Providers.MediaInfo
{
private readonly ILocalizationManager _localization;
- private static readonly HashSet SubtitleExtensions = new HashSet(StringComparer.OrdinalIgnoreCase)
- {
- ".srt",
- ".ssa",
- ".ass",
- ".sub",
- ".smi",
- ".sami",
- ".vtt"
- };
-
public SubtitleResolver(ILocalizationManager localization)
{
_localization = localization;
@@ -88,80 +77,65 @@ namespace MediaBrowser.Providers.MediaInfo
return list;
}
- private void AddExternalSubtitleStreams(
- List streams,
- string folder,
- string videoPath,
- int startIndex,
- IDirectoryService directoryService,
- bool clearCache)
- {
- var files = directoryService.GetFilePaths(folder, clearCache).OrderBy(i => i).ToArray();
-
- AddExternalSubtitleStreams(streams, videoPath, startIndex, files);
- }
-
public void AddExternalSubtitleStreams(
List streams,
string videoPath,
int startIndex,
string[] files)
{
- var videoFileNameWithoutExtension = Path.GetFileNameWithoutExtension(videoPath);
- videoFileNameWithoutExtension = NormalizeFilenameForSubtitleComparison(videoFileNameWithoutExtension);
+ var videoFileNameWithoutExtension = NormalizeFilenameForSubtitleComparison(videoPath);
foreach (var fullName in files)
{
- var extension = Path.GetExtension(fullName);
-
- if (!SubtitleExtensions.Contains(extension))
+ var extension = Path.GetExtension(fullName.AsSpan());
+ if (!IsSubtitleExtension(extension))
{
continue;
}
- var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fullName);
- fileNameWithoutExtension = NormalizeFilenameForSubtitleComparison(fileNameWithoutExtension);
+ var fileNameWithoutExtension = NormalizeFilenameForSubtitleComparison(fullName);
- if (!string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase) &&
- !fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
- {
- continue;
- }
-
- var codec = Path.GetExtension(fullName).ToLowerInvariant().TrimStart('.');
-
- if (string.Equals(codec, "txt", StringComparison.OrdinalIgnoreCase))
- {
- codec = "srt";
- }
+ MediaStream mediaStream;
- // If the subtitle file matches the video file name
- if (string.Equals(videoFileNameWithoutExtension, fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
+ // The subtitle filename must either be equal to the video filename or start with the video filename followed by a dot
+ if (videoFileNameWithoutExtension.Equals(fileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
{
- streams.Add(new MediaStream
+ mediaStream = new MediaStream
{
Index = startIndex++,
Type = MediaStreamType.Subtitle,
IsExternal = true,
- Path = fullName,
- Codec = codec
- });
+ Path = fullName
+ };
}
- else if (fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension + ".", StringComparison.OrdinalIgnoreCase))
+ else if (fileNameWithoutExtension.Length > videoFileNameWithoutExtension.Length
+ && fileNameWithoutExtension[videoFileNameWithoutExtension.Length] == '.'
+ && fileNameWithoutExtension.StartsWith(videoFileNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
{
- var isForced = fullName.IndexOf(".forced.", StringComparison.OrdinalIgnoreCase) != -1 ||
- fullName.IndexOf(".foreign.", StringComparison.OrdinalIgnoreCase) != -1;
+ var isForced = fullName.Contains(".forced.", StringComparison.OrdinalIgnoreCase)
+ || fullName.Contains(".foreign.", StringComparison.OrdinalIgnoreCase);
- var isDefault = fullName.IndexOf(".default.", StringComparison.OrdinalIgnoreCase) != -1;
+ var isDefault = fullName.Contains(".default.", StringComparison.OrdinalIgnoreCase);
// Support xbmc naming conventions - 300.spanish.srt
- var language = fileNameWithoutExtension
- .Replace(".forced", string.Empty, StringComparison.OrdinalIgnoreCase)
- .Replace(".foreign", string.Empty, StringComparison.OrdinalIgnoreCase)
- .Replace(".default", string.Empty, StringComparison.OrdinalIgnoreCase)
- .Split('.')
- .LastOrDefault();
+ var languageSpan = fileNameWithoutExtension;
+ while (languageSpan.Length > 0)
+ {
+ var lastDot = languageSpan.LastIndexOf('.');
+ var currentSlice = languageSpan[lastDot..];
+ if (currentSlice.Equals(".default", StringComparison.OrdinalIgnoreCase)
+ || currentSlice.Equals(".forced", StringComparison.OrdinalIgnoreCase)
+ || currentSlice.Equals(".foreign", StringComparison.OrdinalIgnoreCase))
+ {
+ languageSpan = languageSpan[..lastDot];
+ continue;
+ }
+
+ languageSpan = languageSpan[(lastDot + 1)..];
+ break;
+ }
+ var language = languageSpan.ToString();
// Try to translate to three character code
// Be flexible and check against both the full and three character versions
var culture = _localization.FindLanguageInfo(language);
@@ -171,33 +145,58 @@ namespace MediaBrowser.Providers.MediaInfo
language = culture.ThreeLetterISOLanguageName;
}
- streams.Add(new MediaStream
+ mediaStream = new MediaStream
{
Index = startIndex++,
Type = MediaStreamType.Subtitle,
IsExternal = true,
Path = fullName,
- Codec = codec,
Language = language,
IsForced = isForced,
IsDefault = isDefault
- });
+ };
+ }
+ else
+ {
+ continue;
}
+
+ mediaStream.Codec = extension.TrimStart('.').ToString().ToLowerInvariant();
+
+ streams.Add(mediaStream);
}
}
- private string NormalizeFilenameForSubtitleComparison(string filename)
+ private static bool IsSubtitleExtension(ReadOnlySpan extension)
+ {
+ return extension.Equals(".srt", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".ssa", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".ass", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".sub", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".vtt", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".smi", StringComparison.OrdinalIgnoreCase)
+ || extension.Equals(".sami", StringComparison.OrdinalIgnoreCase);
+ }
+
+ private static ReadOnlySpan NormalizeFilenameForSubtitleComparison(string filename)
{
// Try to account for sloppy file naming
filename = filename.Replace("_", string.Empty, StringComparison.Ordinal);
filename = filename.Replace(" ", string.Empty, StringComparison.Ordinal);
+ return Path.GetFileNameWithoutExtension(filename.AsSpan());
+ }
- // can't normalize this due to languages such as pt-br
- // filename = filename.Replace("-", string.Empty);
-
- // filename = filename.Replace(".", string.Empty);
+ private void AddExternalSubtitleStreams(
+ List streams,
+ string folder,
+ string videoPath,
+ int startIndex,
+ IDirectoryService directoryService,
+ bool clearCache)
+ {
+ var files = directoryService.GetFilePaths(folder, clearCache).OrderBy(i => i).ToArray();
- return filename;
+ AddExternalSubtitleStreams(streams, videoPath, startIndex, files);
}
}
}
diff --git a/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs b/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs
index 9bbbe29709..c56046f039 100644
--- a/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs
+++ b/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs
@@ -148,7 +148,7 @@ namespace Jellyfin.Naming.Tests.Video
yield return new object[]
{
new VideoFileInfo(
- path: @"/server/Movies/Rain Man 1988 REMASTERED 1080p BluRay x264 AAC - Ozlem/Rain Man 1988 REMASTERED 1080p BluRay x264 AAC - Ozlem.mp4",
+ path: @"/server/Movies/Rain Man 1988 REMASTERED 1080p BluRay x264 AAC - JEFF/Rain Man 1988 REMASTERED 1080p BluRay x264 AAC - JEFF.mp4",
container: "mp4",
name: "Rain Man",
year: 1988)
@@ -200,6 +200,10 @@ namespace Jellyfin.Naming.Tests.Video
Assert.NotNull(results[0]);
Assert.NotNull(results[1]);
Assert.Null(results[2]);
+ foreach (var result in results)
+ {
+ Assert.Null(result?.Container);
+ }
}
}
}
diff --git a/tests/Jellyfin.Providers.Tests/Jellyfin.Providers.Tests.csproj b/tests/Jellyfin.Providers.Tests/Jellyfin.Providers.Tests.csproj
new file mode 100644
index 0000000000..670289f376
--- /dev/null
+++ b/tests/Jellyfin.Providers.Tests/Jellyfin.Providers.Tests.csproj
@@ -0,0 +1,37 @@
+
+
+
+ net5.0
+ false
+ true
+ enable
+ AllEnabledByDefault
+ ../jellyfin-tests.ruleset
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs b/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs
new file mode 100644
index 0000000000..b160e676e4
--- /dev/null
+++ b/tests/Jellyfin.Providers.Tests/MediaInfo/SubtitleResolverTests.cs
@@ -0,0 +1,96 @@
+#pragma warning disable CA1002 // Do not expose generic lists
+
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Providers.MediaInfo;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Providers.Tests.MediaInfo
+{
+ public class SubtitleResolverTests
+ {
+ public static IEnumerable