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

Commit

Permalink
BufferWriter.WriteLine String/Utf8String (#2176)
Browse files Browse the repository at this point in the history
* Bug fix in BufferWriter

* BufferWriter WriteLine Strings
  • Loading branch information
KrzysztofCwalina authored Mar 22, 2018
1 parent 587b6a2 commit f5eb04e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// 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.IO.Pipelines;
using System.Threading.Tasks;

namespace System.IO.Pipelines
namespace System.Buffers
{
public interface IPipeWritable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public BufferWriter(T output)
_span = output.GetSpan();
}

public ReadOnlySpan<byte> NewLine;

public Span<byte> Buffer => _span;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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<T> where T : IBufferWriter<byte>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(int value, StandardFormat format = default)
{
int written;
while (!Utf8Formatter.TryFormat(value, Buffer, out written, format))
{
Enlarge();
}
Advance(written);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ulong value, StandardFormat format = default)
{
int written;
while (!Utf8Formatter.TryFormat(value, Buffer, out written, format))
{
Enlarge();
}
Advance(written);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,12 @@

using System.Buffers.Text;
using System.Runtime.CompilerServices;
using System.Text.Utf8;

namespace System.Buffers.Writer
{
public ref partial struct BufferWriter<T> where T : IBufferWriter<byte>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(int value, StandardFormat format = default)
{
int written;
while (!Utf8Formatter.TryFormat(value, Buffer, out written, format))
{
Enlarge();
}
Advance(written);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ulong value, StandardFormat format = default)
{
int written;
while (!Utf8Formatter.TryFormat(value, Buffer, out written, format))
{
Enlarge();
}
Advance(written);
}

public void Write(string value)
{
ReadOnlySpan<byte> utf16Bytes = value.AsSpan().AsBytes();
Expand All @@ -55,46 +34,45 @@ public void Write(string value)
}
}

public void Write<TWritable>(TWritable value, TransformationFormat format) where TWritable : IWritable
// TODO: implement all the overloads taking TransformationFormat
//public void Write(string value, TransformationFormat format);

public void WriteLine(string value)
{
int written;
while (true)
{
while (!value.TryWrite(Buffer, out written, format.Format))
{
Enlarge();
}
if (format.TryTransform(Buffer, ref written)) break;
Enlarge();
}
Advance(written);
Write(value);
Write(NewLine);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write<TWritable>(TWritable value, StandardFormat format) where TWritable : IWritable
//public void WriteLine(string value, TransformationFormat format);

public void Write(Utf8String value) => Write(value.Bytes);

//public void Write(Utf8String value, TransformationFormat format);

public void WriteLine(Utf8String value)
{
int written;
while (!value.TryWrite(Buffer, out written, format))
{
Enlarge();
}
Advance(written);
Write(value.Bytes);
Write(NewLine);
}

//public void WriteLine(Utf8String value, TransformationFormat format);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ReadOnlySpan<byte> source)
public void Write(ReadOnlySpan<byte> value)
{
if (_span.Length >= source.Length)
if (_span.Length >= value.Length)
{
source.CopyTo(_span);
Advance(source.Length);
value.CopyTo(_span);
Advance(value.Length);
}
else
{
WriteMultiBuffer(source);
WriteMultiBuffer(value);
}
}

//public void Write(ReadOnlySpan<byte> value, TransformationFormat format)

private void WriteMultiBuffer(ReadOnlySpan<byte> source)
{
while (source.Length > 0)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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<T> where T : IBufferWriter<byte>
{
public void Write<TWritable>(TWritable value, TransformationFormat format) where TWritable : IWritable
{
int written;
while (true)
{
while (!value.TryWrite(Buffer, out written, format.Format))
{
Enlarge();
}
if (format.TryTransform(Buffer, ref written)) break;
Enlarge();
}
Advance(written);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write<TWritable>(TWritable value, StandardFormat format) where TWritable : IWritable
{
int written;
while (!value.TryWrite(Buffer, out written, format))
{
Enlarge();
}
Advance(written);
}
}
}
28 changes: 28 additions & 0 deletions tests/System.Buffers.ReaderWriter.Tests/BasicUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,34 @@ public void BufferWriterTransform()
writer.WriteBytes(value, transformation);
Assert.Equal(-1, buffer.AsSpan().IndexOf((byte)2));
}

[Fact]
public void WriteLineString()
{
_sink.Reset();
var writer = BufferWriter.Create(_sink);
writer.NewLine = new byte[] { (byte)'X', (byte)'Y' };
writer.WriteLine("hello world");
writer.WriteLine("!");

writer.Flush();
var result = _sink.ToString();
Assert.Equal("hello worldXY!XY", result);
}

[Fact]
public void WriteLineUtf8String()
{
_sink.Reset();
var writer = BufferWriter.Create(_sink);
writer.NewLine = new byte[] { (byte)'X', (byte)'Y' };
writer.WriteLine((Utf8String)"hello world");
writer.WriteLine((Utf8String)"!");

writer.Flush();
var result = _sink.ToString();
Assert.Equal("hello worldXY!XY", result);
}
}

class Sink : IBufferWriter<byte>
Expand Down

0 comments on commit f5eb04e

Please sign in to comment.