From 3c865357ad2653af33ef8c0c39a21da9b511297c Mon Sep 17 00:00:00 2001 From: andreashuber-lawo Date: Mon, 4 Apr 2016 15:06:33 +0200 Subject: [PATCH] Closes #19 --- Lawo.EmberPlusSharp/Ember/EmberWriter.cs | 7 ++++ .../Model/EmberReaderExtensions.cs | 5 --- Lawo.EmberPlusSharp/Model/NodeBase.cs | 40 +++++++++++++------ Lawo/IO/WriteBuffer.cs | 11 ++++- LawoTest/IO/BufferTest.cs | 9 +++-- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/Lawo.EmberPlusSharp/Ember/EmberWriter.cs b/Lawo.EmberPlusSharp/Ember/EmberWriter.cs index 107664ce..3ea2f4f2 100644 --- a/Lawo.EmberPlusSharp/Ember/EmberWriter.cs +++ b/Lawo.EmberPlusSharp/Ember/EmberWriter.cs @@ -264,6 +264,13 @@ public void WriteEndContainer() WriteLength(this.writeBuffer, 0, 0, 1); } + /// Flushes the internal buffer into the stream passed to the constructor. + public void Flush() + { + this.AssertNotDisposed(); + this.writeBuffer.Flush(); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void AssertNotDisposed() diff --git a/Lawo.EmberPlusSharp/Model/EmberReaderExtensions.cs b/Lawo.EmberPlusSharp/Model/EmberReaderExtensions.cs index 069a2c3d..3a466454 100644 --- a/Lawo.EmberPlusSharp/Model/EmberReaderExtensions.cs +++ b/Lawo.EmberPlusSharp/Model/EmberReaderExtensions.cs @@ -13,11 +13,6 @@ namespace Lawo.EmberPlusSharp.Model internal static class EmberReaderExtensions { - internal static void AssertRead(this EmberReader reader) - { - AssertRead(reader, null); - } - internal static bool AssertAndReadContentsAsBoolean(this EmberReader reader) { return AssertAndReadContents(reader, r => r.ReadContentsAsBoolean()); diff --git a/Lawo.EmberPlusSharp/Model/NodeBase.cs b/Lawo.EmberPlusSharp/Model/NodeBase.cs index 4b03ab3e..02e3d4a9 100644 --- a/Lawo.EmberPlusSharp/Model/NodeBase.cs +++ b/Lawo.EmberPlusSharp/Model/NodeBase.cs @@ -8,6 +8,7 @@ namespace Lawo.EmberPlusSharp.Model { using System.Collections.Generic; using System.ComponentModel; + using System.IO; using System.Linq; using System.Text; @@ -319,24 +320,37 @@ private void ReadChildContents( } else { - reader.AssertRead(); - - if (reader.CanReadContents && (reader.OuterId == GlowNodeContents.Identifier.OuterId)) + using (var stream = new MemoryStream()) + using (var writer = new EmberWriter(stream)) { - var context = new Context(this, number, reader.AssertAndReadContentsAsString()); - child = this.ReadNewChildContents(reader, actualType, context, out childRequestState); + // Since EmberReader checks that every end of a container is matched by a start, we need to write + // this dummy here. + writer.WriteStartSet(GlowNode.Contents.OuterId); + var identifier = reader.CopyToEndContainer(writer, GlowNodeContents.Identifier.OuterId) as string; + + if (identifier != null) + { + writer.Flush(); + stream.Position = 0; - if (child != null) + using (var contentsReader = new EmberReader(stream)) + { + contentsReader.Read(); // Read what we have written with WriteStartSet above + var context = new Context(this, number, identifier); + child = this.ReadNewChildContents(contentsReader, actualType, context, out childRequestState); + + if (child != null) + { + this.children.Add(number, child); + } + } + } + else { - this.children.Add(number, child); + childRequestState = RequestState.Complete; + child = null; } } - else - { - reader.SkipToEndContainer(); - childRequestState = RequestState.Complete; - child = null; - } } } diff --git a/Lawo/IO/WriteBuffer.cs b/Lawo/IO/WriteBuffer.cs index 0c0800ab..d7eea6ae 100644 --- a/Lawo/IO/WriteBuffer.cs +++ b/Lawo/IO/WriteBuffer.cs @@ -113,8 +113,15 @@ public WriteBuffer(WriteAsyncCallback writeAsync, int bufferSize) : base(bufferS public bool Flush() { var count = this.Count; - this.Count = 0; // Make sure that the buffer is empty even if write throws - this.write(this.GetBuffer(), 0, count); + + // Prevent call to this.write when buffer is empty so that there is no error when the underlying stream has + // already been disposed. + if (count > 0) + { + this.Count = 0; // Make sure that the buffer is empty even if write throws + this.write(this.GetBuffer(), 0, count); + } + return true; } diff --git a/LawoTest/IO/BufferTest.cs b/LawoTest/IO/BufferTest.cs index 60d9378a..c9096769 100644 --- a/LawoTest/IO/BufferTest.cs +++ b/LawoTest/IO/BufferTest.cs @@ -184,11 +184,14 @@ await AssertThrowAsync( () => writeBuffer.WriteAsync(new byte[3], 0, 3, CancellationToken.None)); var asyncWriteBuffer = new WriteBuffer((WriteAsyncCallback)stream.WriteAsync, 1); + asyncWriteBuffer[asyncWriteBuffer.Count++] = 42; + AssertThrow(() => asyncWriteBuffer.Flush()); + asyncWriteBuffer[asyncWriteBuffer.Count++] = 42; + AssertThrow( + () => asyncWriteBuffer.Reserve(2), () => asyncWriteBuffer.Write(new byte[3], 0, 3)); + asyncWriteBuffer[asyncWriteBuffer.Count++] = 42; var str = "Hello"; AssertThrow( - () => asyncWriteBuffer.Flush(), - () => asyncWriteBuffer.Reserve(2), - () => asyncWriteBuffer.Write(new byte[3], 0, 3), () => asyncWriteBuffer.WriteAsUtf8(str, Encoding.UTF8.GetByteCount(str))); } });