Merge branch 'master' into comparisons

This commit is contained in:
BaronGreenback 2021-05-08 17:11:21 +01:00 committed by GitHub
commit 97c2c523a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
310 changed files with 687 additions and 298 deletions

View File

@ -2,8 +2,6 @@ name: Automation
on:
pull_request:
issues:
issue_comment:
jobs:
main:

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
namespace Emby.Dlna.Configuration

View File

@ -1,4 +1,3 @@
#nullable enable
#pragma warning disable CS1591
using Emby.Dlna.Configuration;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.Globalization;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.IO;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -9,7 +9,7 @@ namespace Emby.Dlna.Didl
{
public class StringWriterWithEncoding : StringWriter
{
private readonly Encoding _encoding;
private readonly Encoding? _encoding;
public StringWriterWithEncoding()
{

View File

@ -1,4 +1,3 @@
#nullable enable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -21,6 +21,7 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Code Analyzers-->

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using MediaBrowser.Model.Dlna;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.IO;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -46,7 +46,7 @@ namespace Emby.Dlna.PlayTo
{
var serviceAction = new ServiceAction
{
Name = container.GetValue(UPnpNamespaces.Svc + "name"),
Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
};
var argumentList = serviceAction.ArgumentList;
@ -68,9 +68,9 @@ namespace Emby.Dlna.PlayTo
return new Argument
{
Name = container.GetValue(UPnpNamespaces.Svc + "name"),
Direction = container.GetValue(UPnpNamespaces.Svc + "direction"),
RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable")
Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
Direction = container.GetValue(UPnpNamespaces.Svc + "direction") ?? string.Empty,
RelatedStateVariable = container.GetValue(UPnpNamespaces.Svc + "relatedStateVariable") ?? string.Empty
};
}
@ -89,8 +89,8 @@ namespace Emby.Dlna.PlayTo
return new StateVariable
{
Name = container.GetValue(UPnpNamespaces.Svc + "name"),
DataType = container.GetValue(UPnpNamespaces.Svc + "dataType"),
Name = container.GetValue(UPnpNamespaces.Svc + "name") ?? string.Empty,
DataType = container.GetValue(UPnpNamespaces.Svc + "dataType") ?? string.Empty,
AllowedValues = allowedValues
};
}
@ -166,7 +166,7 @@ namespace Emby.Dlna.PlayTo
return string.Format(CultureInfo.InvariantCulture, CommandBase, action.Name, xmlNamesapce, stateString);
}
private string BuildArgumentXml(Argument argument, string value, string commandParameter = "")
private string BuildArgumentXml(Argument argument, string? value, string commandParameter = "")
{
var state = StateVariables.FirstOrDefault(a => string.Equals(a.Name, argument.RelatedStateVariable, StringComparison.OrdinalIgnoreCase));

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -250,7 +250,8 @@ namespace Emby.Dlna.Server
url = _serverAddress.TrimEnd('/') + "/dlna/" + _serverUdn + "/" + url.TrimStart('/');
return SecurityElement.Escape(url);
// TODO: @bond remove null-coalescing operator when https://github.com/dotnet/runtime/pull/52442 is merged/released
return SecurityElement.Escape(url) ?? string.Empty;
}
private IEnumerable<DeviceIcon> GetIcons()

View File

@ -47,7 +47,7 @@ namespace Emby.Dlna.Service
private async Task<ControlResponse> ProcessControlRequestInternalAsync(ControlRequest request)
{
ControlRequestInfo requestInfo;
ControlRequestInfo? requestInfo = null;
using (var streamReader = new StreamReader(request.InputXml, Encoding.UTF8))
{
@ -151,7 +151,7 @@ namespace Emby.Dlna.Service
private async Task<ControlRequestInfo> ParseBodyTagAsync(XmlReader reader)
{
string namespaceURI = null, localName = null;
string? namespaceURI = null, localName = null;
await reader.MoveToContentAsync().ConfigureAwait(false);
await reader.ReadAsync().ConfigureAwait(false);

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -7,21 +7,21 @@ namespace Emby.Dlna.Ssdp
{
public static class SsdpExtensions
{
public static string GetValue(this XElement container, XName name)
public static string? GetValue(this XElement container, XName name)
{
var node = container.Element(name);
return node?.Value;
}
public static string GetAttributeValue(this XElement container, XName name)
public static string? GetAttributeValue(this XElement container, XName name)
{
var node = container.Attribute(name);
return node?.Value;
}
public static string GetDescendantValue(this XElement container, XName name)
public static string? GetDescendantValue(this XElement container, XName name)
=> container.Descendants(name).FirstOrDefault()?.Value;
}
}

View File

@ -44,6 +44,11 @@ namespace Emby.Server.Implementations.Library
// Make sure DateCreated and DateModified have values
var fileInfo = directoryService.GetFile(item.Path);
if (fileInfo == null)
{
throw new FileNotFoundException("Can't find item path.", item.Path);
}
SetDateCreated(item, fileInfo);
EnsureName(item, fileInfo);

View File

@ -10,6 +10,7 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Json;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
@ -307,13 +308,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
using (var reader = new StreamReader(source))
{
while (!reader.EndOfStream)
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
{
var line = await reader.ReadLineAsync().ConfigureAwait(false);
var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
await target.WriteAsync(bytes.AsMemory()).ConfigureAwait(false);
await target.FlushAsync().ConfigureAwait(false);
}
}

View File

@ -182,16 +182,16 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
using var sr = new StreamReader(stream, System.Text.Encoding.UTF8);
var tuners = new List<LiveTvTunerInfo>();
while (!sr.EndOfStream)
await foreach (var line in sr.ReadAllLinesAsync().ConfigureAwait(false))
{
string line = StripXML(sr.ReadLine());
if (line.Contains("Channel", StringComparison.Ordinal))
string stripedLine = StripXML(line);
if (stripedLine.Contains("Channel", StringComparison.Ordinal))
{
LiveTvTunerStatus status;
var index = line.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
var name = line.Substring(0, index - 1);
var currentChannel = line.Substring(index + 7);
if (currentChannel != "none")
var index = stripedLine.IndexOf("Channel", StringComparison.OrdinalIgnoreCase);
var name = stripedLine.Substring(0, index - 1);
var currentChannel = stripedLine.Substring(index + 7);
if (string.Equals(currentChannel, "none", StringComparison.Ordinal))
{
status = LiveTvTunerStatus.LiveTv;
}

View File

@ -35,16 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
// Read the file and display it line by line.
using (var reader = new StreamReader(await GetListingsStream(info, cancellationToken).ConfigureAwait(false)))
{
return GetChannels(reader, channelIdPrefix, info.Id);
}
}
public List<ChannelInfo> ParseString(string text, string channelIdPrefix, string tunerHostId)
{
// Read the file and display it line by line.
using (var reader = new StringReader(text))
{
return GetChannels(reader, channelIdPrefix, tunerHostId);
return await GetChannelsAsync(reader, channelIdPrefix, info.Id).ConfigureAwait(false);
}
}
@ -70,43 +61,42 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
private const string ExtInfPrefix = "#EXTINF:";
private List<ChannelInfo> GetChannels(TextReader reader, string channelIdPrefix, string tunerHostId)
private async Task<List<ChannelInfo>> GetChannelsAsync(TextReader reader, string channelIdPrefix, string tunerHostId)
{
var channels = new List<ChannelInfo>();
string line;
string extInf = string.Empty;
while ((line = reader.ReadLine()) != null)
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
{
line = line.Trim();
if (string.IsNullOrWhiteSpace(line))
var trimmedLine = line.Trim();
if (string.IsNullOrWhiteSpace(trimmedLine))
{
continue;
}
if (line.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
if (trimmedLine.StartsWith("#EXTM3U", StringComparison.OrdinalIgnoreCase))
{
continue;
}
if (line.StartsWith(ExtInfPrefix, StringComparison.OrdinalIgnoreCase))
if (trimmedLine.StartsWith(ExtInfPrefix, StringComparison.OrdinalIgnoreCase))
{
extInf = line.Substring(ExtInfPrefix.Length).Trim();
extInf = trimmedLine.Substring(ExtInfPrefix.Length).Trim();
_logger.LogInformation("Found m3u channel: {0}", extInf);
}
else if (!string.IsNullOrWhiteSpace(extInf) && !line.StartsWith('#'))
else if (!string.IsNullOrWhiteSpace(extInf) && !trimmedLine.StartsWith('#'))
{
var channel = GetChannelnfo(extInf, tunerHostId, line);
var channel = GetChannelnfo(extInf, tunerHostId, trimmedLine);
if (string.IsNullOrWhiteSpace(channel.Id))
{
channel.Id = channelIdPrefix + line.GetMD5().ToString("N", CultureInfo.InvariantCulture);
channel.Id = channelIdPrefix + trimmedLine.GetMD5().ToString("N", CultureInfo.InvariantCulture);
}
else
{
channel.Id = channelIdPrefix + channel.Id.GetMD5().ToString("N", CultureInfo.InvariantCulture);
}
channel.Path = line;
channel.Path = trimmedLine;
channels.Add(channel);
extInf = string.Empty;
}

View File

@ -7,6 +7,7 @@ using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Json;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Entities;
@ -72,8 +73,7 @@ namespace Emby.Server.Implementations.Localization
using (var str = _assembly.GetManifestResourceStream(resource))
using (var reader = new StreamReader(str))
{
string line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
{
if (string.IsNullOrWhiteSpace(line))
{
@ -118,10 +118,8 @@ namespace Emby.Server.Implementations.Localization
using (var stream = _assembly.GetManifestResourceStream(ResourcePath))
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
await foreach (var line in reader.ReadAllLinesAsync().ConfigureAwait(false))
{
var line = await reader.ReadLineAsync().ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(line))
{
continue;
@ -179,7 +177,7 @@ namespace Emby.Server.Implementations.Localization
/// <inheritdoc />
public IEnumerable<CountryInfo> GetCountries()
{
StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
using StreamReader reader = new StreamReader(_assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
return JsonSerializer.Deserialize<IEnumerable<CountryInfo>>(reader.ReadToEnd(), _jsonOptions);
}

View File

@ -77,8 +77,9 @@ namespace Jellyfin.Api.Auth
return false;
}
var ip = _httpContextAccessor.HttpContext.GetNormalizedRemoteIp();
var isInLocalNetwork = _networkManager.IsInLocalNetwork(ip);
var isInLocalNetwork = _httpContextAccessor.HttpContext != null
&& _networkManager.IsInLocalNetwork(_httpContextAccessor.HttpContext.GetNormalizedRemoteIp());
// User cannot access remotely and user is remote
if (!user.HasPermission(PermissionKind.EnableRemoteAccess) && !isInLocalNetwork)
{

View File

@ -1,3 +1,4 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Net.Mime;
using System.Text.Json;
@ -94,6 +95,11 @@ namespace Jellyfin.Api.Controllers
{
var configurationType = _configurationManager.GetConfigurationType(key);
var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType, _serializerOptions).ConfigureAwait(false);
if (configuration == null)
{
throw new ArgumentException("Body doesn't contain a valid configuration");
}
_configurationManager.SaveConfiguration(key, configuration);
return NoContent();
}

View File

@ -600,7 +600,7 @@ namespace Jellyfin.Api.Controllers
{
foreach (var item in dto.Updates)
{
_libraryMonitor.ReportFileSystemChanged(item.Path);
_libraryMonitor.ReportFileSystemChanged(item.Path ?? throw new ArgumentException("Item path can't be null."));
}
return NoContent();

View File

@ -118,10 +118,7 @@ namespace Jellyfin.Api.Helpers
/// <returns>The playlist text as a string.</returns>
public static string GetLivePlaylistText(string path, StreamState state)
{
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var reader = new StreamReader(stream);
var text = reader.ReadToEnd();
var text = File.ReadAllText(path);
var segmentFormat = EncodingHelper.GetSegmentFileExtension(state.Request.SegmentContainer).TrimStart('.');
if (string.Equals(segmentFormat, "mp4", StringComparison.OrdinalIgnoreCase))

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
namespace MediaBrowser.Common.Configuration

View File

@ -1,3 +1,4 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
namespace MediaBrowser.Common.Configuration
{
/// <summary>

View File

@ -1,5 +1,4 @@
#pragma warning disable CS1591
#nullable enable
using System;
using System.Collections.Generic;

View File

@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Events
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="EventArgs" /> instance containing the event data.</param>
/// <param name="logger">The logger.</param>
public static void QueueEventIfNotNull(EventHandler handler, object sender, EventArgs args, ILogger logger)
public static void QueueEventIfNotNull(EventHandler? handler, object sender, EventArgs args, ILogger logger)
{
if (handler != null)
{
@ -43,7 +43,7 @@ namespace MediaBrowser.Common.Events
/// <param name="sender">The sender.</param>
/// <param name="args">The args.</param>
/// <param name="logger">The logger.</param>
public static void QueueEventIfNotNull<T>(EventHandler<T> handler, object sender, T args, ILogger logger)
public static void QueueEventIfNotNull<T>(EventHandler<T>? handler, object sender, T args, ILogger logger)
{
if (handler != null)
{

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Security.Cryptography;
using System.Text;

View File

@ -1,5 +1,3 @@
#nullable enable
using System.Collections.Generic;
namespace MediaBrowser.Common.Extensions

View File

@ -17,7 +17,7 @@ namespace MediaBrowser.Common.Extensions
{
return (context.Connection.LocalIpAddress == null
&& context.Connection.RemoteIpAddress == null)
|| context.Connection.LocalIpAddress.Equals(context.Connection.RemoteIpAddress);
|| Equals(context.Connection.LocalIpAddress, context.Connection.RemoteIpAddress);
}
/// <summary>

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
namespace MediaBrowser.Common.Extensions

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Diagnostics;
using System.Threading;

View File

@ -1,4 +1,3 @@
#nullable enable
#pragma warning disable CS1591
using System;

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
namespace MediaBrowser.Common.Extensions

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;

View File

@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#nullable enable
#pragma warning disable CS1591
#pragma warning disable CA1034
using System;

View File

@ -1,5 +1,3 @@
#nullable enable
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -35,11 +33,11 @@ namespace MediaBrowser.Common.Extensions
}
/// <summary>
/// Reads all lines in the <see cref="StreamReader" />.
/// Reads all lines in the <see cref="TextReader" />.
/// </summary>
/// <param name="reader">The <see cref="StreamReader" /> to read from.</param>
/// <param name="reader">The <see cref="TextReader" /> to read from.</param>
/// <returns>All lines in the stream.</returns>
public static IEnumerable<string> ReadAllLines(this StreamReader reader)
public static IEnumerable<string> ReadAllLines(this TextReader reader)
{
string? line;
while ((line = reader.ReadLine()) != null)
@ -47,5 +45,19 @@ namespace MediaBrowser.Common.Extensions
yield return line;
}
}
/// <summary>
/// Reads all lines in the <see cref="TextReader" />.
/// </summary>
/// <param name="reader">The <see cref="TextReader" /> to read from.</param>
/// <returns>All lines in the stream.</returns>
public static async IAsyncEnumerable<string> ReadAllLinesAsync(this TextReader reader)
{
string? line;
while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) != null)
{
yield return line;
}
}
}
}

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.Reflection;

View File

@ -9,67 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
/// Convert comma delimited string to array of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
public class JsonCommaDelimitedArrayConverter<T> : JsonConverter<T[]>
public sealed class JsonCommaDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
{
private readonly TypeConverter _typeConverter;
/// <summary>
/// Initializes a new instance of the <see cref="JsonCommaDelimitedArrayConverter{T}"/> class.
/// </summary>
public JsonCommaDelimitedArrayConverter()
public JsonCommaDelimitedArrayConverter() : base()
{
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
/// <inheritdoc />
public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var stringEntries = reader.GetString().Split(',', StringSplitOptions.RemoveEmptyEntries);
if (stringEntries.Length == 0)
{
return Array.Empty<T>();
}
var parsedValues = new object[stringEntries.Length];
var convertedCount = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
convertedCount++;
}
catch (FormatException)
{
// TODO log when upgraded to .Net6
// https://github.com/dotnet/runtime/issues/42975
// _logger.LogDebug(e, "Error converting value.");
}
}
var typedValues = new T[convertedCount];
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
if (parsedValues[i] != null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
}
}
return typedValues;
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
protected override char Delimiter => ',';
}
}

View File

@ -19,10 +19,10 @@ namespace MediaBrowser.Common.Json.Converters
}
/// <inheritdoc />
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
return (JsonConverter)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
return (JsonConverter?)Activator.CreateInstance(typeof(JsonCommaDelimitedArrayConverter<>).MakeGenericType(structType));
}
}
}

View File

@ -0,0 +1,81 @@
using System;
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MediaBrowser.Common.Json.Converters
{
/// <summary>
/// Convert delimited string to array of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
public abstract class JsonDelimitedArrayConverter<T> : JsonConverter<T[]?>
{
private readonly TypeConverter _typeConverter;
/// <summary>
/// Initializes a new instance of the <see cref="JsonDelimitedArrayConverter{T}"/> class.
/// </summary>
protected JsonDelimitedArrayConverter()
{
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
/// <summary>
/// Gets the array delimiter.
/// </summary>
protected virtual char Delimiter { get; }
/// <inheritdoc />
public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
// GetString can't return null here because we already handled it above
var stringEntries = reader.GetString()?.Split(Delimiter, StringSplitOptions.RemoveEmptyEntries);
if (stringEntries == null || stringEntries.Length == 0)
{
return Array.Empty<T>();
}
var parsedValues = new object[stringEntries.Length];
var convertedCount = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
convertedCount++;
}
catch (FormatException)
{
// TODO log when upgraded to .Net6
// https://github.com/dotnet/runtime/issues/42975
// _logger.LogDebug(e, "Error converting value.");
}
}
var typedValues = new T[convertedCount];
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
if (parsedValues[i] != null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
}
}
return typedValues;
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[]? value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}

View File

@ -18,10 +18,10 @@ namespace MediaBrowser.Common.Json.Converters
}
/// <inheritdoc />
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var structType = typeToConvert.GenericTypeArguments[0];
return (JsonConverter)Activator.CreateInstance(typeof(JsonNullableStructConverter<>).MakeGenericType(structType));
return (JsonConverter?)Activator.CreateInstance(typeof(JsonNullableStructConverter<>).MakeGenericType(structType));
}
}
}
}

