mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-22 06:54:40 +00:00
Updates recommended
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
|
||||
<PackageVersion Include="Bullseye" Version="6.1.0" />
|
||||
<PackageVersion Include="AwesomeAssertions" Version="9.4.0" />
|
||||
<PackageVersion Include="AwesomeAssertions" Version="9.5.0" />
|
||||
<PackageVersion Include="Glob" Version="1.1.9" />
|
||||
<PackageVersion Include="JetBrains.Profiler.SelfApi" Version="2.5.18" />
|
||||
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
|
||||
|
||||
@@ -24,14 +24,6 @@ public enum EncodingType
|
||||
/// </summary>
|
||||
public static class ArchiveEncodingExtensions
|
||||
{
|
||||
#if !NETFRAMEWORK
|
||||
/// <summary>
|
||||
/// Registers the code pages encoding provider.
|
||||
/// </summary>
|
||||
static ArchiveEncodingExtensions() =>
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
|
||||
extension(IArchiveEncoding encoding)
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
52
src/SharpCompress/Common/EncodingProviderRegistration.cs
Normal file
52
src/SharpCompress/Common/EncodingProviderRegistration.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace SharpCompress.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Registers <see cref="CodePagesEncodingProvider"/> so that legacy code pages (e.g. 437, 866)
|
||||
/// used by archive headers are resolvable via <see cref="Encoding.GetEncoding(int)"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This runs from a module initializer rather than a static constructor. Registration must happen
|
||||
/// before <em>any</em> encoding lookup, including lookups a caller performs itself while building an
|
||||
/// <see cref="ArchiveEncoding"/> — for example <c>Encoding.GetEncoding(866)</c>. A static constructor
|
||||
/// only fires when its own type is first touched, which made registration order-dependent and caused
|
||||
/// <see cref="System.NotSupportedException"/> for callers that resolved a code page before touching
|
||||
/// any other SharpCompress type.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// .NET Framework resolves these code pages natively, so registration is only needed elsewhere.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
internal static class EncodingProviderRegistration
|
||||
{
|
||||
#if !NETFRAMEWORK
|
||||
// CA2255 discourages [ModuleInitializer] in libraries because load-time work can surprise consumers.
|
||||
// Registering an encoding provider is the exception it does not account for: the registration has to be
|
||||
// in place before the first Encoding.GetEncoding call, and that call may be made by the consumer before
|
||||
// it touches any SharpCompress type. Every lazier trigger reintroduces the ordering bug. Callers who need
|
||||
// registration to be explicit (e.g. to keep it trimmable) can call RegisterCodePagesProvider themselves.
|
||||
#pragma warning disable CA2255
|
||||
[ModuleInitializer]
|
||||
#pragma warning restore CA2255
|
||||
internal static void Initialize() => RegisterCodePagesProvider();
|
||||
|
||||
private static bool _registered;
|
||||
|
||||
/// <summary>
|
||||
/// Registers the code pages provider if it has not already been registered. Idempotent.
|
||||
/// </summary>
|
||||
internal static void RegisterCodePagesProvider()
|
||||
{
|
||||
if (_registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_registered = true;
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SharpCompress.Common;
|
||||
|
||||
namespace SharpCompress.Compressors.LZMA;
|
||||
|
||||
internal static class Log
|
||||
{
|
||||
private static readonly Stack<string> INDENT = new();
|
||||
private static bool NEEDS_INDENT = true;
|
||||
|
||||
static Log() => INDENT.Push("");
|
||||
|
||||
public static void PushIndent(string indent = " ") => INDENT.Push(INDENT.Peek() + indent);
|
||||
|
||||
public static void PopIndent()
|
||||
{
|
||||
if (INDENT.Count == 1)
|
||||
{
|
||||
throw new ArchiveOperationException();
|
||||
}
|
||||
|
||||
INDENT.Pop();
|
||||
}
|
||||
|
||||
private static void EnsureIndent()
|
||||
{
|
||||
if (NEEDS_INDENT)
|
||||
{
|
||||
NEEDS_INDENT = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(object value)
|
||||
{
|
||||
EnsureIndent();
|
||||
}
|
||||
|
||||
public static void Write(string text)
|
||||
{
|
||||
EnsureIndent();
|
||||
}
|
||||
|
||||
public static void Write(string format, params object[] args)
|
||||
{
|
||||
EnsureIndent();
|
||||
}
|
||||
|
||||
public static void WriteLine()
|
||||
{
|
||||
NEEDS_INDENT = true;
|
||||
}
|
||||
|
||||
public static void WriteLine(object value)
|
||||
{
|
||||
EnsureIndent();
|
||||
NEEDS_INDENT = true;
|
||||
}
|
||||
|
||||
public static void WriteLine(string text)
|
||||
{
|
||||
EnsureIndent();
|
||||
NEEDS_INDENT = true;
|
||||
}
|
||||
|
||||
public static void WriteLine(string format, params object[] args)
|
||||
{
|
||||
EnsureIndent();
|
||||
NEEDS_INDENT = true;
|
||||
}
|
||||
}
|
||||
@@ -36,20 +36,16 @@ public static class StreamStackExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the root underlying stream at the bottom of the stack.
|
||||
/// This is useful for seeking when the intermediate streams don't support it.
|
||||
/// Rewinds by <paramref name="count"/> bytes within the buffered region of the nearest
|
||||
/// <see cref="SharpCompressStream"/> in the stack.
|
||||
/// </summary>
|
||||
public static Stream GetRootStream(this IStreamStack stack)
|
||||
{
|
||||
var current = stack.BaseStream();
|
||||
while (current is IStreamStack streamStack)
|
||||
{
|
||||
current = streamStack.BaseStream();
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
internal static void Rewind(this IStreamStack stream, int count)
|
||||
/// <remarks>
|
||||
/// Named distinctly from <see cref="SharpCompressStream.Rewind()"/> and
|
||||
/// <see cref="SharpCompressStream.Rewind(bool)"/>, which rewind to the recording anchor instead.
|
||||
/// A single <c>Rewind</c> name across both would let <c>Rewind(4)</c> and <c>Rewind(true)</c> select
|
||||
/// unrelated semantics on the same variable with no compiler complaint.
|
||||
/// </remarks>
|
||||
internal static void RewindBytes(this IStreamStack stream, int count)
|
||||
{
|
||||
IStreamStack? current = stream;
|
||||
|
||||
|
||||
19
src/SharpCompress/Polyfills/ModuleInitializerAttribute.cs
Normal file
19
src/SharpCompress/Polyfills/ModuleInitializerAttribute.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
// This file is required for [ModuleInitializer] to work on older target frameworks
|
||||
// (.NET Framework 4.8, .NET Standard 2.0/2.1). The attribute is recognised by the C# compiler
|
||||
// by name, so supplying our own definition is enough to enable module initializers there.
|
||||
|
||||
#if NETFRAMEWORK || NETSTANDARD2_0 || NETSTANDARD2_1
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// Used to indicate to the compiler that a method should be called in its containing module's initializer.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||
internal sealed class ModuleInitializerAttribute : Attribute { }
|
||||
#endif
|
||||
@@ -13,14 +13,6 @@ namespace SharpCompress.Test.Tar;
|
||||
|
||||
public class TarWriterAsyncTests : WriterTests
|
||||
{
|
||||
static TarWriterAsyncTests()
|
||||
{
|
||||
#if !NETFRAMEWORK
|
||||
//fix issue where these tests could not be ran in isolation
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
public TarWriterAsyncTests()
|
||||
: base(ArchiveType.Tar) => UseExtensionInsteadOfNameToVerify = true;
|
||||
|
||||
|
||||
@@ -11,14 +11,6 @@ namespace SharpCompress.Test.Tar;
|
||||
|
||||
public class TarWriterTests : WriterTests
|
||||
{
|
||||
static TarWriterTests()
|
||||
{
|
||||
#if !NETFRAMEWORK
|
||||
//fix issue where these tests could not be ran in isolation
|
||||
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
|
||||
#endif
|
||||
}
|
||||
|
||||
public TarWriterTests()
|
||||
: base(ArchiveType.Tar) => UseExtensionInsteadOfNameToVerify = true;
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
".NETFramework,Version=v4.8": {
|
||||
"AwesomeAssertions": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.4.0, )",
|
||||
"resolved": "9.4.0",
|
||||
"contentHash": "dJxkWiQ8D+xT6Gr2sSL83+Mar+Vpy2JTcUPxFcckpPJ8VYBfSgnk+zqpS6t7kcGnjz8NLyF14qfuoL4bKzzoew==",
|
||||
"requested": "[9.5.0, )",
|
||||
"resolved": "9.5.0",
|
||||
"contentHash": "F92MsjoF8B7IdcWETru4QGZx6VAl38qQPKNGS3kwPwlLB5lb0O4bhFqG8a8sz2estQJWkKmZkVy1r19HTaFcpg==",
|
||||
"dependencies": {
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
@@ -331,9 +331,9 @@
|
||||
"net10.0": {
|
||||
"AwesomeAssertions": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.4.0, )",
|
||||
"resolved": "9.4.0",
|
||||
"contentHash": "dJxkWiQ8D+xT6Gr2sSL83+Mar+Vpy2JTcUPxFcckpPJ8VYBfSgnk+zqpS6t7kcGnjz8NLyF14qfuoL4bKzzoew=="
|
||||
"requested": "[9.5.0, )",
|
||||
"resolved": "9.5.0",
|
||||
"contentHash": "F92MsjoF8B7IdcWETru4QGZx6VAl38qQPKNGS3kwPwlLB5lb0O4bhFqG8a8sz2estQJWkKmZkVy1r19HTaFcpg=="
|
||||
},
|
||||
"Microsoft.NET.Test.Sdk": {
|
||||
"type": "Direct",
|
||||
|
||||
Reference in New Issue
Block a user