< Summary

Information
Class: IceRpc.Slice.Operations.Internal.IncomingFrameExtensions
Assembly: IceRpc.Slice
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Slice/Operations/Internal/IncomingFrameExtensions.cs
Tag: 1856_27024993493
Line coverage
80%
Covered lines: 33
Uncovered lines: 8
Coverable lines: 41
Total lines: 97
Line coverage: 80.4%
Branch coverage
60%
Covered branches: 6
Total branches: 10
Branch coverage: 60%
Method coverage
83%
Covered methods: 5
Fully covered methods: 1
Total methods: 6
Method coverage: 83.3%
Full method coverage: 16.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
DecodeValueAsync(...)50%22100%
DecodeSegment()50%2281.81%
PerformDecodeAsync()100%11100%
DecodeVoidAsync(...)50%2285.71%
DecodeSegment()75%4483.33%
PerformDecodeAsync()100%210%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Slice/Operations/Internal/IncomingFrameExtensions.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using IceRpc.Features;
 4using IceRpc.Internal;
 5using System.IO.Pipelines;
 6using ZeroC.Slice.Codec;
 7
 8namespace IceRpc.Slice.Operations.Internal;
 9
 10/// <summary>Provides extension methods for <see cref="IncomingFrame" /> to decode its payload when this payload is
 11/// encoded with the Slice encoding.</summary>
 12internal static class IncomingFrameExtensions
 13{
 14    /// <summary>Decodes arguments or a response value from a pipe reader.</summary>
 15    /// <param name="frame">The incoming frame.</param>
 16    /// <param name="feature">The Slice feature.</param>
 17    /// <param name="baseProxy">The base proxy.</param>
 18    /// <param name="decodeFunc">The decode function for the payload arguments or return value.</param>
 19    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 20    /// <returns>The decode value.</returns>
 21    internal static ValueTask<T> DecodeValueAsync<T>(
 22        this IncomingFrame frame,
 23        ISliceFeature feature,
 24        ISliceProxy? baseProxy,
 25        DecodeFunc<T> decodeFunc,
 26        CancellationToken cancellationToken)
 14327    {
 14328        return frame.Payload.TryReadSliceSegment(feature.MaxSegmentSize, out ReadResult readResult) ?
 14329            new(DecodeSegment(readResult)) :
 14330            PerformDecodeAsync();
 31
 32        // All the logic is in this local function.
 33        T DecodeSegment(ReadResult readResult)
 14334        {
 35            // We never call CancelPendingRead; an interceptor or middleware can but it's not correct.
 14336            if (readResult.IsCanceled)
 037            {
 038                throw new InvalidOperationException("Unexpected call to CancelPendingRead.");
 39            }
 40
 14341            var decoder = new SliceDecoder(readResult.Buffer, baseProxy, feature.MaxCollectionAllocation);
 14342            T value = decodeFunc(ref decoder);
 14343            decoder.SkipTagged();
 14344            decoder.CheckEndOfBuffer();
 45
 14346            frame.Payload.AdvanceTo(readResult.Buffer.End);
 14347            return value;
 14348        }
 49
 50        async ValueTask<T> PerformDecodeAsync() =>
 451            DecodeSegment(await frame.Payload.ReadSliceSegmentAsync(
 452                feature.MaxSegmentSize,
 453                cancellationToken).ConfigureAwait(false));
 14354    }
 55
 56    /// <summary>Reads/decodes empty args or a void return value.</summary>
 57    /// <param name="frame">The incoming frame.</param>
 58    /// <param name="feature">The Slice feature.</param>
 59    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 60    internal static ValueTask DecodeVoidAsync(
 61        this IncomingFrame frame,
 62        ISliceFeature feature,
 63        CancellationToken cancellationToken)
 4964    {
 4965        if (frame.Payload.TryReadSliceSegment(feature.MaxSegmentSize, out ReadResult readResult))
 4966        {
 4967            DecodeSegment(readResult);
 4968            return default;
 69        }
 70
 071        return PerformDecodeAsync();
 72
 73        // All the logic is in this local function.
 74        void DecodeSegment(ReadResult readResult)
 4975        {
 76            // We never call CancelPendingRead; an interceptor or middleware can but it's not correct.
 4977            if (readResult.IsCanceled)
 078            {
 079                throw new InvalidOperationException("Unexpected call to CancelPendingRead.");
 80            }
 81
 4982            if (!readResult.Buffer.IsEmpty)
 1283            {
 84                // No need to pass maxCollectionAllocation since the only thing this decoding does is skip unknown tags.
 1285                var decoder = new SliceDecoder(readResult.Buffer);
 1286                decoder.SkipTagged();
 1287                decoder.CheckEndOfBuffer();
 1288            }
 4989            frame.Payload.AdvanceTo(readResult.Buffer.End);
 4990        }
 91
 92        async ValueTask PerformDecodeAsync() =>
 093            DecodeSegment(await frame.Payload.ReadSliceSegmentAsync(
 094                feature.MaxSegmentSize,
 095                cancellationToken).ConfigureAwait(false));
 4996    }
 97}