Files
2018-04-11 09:31:39 -07:00

3539 lines
137 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace DotNetty.Buffers.Tests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using DotNetty.Common.Utilities;
using Xunit;
public abstract class AbstractByteBufferTests : IDisposable
{
const int Capacity = 4096; // Must be even
const int BlockSize = 128;
readonly Queue<IByteBuffer> buffers = new Queue<IByteBuffer>();
readonly int seed;
Random random;
IByteBuffer buffer;
// This is used for detection byte buffer types assume int.MaxValue
// to be the MaxCapacity such as CompositeByteBuffer so that the
// MaxCapacity related tests do not run
protected bool AssumedMaxCapacity = false;
protected IByteBuffer NewBuffer(int capacity) => this.NewBuffer(capacity, int.MaxValue);
protected abstract IByteBuffer NewBuffer(int capacity, int maxCapacity);
protected virtual bool DiscardReadBytesDoesNotMoveWritableBytes() => true;
protected AbstractByteBufferTests()
{
this.buffer = this.NewBuffer(Capacity);
this.seed = Environment.TickCount;
this.random = new Random(this.seed);
}
public virtual void Dispose()
{
if (this.buffer != null)
{
Assert.True(this.buffer.Release());
Assert.Equal(0, this.buffer.ReferenceCount);
try
{
this.buffer.Release();
}
catch
{
// Ignore.
}
this.buffer = null;
}
for (;;)
{
IByteBuffer buf = null;
if (this.buffers.Count > 0)
{
buf = this.buffers.Dequeue();
}
if (buf == null)
{
break;
}
try
{
buf.Release();
}
catch
{
// Ignore.
}
}
}
[Fact]
public void ComparableInterfaceNotViolated()
{
this.buffer.SetWriterIndex(this.buffer.ReaderIndex);
Assert.True(this.buffer.WritableBytes >= 4);
this.buffer.WriteLong(0);
IByteBuffer buffer2 = this.NewBuffer(Capacity);
buffer2.SetWriterIndex(buffer2.ReaderIndex);
// Write an unsigned integer that will cause buffer.getUnsignedInt() - buffer2.getUnsignedInt() to underflow the
// int type and wrap around on the negative side.
buffer2.WriteLong(0xF0000000L);
Assert.True(this.buffer.CompareTo(buffer2) < 0);
Assert.True(buffer2.CompareTo(this.buffer) > 0);
buffer2.Release();
}
[Fact]
public void InitialState()
{
Assert.Equal(Capacity, this.buffer.Capacity);
Assert.Equal(0, this.buffer.ReaderIndex);
}
[Fact]
public void ReaderIndexBoundaryCheck1()
{
this.buffer.SetWriterIndex(0);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetReaderIndex(-1));
}
[Fact]
public void ReaderIndexBoundaryCheck2()
{
this.buffer.SetWriterIndex(this.buffer.Capacity);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetReaderIndex(this.buffer.Capacity + 1));
}
[Fact]
public void ReaderIndexBoundaryCheck3()
{
this.buffer.SetWriterIndex(Capacity / 2);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetReaderIndex(Capacity * 3 / 2));
}
[Fact]
public void ReaderIndexBoundaryCheck4()
{
this.buffer.SetWriterIndex(0);
this.buffer.SetReaderIndex(0);
this.buffer.SetWriterIndex(this.buffer.Capacity);
this.buffer.SetReaderIndex(this.buffer.Capacity);
}
[Fact]
public void WriterIndexBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetWriterIndex(-1));
[Fact]
public void WriterIndexBoundaryCheck2()
{
this.buffer.SetWriterIndex(Capacity);
this.buffer.SetReaderIndex(Capacity);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetWriterIndex(this.buffer.Capacity + 1));
}
[Fact]
public void WriterIndexBoundaryCheck3()
{
this.buffer.SetWriterIndex(Capacity);
this.buffer.SetReaderIndex(Capacity / 2);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetWriterIndex(Capacity / 4));
}
[Fact]
public void WriterIndexBoundaryCheck4()
{
this.buffer.SetWriterIndex(0);
this.buffer.SetReaderIndex(0);
this.buffer.SetWriterIndex(Capacity);
this.buffer.WriteBytes(ArrayExtensions.ZeroBytes);
}
[Fact]
public void GetBooleanBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBoolean(-1));
[Fact]
public void GetBooleanBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBoolean(this.buffer.Capacity));
[Fact]
public void GetByteBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetByte(-1));
[Fact]
public void GetByteBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetByte(this.buffer.Capacity));
[Fact]
public void GetShortBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetShort(-1));
[Fact]
public void GetShortBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetShort(this.buffer.Capacity - 1));
[Fact]
public void GetShortLEBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetShortLE(-1));
[Fact]
public void GetShortLEBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetShortLE(this.buffer.Capacity - 1));
[Fact]
public void GetMediumBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetMedium(-1));
[Fact]
public void GetMediumBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetMedium(this.buffer.Capacity - 2));
[Fact]
public void GetMediumLEBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetMediumLE(-1));
[Fact]
public void GetMediumLEBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetMediumLE(this.buffer.Capacity - 2));
[Fact]
public void GetIntBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetInt(-1));
[Fact]
public void GetIntBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetInt(this.buffer.Capacity - 3));
[Fact]
public void GetIntLEBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetIntLE(-1));
[Fact]
public void GetIntLEBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetIntLE(this.buffer.Capacity - 3));
[Fact]
public void GetLongBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetLong(-1));
[Fact]
public void GetLongBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetLong(this.buffer.Capacity - 7));
[Fact]
public void GetLongLEBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetLongLE(-1));
[Fact]
public void GetLongLEBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetLongLE(this.buffer.Capacity - 7));
[Fact]
public void GetByteArrayBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBytes(-1, ArrayExtensions.ZeroBytes));
[Fact]
public void GetByteArrayBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBytes(-1, ArrayExtensions.ZeroBytes, 0, 0));
[Fact]
public void GetByteArrayBoundaryCheck3()
{
var dst = new byte[4];
this.buffer.SetInt(0, 0x01020304);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBytes(0, dst, -1, 4));
// No partial copy is expected.
Assert.Equal(0, dst[0]);
Assert.Equal(0, dst[1]);
Assert.Equal(0, dst[2]);
Assert.Equal(0, dst[3]);
}
[Fact]
public void GetByteArrayBoundaryCheck4()
{
var dst = new byte[4];
this.buffer.SetInt(0, 0x01020304);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBytes(0, dst, 1, 4));
// No partial copy is expected.
Assert.Equal(0, dst[0]);
Assert.Equal(0, dst[1]);
Assert.Equal(0, dst[2]);
Assert.Equal(0, dst[3]);
}
[Fact]
public void CopyBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.Copy(-1, 0));
[Fact]
public void CopyBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.Copy(0, this.buffer.Capacity + 1));
[Fact]
public void CopyBoundaryCheck3() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.Copy(this.buffer.Capacity + 1, 0));
[Fact]
public void CopyBoundaryCheck4() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.Copy(this.buffer.Capacity, 1));
[Fact]
public void SetIndexBoundaryCheck1() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetIndex(-1, Capacity));
[Fact]
public void SetIndexBoundaryCheck2() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetIndex(Capacity / 2, Capacity / 4));
[Fact]
public void SetIndexBoundaryCheck3() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SetIndex(0, Capacity + 1));
[Fact]
public void GetByteBufferState()
{
var dst = new byte[4];
this.buffer.SetByte(0, 1);
this.buffer.SetByte(1, 2);
this.buffer.SetByte(2, 3);
this.buffer.SetByte(3, 4);
this.buffer.GetBytes(1, dst, 1, 2);
Assert.Equal(0, dst[0]);
Assert.Equal(2, dst[1]);
Assert.Equal(3, dst[2]);
Assert.Equal(0, dst[3]);
}
[Fact]
public void GetDirectByteBufferBoundaryCheck() => Assert.Throws<IndexOutOfRangeException>(() => this.buffer.GetBytes(-1, new byte[0]));
[Fact]
public void RandomByteAccess()
{
for (int i = 0; i < this.buffer.Capacity; i ++)
{
byte value = (byte)this.random.Next();
this.buffer.SetByte(i, value);
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i ++)
{
byte value = (byte)this.random.Next();
Assert.Equal(value, this.buffer.GetByte(i));
}
}
[Fact]
public void RandomShortAccess() => this.RandomShortAccess0(true);
[Fact]
public void RandomShortLEAccess() => this.RandomShortAccess0(false);
void RandomShortAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 1; i += 2)
{
short value = (short)this.random.Next();
if (testBigEndian)
{
this.buffer.SetShort(i, value);
}
else
{
this.buffer.SetShortLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 1; i += 2)
{
short value = (short)this.random.Next();
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetShort(i));
}
else
{
Assert.Equal(value, this.buffer.GetShortLE(i));
}
}
}
[Fact]
public void RandomUnsignedShortAccess() => this.RandomUnsignedShortAccess0(true);
[Fact]
public void RandomUnsignedShortLEAccess() => this.RandomUnsignedShortAccess0(false);
void RandomUnsignedShortAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 1; i += 2)
{
ushort value = (ushort)(this.random.Next() & 0xFFFF);
if (testBigEndian)
{
this.buffer.SetUnsignedShort(i, value);
}
else
{
this.buffer.SetUnsignedShortLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 1; i += 2)
{
int value = this.random.Next() & 0xFFFF;
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetUnsignedShort(i));
}
else
{
Assert.Equal(value, this.buffer.GetUnsignedShortLE(i));
}
}
}
[Fact]
public void RandomMediumAccess() => this.RandomMediumAccess0(true);
[Fact]
public void RandomMediumLEAccess() => this.RandomMediumAccess0(false);
void RandomMediumAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 2; i += 3)
{
int value = this.random.Next();
if (testBigEndian)
{
this.buffer.SetMedium(i, value);
}
else
{
this.buffer.SetMediumLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 2; i += 3)
{
int value = this.random.Next() << 8 >> 8;
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetMedium(i));
}
else
{
Assert.Equal(value, this.buffer.GetMediumLE(i));
}
}
}
[Fact]
public void RandomUnsignedMediumAccess() => this.RandomUnsignedMediumAccess0(true);
[Fact]
public void RandomUnsignedMediumLEAccess() => this.RandomUnsignedMediumAccess0(false);
void RandomUnsignedMediumAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 2; i += 3)
{
int value = this.random.Next();
if (testBigEndian)
{
this.buffer.SetMedium(i, value);
}
else
{
this.buffer.SetMediumLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 2; i += 3)
{
int value = this.random.Next().ToUnsignedMediumInt();
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetUnsignedMedium(i));
}
else
{
Assert.Equal(value, this.buffer.GetUnsignedMediumLE(i));
}
}
}
[Fact]
public void RandomIntAccess() => this.RandomIntAccess0(true);
[Fact]
public void RandomIntLEAccess() => this.RandomIntAccess0(false);
void RandomIntAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 3; i += 4)
{
int value = this.random.Next();
if (testBigEndian)
{
this.buffer.SetInt(i, value);
}
else
{
this.buffer.SetIntLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 3; i += 4)
{
int value = this.random.Next();
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetInt(i));
}
else
{
Assert.Equal(value, this.buffer.GetIntLE(i));
}
}
}
[Fact]
public void RandomUnsignedIntAccess() => this.RandomUnsignedIntAccess0(true);
[Fact]
public void RandomUnsignedIntLEAccess() => this.RandomUnsignedIntAccess0(false);
void RandomUnsignedIntAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 3; i += 4)
{
uint value = (uint)(this.random.Next() & 0xFFFFFFFFL);
if (testBigEndian)
{
this.buffer.SetUnsignedInt(i, value);
}
else
{
this.buffer.SetUnsignedIntLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 3; i += 4)
{
long value = this.random.Next() & 0xFFFFFFFFL;
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetUnsignedInt(i));
}
else
{
Assert.Equal(value, this.buffer.GetUnsignedIntLE(i));
}
}
}
[Fact]
public void RandomLongAccess() => this.RandomLongAccess0(true);
[Fact]
public void RandomLongLEAccess() => this.RandomLongAccess0(false);
void RandomLongAccess0(bool testBigEndian)
{
for (int i = 0; i < this.buffer.Capacity - 7; i += 8)
{
long value = this.random.NextLong();
if (testBigEndian)
{
this.buffer.SetLong(i, value);
}
else
{
this.buffer.SetLongLE(i, value);
}
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 7; i += 8)
{
long value = this.random.NextLong();
if (testBigEndian)
{
Assert.Equal(value, this.buffer.GetLong(i));
}
else
{
Assert.Equal(value, this.buffer.GetLongLE(i));
}
}
}
[Fact]
public void RandomFloatAccess()
{
for (int i = 0; i < this.buffer.Capacity - 3; i += 4)
{
float value = (float)this.random.NextDouble();
this.buffer.SetFloat(i, value);
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 3; i += 4)
{
float value = (float)this.random.NextDouble();
Assert.Equal(value, this.buffer.GetFloat(i), 2);
}
}
[Fact]
public void RandomDoubleAccess()
{
for (int i = 0; i < this.buffer.Capacity - 7; i += 8)
{
double value = this.random.NextDouble();
this.buffer.SetDouble(i, value);
}
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity - 7; i += 8)
{
double value = this.random.NextDouble();
Assert.Equal(value, this.buffer.GetDouble(i), 2);
}
}
[Fact]
public void SetZero()
{
this.buffer.Clear();
while (this.buffer.IsWritable())
{
this.buffer.WriteByte(0xFF);
}
for (int i = 0; i < this.buffer.Capacity;)
{
int length = Math.Min(this.buffer.Capacity - i, this.random.Next(32));
this.buffer.SetZero(i, length);
i += length;
}
for (int i = 0; i < this.buffer.Capacity; i++)
{
Assert.Equal(0, this.buffer.GetByte(i));
}
}
[Fact]
public void SequentialByteAccess()
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i ++)
{
byte value = (byte)this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
this.buffer.WriteByte(value);
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsWritable());
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i ++)
{
byte value = (byte)this.random.Next();
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
Assert.Equal(value, this.buffer.ReadByte());
}
Assert.Equal(this.buffer.Capacity, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsReadable());
Assert.False(this.buffer.IsWritable());
}
[Fact]
public void SequentialShortAccess() => this.SequentialShortAccess0(true);
[Fact]
public void SequentialShortLEAccess() => this.SequentialShortAccess0(false);
void SequentialShortAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i += 2)
{
short value = (short)this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteShort(value);
}
else
{
this.buffer.WriteShortLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsWritable());
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i += 2)
{
short value = (short)this.random.Next();
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadShort());
}
else
{
Assert.Equal(value, this.buffer.ReadShortLE());
}
}
Assert.Equal(this.buffer.Capacity, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsReadable());
Assert.False(this.buffer.IsWritable());
}
[Fact]
public void SequentialUnsignedShortAccess() => this.SequentialUnsignedShortAccess0(true);
[Fact]
public void SequentialUnsignedShortLEAccess() => this.SequentialUnsignedShortAccess0(true);
void SequentialUnsignedShortAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i += 2)
{
short value = (short)this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteShort(value);
}
else
{
this.buffer.WriteShortLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsWritable());
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i += 2)
{
int value = this.random.Next() & 0xFFFF;
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadUnsignedShort());
}
else
{
Assert.Equal(value, this.buffer.ReadUnsignedShortLE());
}
}
Assert.Equal(this.buffer.Capacity, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsReadable());
Assert.False(this.buffer.IsWritable());
}
[Fact]
public void SequentialMediumAccess() => this.SequentialMediumAccess0(true);
[Fact]
public void SequentialMediumLEAccess() => this.SequentialMediumAccess0(false);
void SequentialMediumAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity / 3 * 3; i += 3)
{
int value = this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteMedium(value);
}
else
{
this.buffer.WriteMediumLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity / 3 * 3, this.buffer.WriterIndex);
Assert.Equal(this.buffer.Capacity % 3, this.buffer.WritableBytes);
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity / 3 * 3; i += 3)
{
int value = this.random.Next() << 8 >> 8;
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadMedium());
}
else
{
Assert.Equal(value, this.buffer.ReadMediumLE());
}
}
Assert.Equal(this.buffer.Capacity / 3 * 3, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity / 3 * 3, this.buffer.WriterIndex);
Assert.Equal(0, this.buffer.ReadableBytes);
Assert.Equal(this.buffer.Capacity % 3, this.buffer.WritableBytes);
}
[Fact]
public void SequentialUnsignedMediumAccess() => this.SequentialUnsignedMediumAccess0(true);
[Fact]
public void SequentialUnsignedMediumLEAccess() => this.SequentialUnsignedMediumAccess0(false);
void SequentialUnsignedMediumAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity / 3 * 3; i += 3)
{
int value = this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteMedium(value);
}
else
{
this.buffer.WriteMediumLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity / 3 * 3, this.buffer.WriterIndex);
Assert.Equal(this.buffer.Capacity % 3, this.buffer.WritableBytes);
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity / 3 * 3; i += 3)
{
int value = (this.random.Next() << 8).RightUShift(8);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadUnsignedMedium());
}
else
{
Assert.Equal(value, this.buffer.ReadUnsignedMediumLE());
}
}
Assert.Equal(this.buffer.Capacity / 3 * 3, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity / 3 * 3, this.buffer.WriterIndex);
Assert.Equal(0, this.buffer.ReadableBytes);
Assert.Equal(this.buffer.Capacity % 3, this.buffer.WritableBytes);
}
[Fact]
public void SequentialIntAccess() => this.SequentialIntAccess0(true);
[Fact]
public void SequentialIntLEAccess() => this.SequentialIntAccess0(false);
void SequentialIntAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i += 4)
{
int value = this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteInt(value);
}
else
{
this.buffer.WriteIntLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsWritable());
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i += 4)
{
int value = this.random.Next();
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadInt());
}
else
{
Assert.Equal(value, this.buffer.ReadIntLE());
}
}
Assert.Equal(this.buffer.Capacity, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsReadable());
Assert.False(this.buffer.IsWritable());
}
[Fact]
public void SequentialUnsignedIntAccess() => this.SequentialUnsignedIntAccess0(true);
[Fact]
public void SequentialUnsignedIntLEAccess() => this.SequentialUnsignedIntAccess0(false);
void SequentialUnsignedIntAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i += 4)
{
int value = this.random.Next();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteInt(value);
}
else
{
this.buffer.WriteIntLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsWritable());
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i += 4)
{
long value = this.random.Next() & 0xFFFFFFFFL;
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadUnsignedInt());
}
else
{
Assert.Equal(value, this.buffer.ReadUnsignedIntLE());
}
}
Assert.Equal(this.buffer.Capacity, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsReadable());
Assert.False(this.buffer.IsWritable());
}
[Fact]
public void SequentialLongAccess() => this.SequentialLongAccess0(true);
[Fact]
public void SequentialLongLEAccess() => this.SequentialLongAccess0(false);
void SequentialLongAccess0(bool testBigEndian)
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i += 8)
{
long value = this.random.NextLong();
Assert.Equal(i, this.buffer.WriterIndex);
Assert.True(this.buffer.IsWritable());
if (testBigEndian)
{
this.buffer.WriteLong(value);
}
else
{
this.buffer.WriteLongLE(value);
}
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsWritable());
this.random = new Random(this.seed);
for (int i = 0; i < this.buffer.Capacity; i += 8)
{
long value = this.random.NextLong();
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.True(this.buffer.IsReadable());
if (testBigEndian)
{
Assert.Equal(value, this.buffer.ReadLong());
}
else
{
Assert.Equal(value, this.buffer.ReadLongLE());
}
}
Assert.Equal(this.buffer.Capacity, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
Assert.False(this.buffer.IsReadable());
Assert.False(this.buffer.IsWritable());
}
[Fact]
public void ByteArrayTransfer()
{
var value = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
this.buffer.SetBytes(i, value, this.random.Next(BlockSize), BlockSize);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
int valueOffset = this.random.Next(BlockSize);
this.buffer.GetBytes(i, value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue[j], value[j]);
}
}
}
[Fact]
public void RandomByteArrayTransfer1()
{
var value = new byte[BlockSize];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
this.buffer.SetBytes(i, value);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
this.buffer.GetBytes(i, value);
for (int j = 0; j < BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value[j]);
}
}
}
[Fact]
public void RandomByteArrayTransfer2()
{
var value = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
this.buffer.SetBytes(i, value, this.random.Next(BlockSize), BlockSize);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
int valueOffset = this.random.Next(BlockSize);
this.buffer.GetBytes(i, value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value[j]);
}
}
}
[Fact]
public void RandomHeapBufferTransfer1()
{
var valueContent = new byte[BlockSize];
IByteBuffer value = Unpooled.WrappedBuffer(valueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
value.SetIndex(0, BlockSize);
this.buffer.SetBytes(i, value);
Assert.Equal(BlockSize, value.ReaderIndex);
Assert.Equal(BlockSize, value.WriterIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
value.Clear();
this.buffer.GetBytes(i, value);
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(BlockSize, value.WriterIndex);
for (int j = 0; j < BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
}
}
[Fact]
public void RandomHeapBufferTransfer2()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = Unpooled.WrappedBuffer(valueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
this.buffer.SetBytes(i, value, this.random.Next(BlockSize), BlockSize);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
int valueOffset = this.random.Next(BlockSize);
this.buffer.GetBytes(i, value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
}
}
[Fact]
public void RandomDirectBufferTransfer()
{
var tmp = new byte[BlockSize * 2];
IByteBuffer value = this.ReleaseLater(Unpooled.Buffer(BlockSize * 2));
this.buffers.Enqueue(value);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(tmp);
value.SetBytes(0, tmp, 0, value.Capacity);
this.buffer.SetBytes(i, value, this.random.Next(BlockSize), BlockSize);
}
this.random = new Random(this.seed);
IByteBuffer expectedValue = this.ReleaseLater(Unpooled.Buffer(BlockSize * 2));
this.buffers.Enqueue(expectedValue);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(tmp);
expectedValue.SetBytes(0, tmp, 0, expectedValue.Capacity);
int valueOffset = this.random.Next(BlockSize);
this.buffer.GetBytes(i, value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
}
}
[Fact]
public void RandomByteBufferTransfer()
{
var value = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
this.buffer.SetBytes(i, value, this.random.Next(BlockSize), BlockSize);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
int valueOffset = this.random.Next(BlockSize);
this.buffer.GetBytes(i, value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue[j], value[j]);
}
}
}
[Fact]
public void SequentialByteArrayTransfer1()
{
var value = new byte[BlockSize];
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
this.buffer.WriteBytes(value);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
this.buffer.ReadBytes(value);
for (int j = 0; j < BlockSize; j ++)
{
Assert.Equal(expectedValue[j], value[j]);
}
}
}
[Fact]
public void SequentialByteArrayTransfer2()
{
var value = new byte[BlockSize * 2];
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
int readerIndex = this.random.Next(BlockSize);
this.buffer.WriteBytes(value, readerIndex, BlockSize);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
int valueOffset = this.random.Next(BlockSize);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
this.buffer.ReadBytes(value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue[j], value[j]);
}
}
}
[Fact]
public void SequentialHeapBufferTransfer1()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = Unpooled.WrappedBuffer(valueContent);
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
this.buffer.WriteBytes(value, this.random.Next(BlockSize), BlockSize);
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(valueContent.Length, value.WriterIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
int valueOffset = this.random.Next(BlockSize);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
this.buffer.ReadBytes(value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(valueContent.Length, value.WriterIndex);
}
}
[Fact]
public void SequentialHeapBufferTransfer2()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = Unpooled.WrappedBuffer(valueContent);
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
int readerIndex = this.random.Next(BlockSize);
value.SetReaderIndex(readerIndex);
value.SetWriterIndex(readerIndex + BlockSize);
this.buffer.WriteBytes(value);
Assert.Equal(readerIndex + BlockSize, value.WriterIndex);
Assert.Equal(value.WriterIndex, value.ReaderIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
int valueOffset = this.random.Next(BlockSize);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
value.SetReaderIndex(valueOffset);
value.SetWriterIndex(valueOffset);
this.buffer.ReadBytes(value, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
Assert.Equal(valueOffset, value.ReaderIndex);
Assert.Equal(valueOffset + BlockSize, value.WriterIndex);
}
}
[Fact]
public void SequentialDirectBufferTransfer1()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = this.ReleaseLater(Unpooled.Buffer(BlockSize * 2));
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
value.SetBytes(0, valueContent);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
this.buffer.WriteBytes(value, this.random.Next(BlockSize), BlockSize);
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(0, value.WriterIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = this.ReleaseLater(Unpooled.WrappedBuffer(expectedValueContent));
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
int valueOffset = this.random.Next(BlockSize);
value.SetBytes(0, valueContent);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
this.buffer.ReadBytes(value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(0, value.WriterIndex);
}
}
[Fact]
public void SequentialDirectBufferTransfer2()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = this.ReleaseLater(Unpooled.Buffer(BlockSize * 2));
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
value.SetBytes(0, valueContent);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
int readerIndex = this.random.Next(BlockSize);
value.SetReaderIndex(0);
value.SetWriterIndex(readerIndex + BlockSize);
value.SetReaderIndex(readerIndex);
this.buffer.WriteBytes(value);
Assert.Equal(readerIndex + BlockSize, value.WriterIndex);
Assert.Equal(value.WriterIndex, value.ReaderIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = this.ReleaseLater(Unpooled.WrappedBuffer(expectedValueContent));
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
value.SetBytes(0, valueContent);
int valueOffset = this.random.Next(BlockSize);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
value.SetReaderIndex(valueOffset);
value.SetWriterIndex(valueOffset);
this.buffer.ReadBytes(value, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
Assert.Equal(valueOffset, value.ReaderIndex);
Assert.Equal(valueOffset + BlockSize, value.WriterIndex);
}
}
[Fact]
public void SequentialByteBufferBackedHeapBufferTransfer1()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = Unpooled.WrappedBuffer(new byte[BlockSize * 2]);
value.SetWriterIndex(0);
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
value.SetBytes(0, valueContent);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
this.buffer.WriteBytes(value, this.random.Next(BlockSize), BlockSize);
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(0, value.WriterIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
int valueOffset = this.random.Next(BlockSize);
value.SetBytes(0, valueContent);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
this.buffer.ReadBytes(value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
Assert.Equal(0, value.ReaderIndex);
Assert.Equal(0, value.WriterIndex);
}
}
[Fact]
public void SequentialByteBufferBackedHeapBufferTransfer2()
{
var valueContent = new byte[BlockSize * 2];
IByteBuffer value = Unpooled.WrappedBuffer(new byte[BlockSize * 2]);
value.SetWriterIndex(0);
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(valueContent);
value.SetBytes(0, valueContent);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
int readerIndex = this.random.Next(BlockSize);
value.SetReaderIndex(0);
value.SetWriterIndex(readerIndex + BlockSize);
value.SetReaderIndex(readerIndex);
this.buffer.WriteBytes(value);
Assert.Equal(readerIndex + BlockSize, value.WriterIndex);
Assert.Equal(value.WriterIndex, value.ReaderIndex);
}
this.random = new Random(this.seed);
var expectedValueContent = new byte[BlockSize * 2];
IByteBuffer expectedValue = Unpooled.WrappedBuffer(expectedValueContent);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValueContent);
value.SetBytes(0, valueContent);
int valueOffset = this.random.Next(BlockSize);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
value.SetReaderIndex(valueOffset);
value.SetWriterIndex(valueOffset);
this.buffer.ReadBytes(value, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue.GetByte(j), value.GetByte(j));
}
Assert.Equal(valueOffset, value.ReaderIndex);
Assert.Equal(valueOffset + BlockSize, value.WriterIndex);
}
}
[Fact]
public void SequentialByteBufferTransfer()
{
this.buffer.SetWriterIndex(0);
var value = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(value);
this.buffer.WriteBytes(value, this.random.Next(BlockSize), BlockSize);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize * 2];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
int valueOffset = this.random.Next(BlockSize);
this.buffer.ReadBytes(value, valueOffset, BlockSize);
for (int j = valueOffset; j < valueOffset + BlockSize; j ++)
{
Assert.Equal(expectedValue[j], value[j]);
}
}
}
[Fact]
public void SequentialCopiedBufferTransfer1()
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
var value = new byte[BlockSize];
this.random.NextBytes(value);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
this.buffer.WriteBytes(value);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
IByteBuffer actualValue = this.buffer.ReadBytes(BlockSize);
Assert.Equal(Unpooled.WrappedBuffer(expectedValue), actualValue, EqualityComparer<IByteBuffer>.Default);
// Make sure if it is a copied this.buffer.
actualValue.SetByte(0, (byte)(actualValue.GetByte(0) + 1));
Assert.False(this.buffer.GetByte(i) == actualValue.GetByte(0));
actualValue.Release();
}
}
[Fact]
public void SequentialSlice1()
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
var value = new byte[BlockSize];
this.random.NextBytes(value);
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(i, this.buffer.WriterIndex);
this.buffer.WriteBytes(value);
}
this.random = new Random(this.seed);
var expectedValue = new byte[BlockSize];
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
this.random.NextBytes(expectedValue);
Assert.Equal(i, this.buffer.ReaderIndex);
Assert.Equal(Capacity, this.buffer.WriterIndex);
IByteBuffer actualValue = this.buffer.ReadSlice(BlockSize);
Assert.Equal(Unpooled.WrappedBuffer(expectedValue), actualValue, EqualityComparer<IByteBuffer>.Default);
// Make sure if it is a sliced this.buffer.
actualValue.SetByte(0, (byte)(actualValue.GetByte(0) + 1));
Assert.Equal(this.buffer.GetByte(i), actualValue.GetByte(0));
}
}
[Fact]
public void WriteZero()
{
Assert.Throws<ArgumentOutOfRangeException>(() => this.buffer.WriteZero(-1));
this.buffer.Clear();
while (this.buffer.IsWritable())
{
this.buffer.WriteByte(0xFF);
}
this.buffer.Clear();
for (int i = 0; i < this.buffer.Capacity;)
{
int length = Math.Min(this.buffer.Capacity - i, this.random.Next(32));
this.buffer.WriteZero(length);
i += length;
}
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.WriterIndex);
for (int i = 0; i < this.buffer.Capacity; i++)
{
Assert.Equal(0, this.buffer.GetByte(i));
}
}
[Fact]
public void DiscardReadBytes()
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i += 4)
{
this.buffer.WriteInt(i);
}
IByteBuffer copy = Unpooled.CopiedBuffer(this.buffer);
// Make sure there's no effect if called when readerIndex is 0.
this.buffer.SetReaderIndex(Capacity / 4);
this.buffer.MarkReaderIndex();
this.buffer.SetWriterIndex(Capacity / 3);
this.buffer.MarkWriterIndex();
this.buffer.SetReaderIndex(0);
this.buffer.SetWriterIndex(Capacity / 2);
this.buffer.DiscardReadBytes();
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(Capacity / 2, this.buffer.WriterIndex);
Assert.Equal(copy.Slice(0, Capacity / 2), this.buffer.Slice(0, Capacity / 2));
this.buffer.ResetReaderIndex();
Assert.Equal(Capacity / 4, this.buffer.ReaderIndex);
this.buffer.ResetWriterIndex();
Assert.Equal(Capacity / 3, this.buffer.WriterIndex);
// Make sure bytes after writerIndex is not copied.
this.buffer.SetReaderIndex(1);
this.buffer.SetWriterIndex(Capacity / 2);
this.buffer.DiscardReadBytes();
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(Capacity / 2 - 1, this.buffer.WriterIndex);
Assert.Equal(copy.Slice(1, Capacity / 2 - 1), this.buffer.Slice(0, Capacity / 2 - 1));
if (this.DiscardReadBytesDoesNotMoveWritableBytes())
{
// If writable bytes were copied, the test should fail to avoid unnecessary memory bandwidth consumption.
Assert.False(copy.Slice(Capacity / 2, Capacity / 2).Equals(this.buffer.Slice(Capacity / 2 - 1, Capacity / 2)));
}
else
{
Assert.Equal(copy.Slice(Capacity / 2, Capacity / 2), this.buffer.Slice(Capacity / 2 - 1, Capacity / 2));
}
// Marks also should be relocated.
this.buffer.ResetReaderIndex();
Assert.Equal(Capacity / 4 - 1, this.buffer.ReaderIndex);
this.buffer.ResetWriterIndex();
Assert.Equal(Capacity / 3 - 1, this.buffer.WriterIndex);
copy.Release();
}
/**
* The similar test case with {@link #testDiscardReadBytes()} but this one
* discards a large chunk at once.
*/
[Fact]
public void DiscardReadBytes2()
{
this.buffer.SetWriterIndex(0);
for (int i = 0; i < this.buffer.Capacity; i ++)
{
this.buffer.WriteByte((byte)i);
}
IByteBuffer copy = this.ReleaseLater(Unpooled.CopiedBuffer(this.buffer));
// Discard the first (CAPACITY / 2 - 1) bytes.
this.buffer.SetIndex(Capacity / 2 - 1, Capacity - 1);
this.buffer.DiscardReadBytes();
Assert.Equal(0, this.buffer.ReaderIndex);
Assert.Equal(Capacity / 2, this.buffer.WriterIndex);
for (int i = 0; i < Capacity / 2; i ++)
{
Assert.Equal(copy.Slice(Capacity / 2 - 1 + i, Capacity / 2 - i), this.buffer.Slice(i, Capacity / 2 - i));
}
}
[Fact]
public void Copy()
{
for (int i = 0; i < this.buffer.Capacity; i ++)
{
byte value = (byte)this.random.Next();
this.buffer.SetByte(i, value);
}
int readerIndex = Capacity / 3;
int writerIndex = Capacity * 2 / 3;
this.buffer.SetIndex(readerIndex, writerIndex);
// Make sure all properties are copied.
IByteBuffer copy = this.ReleaseLater(this.buffer.Copy());
Assert.Equal(0, copy.ReaderIndex);
Assert.Equal(this.buffer.ReadableBytes, copy.WriterIndex);
Assert.Equal(this.buffer.ReadableBytes, copy.Capacity);
for (int i = 0; i < copy.Capacity; i ++)
{
Assert.Equal(this.buffer.GetByte(i + readerIndex), copy.GetByte(i));
}
// Make sure the this.buffer content is independent from each other.
this.buffer.SetByte(readerIndex, (byte)(this.buffer.GetByte(readerIndex) + 1));
Assert.True(this.buffer.GetByte(readerIndex) != copy.GetByte(0));
copy.SetByte(1, (byte)(copy.GetByte(1) + 1));
Assert.True(this.buffer.GetByte(readerIndex + 1) != copy.GetByte(1));
}
[Fact]
public void Duplicate()
{
for (int i = 0; i < this.buffer.Capacity; i ++)
{
byte value = (byte)this.random.Next();
this.buffer.SetByte(i, value);
}
int readerIndex = Capacity / 3;
int writerIndex = Capacity * 2 / 3;
this.buffer.SetIndex(readerIndex, writerIndex);
// Make sure all properties are copied.
IByteBuffer duplicate = this.buffer.Duplicate();
Assert.Equal(this.buffer.ReadableBytes, duplicate.ReadableBytes);
Assert.Equal(0, this.buffer.CompareTo(duplicate));
// Make sure the this.buffer content is shared.
this.buffer.SetByte(readerIndex, (byte)(this.buffer.GetByte(readerIndex) + 1));
Assert.Equal(this.buffer.GetByte(readerIndex), duplicate.GetByte(duplicate.ReaderIndex));
duplicate.SetByte(duplicate.ReaderIndex, (byte)(duplicate.GetByte(duplicate.ReaderIndex) + 1));
Assert.Equal(this.buffer.GetByte(readerIndex), duplicate.GetByte(duplicate.ReaderIndex));
}
[Fact]
public void SliceIndex()
{
Assert.Equal(0, this.buffer.Slice(0, this.buffer.Capacity).ReaderIndex);
Assert.Equal(0, this.buffer.Slice(0, this.buffer.Capacity - 1).ReaderIndex);
Assert.Equal(0, this.buffer.Slice(1, this.buffer.Capacity - 1).ReaderIndex);
Assert.Equal(0, this.buffer.Slice(1, this.buffer.Capacity - 2).ReaderIndex);
Assert.Equal(this.buffer.Capacity, this.buffer.Slice(0, this.buffer.Capacity).WriterIndex);
Assert.Equal(this.buffer.Capacity - 1, this.buffer.Slice(0, this.buffer.Capacity - 1).WriterIndex);
Assert.Equal(this.buffer.Capacity - 1, this.buffer.Slice(1, this.buffer.Capacity - 1).WriterIndex);
Assert.Equal(this.buffer.Capacity - 2, this.buffer.Slice(1, this.buffer.Capacity - 2).WriterIndex);
}
[Fact]
public void RetainedSliceIndex()
{
IByteBuffer retainedSlice = this.buffer.RetainedSlice(0, this.buffer.Capacity);
Assert.Equal(0, retainedSlice.ReaderIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(0, this.buffer.Capacity - 1);
Assert.Equal(0, retainedSlice.ReaderIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(1, this.buffer.Capacity - 1);
Assert.Equal(0, retainedSlice.ReaderIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(1, this.buffer.Capacity - 2);
Assert.Equal(0, retainedSlice.ReaderIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(0, this.buffer.Capacity);
Assert.Equal(this.buffer.Capacity, retainedSlice.WriterIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(0, this.buffer.Capacity - 1);
Assert.Equal(this.buffer.Capacity - 1, retainedSlice.WriterIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(1, this.buffer.Capacity - 1);
Assert.Equal(this.buffer.Capacity - 1, retainedSlice.WriterIndex);
retainedSlice.Release();
retainedSlice = this.buffer.RetainedSlice(1, this.buffer.Capacity - 2);
Assert.Equal(this.buffer.Capacity - 2, retainedSlice.WriterIndex);
retainedSlice.Release();
}
[Fact]
public void TestEquals()
{
Assert.False(this.buffer.Equals(null));
Assert.False(this.buffer.Equals(new object()));
var value = new byte[32];
this.buffer.SetIndex(0, value.Length);
this.random.NextBytes(value);
this.buffer.SetBytes(0, value);
Assert.Equal(this.buffer, Unpooled.WrappedBuffer(value), EqualityComparer<IByteBuffer>.Default);
value[0] ++;
Assert.False(this.buffer.Equals(Unpooled.WrappedBuffer(value)));
}
[Fact]
public void CompareTo()
{
Assert.Throws<NullReferenceException>(() => this.buffer.CompareTo(null));
// Fill the this.random stuff
var value = new byte[32];
this.random.NextBytes(value);
// Prevent overflow / underflow
if (value[0] == 0)
{
value[0]++;
}
else if (value[0] == 0xFF)
{
value[0]--;
}
this.buffer.SetIndex(0, value.Length);
this.buffer.SetBytes(0, value);
Assert.Equal(0, this.buffer.CompareTo(Unpooled.WrappedBuffer(value)));
value[0]++;
Assert.True(this.buffer.CompareTo(Unpooled.WrappedBuffer(value)) < 0);
value[0] -= 2;
Assert.True(this.buffer.CompareTo(Unpooled.WrappedBuffer(value)) > 0);
value[0]++;
Assert.True(this.buffer.CompareTo(Unpooled.WrappedBuffer(value, 0, 31)) > 0);
Assert.True(this.buffer.Slice(0, 31).CompareTo(Unpooled.WrappedBuffer(value)) < 0);
}
[Fact]
public void CompareTo2()
{
byte[] bytes = { 1, 2, 3, 4 };
byte[] bytesReversed = { 4, 3, 2, 1 };
IByteBuffer buf1 = this.NewBuffer(4).Clear().WriteBytes(bytes);
IByteBuffer buf2 = this.NewBuffer(4).Clear().WriteBytes(bytesReversed);
IByteBuffer buf3 = this.NewBuffer(4).Clear().WriteBytes(bytes);
IByteBuffer buf4 = this.NewBuffer(4).Clear().WriteBytes(bytesReversed);
try
{
Assert.Equal(buf1.CompareTo(buf2), buf3.CompareTo(buf4));
Assert.Equal(buf2.CompareTo(buf1), buf4.CompareTo(buf3));
Assert.Equal(buf1.CompareTo(buf3), buf2.CompareTo(buf4));
Assert.Equal(buf3.CompareTo(buf1), buf4.CompareTo(buf2));
}
finally
{
buf1.Release();
buf2.Release();
buf3.Release();
buf4.Release();
}
}
[Fact]
public void String()
{
IByteBuffer copied = Unpooled.CopiedBuffer(Encoding.GetEncoding("ISO-8859-1").GetBytes("Hello, World!"));
this.buffer.Clear();
this.buffer.WriteBytes(copied);
Assert.Equal("Hello, World!", this.buffer.ToString(Encoding.GetEncoding("ISO-8859-1")));
copied.Release();
}
[Fact]
public void IndexOf()
{
this.buffer.Clear();
this.buffer.WriteByte(1);
this.buffer.WriteByte(2);
this.buffer.WriteByte(3);
this.buffer.WriteByte(2);
this.buffer.WriteByte(1);
Assert.Equal(-1, this.buffer.IndexOf(1, 4, 1));
Assert.Equal(-1, this.buffer.IndexOf(4, 1, 1));
Assert.Equal(1, this.buffer.IndexOf(1, 4, 2));
Assert.Equal(3, this.buffer.IndexOf(4, 1, 2));
}
[Fact]
public void IoBuffer1()
{
if (this.buffer.IoBufferCount != 1)
{
// skipping
return;
}
var value = new byte[this.buffer.Capacity];
this.random.NextBytes(value);
this.buffer.Clear();
this.buffer.WriteBytes(value);
AssertRemainingEquals(new ArraySegment<byte>(value), this.buffer.GetIoBuffer());
}
[Fact]
public void ToByteBuffer2()
{
if (this.buffer.IoBufferCount != 1)
{
// skipping
return;
}
var value = new byte[this.buffer.Capacity];
this.random.NextBytes(value);
this.buffer.Clear();
this.buffer.WriteBytes(value);
for (int i = 0; i < this.buffer.Capacity - BlockSize + 1; i += BlockSize)
{
AssertRemainingEquals(new ArraySegment<byte>(value, i, BlockSize), this.buffer.GetIoBuffer(i, BlockSize));
}
}
static void AssertRemainingEquals(ArraySegment<byte> expected, ArraySegment<byte> actual)
{
int remaining = expected.Count;
int remaining2 = actual.Count;
Assert.Equal(remaining, remaining2);
Assert.Equal(expected, actual);
}
[Fact]
public void SkipBytes1()
{
this.buffer.SetIndex(Capacity / 4, Capacity / 2);
this.buffer.SkipBytes(Capacity / 4);
Assert.Equal(Capacity / 4 * 2, this.buffer.ReaderIndex);
Assert.Throws<IndexOutOfRangeException>(() => this.buffer.SkipBytes(Capacity / 4 + 1));
// Should remain unchanged.
Assert.Equal(Capacity / 4 * 2, this.buffer.ReaderIndex);
}
[Fact]
public void HashCode()
{
IByteBuffer elemA = this.ReleaseLater(Unpooled.Buffer(15));
IByteBuffer elemB = this.ReleaseLater(Unpooled.Buffer(15));
elemA.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 });
elemB.WriteBytes(new byte[] { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 });
var set = new HashSet<IByteBuffer>();
set.Add(elemA);
set.Add(elemB);
Assert.Equal(2, set.Count);
Assert.Contains(this.ReleaseLater(elemA.Copy()), set);
IByteBuffer elemBCopy = this.ReleaseLater(elemB.Copy());
Assert.Contains(elemBCopy, set);
this.buffer.Clear();
this.buffer.WriteBytes(elemA.Duplicate());
Assert.True(set.Remove(this.buffer));
Assert.DoesNotContain(elemA, set);
Assert.Single(set);
this.buffer.Clear();
this.buffer.WriteBytes(elemB.Duplicate());
Assert.True(set.Remove(this.buffer));
Assert.DoesNotContain(elemB, set);
Assert.Empty(set);
}
// Test case for https://github.com/netty/netty/issues/325
[Fact]
public void DiscardAllReadBytes()
{
this.buffer.SetWriterIndex(this.buffer.Capacity);
this.buffer.SetReaderIndex(this.buffer.WriterIndex);
this.buffer.DiscardReadBytes();
}
[Fact]
public void ForEachByte()
{
this.buffer.Clear();
for (int i = 0; i < Capacity; i ++)
{
this.buffer.WriteByte(i + 1);
}
int lastIndex = 0;
this.buffer.SetIndex(Capacity / 4, Capacity * 3 / 4);
int i1 = Capacity / 4;
Assert.Equal(-1,
this.buffer.ForEachByte(new ByteProcessor(
value =>
{
Assert.Equal(value, (byte)(i1 + 1));
Volatile.Write(ref lastIndex, i1);
i1++;
return true;
})));
Assert.Equal(Capacity * 3 / 4 - 1, Volatile.Read(ref lastIndex));
}
[Fact]
public void ForEachByteAbort()
{
this.buffer.Clear();
for (int i = 0; i < Capacity; i ++)
{
this.buffer.WriteByte(i + 1);
}
int stop = Capacity / 2;
int i1 = Capacity / 3;
Assert.Equal(stop, this.buffer.ForEachByte(Capacity / 3, Capacity / 3, new ByteProcessor(value =>
{
Assert.Equal((byte)(i1 + 1), value);
if (i1 == stop)
{
return false;
}
i1++;
return true;
})));
}
[Fact]
public void ForEachByteDesc()
{
this.buffer.Clear();
for (int i = 0; i < Capacity; i ++)
{
this.buffer.WriteByte(i + 1);
}
int lastIndex = 0;
int i1 = Capacity * 3 / 4 - 1;
Assert.Equal(-1, this.buffer.ForEachByteDesc(Capacity / 4, Capacity * 2 / 4, new ByteProcessor(value =>
{
Assert.Equal((byte)(i1 + 1), value);
Volatile.Write(ref lastIndex, i1);
i1 --;
return true;
})));
Assert.Equal(Capacity / 4, Volatile.Read(ref lastIndex));
}
[Fact]
public void DuplicateBytesInArrayMultipleThreads() => this.BytesInArrayMultipleThreads(false);
[Fact]
public void SliceBytesInArrayMultipleThreads() => this.BytesInArrayMultipleThreads(true);
void BytesInArrayMultipleThreads(bool slice)
{
//byte[] bytes = new byte[8];
//this.random.NextBytes(bytes);
//IByteBuffer buffer = ReferenceCountUtil.ReleaseLater(this.NewBuffer(8));
//this.buffer.WriteBytes(bytes);
//final AtomicReference<Throwable> cause = new AtomicReference<Throwable>();
//final CountDownLatch latch = new CountDownLatch(60000);
//final CyclicBarrier barrier = new CyclicBarrier(11);
//for (int i = 0; i < 10; i++) {
// new Thread(new Runnable() {
// public void run() {
// while (cause.get() == null && latch.getCount() > 0) {
// IByteBuffer buf;
// if (slice) {
// buf = this.buffer.Slice();
// } else {
// buf = this.buffer.Duplicate();
// }
// byte[] array = new byte[8];
// buf.ReadBytes(array);
// assertArrayEquals(bytes, array);
// Arrays.fill(array, (byte) 0);
// buf.GetBytes(0, array);
// assertArrayEquals(bytes, array);
// latch.countDown();
// }
// try {
// barrier.await();
// } catch (Exception e) {
// // ignore
// }
// }
// }).start();
//}
//latch.await(10, TimeUnit.SECONDS);
//barrier.await(5, TimeUnit.SECONDS);
//assertNull(cause.get());
}
[Fact]
public void ReadByteThrowsIndexOutOfRangeException()
{
IByteBuffer buf = this.NewBuffer(8);
if (!buf.IsWritable())
{
Assert.Throws<IndexOutOfRangeException>(() => buf.WriteByte(0));
}
else
{
buf.WriteByte(0);
Assert.Equal((byte)0, buf.ReadByte());
Assert.Throws<IndexOutOfRangeException>(() => buf.ReadByte());
}
buf.Release();
}
IByteBuffer ReleasedBuffer()
{
IByteBuffer buf = this.NewBuffer(8);
Assert.True(buf.Release());
return buf;
}
[Fact]
public void DiscardReadBytesAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().DiscardReadBytes());
[Fact]
public void DiscardSomeReadBytesAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().DiscardSomeReadBytes());
[Fact]
public void EnsureWritableAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().EnsureWritable(16));
[Fact]
public void GetBooleanAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetBoolean(0));
[Fact]
public void GetByteAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetByte(0));
[Fact]
public void GetShortAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetShort(0));
[Fact]
public void GetShortLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetShortLE(0));
[Fact]
public void GetUnsignedShortAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetUnsignedShort(0));
[Fact]
public void GetUnsignedShortLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetUnsignedShortLE(0));
[Fact]
public void GetMediumAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetMedium(0));
[Fact]
public void GetMediumLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetMediumLE(0));
[Fact]
public void GetUnsignedMediumAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetUnsignedMedium(0));
[Fact]
public void GetUnsignedMediumLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetUnsignedMediumLE(0));
[Fact]
public void GetIntAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetInt(0));
[Fact]
public void GetIntLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetIntLE(0));
[Fact]
public void GetUnsignedIntAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetUnsignedInt(0));
[Fact]
public void GetUnsignedIntLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetUnsignedIntLE(0));
[Fact]
public void GetLongAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetLong(0));
[Fact]
public void GetLongLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetLongLE(0));
[Fact]
public void GetCharAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetChar(0));
[Fact]
public void GetFloatAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetFloat(0));
[Fact]
public void GetDoubleAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetDouble(0));
[Fact]
public void GetBytesAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetBytes(0, this.ReleaseLater(Unpooled.Buffer(8))));
[Fact]
public void GetBytesAfterRelease2() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetBytes(0, this.ReleaseLater(Unpooled.Buffer()), 1));
[Fact]
public void GetBytesAfterRelease3() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetBytes(0, this.ReleaseLater(Unpooled.Buffer()), 0, 1));
[Fact]
public void GetBytesAfterRelease4() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetBytes(0, new byte[8]));
[Fact]
public void GetBytesAfterRelease5() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetBytes(0, new byte[8], 0, 1));
[Fact]
public void SetBooleanAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetBoolean(0, true));
[Fact]
public void SetByteAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetByte(0, 1));
[Fact]
public void SetShortAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetShort(0, 1));
[Fact]
public void SetShortLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetShortLE(0, 1));
[Fact]
public void SetMediumAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetMedium(0, 1));
[Fact]
public void SetMediumLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetMediumLE(0, 1));
[Fact]
public void SetIntAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetInt(0, 1));
[Fact]
public void SetIntLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetIntLE(0, 1));
[Fact]
public void SetLongAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetLong(0, 1));
[Fact]
public void SetLongLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetLongLE(0, 1));
[Fact]
public void SetCharAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetChar(0, (char)1));
[Fact]
public void SetFloatAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetFloat(0, 1));
[Fact]
public void SetDoubleAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetDouble(0, 1));
[Fact]
public void SetBytesAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetBytes(0, this.ReleaseLater(Unpooled.Buffer())));
[Fact]
public void SetBytesAfterRelease2() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetBytes(0, this.ReleaseLater(Unpooled.Buffer()), 1));
[Fact]
public void SetBytesAfterRelease3() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetBytes(0, this.ReleaseLater(Unpooled.Buffer()), 0, 1));
[Fact]
public void SetUsAsciiCharSequenceAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.SetCharSequenceAfterRelease0(Encoding.ASCII));
[Fact]
public void SetUtf8CharSequenceAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.SetCharSequenceAfterRelease0(Encoding.UTF8));
[Fact]
public void SetUtf16CharSequenceAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.SetCharSequenceAfterRelease0(Encoding.Unicode));
void SetCharSequenceAfterRelease0(Encoding encoding) => this.ReleasedBuffer().SetCharSequence(0, new StringCharSequence("x"), encoding);
[Fact]
public void SetUsAsciiStringAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.SetStringAfterRelease0(Encoding.ASCII));
[Fact]
public void SetUtf8StringAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.SetStringAfterRelease0(Encoding.UTF8));
[Fact]
public void SetUtf16StringAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.SetStringAfterRelease0(Encoding.Unicode));
void SetStringAfterRelease0(Encoding encoding) => this.ReleasedBuffer().SetString(0, "x", encoding);
[Fact]
public void SetBytesAfterRelease4() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetBytes(0, new byte[8]));
[Fact]
public void SetBytesAfterRelease5() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetBytes(0, new byte[8], 0, 1));
[Fact]
public void SetZeroAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().SetZero(0, 1));
[Fact]
public void ReadBooleanAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBoolean());
[Fact]
public void ReadByteAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadByte());
[Fact]
public void ReadShortAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadShort());
[Fact]
public void ReadShortLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadShortLE());
[Fact]
public void ReadUnsignedShortAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadUnsignedShort());
[Fact]
public void ReadUnsignedShortLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadUnsignedShortLE());
[Fact]
public void ReadMediumAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadMedium());
[Fact]
public void ReadMediumLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadMediumLE());
[Fact]
public void ReadUnsignedMediumAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadUnsignedMedium());
[Fact]
public void ReadUnsignedMediumLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadUnsignedMediumLE());
[Fact]
public void ReadIntAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadInt());
[Fact]
public void ReadIntLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadIntLE());
[Fact]
public void ReadUnsignedIntAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadUnsignedInt());
[Fact]
public void ReadUnsignedIntLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadUnsignedIntLE());
[Fact]
public void ReadLongAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadLong());
[Fact]
public void ReadLongLEEfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadLongLE());
[Fact]
public void ReadCharAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadChar());
[Fact]
public void ReadFloatAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadFloat());
[Fact]
public void ReadDoubleAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadDouble());
[Fact]
public void ReadBytesAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBytes(1));
[Fact]
public void ReadBytesAfterRelease2() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBytes(this.ReleaseLater(Unpooled.Buffer(8))));
[Fact]
public void ReadBytesAfterRelease3() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBytes(this.ReleaseLater(Unpooled.Buffer(8))));
[Fact]
public void ReadBytesAfterRelease4() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBytes(this.ReleaseLater(Unpooled.Buffer(8)), 0, 1));
[Fact]
public void ReadBytesAfterRelease5() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBytes(new byte[8]));
[Fact]
public void ReadBytesAfterRelease6() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ReadBytes(new byte[8], 0, 1));
[Fact]
public void WriteBooleanAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteBoolean(true));
[Fact]
public void WriteByteAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteByte(1));
[Fact]
public void WriteShortAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteShort(1));
[Fact]
public void WriteShortLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteShortLE(1));
[Fact]
public void WriteMediumAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteMedium(1));
[Fact]
public void WriteMediumLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteMediumLE(1));
[Fact]
public void WriteIntAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteInt(1));
[Fact]
public void WriteIntLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteIntLE(1));
[Fact]
public void WriteLongAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteLong(1));
[Fact]
public void WriteLongLEAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteLongLE(1));
[Fact]
public void WriteCharAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteChar((char)1));
[Fact]
public void WriteFloatAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteFloat(1));
[Fact]
public void WriteDoubleAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteDouble(1));
[Fact]
public void WriteBytesAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteBytes(this.ReleaseLater(Unpooled.Buffer(8))));
[Fact]
public void WriteBytesAfterRelease2() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteBytes(this.ReleaseLater(Unpooled.CopiedBuffer(new byte[8])), 1));
[Fact]
public void WriteBytesAfterRelease3() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteBytes(this.ReleaseLater(Unpooled.Buffer(8)), 0, 1));
[Fact]
public void WriteBytesAfterRelease4() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteBytes(new byte[8]));
[Fact]
public void WriteBytesAfterRelease5() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteBytes(new byte[8], 0, 1));
[Fact]
public void WriteZeroAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().WriteZero(1));
[Fact]
public void WriteUsAsciiCharSequenceAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.WriteCharSequenceAfterRelease0(Encoding.ASCII));
[Fact]
public void WriteUtf8CharSequenceAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.WriteCharSequenceAfterRelease0(Encoding.UTF8));
[Fact]
public void WriteUtf16CharSequenceAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.WriteCharSequenceAfterRelease0(Encoding.Unicode));
void WriteCharSequenceAfterRelease0(Encoding encoding) => this.ReleasedBuffer().WriteCharSequence(new StringCharSequence("x"), encoding);
[Fact]
public void WriteUsAsciiStringAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.WriteStringAfterRelease0(Encoding.ASCII));
[Fact]
public void WriteUtf8StringAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.WriteStringAfterRelease0(Encoding.UTF8));
[Fact]
public void WriteUtf16StringAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.WriteStringAfterRelease0(Encoding.Unicode));
void WriteStringAfterRelease0(Encoding encoding) => this.ReleasedBuffer().WriteString("x", encoding);
[Fact]
public void ForEachByteAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ForEachByte(new TestByteProcessor()));
[Fact]
public void ForEachByteAfterRelease1() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ForEachByte(0, 1, new TestByteProcessor()));
[Fact]
public void ForEachByteDescAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ForEachByteDesc(new TestByteProcessor()));
[Fact]
public void ForEachByteDescAfterRelease1() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().ForEachByteDesc(0, 1, new TestByteProcessor()));
[Fact]
public void CopyAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().Copy());
[Fact]
public void CopyAfterRelease1() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().Copy());
[Fact]
public void IoBufferAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetIoBuffer());
[Fact]
public void IoBufferAfterRelease1() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetIoBuffer(0, 1));
[Fact]
public void IoBuffersAfterRelease() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetIoBuffers());
[Fact]
public void IoBuffersAfterRelease2() => Assert.Throws<IllegalReferenceCountException>(() => this.ReleasedBuffer().GetIoBuffers(0, 1));
[Fact]
public void ArrayAfterRelease()
{
IByteBuffer buf = this.ReleasedBuffer();
if (buf.HasArray)
{
Assert.Throws<IllegalReferenceCountException>(() =>
{
byte[] _ = buf.Array;
});
}
}
[Fact]
public void MemoryAddressAfterRelease()
{
IByteBuffer buf = this.ReleasedBuffer();
if (buf.HasMemoryAddress)
{
Assert.Throws<IllegalReferenceCountException>(() => buf.GetPinnableMemoryAddress());
}
}
[Fact]
public void SliceRelease()
{
IByteBuffer buf = this.NewBuffer(8);
Assert.Equal(1, buf.ReferenceCount);
Assert.True(buf.Slice().Release());
Assert.Equal(0, buf.ReferenceCount);
}
[Fact]
public void ReadSliceOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.ReadSliceOutOfBounds0(false));
[Fact]
public void ReadRetainedSliceOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.ReadSliceOutOfBounds0(true));
void ReadSliceOutOfBounds0(bool retainedSlice)
{
IByteBuffer buf = this.NewBuffer(100);
try
{
buf.WriteZero(50);
if (retainedSlice)
{
buf.ReadRetainedSlice(51);
}
else
{
buf.ReadSlice(51);
}
}
finally
{
buf.Release();
}
}
[Fact]
public virtual void WriteUsAsciiCharSequenceExpand() => this.WriteCharSequenceExpand(Encoding.ASCII);
[Fact]
public virtual void WriteUtf8CharSequenceExpand() => this.WriteCharSequenceExpand(Encoding.UTF8);
[Fact]
public virtual void WriteUtf16CharSequenceExpand() => this.WriteCharSequenceExpand(Encoding.Unicode);
void WriteCharSequenceExpand(Encoding encoding)
{
IByteBuffer buf = this.NewBuffer(1);
try
{
int writerIndex = buf.Capacity - 1;
buf.SetWriterIndex(writerIndex);
int written = buf.WriteCharSequence(new StringCharSequence("AB"), encoding);
Assert.Equal(writerIndex, buf.WriterIndex - written);
}
finally
{
buf.Release();
}
}
[Fact]
public void SetUsAsciiCharSequenceNoExpand() => Assert.Throws<IndexOutOfRangeException>(() => this.SetCharSequenceNoExpand(Encoding.ASCII));
[Fact]
public void SetUtf8CharSequenceNoExpand() => Assert.Throws<IndexOutOfRangeException>(() => this.SetCharSequenceNoExpand(Encoding.UTF8));
[Fact]
public void SetUtf16CharSequenceNoExpand() => Assert.Throws<IndexOutOfRangeException>(() => this.SetCharSequenceNoExpand(Encoding.Unicode));
void SetCharSequenceNoExpand(Encoding encoding)
{
IByteBuffer buf = this.NewBuffer(1);
try
{
buf.SetCharSequence(0, new StringCharSequence("AB"), encoding);
}
finally
{
buf.Release();
}
}
[Fact]
public void SetUsAsciiStringNoExpand() => Assert.Throws<IndexOutOfRangeException>(() => this.SetStringNoExpand(Encoding.ASCII));
[Fact]
public void SetUtf8StringNoExpand() => Assert.Throws<IndexOutOfRangeException>(() => this.SetStringNoExpand(Encoding.UTF8));
[Fact]
public void SetUtf16StringNoExpand() => Assert.Throws<IndexOutOfRangeException>(() => this.SetStringNoExpand(Encoding.Unicode));
void SetStringNoExpand(Encoding encoding)
{
IByteBuffer buf = this.NewBuffer(1);
try
{
buf.SetString(0, "AB", encoding);
}
finally
{
buf.Release();
}
}
[Fact]
public void SetUsAsciiCharSequence() => this.SetGetCharSequence(Encoding.ASCII);
[Fact]
public void SetUtf8CharSequence() => this.SetGetCharSequence(Encoding.UTF8);
[Fact]
public void SetUtf16CharSequence() => this.SetGetCharSequence(Encoding.Unicode);
void SetGetCharSequence(Encoding encoding)
{
IByteBuffer buf = this.NewBuffer(16);
var sequence = new StringCharSequence("AB");
int bytes = buf.SetCharSequence(1, sequence, encoding);
Assert.Equal(sequence, buf.GetCharSequence(1, bytes, encoding));
buf.Release();
}
[Fact]
public void SetUsAsciiString() => this.SetGetString(Encoding.ASCII);
[Fact]
public void SetUtf8String() => this.SetGetString(Encoding.UTF8);
[Fact]
public void SetUtf16String() => this.SetGetString(Encoding.Unicode);
void SetGetString(Encoding encoding)
{
IByteBuffer buf = this.NewBuffer(16);
const string Sequence = "AB";
int bytes = buf.SetString(1, Sequence, encoding);
Assert.Equal(Sequence, buf.GetString(1, bytes, encoding));
buf.Release();
}
[Fact]
public void WriteReadUsAsciiString() => this.WriteReadString(Encoding.ASCII);
[Fact]
public void WriteReadUtf8String() => this.WriteReadString(Encoding.UTF8);
[Fact]
public void WriteReadUtf16String() => this.WriteReadString(Encoding.Unicode);
void WriteReadString(Encoding encoding)
{
IByteBuffer buf = this.NewBuffer(16);
const string Sequence = "AB";
buf.SetWriterIndex(1);
int bytes = buf.WriteString(Sequence, encoding);
buf.SetReaderIndex(1);
Assert.Equal(Sequence, buf.ReadString(bytes, encoding));
buf.Release();
}
[Fact]
public void RetainedSliceIndexOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.SliceOutOfBounds(true, true, true));
[Fact]
public void RetainedSliceLengthOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.SliceOutOfBounds(true, true, false));
[Fact]
public void MixedSliceAIndexOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.SliceOutOfBounds(true, false, false));
[Fact]
public void MixedSliceBIndexOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.SliceOutOfBounds(false, true, false));
[Fact]
public void SliceIndexOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.SliceOutOfBounds(false, false, true));
[Fact]
public void SliceLEngthOutOfBounds() => Assert.Throws<IndexOutOfRangeException>(() => this.SliceOutOfBounds(false, false, false));
[Fact]
public void RetainedSliceAndRetainedDuplicateContentIsExpected()
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected1 = this.NewBuffer(6).ResetWriterIndex();
IByteBuffer expected2 = this.NewBuffer(5).ResetWriterIndex();
IByteBuffer expected3 = this.NewBuffer(4).ResetWriterIndex();
IByteBuffer expected4 = this.NewBuffer(3).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected1.WriteBytes(new byte[] { 2, 3, 4, 5, 6, 7 });
expected2.WriteBytes(new byte[] { 3, 4, 5, 6, 7 });
expected3.WriteBytes(new byte[] { 4, 5, 6, 7 });
expected4.WriteBytes(new byte[] { 5, 6, 7 });
IByteBuffer slice1 = buf.RetainedSlice(buf.ReaderIndex + 1, 6);
Assert.Equal(0, slice1.CompareTo(expected1));
Assert.Equal(0, slice1.CompareTo(buf.Slice(buf.ReaderIndex + 1, 6)));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
// Advance the reader index on the slice.
slice1.ReadByte();
IByteBuffer dup1 = slice1.RetainedDuplicate();
Assert.Equal(0, dup1.CompareTo(expected2));
Assert.Equal(0, dup1.CompareTo(slice1.Duplicate()));
// Advance the reader index on dup1.
dup1.ReadByte();
IByteBuffer dup2 = dup1.Duplicate();
Assert.Equal(0, dup2.CompareTo(expected3));
// Advance the reader index on dup2.
dup2.ReadByte();
IByteBuffer slice2 = dup2.RetainedSlice(dup2.ReaderIndex, 3);
Assert.Equal(0, slice2.CompareTo(expected4));
Assert.Equal(0, slice2.CompareTo(dup2.Slice(dup2.ReaderIndex, 3)));
// Cleanup the expected buffers used for testing.
Assert.True(expected1.Release());
Assert.True(expected2.Release());
Assert.True(expected3.Release());
Assert.True(expected4.Release());
slice2.Release();
dup2.Release();
Assert.Equal(slice2.ReferenceCount, dup2.ReferenceCount);
Assert.Equal(dup2.ReferenceCount, dup1.ReferenceCount);
// The handler is now done with the original slice
Assert.True(slice1.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, slice1.ReferenceCount);
Assert.Equal(0, slice2.ReferenceCount);
Assert.Equal(0, dup1.ReferenceCount);
Assert.Equal(0, dup2.ReferenceCount);
}
[Fact]
public void RetainedDuplicateAndRetainedSliceContentIsExpected()
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected1 = this.NewBuffer(6).ResetWriterIndex();
IByteBuffer expected2 = this.NewBuffer(5).ResetWriterIndex();
IByteBuffer expected3 = this.NewBuffer(4).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected1.WriteBytes(new byte[] { 2, 3, 4, 5, 6, 7 });
expected2.WriteBytes(new byte[] { 3, 4, 5, 6, 7 });
expected3.WriteBytes(new byte[] { 5, 6, 7 });
IByteBuffer dup1 = buf.RetainedDuplicate();
Assert.Equal(0, dup1.CompareTo(buf));
Assert.Equal(0, dup1.CompareTo(buf.Slice()));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
// Advance the reader index on the dup.
dup1.ReadByte();
IByteBuffer slice1 = dup1.RetainedSlice(dup1.ReaderIndex, 6);
Assert.Equal(0, slice1.CompareTo(expected1));
Assert.Equal(0, slice1.CompareTo(slice1.Duplicate()));
// Advance the reader index on slice1.
slice1.ReadByte();
IByteBuffer dup2 = slice1.Duplicate();
Assert.Equal(0, dup2.CompareTo(slice1));
// Advance the reader index on dup2.
dup2.ReadByte();
IByteBuffer slice2 = dup2.RetainedSlice(dup2.ReaderIndex + 1, 3);
Assert.Equal(0, slice2.CompareTo(expected3));
Assert.Equal(0, slice2.CompareTo(dup2.Slice(dup2.ReaderIndex + 1, 3)));
// Cleanup the expected buffers used for testing.
Assert.True(expected1.Release());
Assert.True(expected2.Release());
Assert.True(expected3.Release());
slice2.Release();
slice1.Release();
Assert.Equal(slice2.ReferenceCount, dup2.ReferenceCount);
Assert.Equal(dup2.ReferenceCount, slice1.ReferenceCount);
// The handler is now done with the original slice
Assert.True(dup1.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, slice1.ReferenceCount);
Assert.Equal(0, slice2.ReferenceCount);
Assert.Equal(0, dup1.ReferenceCount);
Assert.Equal(0, dup2.ReferenceCount);
}
[Fact]
public void RetainedSliceContents() => this.SliceContents0(true);
[Fact]
public void MultipleLevelRetainedSlice1() => this.MultipleLevelRetainedSliceWithNonRetained(true, true);
[Fact]
public void MultipleLevelRetainedSlice2() => this.MultipleLevelRetainedSliceWithNonRetained(true, false);
[Fact]
public void MultipleLevelRetainedSlice3() => this.MultipleLevelRetainedSliceWithNonRetained(false, true);
[Fact]
public void MultipleLevelRetainedSlice4() => this.MultipleLevelRetainedSliceWithNonRetained(false, false);
[Fact]
public void RetainedSliceReleaseOriginal1() => this.SliceReleaseOriginal(true, true);
[Fact]
public void RetainedSliceReleaseOriginal2() => this.SliceReleaseOriginal(true, false);
[Fact]
public void RetainedSliceReleaseOriginal3() => this.SliceReleaseOriginal(false, true);
[Fact]
public void RetainedSliceReleaseOriginal4() => this.SliceReleaseOriginal(false, false);
[Fact]
public void RetainedDuplicateReleaseOriginal1() => this.DuplicateReleaseOriginal(true, true);
[Fact]
public void RetainedDuplicateReleaseOriginal2() => this.DuplicateReleaseOriginal(true, false);
[Fact]
public void RetainedDuplicateReleaseOriginal3() => this.DuplicateReleaseOriginal(false, true);
[Fact]
public void RetainedDuplicateReleaseOriginal4() => this.DuplicateReleaseOriginal(false, false);
[Fact]
public void MultipleRetainedSliceReleaseOriginal1() => this.MultipleRetainedSliceReleaseOriginal(true, true);
[Fact]
public void MultipleRetainedSliceReleaseOriginal2() => this.MultipleRetainedSliceReleaseOriginal(true, false);
[Fact]
public void MultipleRetainedSliceReleaseOriginal3() => this.MultipleRetainedSliceReleaseOriginal(false, true);
[Fact]
public void MultipleRetainedSliceReleaseOriginal4() => this.MultipleRetainedSliceReleaseOriginal(false, false);
[Fact]
public void MultipleRetainedDuplicateReleaseOriginal1() => this.MultipleRetainedDuplicateReleaseOriginal(true, true);
[Fact]
public void MultipleRetainedDuplicateReleaseOriginal2() => this.MultipleRetainedDuplicateReleaseOriginal(true, false);
[Fact]
public void MultipleRetainedDuplicateReleaseOriginal3() => this.MultipleRetainedDuplicateReleaseOriginal(false, true);
[Fact]
public void MultipleRetainedDuplicateReleaseOriginal4() => this.MultipleRetainedDuplicateReleaseOriginal(false, false);
[Fact]
public void SliceContents() => this.SliceContents0(false);
[Fact]
public void RetainedDuplicateContents() => this.DuplicateContents0(true);
[Fact]
public void DuplicateContents() => this.DuplicateContents0(false);
[Fact]
public virtual void DuplicateCapacityChange() => this.DuplicateCapacityChange0(false);
[Fact]
public virtual void RetainedDuplicateCapacityChange() => this.DuplicateCapacityChange0(true);
[Fact]
public void SliceCapacityChange() => Assert.Throws<NotSupportedException>(() => this.SliceCapacityChange0(false));
[Fact]
public void RetainedSliceCapacityChange() => Assert.Throws<NotSupportedException>(() => this.SliceCapacityChange0(true));
void DuplicateCapacityChange0(bool retainedDuplicate)
{
IByteBuffer buf = this.NewBuffer(8);
IByteBuffer dup = retainedDuplicate ? buf.RetainedDuplicate() : buf.Duplicate();
try
{
dup.AdjustCapacity(10);
Assert.Equal(buf.Capacity, dup.Capacity);
dup.AdjustCapacity(5);
Assert.Equal(buf.Capacity, dup.Capacity);
}
finally
{
if (retainedDuplicate)
{
dup.Release();
}
buf.Release();
}
}
void SliceCapacityChange0(bool retainedSlice)
{
IByteBuffer buf = this.NewBuffer(8);
IByteBuffer slice = retainedSlice ? buf.RetainedSlice(buf.ReaderIndex + 1, 3)
: buf.Slice(buf.ReaderIndex + 1, 3);
try
{
slice.AdjustCapacity(10);
}
finally
{
if (retainedSlice)
{
slice.Release();
}
buf.Release();
}
}
void SliceOutOfBounds(bool initRetainedSlice, bool finalRetainedSlice, bool indexOutOfBounds)
{
IByteBuffer buf = this.NewBuffer(8);
IByteBuffer slice = initRetainedSlice ? buf.RetainedSlice(buf.ReaderIndex + 1, 2)
: buf.Slice(buf.ReaderIndex + 1, 2);
try
{
Assert.Equal(2, slice.Capacity);
Assert.Equal(2, slice.MaxCapacity);
int index = indexOutOfBounds ? 3 : 0;
int length = indexOutOfBounds ? 0 : 3;
if (finalRetainedSlice)
{
// This is expected to fail ... so no need to release.
slice.RetainedSlice(index, length);
}
else
{
slice.Slice(index, length);
}
}
finally
{
if (initRetainedSlice)
{
slice.Release();
}
buf.Release();
}
}
void SliceContents0(bool retainedSlice)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected = this.NewBuffer(3).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected.WriteBytes(new byte[] { 4, 5, 6 });
IByteBuffer slice = retainedSlice ? buf.RetainedSlice(buf.ReaderIndex + 3, 3)
: buf.Slice(buf.ReaderIndex + 3, 3);
try
{
Assert.Equal(0, slice.CompareTo(expected));
Assert.Equal(0, slice.CompareTo(slice.Duplicate()));
IByteBuffer b = slice.RetainedDuplicate();
Assert.Equal(0, slice.CompareTo(b));
b.Release();
Assert.Equal(0, slice.CompareTo(slice.Slice(0, slice.Capacity)));
}
finally
{
if (retainedSlice)
{
slice.Release();
}
buf.Release();
expected.Release();
}
}
void SliceReleaseOriginal(bool retainedSlice1, bool retainedSlice2)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected1 = this.NewBuffer(3).ResetWriterIndex();
IByteBuffer expected2 = this.NewBuffer(2).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected1.WriteBytes(new byte[] { 6, 7, 8 });
expected2.WriteBytes(new byte[] { 7, 8 });
IByteBuffer slice1 = retainedSlice1 ? buf.RetainedSlice(buf.ReaderIndex + 5, 3)
: (IByteBuffer) buf.Slice(buf.ReaderIndex + 5, 3).Retain();
Assert.Equal(0, slice1.CompareTo(expected1));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
IByteBuffer slice2 = retainedSlice2 ? slice1.RetainedSlice(slice1.ReaderIndex + 1, 2)
: (IByteBuffer) slice1.Slice(slice1.ReaderIndex + 1, 2).Retain();
Assert.Equal(0, slice2.CompareTo(expected2));
// Cleanup the expected buffers used for testing.
Assert.True(expected1.Release());
Assert.True(expected2.Release());
// The handler created a slice of the slice and is now done with it.
slice2.Release();
// The handler is now done with the original slice
Assert.True(slice1.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, slice1.ReferenceCount);
Assert.Equal(0, slice2.ReferenceCount);
}
void MultipleLevelRetainedSliceWithNonRetained(bool doSlice1, bool doSlice2)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected1 = this.NewBuffer(6).ResetWriterIndex();
IByteBuffer expected2 = this.NewBuffer(4).ResetWriterIndex();
IByteBuffer expected3 = this.NewBuffer(2).ResetWriterIndex();
IByteBuffer expected4SliceSlice = this.NewBuffer(1).ResetWriterIndex();
IByteBuffer expected4DupSlice = this.NewBuffer(1).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected1.WriteBytes(new byte[] { 2, 3, 4, 5, 6, 7 });
expected2.WriteBytes(new byte[] { 3, 4, 5, 6 });
expected3.WriteBytes(new byte[] { 4, 5 });
expected4SliceSlice.WriteBytes(new byte[] { 5 });
expected4DupSlice.WriteBytes(new byte[] { 4 });
IByteBuffer slice1 = buf.RetainedSlice(buf.ReaderIndex + 1, 6);
Assert.Equal(0, slice1.CompareTo(expected1));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
IByteBuffer slice2 = slice1.RetainedSlice(slice1.ReaderIndex + 1, 4);
Assert.Equal(0, slice2.CompareTo(expected2));
Assert.Equal(0, slice2.CompareTo(slice2.Duplicate()));
Assert.Equal(0, slice2.CompareTo(slice2.Slice()));
IByteBuffer tmpBuf = slice2.RetainedDuplicate();
Assert.Equal(0, slice2.CompareTo(tmpBuf));
tmpBuf.Release();
tmpBuf = slice2.RetainedSlice();
Assert.Equal(0, slice2.CompareTo(tmpBuf));
tmpBuf.Release();
IByteBuffer slice3 = doSlice1 ? slice2.Slice(slice2.ReaderIndex + 1, 2) : slice2.Duplicate();
if (doSlice1)
{
Assert.Equal(0, slice3.CompareTo(expected3));
}
else
{
Assert.Equal(0, slice3.CompareTo(expected2));
}
IByteBuffer slice4 = doSlice2 ? slice3.Slice(slice3.ReaderIndex + 1, 1) : slice3.Duplicate();
if (doSlice1 && doSlice2)
{
Assert.Equal(0, slice4.CompareTo(expected4SliceSlice));
}
else if (doSlice2)
{
Assert.Equal(0, slice4.CompareTo(expected4DupSlice));
}
else
{
Assert.Equal(0, slice3.CompareTo(slice4));
}
// Cleanup the expected buffers used for testing.
Assert.True(expected1.Release());
Assert.True(expected2.Release());
Assert.True(expected3.Release());
Assert.True(expected4SliceSlice.Release());
Assert.True(expected4DupSlice.Release());
// Slice 4, 3, and 2 should effectively "share" a reference count.
slice4.Release();
Assert.Equal(slice3.ReferenceCount, slice2.ReferenceCount);
Assert.Equal(slice3.ReferenceCount, slice4.ReferenceCount);
// Slice 1 should also release the original underlying buffer without throwing exceptions
Assert.True(slice1.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, slice1.ReferenceCount);
Assert.Equal(0, slice2.ReferenceCount);
Assert.Equal(0, slice3.ReferenceCount);
}
void DuplicateReleaseOriginal(bool retainedDuplicate1, bool retainedDuplicate2)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected = this.NewBuffer(8).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected.WriteBytes(buf, buf.ReaderIndex, buf.ReadableBytes);
IByteBuffer dup1 = retainedDuplicate1 ? buf.RetainedDuplicate()
: (IByteBuffer) buf.Duplicate().Retain();
Assert.Equal(0, dup1.CompareTo(expected));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
IByteBuffer dup2 = retainedDuplicate2 ? dup1.RetainedDuplicate()
: (IByteBuffer) dup1.Duplicate().Retain();
Assert.Equal(0, dup2.CompareTo(expected));
// Cleanup the expected buffers used for testing.
Assert.True(expected.Release());
// The handler created a slice of the slice and is now done with it.
dup2.Release();
// The handler is now done with the original slice
Assert.True(dup1.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, dup1.ReferenceCount);
Assert.Equal(0, dup2.ReferenceCount);
}
void MultipleRetainedSliceReleaseOriginal(bool retainedSlice1, bool retainedSlice2)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected1 = this.NewBuffer(3).ResetWriterIndex();
IByteBuffer expected2 = this.NewBuffer(2).ResetWriterIndex();
IByteBuffer expected3 = this.NewBuffer(2).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected1.WriteBytes(new byte[] { 6, 7, 8 });
expected2.WriteBytes(new byte[] { 7, 8 });
expected3.WriteBytes(new byte[] { 6, 7 });
IByteBuffer slice1 = retainedSlice1 ? buf.RetainedSlice(buf.ReaderIndex + 5, 3)
: (IByteBuffer)buf.Slice(buf.ReaderIndex + 5, 3).Retain();
Assert.Equal(0, slice1.CompareTo(expected1));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
IByteBuffer slice2 = retainedSlice2 ? slice1.RetainedSlice(slice1.ReaderIndex + 1, 2)
: (IByteBuffer)slice1.Slice(slice1.ReaderIndex + 1, 2).Retain();
Assert.Equal(0, slice2.CompareTo(expected2));
// The handler created a slice of the slice and is now done with it.
slice2.Release();
IByteBuffer slice3 = slice1.RetainedSlice(slice1.ReaderIndex, 2);
Assert.Equal(0, slice3.CompareTo(expected3));
// The handler created another slice of the slice and is now done with it.
slice3.Release();
// The handler is now done with the original slice
Assert.True(slice1.Release());
// Cleanup the expected buffers used for testing.
Assert.True(expected1.Release());
Assert.True(expected2.Release());
Assert.True(expected3.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, slice1.ReferenceCount);
Assert.Equal(0, slice2.ReferenceCount);
Assert.Equal(0, slice3.ReferenceCount);
}
void MultipleRetainedDuplicateReleaseOriginal(bool retainedDuplicate1, bool retainedDuplicate2)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
IByteBuffer expected = this.NewBuffer(8).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
expected.WriteBytes(buf, buf.ReaderIndex, buf.ReadableBytes);
IByteBuffer dup1 = retainedDuplicate1 ? buf.RetainedDuplicate() : (IByteBuffer)buf.Duplicate().Retain();
Assert.Equal(0, dup1.CompareTo(expected));
// Simulate a handler that releases the original buffer, and propagates a slice.
buf.Release();
IByteBuffer dup2 = retainedDuplicate2 ? dup1.RetainedDuplicate() : (IByteBuffer)dup1.Duplicate().Retain();
Assert.Equal(0, dup2.CompareTo(expected));
Assert.Equal(0, dup2.CompareTo(dup2.Duplicate()));
Assert.Equal(0, dup2.CompareTo(dup2.Slice()));
IByteBuffer tmpBuf = dup2.RetainedDuplicate();
Assert.Equal(0, dup2.CompareTo(tmpBuf));
tmpBuf.Release();
tmpBuf = dup2.RetainedSlice();
Assert.Equal(0, dup2.CompareTo(tmpBuf));
tmpBuf.Release();
// The handler created a slice of the slice and is now done with it.
dup2.Release();
IByteBuffer dup3 = dup1.RetainedDuplicate();
Assert.Equal(0, dup3.CompareTo(expected));
// The handler created another slice of the slice and is now done with it.
dup3.Release();
// The handler is now done with the original slice
Assert.True(dup1.Release());
// Cleanup the expected buffers used for testing.
Assert.True(expected.Release());
// Reference counting may be shared, or may be independently tracked, but at this point all buffers should
// be deallocated and have a reference count of 0.
Assert.Equal(0, buf.ReferenceCount);
Assert.Equal(0, dup1.ReferenceCount);
Assert.Equal(0, dup2.ReferenceCount);
Assert.Equal(0, dup3.ReferenceCount);
}
void DuplicateContents0(bool retainedDuplicate)
{
IByteBuffer buf = this.NewBuffer(8).ResetWriterIndex();
buf.WriteBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
IByteBuffer dup = retainedDuplicate ? buf.RetainedDuplicate() : buf.Duplicate();
try
{
Assert.Equal(0, dup.CompareTo(buf));
Assert.Equal(0, dup.CompareTo(dup.Duplicate()));
IByteBuffer b = dup.RetainedDuplicate();
Assert.Equal(0, dup.CompareTo(b));
b.Release();
Assert.Equal(0, dup.CompareTo(dup.Slice(dup.ReaderIndex, dup.ReadableBytes)));
}
finally
{
if (retainedDuplicate)
{
dup.Release();
}
buf.Release();
}
}
[Fact]
public void DuplicateRelease()
{
IByteBuffer buf = this.NewBuffer(8);
Assert.Equal(1, buf.ReferenceCount);
Assert.True(buf.Duplicate().Release());
Assert.Equal(0, buf.ReferenceCount);
}
// Test-case trying to reproduce:
// https://github.com/netty/netty/issues/2843
[Fact]
public void RefCnt() => this.RefCnt0(false);
// Test-case trying to reproduce:
// https://github.com/netty/netty/issues/2843
[Fact]
public void RefCnt2() => this.RefCnt0(true);
[Fact]
public virtual void ReadBytes()
{
IByteBuffer buf = this.NewBuffer(8);
var bytes = new byte[8];
buf.WriteBytes(bytes);
IByteBuffer buffer2 = buf.ReadBytes(4);
Assert.Same(buf.Allocator, buffer2.Allocator);
Assert.Equal(4, buf.ReaderIndex);
Assert.True(buf.Release());
Assert.Equal(0, buf.ReferenceCount);
Assert.True(buffer2.Release());
Assert.Equal(0, buffer2.ReferenceCount);
}
[Fact]
public virtual void ForEachByteDesc2()
{
byte[] expected = { 1, 2, 3, 4 };
IByteBuffer buf = this.NewBuffer(expected.Length);
try
{
buf.WriteBytes(expected);
var processor = new ForEachByteDesc2Processor(expected.Length);
int i = buf.ForEachByteDesc(processor);
Assert.Equal(-1, i);
Assert.True(expected.SequenceEqual(processor.Bytes));
}
finally
{
buf.Release();
}
}
sealed class ForEachByteDesc2Processor : IByteProcessor
{
int index;
public ForEachByteDesc2Processor(int length)
{
this.Bytes = new byte[length];
this.index = length - 1;
}
public byte[] Bytes { get; }
public bool Process(byte value)
{
this.Bytes[this.index--] = value;
return true;
}
}
[Fact]
public virtual void ForEachByte2()
{
byte[] expected = { 1, 2, 3, 4 };
IByteBuffer buf = this.NewBuffer(expected.Length);
try
{
buf.WriteBytes(expected);
var processor = new ForEachByte2Processor(expected.Length);
int i = buf.ForEachByte(processor);
Assert.Equal(-1, i);
Assert.True(expected.SequenceEqual(processor.Bytes));
}
finally
{
buf.Release();
}
}
sealed class ForEachByte2Processor : IByteProcessor
{
int index;
public ForEachByte2Processor(int length)
{
this.Bytes = new byte[length];
this.index = 0;
}
public byte[] Bytes { get; }
public bool Process(byte value)
{
this.Bytes[this.index++] = value;
return true;
}
}
void RefCnt0(bool parameter)
{
for (int i = 0; i < 10; i++)
{
var latch = new ManualResetEventSlim();
var innerLatch = new ManualResetEventSlim();
IByteBuffer buf = this.NewBuffer(4);
Assert.Equal(1, buf.ReferenceCount);
int cnt = int.MaxValue;
var t1 = new Thread(s =>
{
bool released;
if (parameter)
{
released = buf.Release(buf.ReferenceCount);
}
else
{
released = buf.Release();
}
Assert.True(released);
var t2 = new Thread(s2 =>
{
Volatile.Write(ref cnt, buf.ReferenceCount);
latch.Set();
});
t2.Start();
// Keep Thread alive a bit so the ThreadLocal caches are not freed
innerLatch.Wait();
});
t1.Start();
latch.Wait();
Assert.Equal(0, Volatile.Read(ref cnt));
innerLatch.Set();
}
}
[Fact]
public void EmptyIoBuffers()
{
IByteBuffer buf =this.NewBuffer(8);
buf.Clear();
Assert.False(buf.IsReadable());
ArraySegment<byte>[] nioBuffers = buf.GetIoBuffers();
Assert.Single(nioBuffers);
Assert.Empty(nioBuffers[0]);
buf.Release();
}
[Fact]
public void CapacityEnforceMaxCapacity()
{
if (this.AssumedMaxCapacity)
{
return;
}
IByteBuffer buf = this.NewBuffer(3, 13);
Assert.Equal(13, buf.MaxCapacity);
Assert.Equal(3, buf.Capacity);
try
{
Assert.Throws<ArgumentOutOfRangeException>(() => buf.AdjustCapacity(14));
}
finally
{
buf.Release();
}
}
[Fact]
public void CapacityNegative()
{
if (this.AssumedMaxCapacity)
{
return;
}
IByteBuffer buf = this.NewBuffer(3, 13);
Assert.Equal(13, buf.MaxCapacity);
Assert.Equal(3, buf.Capacity);
try
{
Assert.Throws<ArgumentOutOfRangeException>(() => buf.AdjustCapacity(-1));
}
finally
{
buf.Release();
}
}
[Fact]
public void CapacityDecrease()
{
if (this.AssumedMaxCapacity)
{
return;
}
IByteBuffer buf = this.NewBuffer(3, 13);
Assert.Equal(13, buf.MaxCapacity);
Assert.Equal(3, buf.Capacity);
try
{
buf.AdjustCapacity(2);
Assert.Equal(2, buf.Capacity);
Assert.Equal(13, buf.MaxCapacity);
}
finally
{
buf.Release();
}
}
[Fact]
public void CapacityIncrease()
{
if (this.AssumedMaxCapacity)
{
return;
}
IByteBuffer buf = this.NewBuffer(3, 13);
Assert.Equal(13, buf.MaxCapacity);
Assert.Equal(3, buf.Capacity);
try
{
buf.AdjustCapacity(4);
Assert.Equal(4, buf.Capacity);
Assert.Equal(13, buf.MaxCapacity);
}
finally
{
buf.Release();
}
}
[Fact]
public void ReaderIndexLargerThanWriterIndex()
{
const string Content1 = "hello";
const string Content2 = "world";
int length = Content1.Length + Content2.Length;
IByteBuffer buf = this.NewBuffer(length);
buf.SetIndex(0, 0);
buf.WriteString(Content1, Encoding.ASCII);
buf.MarkWriterIndex();
buf.SkipBytes(Content1.Length);
buf.WriteString(Content2, Encoding.ASCII);
buf.SkipBytes(Content2.Length);
Assert.True(buf.ReaderIndex <= buf.WriterIndex);
try
{
Assert.Throws<IndexOutOfRangeException>(() => buf.ResetWriterIndex());
}
finally
{
buf.Release();
}
}
protected IByteBuffer ReleaseLater(IByteBuffer buf)
{
this.buffers.Enqueue(buf);
return buf;
}
sealed class TestByteProcessor : IByteProcessor
{
public bool Process(byte value) => true;
}
}
}