/
dev-npgsql
/
npgsql
Обзор
Документация
Войти
/
dev-npgsql
/
npgsql
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
v9.0.5
test/Npgsql.Tests/ReadBufferTests.cs
172 строки
6 KB
Shay Rojansky
Apply primary constructors to solution (#5908)
30 окт 2024, 18:30
Не верифицирован
30 окт 2024, 18:30
40cc1a1
Код
Авторство
О чём код?
using Npgsql.Internal; using NUnit.Framework; using System; using System.IO; using System.Threading; using System.Threading.Tasks; namespace Npgsql.Tests; [FixtureLifeCycle(LifeCycle.InstancePerTestCase)] // Parallel access to a single buffer class ReadBufferTests { [Test] public void Skip() { for (byte i = 0; i < 50; i++) Writer.WriteByte(i); ReadBuffer.Ensure(10); ReadBuffer.Skip(7); Assert.That(ReadBuffer.ReadByte(), Is.EqualTo(7)); ReadBuffer.Skip(10); ReadBuffer.Ensure(1); Assert.That(ReadBuffer.ReadByte(), Is.EqualTo(18)); ReadBuffer.Skip(20); ReadBuffer.Ensure(1); Assert.That(ReadBuffer.ReadByte(), Is.EqualTo(39)); } [Test] public void ReadSingle() { const float expected = 8.7f; var bytes = BitConverter.GetBytes(expected); Array.Reverse(bytes); Writer.Write(bytes); ReadBuffer.Ensure(4); Assert.That(ReadBuffer.ReadSingle(), Is.EqualTo(expected)); } [Test] public void ReadDouble() { const double expected = 8.7; var bytes = BitConverter.GetBytes(expected); Array.Reverse(bytes); Writer.Write(bytes); ReadBuffer.Ensure(8); Assert.That(ReadBuffer.ReadDouble(), Is.EqualTo(expected)); } [Test] public void ReadNullTerminatedString_buffered_only() { Writer .Write(NpgsqlWriteBuffer.UTF8Encoding.GetBytes(new string("foo"))) .WriteByte(0) .Write(NpgsqlWriteBuffer.UTF8Encoding.GetBytes(new string("bar"))) .WriteByte(0); ReadBuffer.Ensure(1); Assert.That(ReadBuffer.ReadNullTerminatedString(), Is.EqualTo("foo")); Assert.That(ReadBuffer.ReadNullTerminatedString(), Is.EqualTo("bar")); } [Test] public async Task ReadNullTerminatedString_with_io() { Writer.Write(NpgsqlWriteBuffer.UTF8Encoding.GetBytes(new string("Chunked "))); await ReadBuffer.Ensure(1, async: true); var task = ReadBuffer.ReadNullTerminatedString(async: true); Assert.That(!task.IsCompleted); Writer .Write(NpgsqlWriteBuffer.UTF8Encoding.GetBytes(new string("string"))) .WriteByte(0) .Write(NpgsqlWriteBuffer.UTF8Encoding.GetBytes(new string("bar"))) .WriteByte(0); Assert.That(task.IsCompleted); Assert.That(await task, Is.EqualTo("Chunked string")); Assert.That(ReadBuffer.ReadNullTerminatedString(), Is.EqualTo("bar")); } [SetUp] public void SetUp() { var stream = new MockStream(); ReadBuffer = new NpgsqlReadBuffer(null, stream, null, NpgsqlReadBuffer.DefaultSize, NpgsqlWriteBuffer.UTF8Encoding, NpgsqlWriteBuffer.RelaxedUTF8Encoding); Writer = stream.Writer; } // ReSharper disable once InconsistentNaming NpgsqlReadBuffer ReadBuffer = default!; // ReSharper disable once InconsistentNaming MockStream.MockStreamWriter Writer = default!; class MockStream : Stream { const int Size = 8192; internal MockStreamWriter Writer { get; } public MockStream() => Writer = new MockStreamWriter(this); TaskCompletionSource<object> _tcs = new(); readonly byte[] _data = new byte[Size]; int _filled; public override int Read(byte[] buffer, int offset, int count) => Read(buffer, offset, count, async: false).GetAwaiter().GetResult(); public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => Read(buffer, offset, count, async: true); async Task<int> Read(byte[] buffer, int offset, int count, bool async) { if (_filled == 0) { _tcs = new TaskCompletionSource<object>(); if (async) await _tcs.Task; else _tcs.Task.Wait(); } count = Math.Min(count, _filled); new Span<byte>(_data, 0, count).CopyTo(new Span<byte>(buffer, offset, count)); new Span<byte>(_data, count, _filled - count).CopyTo(_data); _filled -= count; return count; } internal class MockStreamWriter(MockStream stream) { public MockStreamWriter WriteByte(byte b) { Span<byte> bytes = stackalloc byte[1]; bytes[0] = b; Write(bytes); return this; } public MockStreamWriter Write(ReadOnlySpan<byte> bytes) { if (stream._filled + bytes.Length > Size) throw new Exception("Mock stream overrun"); bytes.CopyTo(new Span<byte>(stream._data, stream._filled, bytes.Length)); stream._filled += bytes.Length; stream._tcs.TrySetResult(new()); return this; } } public override void SetLength(long value) => throw new NotSupportedException(); public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException(); public override void Flush() => throw new NotSupportedException(); public override bool CanRead => true; public override bool CanSeek => false; public override bool CanWrite => false; public override long Length => throw new NotSupportedException(); public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); } } }