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

Commit

Permalink
Added BufferWriter.Write(int, TransfromationFormat) (#2179)
Browse files Browse the repository at this point in the history
* Bug fix in BufferWriter

* BufferWriter Int32 Transformations
  • Loading branch information
KrzysztofCwalina authored Mar 22, 2018
1 parent e733c13 commit 19f8293
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 4 deletions.
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;
}
}
}

0 comments on commit 19f8293

Please sign in to comment.