using System; using System.Threading; using System.Threading.Tasks; using FrostFS.Object; using Grpc.Core; namespace FrostFS.SDK.ClientV2; public sealed class ObjectReader(AsyncServerStreamingCall call) : IObjectReader { private bool disposed; public AsyncServerStreamingCall Call { get; private set; } = call; internal async Task ReadHeader() { if (!await Call.ResponseStream.MoveNext().ConfigureAwait(false)) throw new FrostFsStreamException("unexpected end of stream"); var response = Call.ResponseStream.Current; Verifier.CheckResponse(response); if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Init) throw new FrostFsStreamException("unexpected message type"); return new Object.Object { ObjectId = response.Body.Init.ObjectId, Header = response.Body.Init.Header, }; } public async ValueTask?> ReadChunk(CancellationToken cancellationToken = default) { if (!await Call.ResponseStream.MoveNext(cancellationToken).ConfigureAwait(false)) return null; var response = Call.ResponseStream.Current; Verifier.CheckResponse(response); if (response.Body.ObjectPartCase != GetResponse.Types.Body.ObjectPartOneofCase.Chunk) throw new FrostFsStreamException("unexpected message type"); return response.Body.Chunk.Memory; } public void Dispose() { if (!disposed) { Call?.Dispose(); GC.SuppressFinalize(this); disposed = true; } } }