save development progress

This commit is contained in:
StellaOps Bot
2025-12-25 23:09:58 +02:00
parent d71853ad7e
commit aa70af062e
351 changed files with 37683 additions and 150156 deletions

View File

@@ -0,0 +1,131 @@
using ZstdSharp;
namespace StellaOps.Concelier.Federation.Compression;
/// <summary>
/// ZStandard compression utilities for federation bundles.
/// </summary>
public static class ZstdCompression
{
/// <summary>Default compression level (balanced speed/ratio).</summary>
public const int DefaultLevel = 3;
/// <summary>Minimum compression level.</summary>
public const int MinLevel = 1;
/// <summary>Maximum compression level.</summary>
public const int MaxLevel = 19;
/// <summary>
/// Create a compression stream wrapping the output.
/// </summary>
/// <param name="output">Target stream for compressed data.</param>
/// <param name="level">Compression level (1-19, default 3).</param>
/// <returns>Stream that compresses data written to it.</returns>
public static CompressionStream CreateCompressionStream(Stream output, int level = DefaultLevel)
{
ValidateLevel(level);
return new CompressionStream(output, level);
}
/// <summary>
/// Create a decompression stream wrapping the input.
/// </summary>
/// <param name="input">Source stream of compressed data.</param>
/// <returns>Stream that decompresses data read from it.</returns>
public static DecompressionStream CreateDecompressionStream(Stream input)
{
return new DecompressionStream(input);
}
/// <summary>
/// Compress data in memory.
/// </summary>
/// <param name="data">Uncompressed data.</param>
/// <param name="level">Compression level (1-19, default 3).</param>
/// <returns>Compressed data.</returns>
public static byte[] Compress(ReadOnlySpan<byte> data, int level = DefaultLevel)
{
ValidateLevel(level);
using var compressor = new Compressor(level);
return compressor.Wrap(data).ToArray();
}
/// <summary>
/// Decompress data in memory.
/// </summary>
/// <param name="compressed">Compressed data.</param>
/// <returns>Decompressed data.</returns>
public static byte[] Decompress(ReadOnlySpan<byte> compressed)
{
using var decompressor = new Decompressor();
return decompressor.Unwrap(compressed).ToArray();
}
/// <summary>
/// Compress a file to another file.
/// </summary>
public static async Task CompressFileAsync(
string inputPath,
string outputPath,
int level = DefaultLevel,
CancellationToken ct = default)
{
ValidateLevel(level);
await using var input = File.OpenRead(inputPath);
await using var output = File.Create(outputPath);
await using var compressor = CreateCompressionStream(output, level);
await input.CopyToAsync(compressor, ct);
}
/// <summary>
/// Decompress a file to another file.
/// </summary>
public static async Task DecompressFileAsync(
string inputPath,
string outputPath,
CancellationToken ct = default)
{
await using var input = File.OpenRead(inputPath);
await using var decompressor = CreateDecompressionStream(input);
await using var output = File.Create(outputPath);
await decompressor.CopyToAsync(output, ct);
}
/// <summary>
/// Decompress from one stream to another.
/// </summary>
public static async Task DecompressAsync(
Stream input,
Stream output,
CancellationToken ct = default)
{
await using var decompressor = CreateDecompressionStream(input);
await decompressor.CopyToAsync(output, ct);
}
/// <summary>
/// Compress from one stream to another.
/// </summary>
public static async Task CompressAsync(
Stream input,
Stream output,
int level = DefaultLevel,
CancellationToken ct = default)
{
ValidateLevel(level);
await using var compressor = CreateCompressionStream(output, level);
await input.CopyToAsync(compressor, ct);
}
private static void ValidateLevel(int level)
{
if (level < MinLevel || level > MaxLevel)
{
throw new ArgumentOutOfRangeException(
nameof(level),
level,
$"Compression level must be between {MinLevel} and {MaxLevel}");
}
}
}