mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-25 00:15:15 +00:00
Updates recommended
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user