This repository has been archived by the owner on Aug 2, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 345
/
BufferWriter.cs
73 lines (59 loc) · 2.5 KB
/
BufferWriter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Buffers.Text;
using System.Runtime.CompilerServices;
namespace System.Buffers.Writer
{
public ref partial struct BufferWriter
{
private Span<byte> _buffer;
private int _written;
public ReadOnlySpan<byte> NewLine { get; set; }
public Func<int, Memory<byte>> Enlarge { get; set; }
private static byte[] s_defaultNewline = new byte[] { (byte)'\n' };
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BufferWriter Create(Span<byte> buffer) => new BufferWriter(buffer);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BufferWriter<TOutput> Create<TOutput>(TOutput output)
where TOutput : IBufferWriter<byte>
=> new BufferWriter<TOutput>(output);
private BufferWriter(Span<byte> buffer)
{
_buffer = buffer;
_written = 0;
NewLine = s_defaultNewline;
Enlarge = null;
}
public Span<byte> Free => _buffer.Slice(_written);
public Span<byte> Written => _buffer.Slice(0, _written);
public int WrittenCount
{
get { return _written; }
set
{
while (value > _buffer.Length) Resize(value);
_written = value;
}
}
public void Clear()
=> _written = 0;
private void Resize(int desiredBufferSize = 0)
{
if (Enlarge == null) throw new BufferTooSmallException();
// double the size; add one to ensure that an empty buffer still resizes
if (desiredBufferSize <= 0) desiredBufferSize = _buffer.Length * 2 + 1;
else if (desiredBufferSize < _buffer.Length + 1) throw new ArgumentOutOfRangeException(nameof(desiredBufferSize));
var newBuffer = Enlarge(desiredBufferSize).Span;
if (newBuffer.Length <= _buffer.Length) throw new Exception("Enlarge delegate created too small buffer");
Written.CopyTo(newBuffer);
_buffer = newBuffer;
}
public override string ToString()
=> TextEncodings.Utf8.ToString(Written);
public class BufferTooSmallException : Exception
{
public BufferTooSmallException() : base("Buffer is too small") { }
}
}
}