Reduce string allocations

Some simple changes to reduce the number of allocated strings
pull/10348/head
Bond_009 8 months ago
parent 40f7eb4e8c
commit b176beb88e

@ -228,7 +228,7 @@ namespace Emby.Dlna
try try
{ {
return _fileSystem.GetFilePaths(path) return _fileSystem.GetFilePaths(path)
.Where(i => string.Equals(Path.GetExtension(i), ".xml", StringComparison.OrdinalIgnoreCase)) .Where(i => Path.GetExtension(i.AsSpan()).Equals(".xml", StringComparison.OrdinalIgnoreCase))
.Select(i => ParseProfileFile(i, type)) .Select(i => ParseProfileFile(i, type))
.Where(i => i is not null) .Where(i => i is not null)
.ToList()!; // We just filtered out all the nulls .ToList()!; // We just filtered out all the nulls

@ -43,7 +43,7 @@ namespace Emby.Naming.ExternalFiles
return null; return null;
} }
var extension = Path.GetExtension(path); var extension = Path.GetExtension(path.AsSpan());
if (!(_type == DlnaProfileType.Subtitle && _namingOptions.SubtitleFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) if (!(_type == DlnaProfileType.Subtitle && _namingOptions.SubtitleFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
&& !(_type == DlnaProfileType.Audio && _namingOptions.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))) && !(_type == DlnaProfileType.Audio && _namingOptions.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)))
{ {

@ -26,19 +26,18 @@ namespace Emby.Naming.Video
return false; return false;
} }
var extension = Path.GetExtension(path); var extension = Path.GetExtension(path.AsSpan());
if (!options.StubFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) if (!options.StubFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
{ {
return false; return false;
} }
path = Path.GetFileNameWithoutExtension(path); var token = Path.GetExtension(Path.GetFileNameWithoutExtension(path.AsSpan())).TrimStart('.');
var token = Path.GetExtension(path).TrimStart('.');
foreach (var rule in options.StubTypes) foreach (var rule in options.StubTypes)
{ {
if (string.Equals(rule.Token, token, StringComparison.OrdinalIgnoreCase)) if (token.Equals(rule.Token, StringComparison.OrdinalIgnoreCase))
{ {
stubType = rule.StubType; stubType = rule.StubType;
return true; return true;

@ -61,7 +61,7 @@ namespace Emby.Photos
item.SetImagePath(ImageType.Primary, item.Path); item.SetImagePath(ImageType.Primary, item.Path);
// Examples: https://github.com/mono/taglib-sharp/blob/a5f6949a53d09ce63ee7495580d6802921a21f14/tests/fixtures/TagLib.Tests.Images/NullOrientationTest.cs // Examples: https://github.com/mono/taglib-sharp/blob/a5f6949a53d09ce63ee7495580d6802921a21f14/tests/fixtures/TagLib.Tests.Images/NullOrientationTest.cs
if (_includeExtensions.Contains(Path.GetExtension(item.Path), StringComparison.OrdinalIgnoreCase)) if (_includeExtensions.Contains(Path.GetExtension(item.Path.AsSpan()), StringComparison.OrdinalIgnoreCase))
{ {
try try
{ {

@ -103,15 +103,17 @@ namespace Emby.Server.Implementations.IO
return filePath; return filePath;
} }
var filePathSpan = filePath.AsSpan();
// relative path // relative path
if (firstChar == '\\') if (firstChar == '\\')
{ {
filePath = filePath.Substring(1); filePathSpan = filePathSpan.Slice(1);
} }
try try
{ {
return Path.GetFullPath(Path.Combine(folderPath, filePath)); return Path.GetFullPath(Path.Join(folderPath, filePathSpan));
} }
catch (ArgumentException) catch (ArgumentException)
{ {

@ -1162,7 +1162,7 @@ namespace Emby.Server.Implementations.Library
Name = Path.GetFileName(dir), Name = Path.GetFileName(dir),
Locations = _fileSystem.GetFilePaths(dir, false) Locations = _fileSystem.GetFilePaths(dir, false)
.Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase)) .Where(i => Path.GetExtension(i.AsSpan()).Equals(ShortcutFileExtension, StringComparison.OrdinalIgnoreCase))
.Select(i => .Select(i =>
{ {
try try
@ -3135,7 +3135,7 @@ namespace Emby.Server.Implementations.Library
} }
var shortcut = _fileSystem.GetFilePaths(virtualFolderPath, true) var shortcut = _fileSystem.GetFilePaths(virtualFolderPath, true)
.Where(i => string.Equals(ShortcutFileExtension, Path.GetExtension(i), StringComparison.OrdinalIgnoreCase)) .Where(i => Path.GetExtension(i.AsSpan()).Equals(ShortcutFileExtension, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault(f => _appHost.ExpandVirtualPath(_fileSystem.ResolveShortcut(f)).Equals(mediaPath, StringComparison.OrdinalIgnoreCase)); .FirstOrDefault(f => _appHost.ExpandVirtualPath(_fileSystem.ResolveShortcut(f)).Equals(mediaPath, StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrEmpty(shortcut)) if (!string.IsNullOrEmpty(shortcut))

@ -94,9 +94,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
if (AudioFileParser.IsAudioFile(args.Path, _namingOptions)) if (AudioFileParser.IsAudioFile(args.Path, _namingOptions))
{ {
var extension = Path.GetExtension(args.Path); var extension = Path.GetExtension(args.Path.AsSpan());
if (string.Equals(extension, ".cue", StringComparison.OrdinalIgnoreCase)) if (extension.Equals(".cue", StringComparison.OrdinalIgnoreCase))
{ {
// if audio file exists of same name, return null // if audio file exists of same name, return null
return null; return null;
@ -128,7 +128,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
if (item is not null) if (item is not null)
{ {
item.IsShortcut = string.Equals(extension, ".strm", StringComparison.OrdinalIgnoreCase); item.IsShortcut = extension.Equals(".strm", StringComparison.OrdinalIgnoreCase);
item.IsInMixedFolder = true; item.IsInMixedFolder = true;
} }

@ -263,7 +263,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
return false; return false;
} }
return directoryService.GetFilePaths(fullPath).Any(i => string.Equals(Path.GetExtension(i), ".vob", StringComparison.OrdinalIgnoreCase)); return directoryService.GetFilePaths(fullPath).Any(i => Path.GetExtension(i.AsSpan()).Equals(".vob", StringComparison.OrdinalIgnoreCase));
} }
/// <summary> /// <summary>

@ -32,9 +32,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
return GetBook(args); return GetBook(args);
} }
var extension = Path.GetExtension(args.Path); var extension = Path.GetExtension(args.Path.AsSpan());
if (extension is not null && _validExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) if (_validExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
{ {
// It's a book // It's a book
return new Book return new Book
@ -51,12 +51,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
{ {
var bookFiles = args.FileSystemChildren.Where(f => var bookFiles = args.FileSystemChildren.Where(f =>
{ {
var fileExtension = Path.GetExtension(f.FullName) var fileExtension = Path.GetExtension(f.FullName.AsSpan());
?? string.Empty;
return _validExtensions.Contains( return _validExtensions.Contains(
fileExtension, fileExtension,
StringComparer.OrdinalIgnoreCase); StringComparison.OrdinalIgnoreCase);
}).ToList(); }).ToList();
// Don't return a Book if there is more (or less) than one document in the directory // Don't return a Book if there is more (or less) than one document in the directory

@ -222,7 +222,7 @@ namespace Emby.Server.Implementations.MediaEncoder
{ {
var deadImages = images var deadImages = images
.Except(chapters.Select(i => i.ImagePath).Where(i => !string.IsNullOrEmpty(i)), StringComparer.OrdinalIgnoreCase) .Except(chapters.Select(i => i.ImagePath).Where(i => !string.IsNullOrEmpty(i)), StringComparer.OrdinalIgnoreCase)
.Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i), StringComparison.OrdinalIgnoreCase)) .Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i.AsSpan()), StringComparison.OrdinalIgnoreCase))
.ToList(); .ToList();
foreach (var image in deadImages) foreach (var image in deadImages)

@ -327,9 +327,9 @@ namespace Emby.Server.Implementations.Playlists
// this is probably best done as a metadata provider // this is probably best done as a metadata provider
// saving a file over itself will require some work to prevent this from happening when not needed // saving a file over itself will require some work to prevent this from happening when not needed
var playlistPath = item.Path; var playlistPath = item.Path;
var extension = Path.GetExtension(playlistPath); var extension = Path.GetExtension(playlistPath.AsSpan());
if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase)) if (extension.Equals(".wpl", StringComparison.OrdinalIgnoreCase))
{ {
var playlist = new WplPlaylist(); var playlist = new WplPlaylist();
foreach (var child in item.GetLinkedChildren()) foreach (var child in item.GetLinkedChildren())
@ -362,8 +362,7 @@ namespace Emby.Server.Implementations.Playlists
string text = new WplContent().ToText(playlist); string text = new WplContent().ToText(playlist);
File.WriteAllText(playlistPath, text); File.WriteAllText(playlistPath, text);
} }
else if (extension.Equals(".zpl", StringComparison.OrdinalIgnoreCase))
if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase))
{ {
var playlist = new ZplPlaylist(); var playlist = new ZplPlaylist();
foreach (var child in item.GetLinkedChildren()) foreach (var child in item.GetLinkedChildren())
@ -396,8 +395,7 @@ namespace Emby.Server.Implementations.Playlists
string text = new ZplContent().ToText(playlist); string text = new ZplContent().ToText(playlist);
File.WriteAllText(playlistPath, text); File.WriteAllText(playlistPath, text);
} }
else if (extension.Equals(".m3u", StringComparison.OrdinalIgnoreCase))
if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
{ {
var playlist = new M3uPlaylist var playlist = new M3uPlaylist
{ {
@ -428,8 +426,7 @@ namespace Emby.Server.Implementations.Playlists
string text = new M3uContent().ToText(playlist); string text = new M3uContent().ToText(playlist);
File.WriteAllText(playlistPath, text); File.WriteAllText(playlistPath, text);
} }
else if (extension.Equals(".m3u8", StringComparison.OrdinalIgnoreCase))
if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase))
{ {
var playlist = new M3uPlaylist(); var playlist = new M3uPlaylist();
playlist.IsExtended = true; playlist.IsExtended = true;
@ -458,8 +455,7 @@ namespace Emby.Server.Implementations.Playlists
string text = new M3uContent().ToText(playlist); string text = new M3uContent().ToText(playlist);
File.WriteAllText(playlistPath, text); File.WriteAllText(playlistPath, text);
} }
else if (extension.Equals(".pls", StringComparison.OrdinalIgnoreCase))
if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase))
{ {
var playlist = new PlsPlaylist(); var playlist = new PlsPlaylist();
foreach (var child in item.GetLinkedChildren()) foreach (var child in item.GetLinkedChildren())

@ -504,8 +504,7 @@ namespace Emby.Server.Implementations.Updates
private async Task PerformPackageInstallation(InstallationInfo package, PluginStatus status, CancellationToken cancellationToken) private async Task PerformPackageInstallation(InstallationInfo package, PluginStatus status, CancellationToken cancellationToken)
{ {
var extension = Path.GetExtension(package.SourceUrl); if (!Path.GetExtension(package.SourceUrl.AsSpan()).Equals(".zip", StringComparison.OrdinalIgnoreCase))
if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase))
{ {
_logger.LogError("Only zip packages are supported. {SourceUrl} is not a zip archive.", package.SourceUrl); _logger.LogError("Only zip packages are supported. {SourceUrl} is not a zip archive.", package.SourceUrl);
return; return;

@ -2041,9 +2041,9 @@ public class DynamicHlsController : BaseJellyfinApiController
return null; return null;
} }
var playlistFilename = Path.GetFileNameWithoutExtension(playlist); var playlistFilename = Path.GetFileNameWithoutExtension(playlist.AsSpan());
var indexString = Path.GetFileNameWithoutExtension(file.Name).Substring(playlistFilename.Length); var indexString = Path.GetFileNameWithoutExtension(file.Name.AsSpan()).Slice(playlistFilename.Length);
return int.Parse(indexString, NumberStyles.Integer, CultureInfo.InvariantCulture); return int.Parse(indexString, NumberStyles.Integer, CultureInfo.InvariantCulture);
} }

@ -59,7 +59,7 @@ public class HlsSegmentController : BaseJellyfinApiController
public ActionResult GetHlsAudioSegmentLegacy([FromRoute, Required] string itemId, [FromRoute, Required] string segmentId) public ActionResult GetHlsAudioSegmentLegacy([FromRoute, Required] string itemId, [FromRoute, Required] string segmentId)
{ {
// TODO: Deprecate with new iOS app // TODO: Deprecate with new iOS app
var file = segmentId + Path.GetExtension(Request.Path); var file = string.Concat(segmentId, Path.GetExtension(Request.Path.Value.AsSpan()));
var transcodePath = _serverConfigurationManager.GetTranscodePath(); var transcodePath = _serverConfigurationManager.GetTranscodePath();
file = Path.GetFullPath(Path.Combine(transcodePath, file)); file = Path.GetFullPath(Path.Combine(transcodePath, file));
var fileDir = Path.GetDirectoryName(file); var fileDir = Path.GetDirectoryName(file);
@ -85,11 +85,12 @@ public class HlsSegmentController : BaseJellyfinApiController
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "itemId", Justification = "Required for ServiceStack")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "itemId", Justification = "Required for ServiceStack")]
public ActionResult GetHlsPlaylistLegacy([FromRoute, Required] string itemId, [FromRoute, Required] string playlistId) public ActionResult GetHlsPlaylistLegacy([FromRoute, Required] string itemId, [FromRoute, Required] string playlistId)
{ {
var file = playlistId + Path.GetExtension(Request.Path); var file = string.Concat(playlistId, Path.GetExtension(Request.Path.Value.AsSpan()));
var transcodePath = _serverConfigurationManager.GetTranscodePath(); var transcodePath = _serverConfigurationManager.GetTranscodePath();
file = Path.GetFullPath(Path.Combine(transcodePath, file)); file = Path.GetFullPath(Path.Combine(transcodePath, file));
var fileDir = Path.GetDirectoryName(file); var fileDir = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(fileDir) || !fileDir.StartsWith(transcodePath, StringComparison.InvariantCulture) || Path.GetExtension(file) != ".m3u8") if (string.IsNullOrEmpty(fileDir) || !fileDir.StartsWith(transcodePath, StringComparison.InvariantCulture)
|| Path.GetExtension(file.AsSpan()).Equals(".m3u8", StringComparison.OrdinalIgnoreCase))
{ {
return BadRequest("Invalid segment."); return BadRequest("Invalid segment.");
} }
@ -138,7 +139,7 @@ public class HlsSegmentController : BaseJellyfinApiController
[FromRoute, Required] string segmentId, [FromRoute, Required] string segmentId,
[FromRoute, Required] string segmentContainer) [FromRoute, Required] string segmentContainer)
{ {
var file = segmentId + Path.GetExtension(Request.Path); var file = string.Concat(segmentId, Path.GetExtension(Request.Path.Value.AsSpan()));
var transcodeFolderPath = _serverConfigurationManager.GetTranscodePath(); var transcodeFolderPath = _serverConfigurationManager.GetTranscodePath();
file = Path.GetFullPath(Path.Combine(transcodeFolderPath, file)); file = Path.GetFullPath(Path.Combine(transcodeFolderPath, file));

@ -243,7 +243,7 @@ public static class StreamingHelpers
? GetOutputFileExtension(state, mediaSource) ? GetOutputFileExtension(state, mediaSource)
: ("." + state.OutputContainer); : ("." + state.OutputContainer);
state.OutputFilePath = GetOutputFilePath(state, ext!, serverConfigurationManager, streamingRequest.DeviceId, streamingRequest.PlaySessionId); state.OutputFilePath = GetOutputFilePath(state, ext, serverConfigurationManager, streamingRequest.DeviceId, streamingRequest.PlaySessionId);
return state; return state;
} }
@ -418,11 +418,11 @@ public static class StreamingHelpers
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
private static string? GetOutputFileExtension(StreamState state, MediaSourceInfo? mediaSource) private static string? GetOutputFileExtension(StreamState state, MediaSourceInfo? mediaSource)
{ {
var ext = Path.GetExtension(state.RequestedUrl); var ext = Path.GetExtension(state.RequestedUrl.AsSpan());
if (!string.IsNullOrEmpty(ext)) if (ext.IsEmpty)
{ {
return ext; return null;
} }
// Try to infer based on the desired video codec // Try to infer based on the desired video codec
@ -504,7 +504,7 @@ public static class StreamingHelpers
/// <param name="deviceId">The device id.</param> /// <param name="deviceId">The device id.</param>
/// <param name="playSessionId">The play session id.</param> /// <param name="playSessionId">The play session id.</param>
/// <returns>The complete file path, including the folder, for the transcoding file.</returns> /// <returns>The complete file path, including the folder, for the transcoding file.</returns>
private static string GetOutputFilePath(StreamState state, string outputFileExtension, IServerConfigurationManager serverConfigurationManager, string? deviceId, string? playSessionId) private static string GetOutputFilePath(StreamState state, string? outputFileExtension, IServerConfigurationManager serverConfigurationManager, string? deviceId, string? playSessionId)
{ {
var data = $"{state.MediaPath}-{state.UserAgent}-{deviceId!}-{playSessionId!}"; var data = $"{state.MediaPath}-{state.UserAgent}-{deviceId!}-{playSessionId!}";

@ -538,7 +538,7 @@ public class TranscodingJobHelper : IDisposable
await _attachmentExtractor.ExtractAllAttachments(state.MediaPath, state.MediaSource, attachmentPath, cancellationTokenSource.Token).ConfigureAwait(false); await _attachmentExtractor.ExtractAllAttachments(state.MediaPath, state.MediaSource, attachmentPath, cancellationTokenSource.Token).ConfigureAwait(false);
} }
if (state.SubtitleStream.IsExternal && string.Equals(Path.GetExtension(state.SubtitleStream.Path), ".mks", StringComparison.OrdinalIgnoreCase)) if (state.SubtitleStream.IsExternal && Path.GetExtension(state.SubtitleStream.Path.AsSpan()).Equals(".mks", StringComparison.OrdinalIgnoreCase))
{ {
string subtitlePath = state.SubtitleStream.Path; string subtitlePath = state.SubtitleStream.Path;
string subtitlePathArgument = string.Format(CultureInfo.InvariantCulture, "file:\"{0}\"", subtitlePath.Replace("\"", "\\\"", StringComparison.Ordinal)); string subtitlePathArgument = string.Format(CultureInfo.InvariantCulture, "file:\"{0}\"", subtitlePath.Replace("\"", "\\\"", StringComparison.Ordinal));

@ -548,25 +548,25 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <returns>System.Nullable{VideoCodecs}.</returns> /// <returns>System.Nullable{VideoCodecs}.</returns>
public string InferVideoCodec(string url) public string InferVideoCodec(string url)
{ {
var ext = Path.GetExtension(url); var ext = Path.GetExtension(url.AsSpan());
if (string.Equals(ext, ".asf", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".asf", StringComparison.OrdinalIgnoreCase))
{ {
return "wmv"; return "wmv";
} }
if (string.Equals(ext, ".webm", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".webm", StringComparison.OrdinalIgnoreCase))
{ {
// TODO: this may not always mean VP8, as the codec ages // TODO: this may not always mean VP8, as the codec ages
return "vp8"; return "vp8";
} }
if (string.Equals(ext, ".ogg", StringComparison.OrdinalIgnoreCase) || string.Equals(ext, ".ogv", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".ogg", StringComparison.OrdinalIgnoreCase) || ext.Equals(".ogv", StringComparison.OrdinalIgnoreCase))
{ {
return "theora"; return "theora";
} }
if (string.Equals(ext, ".m3u8", StringComparison.OrdinalIgnoreCase) || string.Equals(ext, ".ts", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".m3u8", StringComparison.OrdinalIgnoreCase) || ext.Equals(".ts", StringComparison.OrdinalIgnoreCase))
{ {
return "h264"; return "h264";
} }
@ -1080,10 +1080,10 @@ namespace MediaBrowser.Controller.MediaEncoding
&& state.SubtitleStream.IsExternal) && state.SubtitleStream.IsExternal)
{ {
var subtitlePath = state.SubtitleStream.Path; var subtitlePath = state.SubtitleStream.Path;
var subtitleExtension = Path.GetExtension(subtitlePath); var subtitleExtension = Path.GetExtension(subtitlePath.AsSpan());
if (string.Equals(subtitleExtension, ".sub", StringComparison.OrdinalIgnoreCase) if (subtitleExtension.Equals(".sub", StringComparison.OrdinalIgnoreCase)
|| string.Equals(subtitleExtension, ".sup", StringComparison.OrdinalIgnoreCase)) || subtitleExtension.Equals(".sup", StringComparison.OrdinalIgnoreCase))
{ {
var idxFile = Path.ChangeExtension(subtitlePath, ".idx"); var idxFile = Path.ChangeExtension(subtitlePath, ".idx");
if (File.Exists(idxFile)) if (File.Exists(idxFile))
@ -6033,7 +6033,7 @@ namespace MediaBrowser.Controller.MediaEncoding
var format = string.Empty; var format = string.Empty;
var keyFrame = string.Empty; var keyFrame = string.Empty;
if (string.Equals(Path.GetExtension(outputPath), ".mp4", StringComparison.OrdinalIgnoreCase) if (Path.GetExtension(outputPath.AsSpan()).Equals(".mp4", StringComparison.OrdinalIgnoreCase)
&& state.BaseRequest.Context == EncodingContext.Streaming) && state.BaseRequest.Context == EncodingContext.Streaming)
{ {
// Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js // Comparison: https://github.com/jansmolders86/mediacenterjs/blob/master/lib/transcoding/desktop.js

@ -1,4 +1,3 @@
#nullable disable
#pragma warning disable CS1591 #pragma warning disable CS1591
using System; using System;
@ -23,7 +22,7 @@ using Microsoft.Extensions.Logging;
namespace MediaBrowser.MediaEncoding.Attachments namespace MediaBrowser.MediaEncoding.Attachments
{ {
public class AttachmentExtractor : IAttachmentExtractor, IDisposable public sealed class AttachmentExtractor : IAttachmentExtractor
{ {
private readonly ILogger<AttachmentExtractor> _logger; private readonly ILogger<AttachmentExtractor> _logger;
private readonly IApplicationPaths _appPaths; private readonly IApplicationPaths _appPaths;
@ -34,8 +33,6 @@ namespace MediaBrowser.MediaEncoding.Attachments
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks = private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
new ConcurrentDictionary<string, SemaphoreSlim>(); new ConcurrentDictionary<string, SemaphoreSlim>();
private bool _disposed = false;
public AttachmentExtractor( public AttachmentExtractor(
ILogger<AttachmentExtractor> logger, ILogger<AttachmentExtractor> logger,
IApplicationPaths appPaths, IApplicationPaths appPaths,
@ -296,7 +293,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
ArgumentException.ThrowIfNullOrEmpty(outputPath); ArgumentException.ThrowIfNullOrEmpty(outputPath);
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); Directory.CreateDirectory(Path.GetDirectoryName(outputPath) ?? throw new ArgumentException("Path can't be a root directory.", nameof(outputPath)));
var processArgs = string.Format( var processArgs = string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
@ -391,33 +388,8 @@ namespace MediaBrowser.MediaEncoding.Attachments
filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D", CultureInfo.InvariantCulture); filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D", CultureInfo.InvariantCulture);
} }
var prefix = filename.Substring(0, 1); var prefix = filename.AsSpan(0, 1);
return Path.Combine(_appPaths.DataPath, "attachments", prefix, filename); return Path.Join(_appPaths.DataPath, "attachments", prefix, filename);
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
}
_disposed = true;
} }
} }
} }

@ -316,10 +316,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
var files = _fileSystem.GetFilePaths(path, recursive); var files = _fileSystem.GetFilePaths(path, recursive);
var excludeExtensions = new[] { ".c" }; return files.FirstOrDefault(i => Path.GetFileNameWithoutExtension(i.AsSpan()).Equals(filename, StringComparison.OrdinalIgnoreCase)
&& !Path.GetExtension(i.AsSpan()).Equals(".c", StringComparison.OrdinalIgnoreCase));
return files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), filename, StringComparison.OrdinalIgnoreCase)
&& !excludeExtensions.Contains(Path.GetExtension(i) ?? string.Empty));
} }
catch (Exception) catch (Exception)
{ {

@ -188,7 +188,7 @@ public class SkiaEncoder : IImageEncoder
return path; return path;
} }
var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + Path.GetExtension(path)); var tempPath = Path.Combine(_appPaths.TempDirectory, string.Concat(Guid.NewGuid().ToString(), Path.GetExtension(path.AsSpan())));
var directory = Path.GetDirectoryName(tempPath) ?? throw new ResourceNotFoundException($"Provided path ({tempPath}) is not valid."); var directory = Path.GetDirectoryName(tempPath) ?? throw new ResourceNotFoundException($"Provided path ({tempPath}) is not valid.");
Directory.CreateDirectory(directory); Directory.CreateDirectory(directory);
File.Copy(path, tempPath, true); File.Copy(path, tempPath, true);

@ -38,25 +38,25 @@ public partial class StripCollageBuilder
{ {
ArgumentNullException.ThrowIfNull(outputPath); ArgumentNullException.ThrowIfNull(outputPath);
var ext = Path.GetExtension(outputPath); var ext = Path.GetExtension(outputPath.AsSpan());
if (string.Equals(ext, ".jpg", StringComparison.OrdinalIgnoreCase) if (ext.Equals(".jpg", StringComparison.OrdinalIgnoreCase)
|| string.Equals(ext, ".jpeg", StringComparison.OrdinalIgnoreCase)) || ext.Equals(".jpeg", StringComparison.OrdinalIgnoreCase))
{ {
return SKEncodedImageFormat.Jpeg; return SKEncodedImageFormat.Jpeg;
} }
if (string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".webp", StringComparison.OrdinalIgnoreCase))
{ {
return SKEncodedImageFormat.Webp; return SKEncodedImageFormat.Webp;
} }
if (string.Equals(ext, ".gif", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".gif", StringComparison.OrdinalIgnoreCase))
{ {
return SKEncodedImageFormat.Gif; return SKEncodedImageFormat.Gif;
} }
if (string.Equals(ext, ".bmp", StringComparison.OrdinalIgnoreCase)) if (ext.Equals(".bmp", StringComparison.OrdinalIgnoreCase))
{ {
return SKEncodedImageFormat.Bmp; return SKEncodedImageFormat.Bmp;
} }

Loading…
Cancel
Save