aboutsummaryrefslogtreecommitdiff
path: root/src/ProtocolBuffers.Serialization
diff options
context:
space:
mode:
authorcsharptest <roger@csharptest.net>2011-09-09 12:18:16 -0500
committerrogerk <devnull@localhost>2011-09-09 12:18:16 -0500
commit60fd773d300cd0390ba08812590690ab2d28c837 (patch)
tree292994e6c5602566ed50d9911522f2e5e80515b1 /src/ProtocolBuffers.Serialization
parent819b7154d162f3ef4f187f19b020f999c02fcf03 (diff)
downloadprotobuf-60fd773d300cd0390ba08812590690ab2d28c837.tar.gz
protobuf-60fd773d300cd0390ba08812590690ab2d28c837.tar.bz2
protobuf-60fd773d300cd0390ba08812590690ab2d28c837.zip
Completed work and testing for manually reading/writing start/end message
Diffstat (limited to 'src/ProtocolBuffers.Serialization')
-rw-r--r--src/ProtocolBuffers.Serialization/AbstractReader.cs10
-rw-r--r--src/ProtocolBuffers.Serialization/AbstractTextReader.cs4
-rw-r--r--src/ProtocolBuffers.Serialization/AbstractWriter.cs12
-rw-r--r--src/ProtocolBuffers.Serialization/DictionaryReader.cs13
-rw-r--r--src/ProtocolBuffers.Serialization/DictionaryWriter.cs6
-rw-r--r--src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs33
-rw-r--r--src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs2
-rw-r--r--src/ProtocolBuffers.Serialization/Http/ServiceExtensions.cs3
-rw-r--r--src/ProtocolBuffers.Serialization/JsonFormatReader.cs13
-rw-r--r--src/ProtocolBuffers.Serialization/JsonFormatWriter.cs21
-rw-r--r--src/ProtocolBuffers.Serialization/XmlFormatReader.cs142
-rw-r--r--src/ProtocolBuffers.Serialization/XmlFormatWriter.cs28
12 files changed, 138 insertions, 149 deletions
diff --git a/src/ProtocolBuffers.Serialization/AbstractReader.cs b/src/ProtocolBuffers.Serialization/AbstractReader.cs
index 538af38f..f3e6fd6f 100644
--- a/src/ProtocolBuffers.Serialization/AbstractReader.cs
+++ b/src/ProtocolBuffers.Serialization/AbstractReader.cs
@@ -17,12 +17,6 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary> Constructs a new reader </summary>
protected AbstractReader() { MaxDepth = DefaultMaxDepth; }
- /// <summary> Constructs a new child reader </summary>
- protected AbstractReader(AbstractReader copyFrom)
- {
- _depth = copyFrom._depth + 1;
- MaxDepth = copyFrom.MaxDepth;
- }
/// <summary> Gets or sets the maximum recursion depth allowed </summary>
public int MaxDepth { get; set; }
@@ -116,12 +110,12 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// Reads the root-message preamble specific to this formatter
/// </summary>
- public abstract AbstractReader ReadStartMessage();
+ public abstract void ReadMessageStart();
/// <summary>
/// Reads the root-message close specific to this formatter
/// </summary>
- public abstract void ReadEndMessage();
+ public abstract void ReadMessageEnd();
/// <summary>
/// Merges the input stream into the provided IBuilderLite
diff --git a/src/ProtocolBuffers.Serialization/AbstractTextReader.cs b/src/ProtocolBuffers.Serialization/AbstractTextReader.cs
index 59b9057b..ddfa6436 100644
--- a/src/ProtocolBuffers.Serialization/AbstractTextReader.cs
+++ b/src/ProtocolBuffers.Serialization/AbstractTextReader.cs
@@ -11,10 +11,6 @@ namespace Google.ProtocolBuffers.Serialization
{
/// <summary> Constructs a new reader </summary>
protected AbstractTextReader() { }
- /// <summary> Constructs a new child reader </summary>
- protected AbstractTextReader(AbstractTextReader copyFrom)
- : base(copyFrom)
- { }
/// <summary>
/// Reads a typed field as a string
diff --git a/src/ProtocolBuffers.Serialization/AbstractWriter.cs b/src/ProtocolBuffers.Serialization/AbstractWriter.cs
index 50dfe671..7ae26864 100644
--- a/src/ProtocolBuffers.Serialization/AbstractWriter.cs
+++ b/src/ProtocolBuffers.Serialization/AbstractWriter.cs
@@ -45,23 +45,23 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// Used to write any nessary root-message preamble. After this call you can call
- /// IMessageLite.MergeTo(...) and complete the message with a call to EndMessage().
+ /// IMessageLite.MergeTo(...) and complete the message with a call to WriteMessageEnd().
/// These three calls are identical to just calling WriteMessage(message);
/// </summary>
/// <example>
/// AbstractWriter writer;
- /// writer.StartMessage();
+ /// writer.WriteMessageStart();
/// message.WriteTo(writer);
- /// writer.EndMessage();
+ /// writer.WriteMessageEnd();
/// // ... or, but not both ...
/// writer.WriteMessage(message);
/// </example>
- public abstract void StartMessage();
+ public abstract void WriteMessageStart();
/// <summary>
- /// Used to complete a root-message previously started with a call to StartMessage()
+ /// Used to complete a root-message previously started with a call to WriteMessageStart()
/// </summary>
- public abstract void EndMessage();
+ public abstract void WriteMessageEnd();
/// <summary>
/// Writes a Boolean value
diff --git a/src/ProtocolBuffers.Serialization/DictionaryReader.cs b/src/ProtocolBuffers.Serialization/DictionaryReader.cs
index f606bc9b..bb83ef9c 100644
--- a/src/ProtocolBuffers.Serialization/DictionaryReader.cs
+++ b/src/ProtocolBuffers.Serialization/DictionaryReader.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Globalization;
using Google.ProtocolBuffers.Descriptors;
@@ -25,17 +25,14 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// No-op
/// </summary>
- public override AbstractReader ReadStartMessage()
- {
- return this;
- }
+ public override void ReadMessageStart()
+ { }
/// <summary>
/// No-op
/// </summary>
- public override void ReadEndMessage()
- {
- }
+ public override void ReadMessageEnd()
+ { }
/// <summary>
/// Merges the contents of stream into the provided message builder
diff --git a/src/ProtocolBuffers.Serialization/DictionaryWriter.cs b/src/ProtocolBuffers.Serialization/DictionaryWriter.cs
index 4c3b0116..6d823301 100644
--- a/src/ProtocolBuffers.Serialization/DictionaryWriter.cs
+++ b/src/ProtocolBuffers.Serialization/DictionaryWriter.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections;
using System.Collections.Generic;
using Google.ProtocolBuffers.Descriptors;
@@ -57,13 +57,13 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// No-op
/// </summary>
- public override void StartMessage()
+ public override void WriteMessageStart()
{ }
/// <summary>
/// No-op
/// </summary>
- public override void EndMessage()
+ public override void WriteMessageEnd()
{ }
/// <summary>
diff --git a/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs b/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
index 8a19a8b7..2ee7eb4d 100644
--- a/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
+++ b/src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs
@@ -3,7 +3,7 @@ using System.IO;
using System.Xml;
using System.Text;
-namespace Google.ProtocolBuffers.Serialization
+namespace Google.ProtocolBuffers.Serialization.Http
{
/// <summary>
/// Extensions and helpers to abstract the reading/writing of messages by a client-specified content type.
@@ -29,14 +29,14 @@ namespace Google.ProtocolBuffers.Serialization
else if (inputType == FormatType.Json)
{
JsonFormatReader reader = JsonFormatReader.CreateInstance(input);
- codedInput = reader.ReadStartMessage();
+ codedInput = reader;
}
else if (inputType == FormatType.Xml)
{
XmlFormatReader reader = XmlFormatReader.CreateInstance(input);
reader.RootElementName = options.XmlReaderRootElementName;
reader.Options = options.XmlReaderOptions;
- codedInput = reader.ReadStartMessage();
+ codedInput = reader;
}
else
throw new NotSupportedException();
@@ -56,6 +56,7 @@ namespace Google.ProtocolBuffers.Serialization
public static TBuilder MergeFrom<TBuilder>(this TBuilder builder, MessageFormatOptions options, string contentType, Stream input) where TBuilder : IBuilderLite
{
ICodedInputStream codedInput = CreateInputStream(options, contentType, input);
+ codedInput.ReadMessageStart();
return (TBuilder)builder.WeakMergeFrom(codedInput, options.ExtensionRegistry);
}
@@ -82,13 +83,12 @@ namespace Google.ProtocolBuffers.Serialization
{
writer.Formatted();
}
- writer.StartMessage();
codedOutput = writer;
}
else if (outputType == FormatType.Xml)
{
XmlFormatWriter writer;
- if (options.FormattedOutput)
+ if (!options.FormattedOutput)
{
writer = XmlFormatWriter.CreateInstance(output);
}
@@ -99,16 +99,15 @@ namespace Google.ProtocolBuffers.Serialization
CheckCharacters = false,
NewLineHandling = NewLineHandling.Entitize,
OmitXmlDeclaration = true,
- Encoding = Encoding.UTF8,
+ Encoding = new UTF8Encoding(false),
Indent = true,
- IndentChars = " ",
+ IndentChars = " ",
NewLineChars = Environment.NewLine,
};
writer = XmlFormatWriter.CreateInstance(XmlWriter.Create(output, settings));
}
writer.RootElementName = options.XmlWriterRootElementName;
writer.Options = options.XmlWriterOptions;
- writer.StartMessage();
codedOutput = writer;
}
else
@@ -126,19 +125,17 @@ namespace Google.ProtocolBuffers.Serialization
/// <param name="output">The stream to write the message to</param>
public static void WriteTo(this IMessageLite message, MessageFormatOptions options, string contentType, Stream output)
{
- using (ICodedOutputStream codedOutput = CreateOutputStream(options, contentType, output))
- {
- message.WriteTo(codedOutput);
+ ICodedOutputStream codedOutput = CreateOutputStream(options, contentType, output);
- // This is effectivly done by Dispose(); however, if you need to finalize a message
- // without disposing the underlying stream, this is the only way to do it.
- if (codedOutput is AbstractWriter)
- ((AbstractWriter)codedOutput).EndMessage();
+ // Output the appropriate message preamble
+ codedOutput.WriteMessageStart();
- codedOutput.Flush();
- }
- }
+ // Write the message content to the output
+ message.WriteTo(codedOutput);
+ // Write the closing message fragment
+ codedOutput.WriteMessageEnd();
+ }
enum FormatType { ProtoBuffer, Json, Xml };
diff --git a/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs b/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs
index 5b88ac94..02f2ea46 100644
--- a/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs
+++ b/src/ProtocolBuffers.Serialization/Http/MessageFormatOptions.cs
@@ -1,6 +1,6 @@
using System;
-namespace Google.ProtocolBuffers.Serialization
+namespace Google.ProtocolBuffers.Serialization.Http
{
/// <summary>
/// Defines control information for the various formatting used with HTTP services
diff --git a/src/ProtocolBuffers.Serialization/Http/ServiceExtensions.cs b/src/ProtocolBuffers.Serialization/Http/ServiceExtensions.cs
index 3ca9964a..022cfb6a 100644
--- a/src/ProtocolBuffers.Serialization/Http/ServiceExtensions.cs
+++ b/src/ProtocolBuffers.Serialization/Http/ServiceExtensions.cs
@@ -3,7 +3,7 @@ using System.Text;
using Google.ProtocolBuffers;
using System.IO;
-namespace Google.ProtocolBuffers.Serialization
+namespace Google.ProtocolBuffers.Serialization.Http
{
/// <summary>
/// Extensions for the IRpcServerStub
@@ -25,6 +25,7 @@ namespace Google.ProtocolBuffers.Serialization
string contentType, Stream input, string responseType, Stream output)
{
ICodedInputStream codedInput = MessageFormatFactory.CreateInputStream(options, contentType, input);
+ codedInput.ReadMessageStart();
IMessageLite response = stub.CallMethod(methodName, codedInput, options.ExtensionRegistry);
response.WriteTo(options, responseType, output);
}
diff --git a/src/ProtocolBuffers.Serialization/JsonFormatReader.cs b/src/ProtocolBuffers.Serialization/JsonFormatReader.cs
index 40336787..240ce625 100644
--- a/src/ProtocolBuffers.Serialization/JsonFormatReader.cs
+++ b/src/ProtocolBuffers.Serialization/JsonFormatReader.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
@@ -103,19 +103,18 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// Reads the root-message preamble specific to this formatter
/// </summary>
- public override AbstractReader ReadStartMessage()
+ public override void ReadMessageStart()
{
_input.Consume('{');
_stopChar.Push('}');
_state = ReaderState.BeginObject;
- return this;
}
/// <summary>
/// Reads the root-message close specific to this formatter
/// </summary>
- public override void ReadEndMessage()
+ public override void ReadMessageEnd()
{
_input.Consume((char)_stopChar.Pop());
_state = ReaderState.EndValue;
@@ -126,9 +125,9 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
public override TBuilder Merge<TBuilder>(TBuilder builder, ExtensionRegistry registry)
{
- AbstractReader rdr = ReadStartMessage();
- builder.WeakMergeFrom(rdr, registry);
- rdr.ReadEndMessage();
+ ReadMessageStart();
+ builder.WeakMergeFrom(this, registry);
+ ReadMessageEnd();
return builder;
}
diff --git a/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs b/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs
index 5f396ae5..f387f39d 100644
--- a/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs
+++ b/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
@@ -101,7 +101,7 @@ namespace Google.ProtocolBuffers.Serialization
private class JsonStreamWriter : JsonFormatWriter
{
#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35
- static readonly Encoding Encoding = Encoding.UTF8;
+ static readonly Encoding Encoding = new UTF8Encoding(false);
#else
private static readonly Encoding Encoding = Encoding.ASCII;
#endif
@@ -244,9 +244,10 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
protected override void Dispose(bool disposing)
{
- if (disposing && _counter.Count == 1)
+ if (disposing)
{
- EndMessage();
+ while(_counter.Count > 1)
+ WriteMessageEnd();
}
base.Dispose(disposing);
@@ -458,17 +459,17 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
public override void WriteMessage(IMessageLite message)
{
- StartMessage();
+ WriteMessageStart();
message.WriteTo(this);
- EndMessage();
+ WriteMessageEnd();
}
/// <summary>
/// Used to write the root-message preamble, in json this is the left-curly brace '{'.
/// After this call you can call IMessageLite.MergeTo(...) and complete the message with
- /// a call to EndMessage().
+ /// a call to WriteMessageEnd().
/// </summary>
- public override void StartMessage()
+ public override void WriteMessageStart()
{
if (_isArray)
{
@@ -479,9 +480,9 @@ namespace Google.ProtocolBuffers.Serialization
}
/// <summary>
- /// Used to complete a root-message previously started with a call to StartMessage()
+ /// Used to complete a root-message previously started with a call to WriteMessageStart()
/// </summary>
- public override void EndMessage()
+ public override void WriteMessageEnd()
{
_counter.RemoveAt(_counter.Count - 1);
WriteLine("}");
diff --git a/src/ProtocolBuffers.Serialization/XmlFormatReader.cs b/src/ProtocolBuffers.Serialization/XmlFormatReader.cs
index 0d3bca67..98b69776 100644
--- a/src/ProtocolBuffers.Serialization/XmlFormatReader.cs
+++ b/src/ProtocolBuffers.Serialization/XmlFormatReader.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
@@ -14,8 +14,23 @@ namespace Google.ProtocolBuffers.Serialization
{
public const string DefaultRootElementName = XmlFormatWriter.DefaultRootElementName;
private readonly XmlReader _input;
+ private readonly Stack<ElementStack> _elements;
private string _rootElementName;
+ private struct ElementStack
+ {
+ public readonly string LocalName;
+ public readonly int Depth;
+ public readonly bool IsEmpty;
+
+ public ElementStack(string localName, int depth, bool isEmpty) : this()
+ {
+ LocalName = localName;
+ IsEmpty = isEmpty;
+ Depth = depth;
+ }
+ }
+
private static XmlReaderSettings DefaultSettings
{
get
@@ -72,21 +87,11 @@ namespace Google.ProtocolBuffers.Serialization
{
_input = input;
_rootElementName = DefaultRootElementName;
+ _elements = new Stack<ElementStack>();
Options = XmlReaderOptions.None;
}
/// <summary>
- /// Constructs the XmlFormatReader with the XmlReader and options
- /// </summary>
- protected XmlFormatReader(XmlFormatReader copyFrom, XmlReader input)
- : base(copyFrom)
- {
- _input = input;
- _rootElementName = copyFrom._rootElementName;
- Options = copyFrom.Options;
- }
-
- /// <summary>
/// Gets or sets the options to use when reading the xml
/// </summary>
public XmlReaderOptions Options { get; set; }
@@ -113,20 +118,6 @@ namespace Google.ProtocolBuffers.Serialization
}
}
- private XmlFormatReader CloneWith(XmlReader rdr)
- {
- XmlFormatReader copy = new XmlFormatReader(this, rdr);
- return copy;
- }
-
- private void NextElement()
- {
- while (!_input.IsStartElement() && _input.Read())
- {
- continue;
- }
- }
-
private static void Assert(bool cond)
{
if (!cond)
@@ -138,36 +129,49 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// Reads the root-message preamble specific to this formatter
/// </summary>
- public override AbstractReader ReadStartMessage()
+ public override void ReadMessageStart()
{
- return ReadStartMessage(_rootElementName);
+ ReadMessageStart(_rootElementName);
}
- public AbstractReader ReadStartMessage(string element)
+ /// <summary>
+ /// Reads the root-message preamble specific to this formatter
+ /// </summary>
+ public void ReadMessageStart(string element)
{
- string field;
- Assert(PeekNext(out field) && field == element);
-
- XmlReader child = _input.ReadSubtree();
- while (!child.IsStartElement() && child.Read())
+ while (!_input.IsStartElement() && _input.Read())
{
continue;
}
- child.Read();
- return CloneWith(child);
+ Assert(_input.IsStartElement() && _input.LocalName == element);
+ _elements.Push(new ElementStack(element, _input.Depth, _input.IsEmptyElement));
+ _input.Read();
}
/// <summary>
/// Reads the root-message close specific to this formatter, MUST be called
- /// on the reader obtained from ReadStartMessage(string element).
+ /// on the reader obtained from ReadMessageStart(string element).
/// </summary>
- public override void ReadEndMessage()
+ public override void ReadMessageEnd()
{
- Assert(0 == _input.Depth);
- if(_input.NodeType == XmlNodeType.EndElement)
+ Assert(_elements.Count > 0);
+
+ ElementStack stop = _elements.Peek();
+ while (_input.NodeType != XmlNodeType.EndElement && _input.NodeType != XmlNodeType.Element
+ && _input.Depth > stop.Depth && _input.Read())
{
+ continue;
+ }
+
+ if (!stop.IsEmpty)
+ {
+ Assert(_input.NodeType == XmlNodeType.EndElement
+ && _input.LocalName == stop.LocalName
+ && _input.Depth == stop.Depth);
+
_input.Read();
}
+ _elements.Pop();
}
/// <summary>
@@ -192,9 +196,9 @@ namespace Google.ProtocolBuffers.Serialization
public TBuilder Merge<TBuilder>(string element, TBuilder builder, ExtensionRegistry registry)
where TBuilder : IBuilderLite
{
- string field;
- Assert(PeekNext(out field) && field == element);
- ReadMessage(builder, registry);
+ ReadMessageStart(element);
+ builder.WeakMergeFrom(this, registry);
+ ReadMessageEnd();
return builder;
}
@@ -207,7 +211,21 @@ namespace Google.ProtocolBuffers.Serialization
/// </remarks>
protected override bool PeekNext(out string field)
{
- NextElement();
+ ElementStack stopNode;
+ if (_elements.Count == 0)
+ {
+ stopNode = new ElementStack(null, _input.Depth - 1, false);
+ }
+ else
+ {
+ stopNode = _elements.Peek();
+ }
+
+ while (!_input.IsStartElement() && _input.Depth > stopNode.Depth && _input.Read())
+ {
+ continue;
+ }
+
if (_input.IsStartElement())
{
field = _input.LocalName;
@@ -270,20 +288,9 @@ namespace Google.ProtocolBuffers.Serialization
protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry)
{
Assert(_input.IsStartElement());
-
- if (!_input.IsEmptyElement)
- {
- int depth = _input.Depth;
- XmlReader child = _input.ReadSubtree();
- while (!child.IsStartElement() && child.Read())
- {
- continue;
- }
- child.Read();
- builder.WeakMergeFrom(CloneWith(child), registry);
- Assert(depth == _input.Depth && _input.NodeType == XmlNodeType.EndElement);
- }
- _input.Read();
+ ReadMessageStart(_input.LocalName);
+ builder.WeakMergeFrom(this, registry);
+ ReadMessageEnd();
return true;
}
@@ -305,27 +312,16 @@ namespace Google.ProtocolBuffers.Serialization
{
yield return item;
}
- yield break;
}
- if (!_input.IsEmptyElement)
+ else
{
- int depth = _input.Depth;
- XmlReader child = _input.ReadSubtree();
-
- while (!child.IsStartElement() && child.Read())
- {
- continue;
- }
- child.Read();
-
- foreach (string item in CloneWith(child).NonNestedArrayItems("item"))
+ ReadMessageStart(field);
+ foreach (string item in NonNestedArrayItems("item"))
{
yield return item;
}
- Assert(depth == _input.Depth && _input.NodeType == XmlNodeType.EndElement);
+ ReadMessageEnd();
}
- _input.Read();
- yield break;
}
}
} \ No newline at end of file
diff --git a/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs b/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs
index a9cfcc1e..79f403df 100644
--- a/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs
+++ b/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections;
using System.IO;
using System.Text;
@@ -14,10 +14,12 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
public class XmlFormatWriter : AbstractTextWriter
{
+ private static readonly Encoding DefaultEncoding = new UTF8Encoding(false);
public const string DefaultRootElementName = "root";
private const int NestedArrayFlag = 0x0001;
private readonly XmlWriter _output;
private string _rootElementName;
+ private int _messageOpenCount;
private static XmlWriterSettings DefaultSettings(Encoding encoding)
{
@@ -43,7 +45,7 @@ namespace Google.ProtocolBuffers.Serialization
/// </summary>
public static XmlFormatWriter CreateInstance(Stream output)
{
- return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(Encoding.UTF8)));
+ return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(DefaultEncoding)));
}
/// <summary>
@@ -65,6 +67,7 @@ namespace Google.ProtocolBuffers.Serialization
protected XmlFormatWriter(XmlWriter output)
{
_output = output;
+ _messageOpenCount = 0;
_rootElementName = DefaultRootElementName;
}
@@ -75,8 +78,8 @@ namespace Google.ProtocolBuffers.Serialization
{
if (disposing)
{
- if (_output.WriteState != WriteState.Closed && _output.WriteState != WriteState.Start)
- _output.WriteEndDocument();
+ while(_messageOpenCount > 0)
+ WriteMessageEnd();
_output.Close();
}
@@ -128,9 +131,9 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// Used to write the root-message preamble, in xml this is open element for RootElementName,
/// by default "&lt;root&gt;". After this call you can call IMessageLite.MergeTo(...) and
- /// complete the message with a call to EndMessage().
+ /// complete the message with a call to WriteMessageEnd().
/// </summary>
- public override void StartMessage()
+ public override void WriteMessageStart()
{
StartMessage(_rootElementName);
}
@@ -138,7 +141,7 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary>
/// Used to write the root-message preamble, in xml this is open element for elementName.
/// After this call you can call IMessageLite.MergeTo(...) and complete the message with
- /// a call to EndMessage().
+ /// a call to WriteMessageEnd().
/// </summary>
public void StartMessage(string elementName)
{
@@ -151,15 +154,20 @@ namespace Google.ProtocolBuffers.Serialization
{
_output.WriteStartElement(elementName);
}
+ _messageOpenCount++;
}
/// <summary>
- /// Used to complete a root-message previously started with a call to StartMessage()
+ /// Used to complete a root-message previously started with a call to WriteMessageStart()
/// </summary>
- public override void EndMessage()
+ public override void WriteMessageEnd()
{
+ if (_messageOpenCount <= 0)
+ throw new InvalidOperationException();
+
_output.WriteEndElement();
_output.Flush();
+ _messageOpenCount--;
}
/// <summary>
@@ -177,7 +185,7 @@ namespace Google.ProtocolBuffers.Serialization
{
StartMessage(elementName);
message.WriteTo(this);
- EndMessage();
+ WriteMessageEnd();
}
/// <summary>