View File

@ -7,15 +7,21 @@ namespace MediaBrowser.Common.Json.Converters
/// <summary>
/// Converts a string <c>N/A</c> to <c>string.Empty</c>.
/// </summary>
public class JsonOmdbNotAvailableStringConverter : JsonConverter<string>
public class JsonOmdbNotAvailableStringConverter : JsonConverter<string?>
{
/// <inheritdoc />
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
return null;
}
if (reader.TokenType == JsonTokenType.String)
{
var str = reader.GetString();
if (str != null && str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
// GetString can't return null here because we already handled it above
var str = reader.GetString()!;
if (str.Equals("N/A", StringComparison.OrdinalIgnoreCase))
{
return null;
}
@ -23,11 +29,11 @@ namespace MediaBrowser.Common.Json.Converters
return str;
}
return JsonSerializer.Deserialize<string>(ref reader, options);
return JsonSerializer.Deserialize<string?>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
{
writer.WriteStringValue(value);
}

View File

@ -9,67 +9,16 @@ namespace MediaBrowser.Common.Json.Converters
/// Convert Pipe delimited string to array of type.
/// </summary>
/// <typeparam name="T">Type to convert to.</typeparam>
public class JsonPipeDelimitedArrayConverter<T> : JsonConverter<T[]>
public sealed class JsonPipeDelimitedArrayConverter<T> : JsonDelimitedArrayConverter<T>
{
private readonly TypeConverter _typeConverter;
/// <summary>
/// Initializes a new instance of the <see cref="JsonPipeDelimitedArrayConverter{T}"/> class.
/// </summary>
public JsonPipeDelimitedArrayConverter()
public JsonPipeDelimitedArrayConverter() : base()
{
_typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
/// <inheritdoc />
public override T[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String)
{
var stringEntries = reader.GetString()?.Split('|', StringSplitOptions.RemoveEmptyEntries);
if (stringEntries == null || stringEntries.Length == 0)
{
return Array.Empty<T>();
}
var parsedValues = new object[stringEntries.Length];
var convertedCount = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
try
{
parsedValues[i] = _typeConverter.ConvertFrom(stringEntries[i].Trim());
convertedCount++;
}
catch (FormatException)
{
// TODO log when upgraded to .Net6
// https://github.com/dotnet/runtime/issues/42975
// _logger.LogDebug(e, "Error converting value.");
}
}
var typedValues = new T[convertedCount];
var typedValueIndex = 0;
for (var i = 0; i < stringEntries.Length; i++)
{
if (parsedValues[i] != null)
{
typedValues.SetValue(parsedValues[i], typedValueIndex);
typedValueIndex++;
}
}
return typedValues;
}
return JsonSerializer.Deserialize<T[]>(ref reader, options);
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
protected override char Delimiter => '|';
}
}

