From 6eb915c129fc90c6f4c82ae097dd6ffad5239efc Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 25 Jan 2021 14:28:30 +0800 Subject: +scripts --- .../Scripts/XMainClient/ProtoBuf/ProtoReader.cs | 1838 ++++++++++++++++++++ 1 file changed, 1838 insertions(+) create mode 100644 Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs (limited to 'Client/Assets/Scripts/XMainClient/ProtoBuf/ProtoReader.cs') 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 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(); + 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) ? "" : 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; + } + } + } +} -- cgit v1.1-26-g67d0