Files
git.stella-ops.org/src/StellaOps.Concelier.Exporter.TrivyDb/TrivyDbBlob.cs
2025-10-18 20:46:16 +03:00

79 lines
2.2 KiB
C#

using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Concelier.Exporter.TrivyDb;
public sealed class TrivyDbBlob
{
private readonly Func<CancellationToken, ValueTask<Stream>> _openReadAsync;
private TrivyDbBlob(Func<CancellationToken, ValueTask<Stream>> openReadAsync, long length)
{
_openReadAsync = openReadAsync ?? throw new ArgumentNullException(nameof(openReadAsync));
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
Length = length;
}
public long Length { get; }
public ValueTask<Stream> OpenReadAsync(CancellationToken cancellationToken)
=> _openReadAsync(cancellationToken);
public static TrivyDbBlob FromBytes(ReadOnlyMemory<byte> payload)
{
if (payload.IsEmpty)
{
return new TrivyDbBlob(static _ => ValueTask.FromResult<Stream>(Stream.Null), 0);
}
if (MemoryMarshal.TryGetArray(payload, out ArraySegment<byte> segment) && segment.Array is not null && segment.Offset == 0)
{
return FromArray(segment.Array);
}
return FromArray(payload.ToArray());
}
public static TrivyDbBlob FromFile(string path, long length)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException("File path must be provided.", nameof(path));
}
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
return new TrivyDbBlob(
cancellationToken => ValueTask.FromResult<Stream>(new FileStream(
path,
FileMode.Open,
FileAccess.Read,
FileShare.Read,
bufferSize: 81920,
options: FileOptions.Asynchronous | FileOptions.SequentialScan)),
length);
}
public static TrivyDbBlob FromArray(byte[] buffer)
{
if (buffer is null)
{
throw new ArgumentNullException(nameof(buffer));
}
return new TrivyDbBlob(
_ => ValueTask.FromResult<Stream>(new MemoryStream(buffer, writable: false)),
buffer.LongLength);
}
}