View File

@ -19,10 +19,10 @@ namespace MediaBrowser.Common.Json.Converters
}
/// <inheritdoc />
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var structType = typeToConvert.GetElementType() ?? typeToConvert.GenericTypeArguments[0];
return (JsonConverter)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
return (JsonConverter?)Activator.CreateInstance(typeof(JsonPipeDelimitedArrayConverter<>).MakeGenericType(structType));
}
}
}

View File

@ -9,10 +9,10 @@ namespace MediaBrowser.Common.Json.Converters
/// <summary>
/// Converter to allow the serializer to read strings.
/// </summary>
public class JsonStringConverter : JsonConverter<string>
public class JsonStringConverter : JsonConverter<string?>
{
/// <inheritdoc />
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.TokenType switch
{
@ -23,7 +23,7 @@ namespace MediaBrowser.Common.Json.Converters
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
{
writer.WriteStringValue(value);
}
@ -36,4 +36,4 @@ namespace MediaBrowser.Common.Json.Converters
return Encoding.UTF8.GetString(utf8Bytes);
}
}
}
}

View File

@ -14,7 +14,7 @@ namespace MediaBrowser.Common.Json.Converters
{
/// <inheritdoc />
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> new Version(reader.GetString());
=> new Version(reader.GetString()!); // Will throw ArgumentNullException on null
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)

