Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Added BufferWriter.Write(int, TransfromationFormat) #2179

Merged
merged 4 commits into from
Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public ref partial struct BufferWriter
Span<byte> _buffer;
int _written;

public ReadOnlySpan<byte> NewLine;
public Func<int, Memory<byte>> Enlarge;
public ReadOnlySpan<byte> NewLine { get; set; }
public Func<int, Memory<byte>> Enlarge { get; set; }

static byte[] s_defaultNewline = new byte[] { (byte)'\n' };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public BufferWriter(T output)
_span = output.GetSpan();
}

public ReadOnlySpan<byte> NewLine;
public ReadOnlySpan<byte> NewLine { get; set; }

public Span<byte> Buffer => _span;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ namespace System.Buffers.Writer
{
public ref partial struct BufferWriter<T> where T : IBufferWriter<byte>
{
#region Int32
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(int value)
{
int written;
while (!Utf8Formatter.TryFormat(value, Buffer, out written, default))
{
Enlarge();
}
Advance(written);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(int value, StandardFormat format = default)
{
Expand All @@ -20,6 +32,27 @@ public void Write(int value, StandardFormat format = default)
Advance(written);
}

public void Write(int value, TransformationFormat format)
{
int written;
while (true)
{
Span<byte> buffer = Buffer;
while (!Utf8Formatter.TryFormat(value, Buffer, out written, format.Format))
{
Enlarge();
}
if (format.TryTransform(buffer, ref written))
{
Advance(written);
return;
}
Enlarge();
}
}
#endregion

#region UInt64
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ulong value, StandardFormat format = default)
{
Expand All @@ -30,5 +63,6 @@ public void Write(ulong value, StandardFormat format = default)
}
Advance(written);
}
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// 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
Expand Down
40 changes: 40 additions & 0 deletions tests/System.Buffers.ReaderWriter.Tests/BasicUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ public void WriteLineUtf8String()
var result = _sink.ToString();
Assert.Equal("hello worldXY!XY", result);
}

[Fact]
public void WriteInt32Transformed()
{
TransformationFormat widen = new TransformationFormat(new AsciiToUtf16());
_sink.Reset();
var writer = BufferWriter.Create(_sink);
writer.Write(255, widen);
writer.Flush();

var result = _sink.ToStringAssumingUtf16Buffer();
Assert.Equal("255", result);
}
}

class Sink : IBufferWriter<byte>
Expand All @@ -125,10 +138,17 @@ public Memory<byte> GetMemory(int sizeHint = 0)
public Span<byte> GetSpan(int sizeHint = 0)
=> _buffer.AsSpan(_written, _buffer.Length - _written);

public Span<byte> WrittenBytes => _buffer.AsSpan(0, _written);

public override string ToString()
{
return Encoding.UTF8.GetString(_buffer, 0, _written);
}

public string ToStringAssumingUtf16Buffer()
{
return Encoding.Unicode.GetString(_buffer, 0, _written);
}
}

static class DateHeader
Expand Down Expand Up @@ -170,4 +190,24 @@ public static void SetDateValues(DateTimeOffset value)
}
}
}

class AsciiToUtf16 : IBufferTransformation
{
public OperationStatus Execute(ReadOnlySpan<byte> input, Span<byte> output, out int consumed, out int written)
{
throw new NotImplementedException();
}

public OperationStatus Transform(Span<byte> buffer, int dataLength, out int written)
{
written = dataLength * 2;
if (buffer.Length < written) return OperationStatus.DestinationTooSmall;
for(int i = written - 1; i > 0; i-=2)
{
buffer[i] = 0;
buffer[i - 1] = buffer[i / 2];
}
return OperationStatus.Done;
}
}
}