1 // Licensed to the Apache Software Foundation(ASF) under one
2 // or more contributor license agreements.See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
19 using System.Diagnostics;
21 using System.Threading;
22 using System.Threading.Tasks;
24 namespace Thrift.Transport.Client
26 // ReSharper disable once InconsistentNaming
27 public class TMemoryBufferTransport : TTransport
29 private bool IsDisposed;
31 private int _bytesUsed;
33 public TMemoryBufferTransport()
35 Bytes = new byte[2048]; // default size
38 public TMemoryBufferTransport(int initialCapacity)
40 Bytes = new byte[initialCapacity]; // default size
43 public TMemoryBufferTransport(byte[] buf)
45 Bytes = (byte[])buf.Clone();
46 _bytesUsed = Bytes.Length;
49 public int Position { get; set; }
55 Debug.Assert(_bytesUsed <= Bytes.Length);
60 Array.Resize(ref Bytes, value);
68 Debug.Assert(_bytesUsed <= Bytes.Length);
72 if ((Bytes.Length < value) || (Bytes.Length > (10 * value)))
73 Array.Resize(ref Bytes, Math.Max(2048, (int)(value * 1.25)));
78 public void SetLength(int value)
81 Position = Math.Min(Position, value);
84 public override bool IsOpen => true;
86 public override async Task OpenAsync(CancellationToken cancellationToken)
88 if (cancellationToken.IsCancellationRequested)
90 await Task.FromCanceled(cancellationToken);
94 public override void Close()
99 public void Seek(int delta, SeekOrigin origin)
104 case SeekOrigin.Begin:
107 case SeekOrigin.Current:
108 newPos = Position + delta;
111 newPos = _bytesUsed + delta;
114 throw new ArgumentException(nameof(origin));
117 if ((0 > newPos) || (newPos > _bytesUsed))
118 throw new ArgumentException(nameof(origin));
122 public override ValueTask<int> ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
124 var count = Math.Min(Length - Position, length);
125 Buffer.BlockCopy(Bytes, Position, buffer, offset, count);
127 return new ValueTask<int>(count);
130 public override Task WriteAsync(byte[] buffer, CancellationToken cancellationToken)
132 return WriteAsync(buffer, 0, buffer.Length, cancellationToken);
135 public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
137 var free = Length - Position;
138 Length = Length + count - free;
139 Buffer.BlockCopy(buffer, offset, Bytes, Position, count);
141 return Task.CompletedTask;
144 public override async Task FlushAsync(CancellationToken cancellationToken)
146 if (cancellationToken.IsCancellationRequested)
148 await Task.FromCanceled(cancellationToken);
152 public byte[] GetBuffer()
154 var retval = new byte[Length];
155 Buffer.BlockCopy(Bytes, 0, retval, 0, Length);
159 internal bool TryGetBuffer(out ArraySegment<byte> bufSegment)
161 bufSegment = new ArraySegment<byte>(Bytes, 0, _bytesUsed);
167 protected override void Dispose(bool disposing)