View File

@ -33,6 +33,7 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
<PublishRepositoryUrl>true</PublishRepositoryUrl>

View File

@ -1,4 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

View File

@ -1,4 +1,3 @@
#nullable enable
using System;
using System.Diagnostics;
using System.Linq;

View File

@ -1,4 +1,3 @@
#nullable enable
using System;
using System.Net;
using System.Net.Sockets;

View File

@ -1,4 +1,3 @@
#nullable enable
using System;
using System.Net;
using System.Net.Sockets;

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
using System.IO;
using System.Reflection;

View File

@ -1,4 +1,6 @@
#nullable disable
#pragma warning disable SA1649 // File name should match first type name
using System;
using System.IO;
using System.Runtime.InteropServices;

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
using MediaBrowser.Model.Plugins;

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Reflection;

View File

@ -1,4 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;
using MediaBrowser.Model.Plugins;

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Text.Json.Serialization;
using MediaBrowser.Model.Plugins;

View File

@ -14,9 +14,9 @@ namespace MediaBrowser.Common.Progress
/// <summary>
/// The _actions.
/// </summary>
private Action<T> _action;
private Action<T>? _action;
public event EventHandler<T> ProgressChanged;
public event EventHandler<T>? ProgressChanged;
/// <summary>
/// Registers the action.

View File

@ -7,7 +7,7 @@ namespace MediaBrowser.Common.Progress
{
public class SimpleProgress<T> : IProgress<T>
{
public event EventHandler<T> ProgressChanged;
public event EventHandler<T>? ProgressChanged;
public void Report(T value)
{

View File

@ -1,6 +1,4 @@
#nullable enable
using System;
using System;
using System.Diagnostics.CodeAnalysis;
namespace MediaBrowser.Common.Providers

View File

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Threading;

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
using MediaBrowser.Model.Updates;

View File

@ -1,3 +1,4 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using MediaBrowser.Controller.Session;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Threading.Tasks;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
using System;
using System.Linq;
using System.Threading;

View File

@ -1,3 +1,5 @@
#nullable disable
using System.Threading;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Configuration;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Controller.Channels

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
namespace MediaBrowser.Controller.Channels

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System.Collections.Generic;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

View File

@ -1,3 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;

Some files were not shown because too many files have changed in this diff Show More