Exemplo n.º 1
0
        // TODO: packing
        public static async Task <Message> DecodeAsync(Stream s, CancellationToken ct = default)
        {
            var segmentFactory = new ArrayPoolSegmentFactory();
            var msg            = new Message().Init(segmentFactory, false);
            var intBuf         = ArrayPool <byte> .Shared.Rent(16);

            var bytesRead = await s.ReadAsync(intBuf, 0, 4, ct);

            if (bytesRead < 4)
            {
                throw new InvalidOperationException("Expected more data");
            }

            var segmentCount = BitConverter.ToInt32(intBuf, 0) + 1;
            var readLen      = segmentCount * 4 + (segmentCount % 2 == 0 ? 4 : 0);

            if (intBuf.Length < readLen)
            {
                ArrayPool <byte> .Shared.Return(intBuf);

                intBuf = ArrayPool <byte> .Shared.Rent(segmentCount * 4 + 4);
            }

            bytesRead = await s.ReadAsync(intBuf, 0, readLen, ct);

            if (bytesRead < readLen)
            {
                throw new InvalidOperationException("Expected more data");
            }

            for (int i = 0; i < segmentCount; i++)
            {
                var len = BitConverter.ToInt32(intBuf, i * 4) * 8;
                var seg = await segmentFactory.CreateAsync(msg, len);

                seg.Is(out ArraySegment <byte> arrSeg);
                bytesRead = await s.ReadAsync(arrSeg.Array, arrSeg.Offset, len);

                if (bytesRead < len)
                {
                    throw new InvalidOperationException("Expected more data");
                }
            }

            return(msg);
        }
Exemplo n.º 2
0
 public void Dispose()
 {
     _factory._pool.Return(_buffer);
     _buffer  = null;
     _factory = null;
 }
Exemplo n.º 3
0
 public void Init(byte[] buffer, ArrayPoolSegmentFactory factory)
 {
     _buffer  = buffer;
     _factory = factory;
 }