< Summary

Information
Class: IceRpc.Ice.Operations.Internal.IncomingFrameExtensions
Assembly: IceRpc.Ice
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc.Ice/Operations/Internal/IncomingFrameExtensions.cs
Tag: 1321_24790053727
Line coverage
65%
Covered lines: 30
Uncovered lines: 16
Coverable lines: 46
Total lines: 104
Line coverage: 65.2%
Branch coverage
50%
Covered branches: 5
Total branches: 10
Branch coverage: 50%
Method coverage
66%
Covered methods: 4
Fully covered methods: 0
Total methods: 6
Method coverage: 66.6%
Full method coverage: 0%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
DecodeValueAsync(...)50%22100%
DecodePayload()50%2287.5%
PerformDecodeAsync()100%210%
DecodeVoidAsync(...)50%2285.71%
DecodePayload()50%7441.66%
PerformDecodeAsync()100%210%

File(s)

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

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using IceRpc.Features;
 4using IceRpc.Ice.Codec;
 5using System.IO.Pipelines;
 6
 7namespace IceRpc.Ice.Operations.Internal;
 8
 9/// <summary>Provides extension methods for <see cref="IncomingFrame" /> to decode its payload when this payload is
 10/// encoded with the Ice encoding.</summary>
 11internal static class IncomingFrameExtensions
 12{
 13    /// <summary>Decodes arguments or a response value from a pipe reader.</summary>
 14    /// <param name="frame">The incoming frame.</param>
 15    /// <param name="feature">The Ice feature.</param>
 16    /// <param name="baseProxy">The base proxy.</param>
 17    /// <param name="decodeFunc">The decode function for the payload arguments or return value.</param>
 18    /// <param name="activator">The activator.</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        IIceFeature feature,
 24        IIceProxy? baseProxy,
 25        DecodeFunc<T> decodeFunc,
 26        IActivator activator,
 27        CancellationToken cancellationToken)
 11328    {
 11329        return frame.Payload.TryReadFullPayload(feature.MaxPayloadSize, out ReadResult readResult) ?
 11330                new(DecodePayload(readResult)) :
 11331                PerformDecodeAsync();
 32
 33        // All the logic is in this local function.
 34        T DecodePayload(ReadResult readResult)
 11335        {
 36            // We never call CancelPendingRead; an interceptor or middleware can but it's not correct.
 11337            if (readResult.IsCanceled)
 038            {
 039                throw new InvalidOperationException("Unexpected call to CancelPendingRead.");
 40            }
 41
 11342            var decoder = new IceDecoder(
 11343                readResult.Buffer,
 11344                baseProxy,
 11345                feature.MaxCollectionAllocation,
 11346                activator,
 11347                feature.MaxDepth);
 11348            T value = decodeFunc(ref decoder);
 49
 11350            decoder.SkipTagged();
 11351            decoder.CheckEndOfBuffer();
 52
 11353            frame.Payload.AdvanceTo(readResult.Buffer.End);
 11354            return value;
 11355        }
 56
 57        async ValueTask<T> PerformDecodeAsync() =>
 058            DecodePayload(await frame.Payload.ReadFullPayloadAsync(
 059                feature.MaxPayloadSize,
 060                cancellationToken).ConfigureAwait(false));
 11361    }
 62
 63    /// <summary>Reads/decodes empty args or a void return value.</summary>
 64    /// <param name="frame">The incoming frame.</param>
 65    /// <param name="feature">The Ice feature.</param>
 66    /// <param name="cancellationToken">A cancellation token that receives the cancellation requests.</param>
 67    internal static ValueTask DecodeVoidAsync(
 68        this IncomingFrame frame,
 69        IIceFeature feature,
 70        CancellationToken cancellationToken)
 11271    {
 11272        if (frame.Payload.TryReadFullPayload(feature.MaxPayloadSize, out ReadResult readResult))
 11273        {
 11274            DecodePayload(readResult);
 11275            return default;
 76        }
 77
 078        return PerformDecodeAsync();
 79
 80        // All the logic is in this local function.
 81        void DecodePayload(ReadResult readResult)
 11282        {
 83            // We never call CancelPendingRead; an interceptor or middleware can but it's not correct.
 11284            if (readResult.IsCanceled)
 085            {
 086                throw new InvalidOperationException("Unexpected call to CancelPendingRead.");
 87            }
 88
 11289            if (!readResult.Buffer.IsEmpty)
 090            {
 91                // No need to pass maxCollectionAllocation since the only thing this decoding does is skip unknown tags.
 092                var decoder = new IceDecoder(readResult.Buffer);
 093                decoder.SkipTagged();
 094                decoder.CheckEndOfBuffer();
 095            }
 11296            frame.Payload.AdvanceTo(readResult.Buffer.End);
 11297        }
 98
 99        async ValueTask PerformDecodeAsync() =>
 0100            DecodePayload(await frame.Payload.ReadFullPayloadAsync(
 0101                feature.MaxPayloadSize,
 0102                cancellationToken).ConfigureAwait(false));
 112103    }
 104}