summaryrefslogtreecommitdiff
path: root/Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs')
-rw-r--r--Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs1838
1 files changed, 1838 insertions, 0 deletions
diff --git a/Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs b/Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs
new file mode 100644
index 00000000..74daf36f
--- /dev/null
+++ b/Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs
@@ -0,0 +1,1838 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using ProtoBuf.Meta;
+
+namespace ProtoBuf
+{
+ public sealed class ProtoReader : IDisposable
+ {
+ public int FieldNumber
+ {
+ get
+ {
+ return this.fieldNumber;
+ }
+ }
+
+ public WireType WireType
+ {
+ get
+ {
+ return this.wireType;
+ }
+ }
+
+ public bool InternStrings
+ {
+ get
+ {
+ return this.internStrings;
+ }
+ set
+ {
+ this.internStrings = value;
+ }
+ }
+
+ public SerializationContext Context
+ {
+ get
+ {
+ return this.context;
+ }
+ }
+
+ public int Position
+ {
+ get
+ {
+ return this.position;
+ }
+ }
+
+ public TypeModel Model
+ {
+ get
+ {
+ return this.model;
+ }
+ }
+
+ internal NetObjectCache NetCache
+ {
+ get
+ {
+ return this.netCache;
+ }
+ }
+
+ private Stream source;
+
+ private byte[] ioBuffer;
+
+ private TypeModel model;
+
+ private int fieldNumber;
+
+ private int depth;
+
+ private int dataRemaining;
+
+ private int ioIndex;
+
+ private int position;
+
+ private int available;
+
+ private int blockEnd;
+
+ private WireType wireType;
+
+ private bool isFixedLength;
+
+ private bool internStrings;
+
+ private NetObjectCache netCache;
+
+ private uint trapCount;
+
+ internal const int TO_EOF = -1;
+
+ private SerializationContext context;
+
+ private const long Int64Msb = -9223372036854775808L;
+
+ private const int Int32Msb = -2147483648;
+
+ private Dictionary<string, string> stringInterner;
+
+ private static readonly UTF8Encoding encoding = new UTF8Encoding();
+
+ private static readonly byte[] EmptyBlob = new byte[0];
+
+ [ThreadStatic]
+ private static ProtoReader lastReader;
+
+ public ProtoReader(Stream source, TypeModel model, SerializationContext context)
+ {
+ ProtoReader.Init(this, source, model, context, -1);
+ }
+
+ public ProtoReader(Stream source, TypeModel model, SerializationContext context, int length)
+ {
+ ProtoReader.Init(this, source, model, context, length);
+ }
+
+ private static void Init(ProtoReader reader, Stream source, TypeModel model, SerializationContext context, int length)
+ {
+ bool flag = source == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("source");
+ }
+ bool flag2 = !source.CanRead;
+ if (flag2)
+ {
+ throw new ArgumentException("Cannot read from stream", "source");
+ }
+ reader.source = source;
+ reader.ioBuffer = BufferPool.GetBuffer();
+ reader.model = model;
+ bool flag3 = length >= 0;
+ reader.isFixedLength = flag3;
+ reader.dataRemaining = (flag3 ? length : 0);
+ bool flag4 = context == null;
+ if (flag4)
+ {
+ context = SerializationContext.Default;
+ }
+ else
+ {
+ context.Freeze();
+ }
+ reader.context = context;
+ reader.position = (reader.available = (reader.depth = (reader.fieldNumber = (reader.ioIndex = 0))));
+ reader.blockEnd = int.MaxValue;
+ reader.internStrings = true;
+ reader.wireType = WireType.None;
+ reader.trapCount = 1u;
+ bool flag5 = reader.netCache == null;
+ if (flag5)
+ {
+ reader.netCache = new NetObjectCache();
+ }
+ }
+
+ public void Dispose()
+ {
+ this.source = null;
+ this.model = null;
+ BufferPool.ReleaseBufferToPool(ref this.ioBuffer);
+ bool flag = this.stringInterner != null;
+ if (flag)
+ {
+ this.stringInterner.Clear();
+ }
+ bool flag2 = this.netCache != null;
+ if (flag2)
+ {
+ this.netCache.Clear();
+ }
+ }
+
+ internal int TryReadUInt32VariantWithoutMoving(bool trimNegative, out uint value)
+ {
+ bool flag = this.available < 10;
+ if (flag)
+ {
+ this.Ensure(10, false);
+ }
+ bool flag2 = this.available == 0;
+ int result;
+ if (flag2)
+ {
+ value = 0u;
+ result = 0;
+ }
+ else
+ {
+ int num = this.ioIndex;
+ value = (uint)this.ioBuffer[num++];
+ bool flag3 = (value & 128u) == 0u;
+ if (flag3)
+ {
+ result = 1;
+ }
+ else
+ {
+ value &= 127u;
+ bool flag4 = this.available == 1;
+ if (flag4)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ uint num2 = (uint)this.ioBuffer[num++];
+ value |= (num2 & 127u) << 7;
+ bool flag5 = (num2 & 128u) == 0u;
+ if (flag5)
+ {
+ result = 2;
+ }
+ else
+ {
+ bool flag6 = this.available == 2;
+ if (flag6)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (uint)this.ioBuffer[num++];
+ value |= (num2 & 127u) << 14;
+ bool flag7 = (num2 & 128u) == 0u;
+ if (flag7)
+ {
+ result = 3;
+ }
+ else
+ {
+ bool flag8 = this.available == 3;
+ if (flag8)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (uint)this.ioBuffer[num++];
+ value |= (num2 & 127u) << 21;
+ bool flag9 = (num2 & 128u) == 0u;
+ if (flag9)
+ {
+ result = 4;
+ }
+ else
+ {
+ bool flag10 = this.available == 4;
+ if (flag10)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (uint)this.ioBuffer[num];
+ value |= num2 << 28;
+ bool flag11 = (num2 & 240u) == 0u;
+ if (flag11)
+ {
+ result = 5;
+ }
+ else
+ {
+ bool flag12 = trimNegative && (num2 & 240u) == 240u && this.available >= 10 && this.ioBuffer[++num] == byte.MaxValue && this.ioBuffer[++num] == byte.MaxValue && this.ioBuffer[++num] == byte.MaxValue && this.ioBuffer[++num] == byte.MaxValue && this.ioBuffer[num + 1] == 1;
+ if (!flag12)
+ {
+ throw ProtoReader.AddErrorData(new OverflowException(), this);
+ }
+ result = 10;
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private uint ReadUInt32Variant(bool trimNegative)
+ {
+ uint result;
+ int num = this.TryReadUInt32VariantWithoutMoving(trimNegative, out result);
+ bool flag = num > 0;
+ if (flag)
+ {
+ this.ioIndex += num;
+ this.available -= num;
+ this.position += num;
+ return result;
+ }
+ throw ProtoReader.EoF(this);
+ }
+
+ private bool TryReadUInt32Variant(out uint value)
+ {
+ int num = this.TryReadUInt32VariantWithoutMoving(false, out value);
+ bool flag = num > 0;
+ bool result;
+ if (flag)
+ {
+ this.ioIndex += num;
+ this.available -= num;
+ this.position += num;
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ return result;
+ }
+
+ public uint ReadUInt32()
+ {
+ WireType wireType = this.wireType;
+ uint result;
+ if (wireType != WireType.Variant)
+ {
+ if (wireType != WireType.Fixed64)
+ {
+ if (wireType != WireType.Fixed32)
+ {
+ throw this.CreateWireTypeException();
+ }
+ bool flag = this.available < 4;
+ if (flag)
+ {
+ this.Ensure(4, true);
+ }
+ this.position += 4;
+ this.available -= 4;
+ byte[] array = this.ioBuffer;
+ int num = this.ioIndex;
+ this.ioIndex = num + 1;
+ uint num2 = array[num];
+ byte[] array2 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ uint num3 = (uint)(num2 | array2[num] << 8);
+ byte[] array3 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ uint num4 = (uint)(num3 | array3[num] << 16);
+ byte[] array4 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ result = (uint)(num4 | array4[num] << 24);
+ }
+ else
+ {
+ ulong num5 = this.ReadUInt64();
+ result = checked((uint)num5);
+ }
+ }
+ else
+ {
+ result = this.ReadUInt32Variant(false);
+ }
+ return result;
+ }
+
+ internal void Ensure(int count, bool strict)
+ {
+ Helpers.DebugAssert(this.available <= count, "Asking for data without checking first");
+ bool flag = count > this.ioBuffer.Length;
+ if (flag)
+ {
+ BufferPool.ResizeAndFlushLeft(ref this.ioBuffer, count, this.ioIndex, this.available);
+ this.ioIndex = 0;
+ }
+ else
+ {
+ bool flag2 = this.ioIndex + count >= this.ioBuffer.Length;
+ if (flag2)
+ {
+ Helpers.BlockCopy(this.ioBuffer, this.ioIndex, this.ioBuffer, 0, this.available);
+ this.ioIndex = 0;
+ }
+ }
+ count -= this.available;
+ int num = this.ioIndex + this.available;
+ int num2 = this.ioBuffer.Length - num;
+ bool flag3 = this.isFixedLength;
+ if (flag3)
+ {
+ bool flag4 = this.dataRemaining < num2;
+ if (flag4)
+ {
+ num2 = this.dataRemaining;
+ }
+ }
+ int num3;
+ while (count > 0 && num2 > 0 && (num3 = this.source.Read(this.ioBuffer, num, num2)) > 0)
+ {
+ this.available += num3;
+ count -= num3;
+ num2 -= num3;
+ num += num3;
+ bool flag5 = this.isFixedLength;
+ if (flag5)
+ {
+ this.dataRemaining -= num3;
+ }
+ }
+ bool flag6 = strict && count > 0;
+ if (flag6)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ }
+
+ public short ReadInt16()
+ {
+ return checked((short)this.ReadInt32());
+ }
+
+ public ushort ReadUInt16()
+ {
+ return checked((ushort)this.ReadUInt32());
+ }
+
+ public byte ReadByte()
+ {
+ return checked((byte)this.ReadUInt32());
+ }
+
+ public sbyte ReadSByte()
+ {
+ return checked((sbyte)this.ReadInt32());
+ }
+
+ public int ReadInt32()
+ {
+ WireType wireType = this.wireType;
+ if (wireType <= WireType.Fixed64)
+ {
+ if (wireType == WireType.Variant)
+ {
+ return (int)this.ReadUInt32Variant(true);
+ }
+ if (wireType == WireType.Fixed64)
+ {
+ long num = this.ReadInt64();
+ return checked((int)num);
+ }
+ }
+ else
+ {
+ if (wireType == WireType.Fixed32)
+ {
+ bool flag = this.available < 4;
+ if (flag)
+ {
+ this.Ensure(4, true);
+ }
+ this.position += 4;
+ this.available -= 4;
+ byte[] array = this.ioBuffer;
+ int num2 = this.ioIndex;
+ this.ioIndex = num2 + 1;
+ int num3 = array[num2];
+ byte[] array2 = this.ioBuffer;
+ num2 = this.ioIndex;
+ this.ioIndex = num2 + 1;
+ int num4 = num3 | array2[num2] << 8;
+ byte[] array3 = this.ioBuffer;
+ num2 = this.ioIndex;
+ this.ioIndex = num2 + 1;
+ int num5 = num4 | array3[num2] << 16;
+ byte[] array4 = this.ioBuffer;
+ num2 = this.ioIndex;
+ this.ioIndex = num2 + 1;
+ return num5 | array4[num2] << 24;
+ }
+ if (wireType == WireType.SignedVariant)
+ {
+ return ProtoReader.Zag(this.ReadUInt32Variant(true));
+ }
+ }
+ throw this.CreateWireTypeException();
+ }
+
+ private static int Zag(uint ziggedValue)
+ {
+ return (int)(-(ziggedValue & 1u) ^ (uint)((int)ziggedValue >> 1 & int.MaxValue));
+ }
+
+ private static long Zag(ulong ziggedValue)
+ {
+ //!
+ //return (long)(-(long)(ziggedValue & 1UL) ^ (ziggedValue >> 1 & 9223372036854775807UL));
+ long rightPart = (long)( ziggedValue >> 1 & long.MaxValue );
+ long leftPart = -(long)(ziggedValue & 1UL);
+ return leftPart ^ rightPart;
+ }
+
+ public long ReadInt64()
+ {
+ WireType wireType = this.wireType;
+ if (wireType <= WireType.Fixed64)
+ {
+ if (wireType == WireType.Variant)
+ {
+ return (long)this.ReadUInt64Variant();
+ }
+ if (wireType == WireType.Fixed64)
+ {
+ bool flag = this.available < 8;
+ if (flag)
+ {
+ this.Ensure(8, true);
+ }
+ this.position += 8;
+ this.available -= 8;
+ byte[] array = this.ioBuffer;
+ int num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num2 = (long)array[num];
+ byte[] array2 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num3 = num2 | (long)((long)array2[num] << 8);
+ byte[] array3 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num4 = num3 | (long)((long)array3[num] << 16);
+ byte[] array4 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num5 = num4 | (long)((long)array4[num] << 24);
+ byte[] array5 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num6 = num5 | (long)((long)array5[num] << 32);
+ byte[] array6 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num7 = num6 | (long)((long)array6[num] << 40);
+ byte[] array7 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ long num8 = num7 | (long)((long)array7[num] << 48);
+ byte[] array8 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ return num8 | (long)((long)array8[num] << 56);
+ }
+ }
+ else
+ {
+ if (wireType == WireType.Fixed32)
+ {
+ return (long)this.ReadInt32();
+ }
+ if (wireType == WireType.SignedVariant)
+ {
+ return ProtoReader.Zag(this.ReadUInt64Variant());
+ }
+ }
+ throw this.CreateWireTypeException();
+ }
+
+ private int TryReadUInt64VariantWithoutMoving(out ulong value)
+ {
+ bool flag = this.available < 10;
+ if (flag)
+ {
+ this.Ensure(10, false);
+ }
+ bool flag2 = this.available == 0;
+ int result;
+ if (flag2)
+ {
+ value = 0UL;
+ result = 0;
+ }
+ else
+ {
+ int num = this.ioIndex;
+ value = (ulong)this.ioBuffer[num++];
+ bool flag3 = (value & 128UL) == 0UL;
+ if (flag3)
+ {
+ result = 1;
+ }
+ else
+ {
+ value &= 127UL;
+ bool flag4 = this.available == 1;
+ if (flag4)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ ulong num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 7;
+ bool flag5 = (num2 & 128UL) == 0UL;
+ if (flag5)
+ {
+ result = 2;
+ }
+ else
+ {
+ bool flag6 = this.available == 2;
+ if (flag6)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 14;
+ bool flag7 = (num2 & 128UL) == 0UL;
+ if (flag7)
+ {
+ result = 3;
+ }
+ else
+ {
+ bool flag8 = this.available == 3;
+ if (flag8)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 21;
+ bool flag9 = (num2 & 128UL) == 0UL;
+ if (flag9)
+ {
+ result = 4;
+ }
+ else
+ {
+ bool flag10 = this.available == 4;
+ if (flag10)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 28;
+ bool flag11 = (num2 & 128UL) == 0UL;
+ if (flag11)
+ {
+ result = 5;
+ }
+ else
+ {
+ bool flag12 = this.available == 5;
+ if (flag12)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 35;
+ bool flag13 = (num2 & 128UL) == 0UL;
+ if (flag13)
+ {
+ result = 6;
+ }
+ else
+ {
+ bool flag14 = this.available == 6;
+ if (flag14)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 42;
+ bool flag15 = (num2 & 128UL) == 0UL;
+ if (flag15)
+ {
+ result = 7;
+ }
+ else
+ {
+ bool flag16 = this.available == 7;
+ if (flag16)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 49;
+ bool flag17 = (num2 & 128UL) == 0UL;
+ if (flag17)
+ {
+ result = 8;
+ }
+ else
+ {
+ bool flag18 = this.available == 8;
+ if (flag18)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num++];
+ value |= (num2 & 127UL) << 56;
+ bool flag19 = (num2 & 128UL) == 0UL;
+ if (flag19)
+ {
+ result = 9;
+ }
+ else
+ {
+ bool flag20 = this.available == 9;
+ if (flag20)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ num2 = (ulong)this.ioBuffer[num];
+ value |= num2 << 63;
+ bool flag21 = (num2 & 18446744073709551614UL) > 0UL;
+ if (flag21)
+ {
+ throw ProtoReader.AddErrorData(new OverflowException(), this);
+ }
+ result = 10;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private ulong ReadUInt64Variant()
+ {
+ ulong result;
+ int num = this.TryReadUInt64VariantWithoutMoving(out result);
+ bool flag = num > 0;
+ if (flag)
+ {
+ this.ioIndex += num;
+ this.available -= num;
+ this.position += num;
+ return result;
+ }
+ throw ProtoReader.EoF(this);
+ }
+
+ private string Intern(string value)
+ {
+ bool flag = value == null;
+ string result;
+ if (flag)
+ {
+ result = null;
+ }
+ else
+ {
+ bool flag2 = value.Length == 0;
+ if (flag2)
+ {
+ result = "";
+ }
+ else
+ {
+ bool flag3 = this.stringInterner == null;
+ if (flag3)
+ {
+ this.stringInterner = new Dictionary<string, string>();
+ this.stringInterner.Add(value, value);
+ }
+ else
+ {
+ string text;
+ bool flag4 = this.stringInterner.TryGetValue(value, out text);
+ if (flag4)
+ {
+ value = text;
+ }
+ else
+ {
+ this.stringInterner.Add(value, value);
+ }
+ }
+ result = value;
+ }
+ }
+ return result;
+ }
+
+ public string ReadString()
+ {
+ bool flag = this.wireType == WireType.String;
+ if (flag)
+ {
+ int num = (int)this.ReadUInt32Variant(false);
+ bool flag2 = num == 0;
+ string result;
+ if (flag2)
+ {
+ result = "";
+ }
+ else
+ {
+ bool flag3 = this.available < num;
+ if (flag3)
+ {
+ this.Ensure(num, true);
+ }
+ string text = ProtoReader.encoding.GetString(this.ioBuffer, this.ioIndex, num);
+ bool flag4 = this.internStrings;
+ if (flag4)
+ {
+ text = this.Intern(text);
+ }
+ this.available -= num;
+ this.position += num;
+ this.ioIndex += num;
+ result = text;
+ }
+ return result;
+ }
+ throw this.CreateWireTypeException();
+ }
+
+ public void ThrowEnumException(Type type, int value)
+ {
+ string str = (type == null) ? "<null>" : type.FullName;
+ throw ProtoReader.AddErrorData(new ProtoException("No " + str + " enum is mapped to the wire-value " + value.ToString()), this);
+ }
+
+ private Exception CreateWireTypeException()
+ {
+ return this.CreateException("Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see http://stackoverflow.com/q/2152978/23354");
+ }
+
+ private Exception CreateException(string message)
+ {
+ return ProtoReader.AddErrorData(new ProtoException(message), this);
+ }
+
+ public unsafe double ReadDouble()
+ {
+ WireType wireType = this.wireType;
+ double result;
+ if (wireType != WireType.Fixed64)
+ {
+ if (wireType != WireType.Fixed32)
+ {
+ throw this.CreateWireTypeException();
+ }
+ result = (double)this.ReadSingle();
+ }
+ else
+ {
+ long num = this.ReadInt64();
+ result = *(double*)(&num);
+ }
+ return result;
+ }
+
+ public static object ReadObject(object value, int key, ProtoReader reader)
+ {
+ return ProtoReader.ReadTypedObject(value, key, reader, null);
+ }
+
+ internal static object ReadTypedObject(object value, int key, ProtoReader reader, Type type)
+ {
+ bool flag = reader.model == null;
+ if (flag)
+ {
+ throw ProtoReader.AddErrorData(new InvalidOperationException("Cannot deserialize sub-objects unless a model is provided"), reader);
+ }
+ SubItemToken token = ProtoReader.StartSubItem(reader);
+ bool flag2 = key >= 0;
+ if (flag2)
+ {
+ value = reader.model.Deserialize(key, value, reader);
+ }
+ else
+ {
+ bool flag3 = type != null && reader.model.TryDeserializeAuxiliaryType(reader, DataFormat.Default, 1, type, ref value, true, false, true, false);
+ if (!flag3)
+ {
+ TypeModel.ThrowUnexpectedType(type);
+ }
+ }
+ ProtoReader.EndSubItem(token, reader);
+ return value;
+ }
+
+ public static void EndSubItem(SubItemToken token, ProtoReader reader)
+ {
+ bool flag = reader == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("reader");
+ }
+ int value = token.value;
+ WireType wireType = reader.wireType;
+ if (wireType != WireType.EndGroup)
+ {
+ bool flag2 = value < reader.position;
+ if (flag2)
+ {
+ throw reader.CreateException("Sub-message not read entirely");
+ }
+ bool flag3 = reader.blockEnd != reader.position && reader.blockEnd != int.MaxValue;
+ if (flag3)
+ {
+ throw reader.CreateException("Sub-message not read correctly");
+ }
+ reader.blockEnd = value;
+ reader.depth--;
+ }
+ else
+ {
+ bool flag4 = value >= 0;
+ if (flag4)
+ {
+ throw ProtoReader.AddErrorData(new ArgumentException("token"), reader);
+ }
+ bool flag5 = -value != reader.fieldNumber;
+ if (flag5)
+ {
+ throw reader.CreateException("Wrong group was ended");
+ }
+ reader.wireType = WireType.None;
+ reader.depth--;
+ }
+ }
+
+ public static SubItemToken StartSubItem(ProtoReader reader)
+ {
+ bool flag = reader == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("reader");
+ }
+ WireType wireType = reader.wireType;
+ SubItemToken result;
+ if (wireType != WireType.String)
+ {
+ if (wireType != WireType.StartGroup)
+ {
+ throw reader.CreateWireTypeException();
+ }
+ reader.wireType = WireType.None;
+ reader.depth++;
+ result = new SubItemToken(-reader.fieldNumber);
+ }
+ else
+ {
+ int num = (int)reader.ReadUInt32Variant(false);
+ bool flag2 = num < 0;
+ if (flag2)
+ {
+ throw ProtoReader.AddErrorData(new InvalidOperationException(), reader);
+ }
+ int value = reader.blockEnd;
+ reader.blockEnd = reader.position + num;
+ reader.depth++;
+ result = new SubItemToken(value);
+ }
+ return result;
+ }
+
+ public int ReadFieldHeader()
+ {
+ bool flag = this.blockEnd <= this.position || this.wireType == WireType.EndGroup;
+ int result;
+ if (flag)
+ {
+ result = 0;
+ }
+ else
+ {
+ uint num;
+ bool flag2 = this.TryReadUInt32Variant(out num);
+ if (flag2)
+ {
+ this.wireType = (WireType)(num & 7u);
+ this.fieldNumber = (int)(num >> 3);
+ bool flag3 = this.fieldNumber < 1;
+ if (flag3)
+ {
+ throw new ProtoException("Invalid field in source data: " + this.fieldNumber.ToString());
+ }
+ }
+ else
+ {
+ this.wireType = WireType.None;
+ this.fieldNumber = 0;
+ }
+ bool flag4 = this.wireType == WireType.EndGroup;
+ if (flag4)
+ {
+ bool flag5 = this.depth > 0;
+ if (!flag5)
+ {
+ throw new ProtoException("Unexpected end-group in source data; this usually means the source data is corrupt");
+ }
+ result = 0;
+ }
+ else
+ {
+ result = this.fieldNumber;
+ }
+ }
+ return result;
+ }
+
+ public bool TryReadFieldHeader(int field)
+ {
+ bool flag = this.blockEnd <= this.position || this.wireType == WireType.EndGroup;
+ bool result;
+ if (flag)
+ {
+ result = false;
+ }
+ else
+ {
+ uint num2;
+ int num = this.TryReadUInt32VariantWithoutMoving(false, out num2);
+ WireType wireType = WireType.None;
+ bool flag2 = num > 0 && (int)num2 >> 3 == field && (wireType = (WireType)(num2 & 7u)) != WireType.EndGroup;
+ if (flag2)
+ {
+ this.wireType = wireType;
+ this.fieldNumber = field;
+ this.position += num;
+ this.ioIndex += num;
+ this.available -= num;
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ public void Hint(WireType wireType)
+ {
+ bool flag = this.wireType == wireType;
+ if (!flag)
+ {
+ bool flag2 = (wireType & (WireType)7) == this.wireType;
+ if (flag2)
+ {
+ this.wireType = wireType;
+ }
+ }
+ }
+
+ public void Assert(WireType wireType)
+ {
+ bool flag = this.wireType == wireType;
+ if (!flag)
+ {
+ bool flag2 = (wireType & (WireType)7) == this.wireType;
+ if (!flag2)
+ {
+ throw this.CreateWireTypeException();
+ }
+ this.wireType = wireType;
+ }
+ }
+
+ public void SkipField()
+ {
+ switch (this.wireType)
+ {
+ case WireType.Variant:
+ case WireType.SignedVariant:
+ this.ReadUInt64Variant();
+ return;
+ case WireType.Fixed64:
+ {
+ bool flag = this.available < 8;
+ if (flag)
+ {
+ this.Ensure(8, true);
+ }
+ this.available -= 8;
+ this.ioIndex += 8;
+ this.position += 8;
+ return;
+ }
+ case WireType.String:
+ {
+ int num = (int)this.ReadUInt32Variant(false);
+ bool flag2 = num <= this.available;
+ if (flag2)
+ {
+ this.available -= num;
+ this.ioIndex += num;
+ this.position += num;
+ return;
+ }
+ this.position += num;
+ num -= this.available;
+ this.ioIndex = (this.available = 0);
+ bool flag3 = this.isFixedLength;
+ if (flag3)
+ {
+ bool flag4 = num > this.dataRemaining;
+ if (flag4)
+ {
+ throw ProtoReader.EoF(this);
+ }
+ this.dataRemaining -= num;
+ }
+ ProtoReader.Seek(this.source, num, this.ioBuffer);
+ return;
+ }
+ case WireType.StartGroup:
+ {
+ int num2 = this.fieldNumber;
+ this.depth++;
+ while (this.ReadFieldHeader() > 0)
+ {
+ this.SkipField();
+ }
+ this.depth--;
+ bool flag5 = this.wireType == WireType.EndGroup && this.fieldNumber == num2;
+ if (flag5)
+ {
+ this.wireType = WireType.None;
+ return;
+ }
+ throw this.CreateWireTypeException();
+ }
+ case WireType.Fixed32:
+ {
+ bool flag6 = this.available < 4;
+ if (flag6)
+ {
+ this.Ensure(4, true);
+ }
+ this.available -= 4;
+ this.ioIndex += 4;
+ this.position += 4;
+ return;
+ }
+ }
+ throw this.CreateWireTypeException();
+ }
+
+ public ulong ReadUInt64()
+ {
+ WireType wireType = this.wireType;
+ ulong result;
+ if (wireType != WireType.Variant)
+ {
+ if (wireType != WireType.Fixed64)
+ {
+ if (wireType != WireType.Fixed32)
+ {
+ throw this.CreateWireTypeException();
+ }
+ result = (ulong)this.ReadUInt32();
+ }
+ else
+ {
+ bool flag = this.available < 8;
+ if (flag)
+ {
+ this.Ensure(8, true);
+ }
+ this.position += 8;
+ this.available -= 8;
+ byte[] array = this.ioBuffer;
+ int num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num2 = array[num];
+ byte[] array2 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num3 = num2 | (ulong) ( array2[num] << 8);
+ byte[] array3 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num4 = num3 | (ulong) (array3[num] << 16);
+ byte[] array4 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num5 = num4 | (ulong) ( array4[num] << 24);
+ byte[] array5 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num6 = num5 | (ulong)(array5[num] << 32);
+ byte[] array6 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num7 = num6 | (ulong)( array6[num] << 40);
+ byte[] array7 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ ulong num8 = num7 | (ulong)(array7[num] << 48);
+ byte[] array8 = this.ioBuffer;
+ num = this.ioIndex;
+ this.ioIndex = num + 1;
+ result = (num8 | (ulong) ( array8[num] << 56));
+ }
+ }
+ else
+ {
+ result = this.ReadUInt64Variant();
+ }
+ return result;
+ }
+
+ public unsafe float ReadSingle()
+ {
+ WireType wireType = this.wireType;
+ float result;
+ if (wireType != WireType.Fixed64)
+ {
+ if (wireType != WireType.Fixed32)
+ {
+ throw this.CreateWireTypeException();
+ }
+ int num = this.ReadInt32();
+ result = *(float*)(&num);
+ }
+ else
+ {
+ double num2 = this.ReadDouble();
+ float num3 = (float)num2;
+ bool flag = Helpers.IsInfinity(num3) && !Helpers.IsInfinity(num2);
+ if (flag)
+ {
+ throw ProtoReader.AddErrorData(new OverflowException(), this);
+ }
+ result = num3;
+ }
+ return result;
+ }
+
+ public bool ReadBoolean()
+ {
+ uint num = this.ReadUInt32();
+ bool result;
+ if (num != 0u)
+ {
+ if (num != 1u)
+ {
+ throw this.CreateException("Unexpected boolean value");
+ }
+ result = true;
+ }
+ else
+ {
+ result = false;
+ }
+ return result;
+ }
+
+ public static byte[] AppendBytes(byte[] value, ProtoReader reader)
+ {
+ bool flag = reader == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("reader");
+ }
+ WireType wireType = reader.wireType;
+ if (wireType != WireType.String)
+ {
+ throw reader.CreateWireTypeException();
+ }
+ int i = (int)reader.ReadUInt32Variant(false);
+ reader.wireType = WireType.None;
+ bool flag2 = i == 0;
+ byte[] result;
+ if (flag2)
+ {
+ result = ((value == null) ? ProtoReader.EmptyBlob : value);
+ }
+ else
+ {
+ bool flag3 = value == null || value.Length == 0;
+ int num;
+ if (flag3)
+ {
+ num = 0;
+ value = new byte[i];
+ }
+ else
+ {
+ num = value.Length;
+ byte[] array = new byte[value.Length + i];
+ Helpers.BlockCopy(value, 0, array, 0, value.Length);
+ value = array;
+ }
+ reader.position += i;
+ while (i > reader.available)
+ {
+ bool flag4 = reader.available > 0;
+ if (flag4)
+ {
+ Helpers.BlockCopy(reader.ioBuffer, reader.ioIndex, value, num, reader.available);
+ i -= reader.available;
+ num += reader.available;
+ reader.ioIndex = (reader.available = 0);
+ }
+ int num2 = (i > reader.ioBuffer.Length) ? reader.ioBuffer.Length : i;
+ bool flag5 = num2 > 0;
+ if (flag5)
+ {
+ reader.Ensure(num2, true);
+ }
+ }
+ bool flag6 = i > 0;
+ if (flag6)
+ {
+ Helpers.BlockCopy(reader.ioBuffer, reader.ioIndex, value, num, i);
+ reader.ioIndex += i;
+ reader.available -= i;
+ }
+ result = value;
+ }
+ return result;
+ }
+
+ private static int ReadByteOrThrow(Stream source)
+ {
+ int num = source.ReadByte();
+ bool flag = num < 0;
+ if (flag)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ return num;
+ }
+
+ public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber)
+ {
+ int num;
+ return ProtoReader.ReadLengthPrefix(source, expectHeader, style, out fieldNumber, out num);
+ }
+
+ public static int DirectReadLittleEndianInt32(Stream source)
+ {
+ return ProtoReader.ReadByteOrThrow(source) | ProtoReader.ReadByteOrThrow(source) << 8 | ProtoReader.ReadByteOrThrow(source) << 16 | ProtoReader.ReadByteOrThrow(source) << 24;
+ }
+
+ public static int DirectReadBigEndianInt32(Stream source)
+ {
+ return ProtoReader.ReadByteOrThrow(source) << 24 | ProtoReader.ReadByteOrThrow(source) << 16 | ProtoReader.ReadByteOrThrow(source) << 8 | ProtoReader.ReadByteOrThrow(source);
+ }
+
+ public static int DirectReadVarintInt32(Stream source)
+ {
+ uint result;
+ int num = ProtoReader.TryReadUInt32Variant(source, out result);
+ bool flag = num <= 0;
+ if (flag)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ return (int)result;
+ }
+
+ public static void DirectReadBytes(Stream source, byte[] buffer, int offset, int count)
+ {
+ bool flag = source == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("source");
+ }
+ int num;
+ while (count > 0 && (num = source.Read(buffer, offset, count)) > 0)
+ {
+ count -= num;
+ offset += num;
+ }
+ bool flag2 = count > 0;
+ if (flag2)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ }
+
+ public static byte[] DirectReadBytes(Stream source, int count)
+ {
+ byte[] array = new byte[count];
+ ProtoReader.DirectReadBytes(source, array, 0, count);
+ return array;
+ }
+
+ public static string DirectReadString(Stream source, int length)
+ {
+ byte[] array = new byte[length];
+ ProtoReader.DirectReadBytes(source, array, 0, length);
+ return Encoding.UTF8.GetString(array, 0, length);
+ }
+
+ public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber, out int bytesRead)
+ {
+ fieldNumber = 0;
+ int result;
+ switch (style)
+ {
+ case PrefixStyle.None:
+ bytesRead = 0;
+ result = int.MaxValue;
+ break;
+ case PrefixStyle.Base128:
+ bytesRead = 0;
+ if (expectHeader)
+ {
+ uint num2;
+ int num = ProtoReader.TryReadUInt32Variant(source, out num2);
+ bytesRead += num;
+ bool flag = num > 0;
+ if (flag)
+ {
+ bool flag2 = (num2 & 7u) != 2u;
+ if (flag2)
+ {
+ throw new InvalidOperationException();
+ }
+ fieldNumber = (int)(num2 >> 3);
+ num = ProtoReader.TryReadUInt32Variant(source, out num2);
+ bytesRead += num;
+ bool flag3 = bytesRead == 0;
+ if (flag3)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ result = (int)num2;
+ }
+ else
+ {
+ bytesRead = 0;
+ result = -1;
+ }
+ }
+ else
+ {
+ uint num2;
+ int num = ProtoReader.TryReadUInt32Variant(source, out num2);
+ bytesRead += num;
+ result = (int)((bytesRead < 0) ? uint.MaxValue : num2);
+ }
+ break;
+ case PrefixStyle.Fixed32:
+ {
+ int num3 = source.ReadByte();
+ bool flag4 = num3 < 0;
+ if (flag4)
+ {
+ bytesRead = 0;
+ result = -1;
+ }
+ else
+ {
+ bytesRead = 4;
+ result = (num3 | ProtoReader.ReadByteOrThrow(source) << 8 | ProtoReader.ReadByteOrThrow(source) << 16 | ProtoReader.ReadByteOrThrow(source) << 24);
+ }
+ break;
+ }
+ case PrefixStyle.Fixed32BigEndian:
+ {
+ int num4 = source.ReadByte();
+ bool flag5 = num4 < 0;
+ if (flag5)
+ {
+ bytesRead = 0;
+ result = -1;
+ }
+ else
+ {
+ bytesRead = 4;
+ result = (num4 << 24 | ProtoReader.ReadByteOrThrow(source) << 16 | ProtoReader.ReadByteOrThrow(source) << 8 | ProtoReader.ReadByteOrThrow(source));
+ }
+ break;
+ }
+ default:
+ throw new ArgumentOutOfRangeException("style");
+ }
+ return result;
+ }
+
+ private static int TryReadUInt32Variant(Stream source, out uint value)
+ {
+ value = 0u;
+ int num = source.ReadByte();
+ bool flag = num < 0;
+ int result;
+ if (flag)
+ {
+ result = 0;
+ }
+ else
+ {
+ value = (uint)num;
+ bool flag2 = (value & 128u) == 0u;
+ if (flag2)
+ {
+ result = 1;
+ }
+ else
+ {
+ value &= 127u;
+ num = source.ReadByte();
+ bool flag3 = num < 0;
+ if (flag3)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ value |= (uint)((uint)(num & 127) << 7);
+ bool flag4 = (num & 128) == 0;
+ if (flag4)
+ {
+ result = 2;
+ }
+ else
+ {
+ num = source.ReadByte();
+ bool flag5 = num < 0;
+ if (flag5)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ value |= (uint)((uint)(num & 127) << 14);
+ bool flag6 = (num & 128) == 0;
+ if (flag6)
+ {
+ result = 3;
+ }
+ else
+ {
+ num = source.ReadByte();
+ bool flag7 = num < 0;
+ if (flag7)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ value |= (uint)((uint)(num & 127) << 21);
+ bool flag8 = (num & 128) == 0;
+ if (flag8)
+ {
+ result = 4;
+ }
+ else
+ {
+ num = source.ReadByte();
+ bool flag9 = num < 0;
+ if (flag9)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ value |= (uint)((uint)num << 28);
+ bool flag10 = (num & 240) == 0;
+ if (!flag10)
+ {
+ throw new OverflowException();
+ }
+ result = 5;
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ internal static void Seek(Stream source, int count, byte[] buffer)
+ {
+ bool canSeek = source.CanSeek;
+ if (canSeek)
+ {
+ source.Seek((long)count, SeekOrigin.Current);
+ count = 0;
+ }
+ else
+ {
+ bool flag = buffer != null;
+ if (flag)
+ {
+ int num;
+ while (count > buffer.Length && (num = source.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ count -= num;
+ }
+ while (count > 0 && (num = source.Read(buffer, 0, count)) > 0)
+ {
+ count -= num;
+ }
+ }
+ else
+ {
+ buffer = BufferPool.GetBuffer();
+ try
+ {
+ int num2;
+ while (count > buffer.Length && (num2 = source.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ count -= num2;
+ }
+ while (count > 0 && (num2 = source.Read(buffer, 0, count)) > 0)
+ {
+ count -= num2;
+ }
+ }
+ finally
+ {
+ BufferPool.ReleaseBufferToPool(ref buffer);
+ }
+ }
+ }
+ bool flag2 = count > 0;
+ if (flag2)
+ {
+ throw ProtoReader.EoF(null);
+ }
+ }
+
+ internal static Exception AddErrorData(Exception exception, ProtoReader source)
+ {
+ bool flag = exception != null && source != null && !exception.Data.Contains("protoSource");
+ if (flag)
+ {
+ exception.Data.Add("protoSource", string.Format("tag={0}; wire-type={1}; offset={2}; depth={3}", new object[]
+ {
+ source.fieldNumber,
+ source.wireType,
+ source.position,
+ source.depth
+ }));
+ }
+ return exception;
+ }
+
+ private static Exception EoF(ProtoReader source)
+ {
+ return ProtoReader.AddErrorData(new EndOfStreamException(), source);
+ }
+
+ public void AppendExtensionData(IExtensible instance)
+ {
+ bool flag = instance == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("instance");
+ }
+ IExtension extensionObject = instance.GetExtensionObject(true);
+ bool commit = false;
+ Stream stream = extensionObject.BeginAppend();
+ try
+ {
+ using (ProtoWriter protoWriter = new ProtoWriter(stream, this.model, null))
+ {
+ this.AppendExtensionField(protoWriter);
+ protoWriter.Close();
+ }
+ commit = true;
+ }
+ finally
+ {
+ extensionObject.EndAppend(stream, commit);
+ }
+ }
+
+ private void AppendExtensionField(ProtoWriter writer)
+ {
+ ProtoWriter.WriteFieldHeader(this.fieldNumber, this.wireType, writer);
+ switch (this.wireType)
+ {
+ case WireType.Variant:
+ case WireType.Fixed64:
+ case WireType.SignedVariant:
+ ProtoWriter.WriteInt64(this.ReadInt64(), writer);
+ return;
+ case WireType.String:
+ ProtoWriter.WriteBytes(ProtoReader.AppendBytes(null, this), writer);
+ return;
+ case WireType.StartGroup:
+ {
+ SubItemToken token = ProtoReader.StartSubItem(this);
+ SubItemToken token2 = ProtoWriter.StartSubItem(null, writer);
+ while (this.ReadFieldHeader() > 0)
+ {
+ this.AppendExtensionField(writer);
+ }
+ ProtoReader.EndSubItem(token, this);
+ ProtoWriter.EndSubItem(token2, writer);
+ return;
+ }
+ case WireType.Fixed32:
+ ProtoWriter.WriteInt32(this.ReadInt32(), writer);
+ return;
+ }
+ throw this.CreateWireTypeException();
+ }
+
+ public static bool HasSubValue(WireType wireType, ProtoReader source)
+ {
+ bool flag = source == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("source");
+ }
+ bool flag2 = source.blockEnd <= source.position || wireType == WireType.EndGroup;
+ bool result;
+ if (flag2)
+ {
+ result = false;
+ }
+ else
+ {
+ source.wireType = wireType;
+ result = true;
+ }
+ return result;
+ }
+
+ internal int GetTypeKey(ref Type type)
+ {
+ return this.model.GetKey(ref type);
+ }
+
+ internal Type DeserializeType(string value)
+ {
+ return TypeModel.DeserializeType(this.model, value);
+ }
+
+ internal void SetRootObject(object value)
+ {
+ this.netCache.SetKeyedObject(0, value);
+ this.trapCount -= 1u;
+ }
+
+ public static void NoteObject(object value, ProtoReader reader)
+ {
+ bool flag = reader == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("reader");
+ }
+ bool flag2 = reader.trapCount > 0u;
+ if (flag2)
+ {
+ reader.netCache.RegisterTrappedObject(value);
+ reader.trapCount -= 1u;
+ }
+ }
+
+ public Type ReadType()
+ {
+ return TypeModel.DeserializeType(this.model, this.ReadString());
+ }
+
+ internal void TrapNextObject(int newObjectKey)
+ {
+ this.trapCount += 1u;
+ this.netCache.SetKeyedObject(newObjectKey, null);
+ }
+
+ internal void CheckFullyConsumed()
+ {
+ bool flag = this.isFixedLength;
+ if (flag)
+ {
+ bool flag2 = this.dataRemaining != 0;
+ if (flag2)
+ {
+ throw new ProtoException("Incorrect number of bytes consumed");
+ }
+ }
+ else
+ {
+ bool flag3 = this.available != 0;
+ if (flag3)
+ {
+ throw new ProtoException("Unconsumed data left in the buffer; this suggests corrupt input");
+ }
+ }
+ }
+
+ public static object Merge(ProtoReader parent, object from, object to)
+ {
+ bool flag = parent == null;
+ if (flag)
+ {
+ throw new ArgumentNullException("parent");
+ }
+ TypeModel typeModel = parent.Model;
+ SerializationContext serializationContext = parent.Context;
+ bool flag2 = typeModel == null;
+ if (flag2)
+ {
+ throw new InvalidOperationException("Types cannot be merged unless a type-model has been specified");
+ }
+ object result;
+ using (MemoryStream memoryStream = new MemoryStream())
+ {
+ typeModel.Serialize(memoryStream, from, serializationContext);
+ memoryStream.Position = 0L;
+ result = typeModel.Deserialize(memoryStream, to, null);
+ }
+ return result;
+ }
+
+ internal static ProtoReader Create(Stream source, TypeModel model, SerializationContext context, int len)
+ {
+ ProtoReader recycled = ProtoReader.GetRecycled();
+ bool flag = recycled == null;
+ ProtoReader result;
+ if (flag)
+ {
+ result = new ProtoReader(source, model, context, len);
+ }
+ else
+ {
+ ProtoReader.Init(recycled, source, model, context, len);
+ result = recycled;
+ }
+ return result;
+ }
+
+ private static ProtoReader GetRecycled()
+ {
+ ProtoReader result = ProtoReader.lastReader;
+ ProtoReader.lastReader = null;
+ return result;
+ }
+
+ internal static void Recycle(ProtoReader reader)
+ {
+ bool flag = reader != null;
+ if (flag)
+ {
+ reader.Dispose();
+ ProtoReader.lastReader = reader;
+ }
+ }
+ }
+}