// 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); }
public void Dispose() { _factory._pool.Return(_buffer); _buffer = null; _factory = null; }
public void Init(byte[] buffer, ArrayPoolSegmentFactory factory) { _buffer = buffer; _factory = factory; }