From 84b7fc901e1555fe83d11b3e8ab94e9e844566db Mon Sep 17 00:00:00 2001 From: MaxXor Date: Tue, 17 Mar 2015 22:28:03 +0100 Subject: [PATCH] Fixed ProtoWriter Dispose this broke protobuf --- Client/Core/ProtoBuf/ProtoWriter.cs | 54 ++----------- Server/Core/ProtoBuf/ProtoWriter.cs | 119 ++++++++++------------------ 2 files changed, 50 insertions(+), 123 deletions(-) diff --git a/Client/Core/ProtoBuf/ProtoWriter.cs b/Client/Core/ProtoBuf/ProtoWriter.cs index 5b0ea59b..9d1e8535 100644 --- a/Client/Core/ProtoBuf/ProtoWriter.cs +++ b/Client/Core/ProtoBuf/ProtoWriter.cs @@ -474,60 +474,22 @@ public ProtoWriter(Stream dest, TypeModel model, SerializationContext context) /// void IDisposable.Dispose() { - // Dispose of it all. - Dispose(true); - - // Don't waste time finalizing because we have already disposed of the object ourselves. - GC.SuppressFinalize(this); - } - - /// - /// Release some resources of the ProtoWriter, but NOT the underlying stream. - /// - public void Dispose() - { - // ProtoWriter's own definition of dispose. Will release some resources, but not the underlying stream. - Dispose(false); + Dispose(); } /// /// Releases some resources of the ProtoWriter. Optionally dispose of it all, including the underlying stream. /// - /// Determines whether to dispose of everything, including the underlying stream. - public void Dispose(bool disposing) + public void Dispose() { - if (!disposed) + if (dest != null) { - model = null; - BufferPool.ReleaseBufferToPool(ref ioBuffer); - - if (disposing) - { - if (dest != null) - { - try - { - // Flush can throw a few exceptions, so make sure that, even if it messes up, dispose of the underlying stream. - Flush(this); - } - finally - { - dest.Dispose(); - dest = null; - } - } - - disposed = true; - } + Flush(this); + dest.Dispose(); + dest = null; } - } - - ~ProtoWriter() - { - // The object has been destroyed. Make sure everything is cleaned up. - // If the object has already been fully disposed, this finalizer would - // be suppressed. - Dispose(true); + model = null; + BufferPool.ReleaseBufferToPool(ref ioBuffer); } private byte[] ioBuffer; diff --git a/Server/Core/ProtoBuf/ProtoWriter.cs b/Server/Core/ProtoBuf/ProtoWriter.cs index 5b0ea59b..b82fc54c 100644 --- a/Server/Core/ProtoBuf/ProtoWriter.cs +++ b/Server/Core/ProtoBuf/ProtoWriter.cs @@ -24,7 +24,7 @@ public sealed class ProtoWriter : IDisposable private Stream dest; TypeModel model; private bool disposed = false; - + /// /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). /// @@ -56,7 +56,7 @@ public static void WriteObject(object value, int key, ProtoWriter writer) TypeModel.ThrowUnexpectedType(value.GetType()); } EndSubItem(token, writer); -#endif +#endif } /// /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the @@ -116,18 +116,18 @@ internal static void WriteObject(object value, int key, ProtoWriter writer, Pref writer.model.Serialize(key, value, writer); } EndSubItem(token, writer, style); -#endif +#endif } internal int GetTypeKey(ref Type type) { return model.GetKey(ref type); } - + private readonly NetObjectCache netCache = new NetObjectCache(); internal NetObjectCache NetCache { - get { return netCache;} + get { return netCache; } } private int fieldNumber, flushLock; @@ -136,11 +136,12 @@ internal NetObjectCache NetCache /// /// Writes a field-header, indicating the format of the next data we plan to write. /// - public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) { + public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) + { if (writer == null) throw new ArgumentNullException("writer"); if (writer.wireType != WireType.None) throw new InvalidOperationException("Cannot write a " + wireType.ToString() + " header until the " + writer.wireType.ToString() + " data has been written"); - if(fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber"); + if (fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber"); #if DEBUG switch (wireType) { // validate requested header-type @@ -154,10 +155,11 @@ internal NetObjectCache NetCache case WireType.None: case WireType.EndGroup: default: - throw new ArgumentException("Invalid wire-type: " + wireType.ToString(), "wireType"); + throw new ArgumentException("Invalid wire-type: " + wireType.ToString(), "wireType"); } #endif - if (writer.packedFieldNumber == 0) { + if (writer.packedFieldNumber == 0) + { writer.fieldNumber = fieldNumber; writer.wireType = wireType; WriteHeaderCore(fieldNumber, wireType, writer); @@ -226,7 +228,7 @@ public static void WriteBytes(byte[] data, int offset, int length, ProtoWriter w // now just write directly to the underlying stream writer.dest.Write(data, offset, length); writer.position += length; // since we've flushed offset etc is 0, and remains - // zero since we're writing directly to the stream + // zero since we're writing directly to the stream return; } throw CreateException(writer); @@ -239,13 +241,13 @@ private static void CopyRawFromStream(Stream source, ProtoWriter writer) { byte[] buffer = writer.ioBuffer; int space = buffer.Length - writer.ioIndex, bytesRead = 1; // 1 here to spoof case where already full - + // try filling the buffer first while (space > 0 && (bytesRead = source.Read(buffer, writer.ioIndex, space)) > 0) { writer.ioIndex += bytesRead; writer.position += bytesRead; - space -= bytesRead; + space -= bytesRead; } if (bytesRead <= 0) return; // all done using just the buffer; stream exhausted @@ -268,7 +270,7 @@ private static void CopyRawFromStream(Stream source, ProtoWriter writer) // (128 is the minimum; there may actually be much // more space than this in the buffer) DemandSpace(128, writer); - if((bytesRead = source.Read(writer.ioBuffer, writer.ioIndex, + if ((bytesRead = source.Read(writer.ioBuffer, writer.ioIndex, writer.ioBuffer.Length - writer.ioIndex)) <= 0) break; writer.position += bytesRead; writer.ioIndex += bytesRead; @@ -305,7 +307,7 @@ private void CheckRecursionStackAndPush(object instance) { #if DEBUG Helpers.DebugWriteLine("Stack:"); - foreach(object obj in recursionStack) + foreach (object obj in recursionStack) { Helpers.DebugWriteLine(obj == null ? "" : obj.ToString()); } @@ -324,7 +326,7 @@ private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bo { writer.CheckRecursionStackAndPush(instance); } - if(writer.packedFieldNumber != 0) throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); + if (writer.packedFieldNumber != 0) throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); switch (writer.wireType) { case WireType.StartGroup: @@ -332,7 +334,7 @@ private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bo return new SubItemToken(-writer.fieldNumber); case WireType.String: #if DEBUG - if(writer.model != null && writer.model.ForwardsOnly) + if (writer.model != null && writer.model.ForwardsOnly) { throw new ProtoException("Should not be buffering data"); } @@ -385,7 +387,7 @@ private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixSty // so we're backfilling the length into an existing sequence int len; - switch(style) + switch (style) { case PrefixStyle.Fixed32: len = (int)((writer.ioIndex - value) - 4); @@ -439,7 +441,7 @@ private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixSty { ProtoWriter.Flush(writer); } - + } /// @@ -460,7 +462,7 @@ public ProtoWriter(Stream dest, TypeModel model, SerializationContext context) if (context == null) { context = SerializationContext.Default; } else { context.Freeze(); } this.context = context; - + } private readonly SerializationContext context; @@ -474,60 +476,22 @@ public ProtoWriter(Stream dest, TypeModel model, SerializationContext context) /// void IDisposable.Dispose() { - // Dispose of it all. - Dispose(true); - - // Don't waste time finalizing because we have already disposed of the object ourselves. - GC.SuppressFinalize(this); - } - - /// - /// Release some resources of the ProtoWriter, but NOT the underlying stream. - /// - public void Dispose() - { - // ProtoWriter's own definition of dispose. Will release some resources, but not the underlying stream. - Dispose(false); + Dispose(); } /// /// Releases some resources of the ProtoWriter. Optionally dispose of it all, including the underlying stream. /// - /// Determines whether to dispose of everything, including the underlying stream. - public void Dispose(bool disposing) + public void Dispose() { - if (!disposed) + if (dest != null) { - model = null; - BufferPool.ReleaseBufferToPool(ref ioBuffer); - - if (disposing) - { - if (dest != null) - { - try - { - // Flush can throw a few exceptions, so make sure that, even if it messes up, dispose of the underlying stream. - Flush(this); - } - finally - { - dest.Dispose(); - dest = null; - } - } - - disposed = true; - } + Flush(this); + dest.Dispose(); + dest = null; } - } - - ~ProtoWriter() - { - // The object has been destroyed. Make sure everything is cleaned up. - // If the object has already been fully disposed, this finalizer would - // be suppressed. - Dispose(true); + model = null; + BufferPool.ReleaseBufferToPool(ref ioBuffer); } private byte[] ioBuffer; @@ -580,7 +544,7 @@ internal static void Flush(ProtoWriter writer) if (writer.flushLock == 0 && writer.ioIndex != 0) { writer.dest.Write(writer.ioBuffer, 0, writer.ioIndex); - writer.ioIndex = 0; + writer.ioIndex = 0; } } @@ -591,18 +555,19 @@ private static void WriteUInt32Variant(uint value, ProtoWriter writer) { DemandSpace(5, writer); int count = 0; - do { + do + { writer.ioBuffer[writer.ioIndex++] = (byte)((value & 0x7F) | 0x80); count++; } while ((value >>= 7) != 0); writer.ioBuffer[writer.ioIndex - 1] &= 0x7F; writer.position += count; } - + static readonly UTF8Encoding encoding = new UTF8Encoding(); internal static uint Zig(int value) - { + { return (uint)((value << 1) ^ (value >> 31)); } internal static ulong Zig(long value) @@ -806,7 +771,7 @@ public static void WriteInt32(int value, ProtoWriter writer) { case WireType.Fixed32: DemandSpace(4, writer); - WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); + WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); IncrementedAndReset(4, writer); return; case WireType.Fixed64: @@ -850,17 +815,17 @@ public static void WriteInt32(int value, ProtoWriter writer) default: throw CreateException(writer); } - + } /// /// Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64 /// public #if !FEAT_SAFE - unsafe + unsafe #endif - static void WriteDouble(double value, ProtoWriter writer) + static void WriteDouble(double value, ProtoWriter writer) { if (writer == null) throw new ArgumentNullException("writer"); switch (writer.wireType) @@ -888,11 +853,11 @@ static void WriteDouble(double value, ProtoWriter writer) /// /// Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64 /// - public + public #if !FEAT_SAFE - unsafe + unsafe #endif - static void WriteSingle(float value, ProtoWriter writer) + static void WriteSingle(float value, ProtoWriter writer) { if (writer == null) throw new ArgumentNullException("writer"); switch (writer.wireType) @@ -944,7 +909,7 @@ public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) if (writer == null) throw new ArgumentNullException("writer"); // we expect the writer to be raw here; the extension data will have the // header detail, so we'll copy it implicitly - if(writer.wireType != WireType.None) throw CreateException(writer); + if (writer.wireType != WireType.None) throw CreateException(writer); IExtension extn = instance.GetExtensionObject(false); if (extn != null)