From f5eb04e6e8d38b781609107a1a7e2cc803b463da Mon Sep 17 00:00:00 2001 From: Krzysztof Cwalina Date: Thu, 22 Mar 2018 10:04:23 -0700 Subject: [PATCH] BufferWriter.WriteLine String/Utf8String (#2176) * Bug fix in BufferWriter * BufferWriter WriteLine Strings --- .../System/Buffers/IPipeWritable.cs | 3 +- .../{OutputWriter.cs => BufferWriterT.cs} | 2 + .../Buffers/Writer/BufferWriterT_ints.cs | 34 +++++++++ ..._overloads.cs => BufferWriterT_strings.cs} | 72 +++++++------------ .../Buffers/Writer/BufferWriterT_writable.cs | 38 ++++++++++ .../BasicUnitTests.cs | 28 ++++++++ 6 files changed, 129 insertions(+), 48 deletions(-) rename src/System.Buffers.ReaderWriter/System/Buffers/Writer/{OutputWriter.cs => BufferWriterT.cs} (97%) create mode 100644 src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_ints.cs rename src/System.Buffers.ReaderWriter/System/Buffers/Writer/{OutputWriter_overloads.cs => BufferWriterT_strings.cs} (54%) create mode 100644 src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_writable.cs diff --git a/src/System.Buffers.ReaderWriter/System/Buffers/IPipeWritable.cs b/src/System.Buffers.ReaderWriter/System/Buffers/IPipeWritable.cs index 79f52ef6fb8..e7de8b8334c 100644 --- a/src/System.Buffers.ReaderWriter/System/Buffers/IPipeWritable.cs +++ b/src/System.Buffers.ReaderWriter/System/Buffers/IPipeWritable.cs @@ -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 { diff --git a/src/System.Buffers.ReaderWriter/System/Buffers/Writer/OutputWriter.cs b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT.cs similarity index 97% rename from src/System.Buffers.ReaderWriter/System/Buffers/Writer/OutputWriter.cs rename to src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT.cs index 37521191ef2..36a944dc0e5 100644 --- a/src/System.Buffers.ReaderWriter/System/Buffers/Writer/OutputWriter.cs +++ b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT.cs @@ -19,6 +19,8 @@ public BufferWriter(T output) _span = output.GetSpan(); } + public ReadOnlySpan NewLine; + public Span Buffer => _span; [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_ints.cs b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_ints.cs new file mode 100644 index 00000000000..db82a67d754 --- /dev/null +++ b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_ints.cs @@ -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 where T : IBufferWriter + { + [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); + } + } +} diff --git a/src/System.Buffers.ReaderWriter/System/Buffers/Writer/OutputWriter_overloads.cs b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_strings.cs similarity index 54% rename from src/System.Buffers.ReaderWriter/System/Buffers/Writer/OutputWriter_overloads.cs rename to src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_strings.cs index 3adf4825432..999f55af43d 100644 --- a/src/System.Buffers.ReaderWriter/System/Buffers/Writer/OutputWriter_overloads.cs +++ b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_strings.cs @@ -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 where T : IBufferWriter { - [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 utf16Bytes = value.AsSpan().AsBytes(); @@ -55,46 +34,45 @@ public void Write(string value) } } - public void Write(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 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 source) + public void Write(ReadOnlySpan 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 value, TransformationFormat format) + private void WriteMultiBuffer(ReadOnlySpan source) { while (source.Length > 0) diff --git a/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_writable.cs b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_writable.cs new file mode 100644 index 00000000000..f05a756f9c3 --- /dev/null +++ b/src/System.Buffers.ReaderWriter/System/Buffers/Writer/BufferWriterT_writable.cs @@ -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 where T : IBufferWriter + { + public void Write(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 value, StandardFormat format) where TWritable : IWritable + { + int written; + while (!value.TryWrite(Buffer, out written, format)) + { + Enlarge(); + } + Advance(written); + } + } +} diff --git a/tests/System.Buffers.ReaderWriter.Tests/BasicUnitTests.cs b/tests/System.Buffers.ReaderWriter.Tests/BasicUnitTests.cs index 580e5192265..09c1998fb67 100644 --- a/tests/System.Buffers.ReaderWriter.Tests/BasicUnitTests.cs +++ b/tests/System.Buffers.ReaderWriter.Tests/BasicUnitTests.cs @@ -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