< Summary

Information
Class: Ice.Internal.Buffer
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/Internal/Buffer.cs
Tag: 71_18251537082
Line coverage
82%
Covered lines: 75
Uncovered lines: 16
Coverable lines: 91
Total lines: 207
Line coverage: 82.4%
Branch coverage
96%
Covered branches: 25
Total branches: 26
Branch coverage: 96.1%
Method coverage
86%
Covered methods: 13
Total methods: 15
Method coverage: 86.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%210%
.ctor(...)100%210%
.ctor(...)100%22100%
size()100%11100%
empty()100%11100%
clear()100%11100%
expand(...)100%44100%
resize(...)100%66100%
reset()100%88100%
reserve(...)83.33%6.7673.08%
.cctor()100%11100%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/Internal/Buffer.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4
 5namespace Ice.Internal;
 6
 7// An instance of ByteBuffer cannot grow beyond its initial capacity.
 8// This class wraps a ByteBuffer and supports reallocation.
 9public class Buffer
 10{
 11    public Buffer()
 112        : this(ByteBuffer.ByteOrder.LittleEndian)
 13    {
 114    }
 15
 116    public Buffer(ByteBuffer.ByteOrder order)
 17    {
 118        b = _emptyBuffer;
 119        _size = 0;
 120        _capacity = 0;
 121        _order = order;
 122    }
 23
 24    public Buffer(byte[] data)
 125        : this(data, ByteBuffer.ByteOrder.LittleEndian)
 26    {
 127    }
 28
 129    public Buffer(byte[] data, ByteBuffer.ByteOrder order)
 30    {
 131        b = ByteBuffer.wrap(data);
 132        b.order(order);
 133        _size = data.Length;
 134        _capacity = b.capacity();
 135        _order = order;
 136    }
 37
 38    public Buffer(ByteBuffer data)
 039        : this(data, ByteBuffer.ByteOrder.LittleEndian)
 40    {
 041    }
 42
 043    public Buffer(ByteBuffer data, ByteBuffer.ByteOrder order)
 44    {
 045        b = data;
 046        b.order(order);
 047        _size = data.remaining();
 048        _capacity = 0;
 049        _order = order;
 050    }
 51
 152    public Buffer(Buffer buf, bool adopt)
 53    {
 154        b = buf.b;
 155        _size = buf._size;
 156        _capacity = buf._capacity;
 157        _shrinkCounter = buf._shrinkCounter;
 158        _order = buf._order;
 59
 160        if (adopt)
 61        {
 162            buf.clear();
 63        }
 164    }
 65
 166    public int size() => _size;
 67
 168    public bool empty() => _size == 0;
 69
 70    public void clear()
 71    {
 172        b = _emptyBuffer;
 173        _size = 0;
 174        _capacity = 0;
 175        _shrinkCounter = 0;
 176    }
 77
 78    //
 79    // Call expand(n) to add room for n additional bytes. Note that expand()
 80    // examines the current position of the buffer first; we don't want to
 81    // expand the buffer if the caller is writing to a location that is
 82    // already in the buffer.
 83    //
 84    public void expand(int n)
 85    {
 186        int sz = (b == _emptyBuffer) ? n : b.position() + n;
 187        if (sz > _size)
 88        {
 189            resize(sz, false);
 90        }
 191    }
 92
 93    public void resize(int n, bool reading)
 94    {
 95        Debug.Assert(b == _emptyBuffer || _capacity > 0);
 96
 197        if (n == 0)
 98        {
 199            clear();
 100        }
 1101        else if (n > _capacity)
 102        {
 1103            reserve(n);
 104        }
 1105        _size = n;
 106
 107        //
 108        // When used for reading, we want to set the buffer's limit to the new size.
 109        //
 1110        if (reading)
 111        {
 1112            b.limit(_size);
 113        }
 1114    }
 115
 116    public void reset()
 117    {
 1118        if (_size > 0 && _size * 2 < _capacity)
 119        {
 120            //
 121            // If the current buffer size is smaller than the
 122            // buffer capacity, we shrink the buffer memory to the
 123            // current size. This is to avoid holding on to too much
 124            // memory if it's not needed anymore.
 125            //
 1126            if (++_shrinkCounter > 2)
 127            {
 1128                reserve(_size);
 1129                _shrinkCounter = 0;
 130            }
 131        }
 132        else
 133        {
 1134            _shrinkCounter = 0;
 135        }
 1136        _size = 0;
 1137        if (b != _emptyBuffer)
 138        {
 1139            b.limit(b.capacity());
 1140            b.position(0);
 141        }
 1142    }
 143
 144    private void reserve(int n)
 145    {
 146        Debug.Assert(_capacity == b.capacity());
 147
 1148        if (n > _capacity)
 149        {
 1150            _capacity = System.Math.Max(n, 2 * _capacity);
 1151            _capacity = System.Math.Max(240, _capacity);
 152        }
 1153        else if (n < _capacity)
 154        {
 1155            _capacity = n;
 156        }
 157        else
 158        {
 0159            return;
 160        }
 161
 162        try
 163        {
 1164            var buf = ByteBuffer.allocate(_capacity);
 165
 1166            if (b == _emptyBuffer)
 167            {
 1168                b = buf;
 169            }
 170            else
 171            {
 1172                int pos = b.position();
 1173                b.position(0);
 1174                b.limit(System.Math.Min(_capacity, b.capacity()));
 1175                buf.put(b);
 1176                b = buf;
 1177                b.limit(b.capacity());
 1178                b.position(pos);
 179            }
 180
 1181            b.order(_order);
 1182        }
 0183        catch (System.OutOfMemoryException)
 184        {
 0185            _capacity = b.capacity(); // Restore the previous capacity
 0186            throw;
 187        }
 0188        catch (System.Exception ex)
 189        {
 0190            _capacity = b.capacity(); // Restore the previous capacity.
 0191            throw new MarshalException("unexpected exception while trying to allocate a ByteBuffer", ex);
 192        }
 193        finally
 194        {
 195            Debug.Assert(_capacity == b.capacity());
 1196        }
 1197    }
 198
 199    public ByteBuffer b;
 200    // Sentinel used for null buffer.
 1201    private static readonly ByteBuffer _emptyBuffer = new();
 202
 203    private int _size;
 204    private int _capacity; // Cache capacity to avoid excessive method calls.
 205    private int _shrinkCounter;
 206    private readonly ByteBuffer.ByteOrder _order;
 207}