Commit 819b7154 authored by csharptest's avatar csharptest Committed by rogerk

Added IDisposable to ICodedOutputStream

parent c2d2c1ad
...@@ -58,15 +58,15 @@ namespace Google.ProtocolBuffers.Serialization ...@@ -58,15 +58,15 @@ namespace Google.ProtocolBuffers.Serialization
ICodedInputStream codedInput = CreateInputStream(options, contentType, input); ICodedInputStream codedInput = CreateInputStream(options, contentType, input);
return (TBuilder)builder.WeakMergeFrom(codedInput, options.ExtensionRegistry); return (TBuilder)builder.WeakMergeFrom(codedInput, options.ExtensionRegistry);
} }
/// <summary> /// <summary>
/// Writes the message instance to the stream using the content type provided /// Writes the message instance to the stream using the content type provided
/// </summary> /// </summary>
/// <param name="message">An instance of a message</param>
/// <param name="options">Options specific to writing this message and/or content type</param> /// <param name="options">Options specific to writing this message and/or content type</param>
/// <param name="contentType">The mime type of the content to be written</param> /// <param name="contentType">The mime type of the content to be written</param>
/// <param name="output">The stream to write the message to</param> /// <param name="output">The stream to write the message to</param>
public static void WriteTo(this IMessageLite message, MessageFormatOptions options, string contentType, Stream output) /// <remarks> If you do not dispose of ICodedOutputStream some formats may yield incomplete output </remarks>
public static ICodedOutputStream CreateOutputStream(MessageFormatOptions options, string contentType, Stream output)
{ {
FormatType outputType = ContentTypeToFormat(contentType, options.DefaultContentType); FormatType outputType = ContentTypeToFormat(contentType, options.DefaultContentType);
...@@ -95,15 +95,15 @@ namespace Google.ProtocolBuffers.Serialization ...@@ -95,15 +95,15 @@ namespace Google.ProtocolBuffers.Serialization
else else
{ {
XmlWriterSettings settings = new XmlWriterSettings() XmlWriterSettings settings = new XmlWriterSettings()
{ {
CheckCharacters = false, CheckCharacters = false,
NewLineHandling = NewLineHandling.Entitize, NewLineHandling = NewLineHandling.Entitize,
OmitXmlDeclaration = true, OmitXmlDeclaration = true,
Encoding = Encoding.UTF8, Encoding = Encoding.UTF8,
Indent = true, Indent = true,
IndentChars = " ", IndentChars = " ",
NewLineChars = Environment.NewLine, NewLineChars = Environment.NewLine,
}; };
writer = XmlFormatWriter.CreateInstance(XmlWriter.Create(output, settings)); writer = XmlFormatWriter.CreateInstance(XmlWriter.Create(output, settings));
} }
writer.RootElementName = options.XmlWriterRootElementName; writer.RootElementName = options.XmlWriterRootElementName;
...@@ -114,12 +114,29 @@ namespace Google.ProtocolBuffers.Serialization ...@@ -114,12 +114,29 @@ namespace Google.ProtocolBuffers.Serialization
else else
throw new NotSupportedException(); throw new NotSupportedException();
message.WriteTo(codedOutput); return codedOutput;
}
/// <summary>
/// Writes the message instance to the stream using the content type provided
/// </summary>
/// <param name="message">An instance of a message</param>
/// <param name="options">Options specific to writing this message and/or content type</param>
/// <param name="contentType">The mime type of the content to be written</param>
/// <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);
if (codedOutput is AbstractWriter) // This is effectivly done by Dispose(); however, if you need to finalize a message
((AbstractWriter) codedOutput).EndMessage(); // without disposing the underlying stream, this is the only way to do it.
if (codedOutput is AbstractWriter)
((AbstractWriter)codedOutput).EndMessage();
codedOutput.Flush(); codedOutput.Flush();
}
} }
......
...@@ -239,6 +239,19 @@ namespace Google.ProtocolBuffers.Serialization ...@@ -239,6 +239,19 @@ namespace Google.ProtocolBuffers.Serialization
/// <summary> Gets or sets the whitespace to use to separate the text, default = empty </summary> /// <summary> Gets or sets the whitespace to use to separate the text, default = empty </summary>
public string Whitespace { get; set; } public string Whitespace { get; set; }
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing && _counter.Count == 1)
{
EndMessage();
}
base.Dispose(disposing);
}
private void Seperator() private void Seperator()
{ {
if (_counter.Count == 0) if (_counter.Count == 0)
......
...@@ -75,8 +75,13 @@ namespace Google.ProtocolBuffers.Serialization ...@@ -75,8 +75,13 @@ namespace Google.ProtocolBuffers.Serialization
{ {
if (disposing) if (disposing)
{ {
if (_output.WriteState != WriteState.Closed && _output.WriteState != WriteState.Start)
_output.WriteEndDocument();
_output.Close(); _output.Close();
} }
base.Dispose(disposing);
} }
/// <summary> /// <summary>
...@@ -111,6 +116,15 @@ namespace Google.ProtocolBuffers.Serialization ...@@ -111,6 +116,15 @@ namespace Google.ProtocolBuffers.Serialization
return (Options & option) != 0; return (Options & option) != 0;
} }
/// <summary>
/// Completes any pending write operations
/// </summary>
public override void Flush()
{
_output.Flush();
base.Flush();
}
/// <summary> /// <summary>
/// Used to write the root-message preamble, in xml this is open element for RootElementName, /// 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 /// by default "&lt;root&gt;". After this call you can call IMessageLite.MergeTo(...) and
......
...@@ -57,7 +57,7 @@ namespace Google.ProtocolBuffers ...@@ -57,7 +57,7 @@ namespace Google.ProtocolBuffers
/// methods are taken from the protocol buffer type names, not .NET types. /// methods are taken from the protocol buffer type names, not .NET types.
/// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.) /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)
/// </remarks> /// </remarks>
public sealed partial class CodedOutputStream : ICodedOutputStream public sealed partial class CodedOutputStream : ICodedOutputStream, IDisposable
{ {
/// <summary> /// <summary>
/// The buffer size used by CreateInstance(Stream). /// The buffer size used by CreateInstance(Stream).
...@@ -125,6 +125,16 @@ namespace Google.ProtocolBuffers ...@@ -125,6 +125,16 @@ namespace Google.ProtocolBuffers
} }
#endregion #endregion
public void Dispose()
{
if (output != null)
{
if (position > 0)
Flush();
output.Dispose();
}
}
#region Writing of unknown fields #region Writing of unknown fields
......
...@@ -49,7 +49,7 @@ namespace Google.ProtocolBuffers ...@@ -49,7 +49,7 @@ namespace Google.ProtocolBuffers
/// in their binary form by creating a instance via the CodedOutputStream.CreateInstance /// in their binary form by creating a instance via the CodedOutputStream.CreateInstance
/// static factory. /// static factory.
/// </summary> /// </summary>
public interface ICodedOutputStream public interface ICodedOutputStream : IDisposable
{ {
/// <summary> /// <summary>
/// Indicates that all temporary buffers be written to the final output. /// Indicates that all temporary buffers be written to the final output.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment