Ver código fonte

Added IDisposable to ICodedOutputStream

csharptest 14 anos atrás
pai
commit
819b7154d1

+ 33 - 16
src/ProtocolBuffers.Serialization/Http/MessageFormatFactory.cs

@@ -58,15 +58,15 @@ namespace Google.ProtocolBuffers.Serialization
             ICodedInputStream codedInput = CreateInputStream(options, contentType, input);
             return (TBuilder)builder.WeakMergeFrom(codedInput, options.ExtensionRegistry);
         }
-
+        
         /// <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)
+        /// <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);
 
@@ -95,15 +95,15 @@ namespace Google.ProtocolBuffers.Serialization
                 else
                 {
                     XmlWriterSettings settings = new XmlWriterSettings()
-                       {
-                           CheckCharacters = false,
-                           NewLineHandling = NewLineHandling.Entitize,
-                           OmitXmlDeclaration = true,
-                           Encoding = Encoding.UTF8,
-                           Indent = true,
-                           IndentChars = "  ",
-                           NewLineChars = Environment.NewLine,
-                       };
+                                                     {
+                                                         CheckCharacters = false,
+                                                         NewLineHandling = NewLineHandling.Entitize,
+                                                         OmitXmlDeclaration = true,
+                                                         Encoding = Encoding.UTF8,
+                                                         Indent = true,
+                                                         IndentChars = "  ",
+                                                         NewLineChars = Environment.NewLine,
+                                                     };
                     writer = XmlFormatWriter.CreateInstance(XmlWriter.Create(output, settings));
                 }
                 writer.RootElementName = options.XmlWriterRootElementName;
@@ -114,12 +114,29 @@ namespace Google.ProtocolBuffers.Serialization
             else
                 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)
-                ((AbstractWriter) codedOutput).EndMessage();
+                // 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();
 
-            codedOutput.Flush();
+                codedOutput.Flush();
+            }
         }
 
 

+ 13 - 0
src/ProtocolBuffers.Serialization/JsonFormatWriter.cs

@@ -239,6 +239,19 @@ namespace Google.ProtocolBuffers.Serialization
         /// <summary> Gets or sets the whitespace to use to separate the text, default = empty </summary>
         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()
         {
             if (_counter.Count == 0)

+ 14 - 0
src/ProtocolBuffers.Serialization/XmlFormatWriter.cs

@@ -75,8 +75,13 @@ namespace Google.ProtocolBuffers.Serialization
         {
             if (disposing)
             {
+                if (_output.WriteState != WriteState.Closed && _output.WriteState != WriteState.Start)
+                    _output.WriteEndDocument();
+
                 _output.Close();
             }
+
+            base.Dispose(disposing);
         }
 
         /// <summary>
@@ -111,6 +116,15 @@ namespace Google.ProtocolBuffers.Serialization
             return (Options & option) != 0;
         }
 
+        /// <summary>
+        /// Completes any pending write operations
+        /// </summary>
+        public override void Flush()
+        {
+            _output.Flush();
+            base.Flush();
+        }
+
         /// <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 

+ 11 - 1
src/ProtocolBuffers/CodedOutputStream.cs

@@ -57,7 +57,7 @@ namespace Google.ProtocolBuffers
     /// methods are taken from the protocol buffer type names, not .NET types.
     /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)
     /// </remarks>
-    public sealed partial class CodedOutputStream : ICodedOutputStream
+    public sealed partial class CodedOutputStream : ICodedOutputStream, IDisposable
     {
         /// <summary>
         /// The buffer size used by CreateInstance(Stream).
@@ -125,6 +125,16 @@ namespace Google.ProtocolBuffers
         }
 
         #endregion
+        
+        public void Dispose()
+        {
+            if (output != null)
+            {
+                if (position > 0)
+                    Flush();
+                output.Dispose();
+            }
+        }
 
         #region Writing of unknown fields
 

+ 1 - 1
src/ProtocolBuffers/ICodedOutputStream.cs

@@ -49,7 +49,7 @@ namespace Google.ProtocolBuffers
     /// in their binary form by creating a instance via the CodedOutputStream.CreateInstance
     /// static factory.
     /// </summary>
-    public interface ICodedOutputStream
+    public interface ICodedOutputStream : IDisposable
     {
         /// <summary>
         /// Indicates that all temporary buffers be written to the final output.