< Summary

Information
Class: ZeroC.Slice.SliceEncoderExtensions
Assembly: ZeroC.Slice
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/ZeroC.Slice/SliceEncoderExtensions.cs
Tag: 275_13775359185
Line coverage
91%
Covered lines: 87
Uncovered lines: 8
Coverable lines: 95
Total lines: 214
Line coverage: 91.5%
Branch coverage
86%
Covered branches: 33
Total branches: 38
Branch coverage: 86.8%
Method coverage
100%
Covered methods: 8
Total methods: 8
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
EncodeDictionary(...)100%22100%
EncodeDictionaryWithOptionalValueType(...)100%66100%
EncodeResult(...)75%4.1481.81%
EncodeSequence(...)90%10.241086.66%
EncodeSequence(...)100%22100%
EncodeSequenceOfOptionals(...)100%66100%
EncodeSpan(...)100%22100%
WriteByteSequence(...)50%8.3660%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/ZeroC.Slice/SliceEncoderExtensions.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Buffers;
 4using System.Collections.Immutable;
 5using System.Diagnostics;
 6using System.Runtime.InteropServices;
 7
 8namespace ZeroC.Slice;
 9
 10/// <summary>Provides extension methods for <see cref="SliceEncoder" /> to encode sequences or dictionaries.</summary>
 11public static class SliceEncoderExtensions
 12{
 13    /// <summary>Encodes a dictionary.</summary>
 14    /// <typeparam name="TKey">The dictionary key type.</typeparam>
 15    /// <typeparam name="TValue">The dictionary value type.</typeparam>
 16    /// <param name="encoder">The Slice encoder.</param>
 17    /// <param name="v">The dictionary to encode.</param>
 18    /// <param name="keyEncodeAction">The encode action for the keys.</param>
 19    /// <param name="valueEncodeAction">The encode action for the values.</param>
 20    public static void EncodeDictionary<TKey, TValue>(
 21        this ref SliceEncoder encoder,
 22        IEnumerable<KeyValuePair<TKey, TValue>> v,
 23        EncodeAction<TKey> keyEncodeAction,
 24        EncodeAction<TValue> valueEncodeAction)
 25        where TKey : notnull
 552526    {
 552527        encoder.EncodeSize(v.Count());
 3359528        foreach ((TKey key, TValue value) in v)
 851129        {
 851130            keyEncodeAction(ref encoder, key);
 851131            valueEncodeAction(ref encoder, value);
 850932        }
 552333    }
 34
 35    /// <summary>Encodes a dictionary with an optional value type (T? in Slice).</summary>
 36    /// <typeparam name="TKey">The dictionary key type.</typeparam>
 37    /// <typeparam name="TValue">The dictionary value type.</typeparam>
 38    /// <param name="encoder">The Slice encoder.</param>
 39    /// <param name="v">The dictionary to encode.</param>
 40    /// <param name="keyEncodeAction">The encode action for the keys.</param>
 41    /// <param name="valueEncodeAction">The encode action for the non-null values.</param>
 42    public static void EncodeDictionaryWithOptionalValueType<TKey, TValue>(
 43        this ref SliceEncoder encoder,
 44        IEnumerable<KeyValuePair<TKey, TValue>> v,
 45        EncodeAction<TKey> keyEncodeAction,
 46        EncodeAction<TValue> valueEncodeAction)
 47        where TKey : notnull
 1748    {
 1749        int count = v.Count();
 1750        encoder.EncodeSize(count);
 1751        if (count > 0)
 1752        {
 627553            foreach ((TKey key, TValue value) in v)
 311254            {
 55                // Each entry is encoded like a:
 56                // compact struct Pair
 57                // {
 58                //     key: Key,
 59                //     value: Value?
 60                // }
 311261                encoder.EncodeBool(value is not null); // simplified bit sequence
 62
 311263                keyEncodeAction(ref encoder, key);
 311264                if (value is not null)
 53865                {
 53866                    valueEncodeAction(ref encoder, value);
 53867                }
 311268            }
 1769        }
 1770    }
 71
 72    /// <summary>Encodes a result.</summary>
 73    /// <typeparam name="TSuccess">The type of the success value.</typeparam>
 74    /// <typeparam name="TFailure">The type of the failure value.</typeparam>
 75    /// <param name="encoder">The Slice encoder.</param>
 76    /// <param name="v">The result to encode.</param>
 77    /// <param name="successEncodeAction">The encode action for the success type.</param>
 78    /// <param name="failureEncodeAction">The encode action for the failure type.</param>
 79    public static void EncodeResult<TSuccess, TFailure>(
 80        this ref SliceEncoder encoder,
 81        Result<TSuccess, TFailure> v,
 82        EncodeAction<TSuccess> successEncodeAction,
 83        EncodeAction<TFailure> failureEncodeAction)
 484    {
 485        switch (v)
 86        {
 87            case Result<TSuccess, TFailure>.Success success:
 288                encoder.EncodeVarInt32(0);
 289                successEncodeAction(ref encoder, success.Value);
 290                break;
 91
 92            case Result<TSuccess, TFailure>.Failure failure:
 293                encoder.EncodeVarInt32(1);
 294                failureEncodeAction(ref encoder, failure.Value);
 295                break;
 96
 97            default:
 98                // Our result type somehow got extended with an additional enumerator.
 099                Debug.Fail("Unexpected result type");
 0100                break;
 101        }
 4102    }
 103
 104    /// <summary>Encodes a sequence of fixed-size numeric values, such as int or ulong.</summary>
 105    /// <typeparam name="T">The sequence element type.</typeparam>
 106    /// <param name="encoder">The Slice encoder.</param>
 107    /// <param name="v">The sequence of numeric values.</param>
 108    public static void EncodeSequence<T>(this ref SliceEncoder encoder, IEnumerable<T> v)
 109        where T : struct
 6381110    {
 6381111        switch (v)
 112        {
 113            case T[] vArray:
 6368114                encoder.EncodeSpan(new ReadOnlySpan<T>(vArray));
 6368115                break;
 116
 117            case ImmutableArray<T> vImmutableArray:
 4118                encoder.EncodeSpan(vImmutableArray.AsSpan());
 4119                break;
 120
 121            case ArraySegment<T> vArraySegment:
 4122                encoder.EncodeSpan((ReadOnlySpan<T>)vArraySegment.AsSpan());
 4123                break;
 124
 125            case List<T> list:
 1126                encoder.EncodeSpan((ReadOnlySpan<T>)CollectionsMarshal.AsSpan(list));
 1127                break;
 128
 129            default:
 4130                encoder.EncodeSequence(
 4131                    v,
 516132                    (ref SliceEncoder encoder, T element) => encoder.EncodeFixedSizeNumeric(element));
 4133                break;
 134        }
 6381135    }
 136
 137    /// <summary>Encodes a sequence.</summary>
 138    /// <typeparam name="T">The type of the sequence elements. It is non-nullable except for nullable class and nullable
 139    /// custom types with Slice1.</typeparam>
 140    /// <param name="encoder">The Slice encoder.</param>
 141    /// <param name="v">The sequence to encode.</param>
 142    /// <param name="encodeAction">The encode action for an element.</param>
 143    public static void EncodeSequence<T>(this ref SliceEncoder encoder, IEnumerable<T> v, EncodeAction<T> encodeAction)
 57144    {
 57145        encoder.EncodeSize(v.Count()); // potentially slow Linq Count()
 11665146        foreach (T item in v)
 5747147        {
 5747148            encodeAction(ref encoder, item);
 5747149        }
 57150    }
 151
 152    /// <summary>Encodes a sequence where the element type is an optional Slice type (T?).</summary>
 153    /// <typeparam name="T">The nullable type of the sequence elements.</typeparam>
 154    /// <param name="encoder">The Slice encoder.</param>
 155    /// <param name="v">The sequence to encode.</param>
 156    /// <param name="encodeAction">The encode action for a non-null value.</param>
 157    /// <remarks>This method always encodes a bit sequence.</remarks>
 158    public static void EncodeSequenceOfOptionals<T>(
 159        this ref SliceEncoder encoder,
 160        IEnumerable<T> v,
 161        EncodeAction<T> encodeAction)
 17162    {
 17163        int count = v.Count(); // potentially slow Linq Count()
 17164        encoder.EncodeSize(count);
 17165        if (count > 0)
 17166        {
 17167            BitSequenceWriter bitSequenceWriter = encoder.GetBitSequenceWriter(count);
 2583168            foreach (T item in v)
 1266169            {
 1266170                bitSequenceWriter.Write(item is not null);
 1266171                if (item is not null)
 540172                {
 540173                    encodeAction(ref encoder, item);
 540174                }
 1266175            }
 17176        }
 17177    }
 178
 179    /// <summary>Encodes a span of fixed-size numeric values, such as int or ulong.</summary>
 180    /// <typeparam name="T">The span element type.</typeparam>
 181    /// <param name="encoder">The Slice encoder.</param>
 182    /// <param name="v">The span of numeric values represented by a <see cref="ReadOnlySpan{T}" />.</param>
 183    public static void EncodeSpan<T>(this ref SliceEncoder encoder, ReadOnlySpan<T> v)
 184        where T : struct
 6396185    {
 186        // This method works because (as long as) there is no padding in the memory representation of the ReadOnlySpan.
 6396187        encoder.EncodeSize(v.Length);
 6396188        if (!v.IsEmpty)
 6390189        {
 6390190            encoder.WriteByteSpan(MemoryMarshal.AsBytes(v));
 6390191        }
 6396192    }
 193
 194    /// <summary>Copies a sequence of bytes to the underlying buffer writer.</summary>
 195    /// <param name="encoder">The Slice encoder.</param>
 196    /// <param name="v">The sequence to copy.</param>
 197    public static void WriteByteSequence(this ref SliceEncoder encoder, ReadOnlySequence<byte> v)
 11198    {
 11199        if (!v.IsEmpty)
 6200        {
 6201            if (v.IsSingleSegment)
 6202            {
 6203                encoder.WriteByteSpan(v.FirstSpan);
 6204            }
 205            else
 0206            {
 0207                foreach (ReadOnlyMemory<byte> buffer in v)
 0208                {
 0209                    encoder.WriteByteSpan(buffer.Span);
 0210                }
 0211            }
 6212        }
 11213    }
 214}