Decompiled source of TestFilter protobuf net Core dll 7F09BF13 v0.0.0
protobuf-net.Core.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Buffers.Binary; using System.Buffers.Text; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Microsoft.CodeAnalysis; using ProtoBuf.Internal; using ProtoBuf.Meta; using ProtoBuf.Serializers; using ProtoBuf.WellKnownTypes; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("3.2.30.709")] [assembly: AssemblyInformationalVersion("3.2.30+02c5dfe7c9")] [assembly: InternalsVisibleTo("protobuf-net.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("protobuf-net, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("Benchmark, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("protobuf-net.MessagePipes, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: InternalsVisibleTo("protobuf-net.ServiceModel, PublicKey=002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Marc Gravell")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("See https://github.com/protobuf-net/protobuf-net")] [assembly: AssemblyDescription("Provides simple access to fast and efficient \"Protocol Buffers\" serialization from .NET applications")] [assembly: AssemblyProduct("protobuf-net (net462)")] [assembly: AssemblyTitle("protobuf-net.Core")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/protobuf-net/protobuf-net")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } } [GeneratedCode("Nerdbank.GitVersioning.Tasks", "3.5.119.9565")] [ExcludeFromCodeCoverage] internal static class ThisAssembly { internal const string AssemblyConfiguration = "Release"; internal const string AssemblyFileVersion = "3.2.30.709"; internal const string AssemblyInformationalVersion = "3.2.30+02c5dfe7c9"; internal const string AssemblyName = "protobuf-net.Core"; internal const string AssemblyTitle = "protobuf-net.Core"; internal const string AssemblyVersion = "3.0.0.0"; internal static readonly DateTime GitCommitDate = new DateTime(638314372430000000L, DateTimeKind.Utc); internal const string GitCommitId = "02c5dfe7c99ac8550830662ce2b9bc6e1301a493"; internal const bool IsPrerelease = false; internal const bool IsPublicRelease = true; internal const string PublicKey = "002400000480000094000000060200000024000052534131000400000100010009ed9caa457bfc205716c3d4e8b255a63ddf71c9e53b1b5f574ab6ffdba11e80ab4b50be9c46d43b75206280070ddba67bd4c830f93f0317504a76ba6a48243c36d2590695991164592767a7bbc4453b34694e31e20815a096e4483605139a32a76ec2fef196507487329c12047bf6a68bca8ee9354155f4d01daf6eec5ff6bc"; internal const string PublicKeyToken = "257b51d87d2e4d67"; internal const string RootNamespace = "ProtoBuf"; } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)] internal sealed class DynamicallyAccessedMembersAttribute : Attribute { public DynamicallyAccessedMemberTypes MemberTypes { get; } public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes) { MemberTypes = memberTypes; } } [Flags] internal enum DynamicallyAccessedMemberTypes { None = 0, PublicParameterlessConstructor = 1, PublicConstructors = 3, NonPublicConstructors = 4, PublicMethods = 8, NonPublicMethods = 0x10, PublicFields = 0x20, NonPublicFields = 0x40, PublicNestedTypes = 0x80, NonPublicNestedTypes = 0x100, PublicProperties = 0x200, NonPublicProperties = 0x400, PublicEvents = 0x800, NonPublicEvents = 0x1000, All = -1 } } namespace ProtoBuf { internal enum TimeSpanScale { Days = 0, Hours = 1, Minutes = 2, Seconds = 3, Milliseconds = 4, Ticks = 5, MinMax = 15 } public static class BclHelpers { internal static readonly DateTime[] EpochOrigin = new DateTime[3] { new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local) }; private const int MAX_DECIMAL_BYTES = 32; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static object GetUninitializedObject(Type type) { return FormatterServices.GetUninitializedObject(type); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteTimeSpanImpl(ref state, timeSpan, DateTimeKind.Unspecified); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimeSpan(ref ProtoWriter.State state, TimeSpan value) { WriteTimeSpanImpl(ref state, value, DateTimeKind.Unspecified); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteTimeSpanImpl(ref ProtoWriter.State state, TimeSpan timeSpan, DateTimeKind kind) { switch (state.WireType) { case WireType.String: case WireType.StartGroup: { PrimaryTypeProvider.ScaledTicks value = new PrimaryTypeProvider.ScaledTicks(timeSpan, kind); state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, value, SerializerCache<PrimaryTypeProvider>.InstanceField); break; } case WireType.Fixed64: state.WriteInt64(timeSpan.Ticks); break; default: ThrowHelper.ThrowProtoException("Unexpected wire-type: " + state.WireType); break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadTimeSpan(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadTimeSpan(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadTimeSpan(ref ProtoReader.State state) { switch (state.WireType) { case WireType.String: case WireType.StartGroup: return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(PrimaryTypeProvider.ScaledTicks), SerializerCache<PrimaryTypeProvider>.InstanceField).ToTimeSpan(); case WireType.Fixed64: { long num = state.ReadInt64(); return num switch { long.MinValue => TimeSpan.MinValue, long.MaxValue => TimeSpan.MaxValue, _ => TimeSpan.FromTicks(num), }; } default: ThrowHelper.ThrowProtoException($"Unexpected wire-type: {state.WireType}"); return default(TimeSpan); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadDuration(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadDuration(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TimeSpan ReadDuration(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(Duration), SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDuration(TimeSpan value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteDuration(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDuration(ref ProtoWriter.State state, TimeSpan value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, (Duration)value, (ISerializer<Duration>)SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadTimestamp(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadTimestamp(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadTimestamp(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(Timestamp), SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimestamp(DateTime value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteTimestamp(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteTimestamp(ref ProtoWriter.State state, DateTime value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, (Timestamp)value, (ISerializer<Timestamp>)SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadDateTime(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadDateTime(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static DateTime ReadDateTime(ref ProtoReader.State state) { switch (state.WireType) { case WireType.String: case WireType.StartGroup: return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(PrimaryTypeProvider.ScaledTicks), SerializerCache<PrimaryTypeProvider>.InstanceField).ToDateTime(); case WireType.Fixed64: { long num = state.ReadInt64(); return num switch { long.MinValue => DateTime.MinValue, long.MaxValue => DateTime.MaxValue, _ => EpochOrigin[0].AddTicks(num), }; } default: ThrowHelper.ThrowProtoException($"Unexpected wire-type: {state.WireType}"); return default(DateTime); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTime(DateTime value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteDateTimeImpl(ref state, value, includeKind: false); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTime(ref ProtoWriter.State state, DateTime value) { WriteDateTimeImpl(ref state, value, includeKind: false); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTimeWithKind(DateTime value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteDateTimeImpl(ref state, value, includeKind: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDateTimeWithKind(ref ProtoWriter.State state, DateTime value) { WriteDateTimeImpl(ref state, value, includeKind: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteDateTimeImpl(ref ProtoWriter.State state, DateTime value, bool includeKind) { WireType wireType = state.WireType; TimeSpan timeSpan; if ((uint)(wireType - 2) <= 1u) { if (value == DateTime.MaxValue) { timeSpan = TimeSpan.MaxValue; includeKind = false; } else if (value == DateTime.MinValue) { timeSpan = TimeSpan.MinValue; includeKind = false; } else { timeSpan = value - EpochOrigin[0]; } } else { timeSpan = value - EpochOrigin[0]; } WriteTimeSpanImpl(ref state, timeSpan, includeKind ? value.Kind : DateTimeKind.Unspecified); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal ReadDecimal(ProtoReader reader) { ProtoReader.State state = reader.DefaultState(); return ReadDecimal(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static decimal ReadDecimal(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, 0m, SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static decimal ReadDecimalString(ref ProtoReader.State state) { byte* ptr = stackalloc byte[32]; Span<byte> span = state.ReadBytes(new Span<byte>(ptr, 32)); if (!Utf8Parser.TryParse((ReadOnlySpan<byte>)span, out decimal value, out int bytesConsumed, '\0') || bytesConsumed != span.Length) { ThrowHelper.ThrowInvalidOperationException("Unable to parse decimal: '" + Encoding.UTF8.GetString(ptr, span.Length) + "'"); } return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDecimal(decimal value, ProtoWriter writer) { ProtoWriter.State state = writer.DefaultState(); WriteDecimal(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDecimal(ref ProtoWriter.State state, decimal value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, value, SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteDecimalString(ref ProtoWriter.State state, decimal value) { byte[] array = ArrayPool<byte>.Shared.Rent(32); try { if (!Utf8Formatter.TryFormat(value, array, out var bytesWritten)) { ThrowHelper.ThrowInvalidOperationException($"Unable to format decimal: '{value}'"); } state.WriteBytes(new ReadOnlyMemory<byte>(array, 0, bytesWritten)); } finally { ArrayPool<byte>.Shared.Return(array); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuid(Guid value, ProtoWriter dest) { ProtoWriter.State state = dest.DefaultState(); WriteGuid(ref state, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuid(ref ProtoWriter.State state, Guid value) { state.WriteMessage(SerializerFeatures.OptionSkipRecursionCheck, value, SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuidBytes(ref ProtoWriter.State state, Guid value) { GuidHelper.Write(ref state, in value, asBytes: true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteGuidString(ref ProtoWriter.State state, Guid value) { GuidHelper.Write(ref state, in value, asBytes: false); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuid(ProtoReader source) { ProtoReader.State state = source.DefaultState(); return ReadGuid(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuid(ref ProtoReader.State state) { return state.ReadMessage(SerializerFeatures.CategoryRepeated, default(Guid), SerializerCache<PrimaryTypeProvider>.InstanceField); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuidBytes(ref ProtoReader.State state) { return GuidHelper.Read(ref state); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Guid ReadGuidString(ref ProtoReader.State state) { return GuidHelper.Read(ref state); } } public sealed class BufferExtension : IExtension, IExtensionResettable { private ArraySegment<byte> _buffer; internal Type Type { get; private set; } internal BufferExtension Tail { get; private set; } internal void SetTail(Type type, BufferExtension tail) { Type = type; Tail = tail; } void IExtensionResettable.Reset() { _buffer = default(ArraySegment<byte>); } int IExtension.GetLength() { return _buffer.Count; } Stream IExtension.BeginAppend() { return new MemoryStream(); } void IExtension.EndAppend(Stream stream, bool commit) { using (stream) { if (!commit || !(stream is MemoryStream memoryStream) || !memoryStream.TryGetBuffer(out var buffer) || buffer.Count == 0) { return; } if (_buffer.Count == 0) { _buffer = buffer; return; } int num = _buffer.Offset + _buffer.Count; int num2 = _buffer.Array.Length - num; if (num2 >= buffer.Count) { Buffer.BlockCopy(buffer.Array, buffer.Offset, _buffer.Array, num, buffer.Count); _buffer = new ArraySegment<byte>(_buffer.Array, _buffer.Offset, num + buffer.Count); return; } byte[] array = new byte[_buffer.Count + buffer.Count]; Buffer.BlockCopy(_buffer.Array, _buffer.Offset, array, 0, _buffer.Count); Buffer.BlockCopy(buffer.Array, buffer.Offset, array, _buffer.Count, buffer.Count); _buffer = new ArraySegment<byte>(array, 0, _buffer.Count + buffer.Count); } } Stream IExtension.BeginQuery() { if (_buffer.Count != 0) { return new MemoryStream(_buffer.Array, _buffer.Offset, _buffer.Count, writable: false, publiclyVisible: true); } return Stream.Null; } void IExtension.EndQuery(Stream stream) { using (stream) { } } } internal static class BufferPool { private static readonly ArrayPool<byte> _pool = ArrayPool<byte>.Shared; internal const int BUFFER_LENGTH = 1024; private const int MaxByteArraySize = 2147483591; internal static byte[] GetBuffer() { return GetBuffer(1024); } internal static byte[] GetBuffer(int minSize) { byte[] cachedBuffer = GetCachedBuffer(minSize); return cachedBuffer ?? new byte[minSize]; } internal static byte[] GetCachedBuffer(int minSize) { return _pool.Rent(minSize); } internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex, int copyBytes) { int num = buffer.Length * 2; if (num < 0) { num = 2147483591; } if (num < toFitAtLeastBytes) { num = toFitAtLeastBytes; } if (copyBytes == 0) { ReleaseBufferToPool(ref buffer); } byte[] array = GetCachedBuffer(num) ?? new byte[num]; if (copyBytes > 0) { Buffer.BlockCopy(buffer, copyFromIndex, array, 0, copyBytes); ReleaseBufferToPool(ref buffer); } buffer = array; } internal static void ReleaseBufferToPool(ref byte[] buffer) { byte[] array = buffer; buffer = null; if (array != null) { _pool.Return(array); } } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoBeforeSerializationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoAfterSerializationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoBeforeDeserializationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [ImmutableObject(true)] public sealed class ProtoAfterDeserializationAttribute : Attribute { } public enum CompatibilityLevel { NotSpecified = 0, Level200 = 200, Level240 = 240, Level300 = 300 } [ImmutableObject(true)] [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)] public sealed class CompatibilityLevelAttribute : Attribute { public CompatibilityLevel Level { get; } public CompatibilityLevelAttribute(CompatibilityLevel level) { Level = level; } internal static void AssertValid(CompatibilityLevel compatibilityLevel) { switch (compatibilityLevel) { case CompatibilityLevel.NotSpecified: case CompatibilityLevel.Level200: case CompatibilityLevel.Level240: case CompatibilityLevel.Level300: return; } Throw(compatibilityLevel); static void Throw(CompatibilityLevel compatibilityLevel) { throw new ArgumentOutOfRangeException("compatibilityLevel", $"Compatiblity level '{compatibilityLevel}' is not recognized."); } } } public enum DataFormat { Default, ZigZag, TwosComplement, FixedSize, Group, [Obsolete("This option is replaced with CompatibilityLevel, and is only used for Level200, where it changes this field to Level240", false)] WellKnown } [Serializable] [StructLayout(LayoutKind.Auto)] public readonly struct DiscriminatedUnionObject : ISerializable { public readonly object Object; public int Discriminator { get; } public bool Is(int discriminator) { return Discriminator == discriminator; } public DiscriminatedUnionObject(int discriminator, object value) { Discriminator = discriminator; Object = value; } public static void Reset(ref DiscriminatedUnionObject value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnionObject); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (Discriminator != 0) { info.AddValue("d", Discriminator); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnionObject(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnionObject); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; string name = current.Name; if (!(name == "d")) { if (name == "o") { Object = current.Value; } } else { Discriminator = (int)current.Value; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion64 : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; public int Discriminator => _discriminator; private DiscriminatedUnion64(int discriminator) { this = default(DiscriminatedUnion64); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion64(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion64(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion64(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion64(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion64(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion64(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion64(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion64(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion64(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion64 value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion64); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int64 != 0L) { info.AddValue("i", Int64); } } private DiscriminatedUnion64(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion64); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; string name = current.Name; if (!(name == "d")) { if (name == "i") { Int64 = (long)current.Value; } } else { _discriminator = (int)current.Value; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion128Object : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; [FieldOffset(8)] public readonly Guid Guid; [FieldOffset(24)] public readonly object Object; [FieldOffset(8)] private readonly long _lo; [FieldOffset(16)] private readonly long _hi; public int Discriminator => _discriminator; private DiscriminatedUnion128Object(int discriminator) { this = default(DiscriminatedUnion128Object); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion128Object(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion128Object(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion128Object(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion128Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion128Object(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion128Object(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion128Object(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion128Object(int discriminator, object value) : this((value != null) ? discriminator : 0) { Object = value; } public DiscriminatedUnion128Object(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion128Object(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public DiscriminatedUnion128Object(int discriminator, Guid? value) : this(value.HasValue ? discriminator : 0) { Guid = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion128Object value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion128Object); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (_lo != 0L) { info.AddValue("l", _lo); } if (_hi != 0L) { info.AddValue("h", _hi); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnion128Object(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion128Object); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "l": _lo = (long)current.Value; break; case "h": _hi = (long)current.Value; break; case "o": Object = current.Value; break; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion128 : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; [FieldOffset(8)] public readonly Guid Guid; [FieldOffset(8)] private readonly long _lo; [FieldOffset(16)] private readonly long _hi; public int Discriminator => _discriminator; private DiscriminatedUnion128(int discriminator) { this = default(DiscriminatedUnion128); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion128(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion128(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion128(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion128(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion128(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion128(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion128(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion128(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion128(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public DiscriminatedUnion128(int discriminator, Guid? value) : this(value.HasValue ? discriminator : 0) { Guid = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion128 value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion128); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (_lo != 0L) { info.AddValue("l", _lo); } if (_hi != 0L) { info.AddValue("h", _hi); } } private DiscriminatedUnion128(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion128); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "l": _lo = (long)current.Value; break; case "h": _hi = (long)current.Value; break; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion64Object : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(8)] public readonly long Int64; [FieldOffset(8)] public readonly ulong UInt64; [FieldOffset(8)] public readonly int Int32; [FieldOffset(8)] public readonly uint UInt32; [FieldOffset(8)] public readonly bool Boolean; [FieldOffset(8)] public readonly float Single; [FieldOffset(8)] public readonly double Double; [FieldOffset(8)] public readonly DateTime DateTime; [FieldOffset(8)] public readonly TimeSpan TimeSpan; [FieldOffset(16)] public readonly object Object; public int Discriminator => _discriminator; private DiscriminatedUnion64Object(int discriminator) { this = default(DiscriminatedUnion64Object); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion64Object(int discriminator, long value) : this(discriminator) { Int64 = value; } public DiscriminatedUnion64Object(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion64Object(int discriminator, ulong value) : this(discriminator) { UInt64 = value; } public DiscriminatedUnion64Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion64Object(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion64Object(int discriminator, double value) : this(discriminator) { Double = value; } public DiscriminatedUnion64Object(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion64Object(int discriminator, object value) : this((value != null) ? discriminator : 0) { Object = value; } public DiscriminatedUnion64Object(int discriminator, DateTime? value) : this(value.HasValue ? discriminator : 0) { DateTime = value.GetValueOrDefault(); } public DiscriminatedUnion64Object(int discriminator, TimeSpan? value) : this(value.HasValue ? discriminator : 0) { TimeSpan = value.GetValueOrDefault(); } public static void Reset(ref DiscriminatedUnion64Object value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion64Object); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int64 != 0L) { info.AddValue("i", Int64); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnion64Object(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion64Object); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "i": Int64 = (long)current.Value; break; case "o": Object = current.Value; break; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion32 : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(4)] public readonly int Int32; [FieldOffset(4)] public readonly uint UInt32; [FieldOffset(4)] public readonly bool Boolean; [FieldOffset(4)] public readonly float Single; public int Discriminator => _discriminator; private DiscriminatedUnion32(int discriminator) { this = default(DiscriminatedUnion32); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion32(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion32(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion32(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion32(int discriminator, bool value) : this(discriminator) { Boolean = value; } public static void Reset(ref DiscriminatedUnion32 value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion32); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int32 != 0) { info.AddValue("i", Int32); } } private DiscriminatedUnion32(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion32); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; string name = current.Name; if (!(name == "d")) { if (name == "i") { Int32 = (int)current.Value; } } else { _discriminator = (int)current.Value; } } } } [Serializable] [StructLayout(LayoutKind.Explicit)] public readonly struct DiscriminatedUnion32Object : ISerializable { [FieldOffset(0)] private readonly int _discriminator; [FieldOffset(4)] public readonly int Int32; [FieldOffset(4)] public readonly uint UInt32; [FieldOffset(4)] public readonly bool Boolean; [FieldOffset(4)] public readonly float Single; [FieldOffset(8)] public readonly object Object; public int Discriminator => _discriminator; private DiscriminatedUnion32Object(int discriminator) { this = default(DiscriminatedUnion32Object); _discriminator = discriminator; } public bool Is(int discriminator) { return _discriminator == discriminator; } public DiscriminatedUnion32Object(int discriminator, int value) : this(discriminator) { Int32 = value; } public DiscriminatedUnion32Object(int discriminator, uint value) : this(discriminator) { UInt32 = value; } public DiscriminatedUnion32Object(int discriminator, float value) : this(discriminator) { Single = value; } public DiscriminatedUnion32Object(int discriminator, bool value) : this(discriminator) { Boolean = value; } public DiscriminatedUnion32Object(int discriminator, object value) : this((value != null) ? discriminator : 0) { Object = value; } public static void Reset(ref DiscriminatedUnion32Object value, int discriminator) { if (value.Discriminator == discriminator) { value = default(DiscriminatedUnion32Object); } } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (_discriminator != 0) { info.AddValue("d", _discriminator); } if (Int32 != 0) { info.AddValue("i", Int32); } if (Object != null) { info.AddValue("o", Object); } } private DiscriminatedUnion32Object(SerializationInfo info, StreamingContext context) { this = default(DiscriminatedUnion32Object); SerializationInfoEnumerator enumerator = info.GetEnumerator(); while (enumerator.MoveNext()) { SerializationEntry current = enumerator.Current; switch (current.Name) { case "d": _discriminator = (int)current.Value; break; case "i": Int32 = (int)current.Value; break; case "o": Object = current.Value; break; } } } } public abstract class Extensible : ITypedExtensible, IExtensible { private IExtension extensionObject; IExtension IExtensible.GetExtensionObject(bool createIfMissing) { return GetExtensionObject(createIfMissing); } IExtension ITypedExtensible.GetExtensionObject(Type type, bool createIfMissing) { if ((object)type != GetType()) { return GetExtensionObject(ref extensionObject, type, createIfMissing); } return GetExtensionObject(createIfMissing); } [Obsolete("This API is considered, and may no longer be used in all scenarios (in particular when inheritance is involved); it is not recommended to rely on this API")] protected virtual IExtension GetExtensionObject(bool createIfMissing) { return GetExtensionObject(ref extensionObject, GetType(), createIfMissing); } public static IExtension GetExtensionObject(ref IExtension extensionObject, Type type, bool createIfMissing) { if ((object)type == null) { ThrowHelper.ThrowArgumentNullException("type"); } BufferExtension bufferExtension = extensionObject as BufferExtension; BufferExtension bufferExtension2 = bufferExtension; if (bufferExtension == null) { if (extensionObject != null) { ThrowHelper.ThrowNotSupportedException("Custom extension implementations should not be passed to GetExtensionObject"); } } else { while (bufferExtension2 != null) { Type type2 = bufferExtension2.Type; if ((object)type2 == null) { ThrowHelper.ThrowInvalidOperationException("Typed and untyped extension data cannot be mixed"); } if ((object)type2 == type) { return bufferExtension2; } bufferExtension2 = bufferExtension2.Tail; } } if (createIfMissing) { BufferExtension bufferExtension3 = new BufferExtension(); bufferExtension3.SetTail(type, bufferExtension); bufferExtension2 = (BufferExtension)(extensionObject = bufferExtension3); } return bufferExtension2; } public static IExtension GetExtensionObject(ref IExtension extensionObject, bool createIfMissing) { if (extensionObject == null) { if (createIfMissing) { extensionObject = new BufferExtension(); } } else if (extensionObject is BufferExtension bufferExtension && (object)bufferExtension.Type != null) { ThrowHelper.ThrowInvalidOperationException("Typed and untyped extension data cannot be mixed"); } return extensionObject; } public static void AppendValue<TValue>(IExtensible instance, int tag, TValue value) { ExtensibleUtil.AppendExtendValue(null, instance, tag, DataFormat.Default, value); } public static void AppendValue<TValue>(IExtensible instance, int tag, DataFormat format, TValue value) { ExtensibleUtil.AppendExtendValue(null, instance, tag, format, value); } public static void AppendValue<TValue>(TypeModel model, IExtensible instance, int tag, TValue value, DataFormat format = DataFormat.Default) { ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); } public static TValue GetValue<TValue>(IExtensible instance, int tag) { return GetValue<TValue>(null, instance, tag); } public static TValue GetValue<TValue>(IExtensible instance, int tag, DataFormat format) { return GetValue<TValue>(null, instance, tag, format); } public static TValue GetValue<TValue>(TypeModel model, IExtensible instance, int tag, DataFormat format = DataFormat.Default) { if (!TryGetValue<TValue>(model, instance, tag, out var value, format)) { return default(TValue); } return value; } public static bool TryGetValue<TValue>(IExtensible instance, int tag, out TValue value) { return TryGetValue<TValue>(null, instance, tag, out value); } public static bool TryGetValue<TValue>(IExtensible instance, int tag, DataFormat format, out TValue value) { return TryGetValue<TValue>(null, instance, tag, out value, format); } public static bool TryGetValue<TValue>(IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out TValue value) { return TryGetValue<TValue>(null, instance, tag, out value, format, allowDefinedTag); } public static bool TryGetValue<TValue>(TypeModel model, IExtensible instance, int tag, out TValue value, DataFormat format = DataFormat.Default, bool allowDefinedTag = false) { value = default(TValue); bool result = false; foreach (TValue extendedValue in ExtensibleUtil.GetExtendedValues<TValue>(model, instance, tag, format, singleton: true, allowDefinedTag)) { value = extendedValue; result = true; } return result; } public static IEnumerable<TValue> GetValues<TValue>(IExtensible instance, int tag) { return ExtensibleUtil.GetExtendedValues<TValue>(null, instance, tag, DataFormat.Default, singleton: false, allowDefinedTag: false); } public static IEnumerable<TValue> GetValues<TValue>(IExtensible instance, int tag, DataFormat format) { return ExtensibleUtil.GetExtendedValues<TValue>(null, instance, tag, format, singleton: false, allowDefinedTag: false); } public static IEnumerable<TValue> GetValues<TValue>(TypeModel model, IExtensible instance, int tag, DataFormat format = DataFormat.Default) { return ExtensibleUtil.GetExtendedValues<TValue>(model, instance, tag, format, singleton: false, allowDefinedTag: false); } public static bool TryGetValue(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out object value) { value = null; bool result = false; foreach (object extendedValue in ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, singleton: true, allowDefinedTag)) { value = extendedValue; result = true; } return result; } public static IEnumerable GetValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format = DataFormat.Default) { return ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, singleton: false, allowDefinedTag: false); } public static void AppendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) { ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); } } internal static class ExtensibleUtil { internal static IEnumerable<TValue> GetExtendedValues<TValue>(TypeModel model, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { foreach (TValue extendedValue in GetExtendedValues(model, typeof(TValue), instance, tag, format, singleton, allowDefinedTag)) { yield return extendedValue; } } internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } if (tag <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException("tag"); } return GetExtendedValues(model, type, instance.GetExtensionObject(createIfMissing: false), tag, format, singleton); } internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtension extn, int tag, DataFormat format, bool singleton) { if (model == null) { model = TypeModel.DefaultModel; } if (extn == null) { yield break; } Stream stream = extn.BeginQuery(); try { object value = null; SerializationContext userState = new SerializationContext(); ProtoReader.SolidState state = ProtoReader.State.Create(stream, model, userState, -1L).Solidify(); try { while (model.TryDeserializeAuxiliaryType(ref state, format, tag, type, ref value, skipOtherFields: true, asListItem: true, autoCreate: false, insideList: false, null, isRoot: false) && value != null) { if (!singleton) { yield return value; value = null; } } if (singleton && value != null) { yield return value; } } finally { state.Dispose(); } } finally { extn.EndQuery(stream); } } internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) { if (instance == null) { ThrowHelper.ThrowArgumentNullException("instance"); } if (value == null) { ThrowHelper.ThrowArgumentNullException("value"); } AppendExtendValue(model, instance.GetExtensionObject(createIfMissing: true), tag, format, value); } internal static void AppendExtendValue(TypeModel model, IExtension extn, int tag, DataFormat format, object value) { if (model == null) { model = TypeModel.DefaultModel; } if (extn == null) { ThrowHelper.ThrowInvalidOperationException("No extension object available; appended data would be lost."); } bool commit = false; Stream stream = extn.BeginAppend(); try { ProtoWriter.State state = ProtoWriter.State.Create(stream, model); try { model.TrySerializeAuxiliaryType(ref state, null, format, tag, value, isInsideList: false, null, isRoot: false); state.Close(); } catch { state.Abandon(); throw; } finally { state.Dispose(); } commit = true; } finally { extn.EndAppend(stream, commit); } } } internal static class Helpers { internal static MethodInfo GetInstanceMethod(Type declaringType, string name) { return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } internal static MethodInfo GetStaticMethod(Type declaringType, string name) { return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) { if (types == null) { types = Type.EmptyTypes; } return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null); } internal static bool IsSubclassOf(Type type, Type baseClass) { return type.IsSubclassOf(baseClass); } public static ProtoTypeCode GetTypeCode(Type type) { TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Empty: case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte: case TypeCode.Byte: case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: case TypeCode.UInt32: case TypeCode.Int64: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: return (ProtoTypeCode)typeCode; default: if (type == typeof(TimeSpan)) { return ProtoTypeCode.TimeSpan; } if (type == typeof(Guid)) { return ProtoTypeCode.Guid; } if (type == typeof(Uri)) { return ProtoTypeCode.Uri; } if (type == typeof(byte[])) { return ProtoTypeCode.ByteArray; } if (type == typeof(ArraySegment<byte>)) { return ProtoTypeCode.ByteArraySegment; } if (type == typeof(Memory<byte>)) { return ProtoTypeCode.ByteMemory; } if (type == typeof(ReadOnlyMemory<byte>)) { return ProtoTypeCode.ByteReadOnlyMemory; } if (type == typeof(Type)) { return ProtoTypeCode.Type; } if (type == typeof(IntPtr)) { return ProtoTypeCode.IntPtr; } if (type == typeof(UIntPtr)) { return ProtoTypeCode.UIntPtr; } return ProtoTypeCode.Unknown; } } internal static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) { if ((object)property == null) { return null; } MethodInfo methodInfo = property.GetGetMethod(nonPublic); if ((object)methodInfo == null && !nonPublic && allowInternal) { methodInfo = property.GetGetMethod(nonPublic: true); if ((object)methodInfo != null && !methodInfo.IsAssembly && !methodInfo.IsFamilyOrAssembly) { methodInfo = null; } } return methodInfo; } internal static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) { if ((object)property == null) { return null; } MethodInfo methodInfo = property.GetSetMethod(nonPublic); if ((object)methodInfo == null && !nonPublic && allowInternal) { methodInfo = property.GetGetMethod(nonPublic: true); if ((object)methodInfo != null && !methodInfo.IsAssembly && !methodInfo.IsFamilyOrAssembly) { methodInfo = null; } } return methodInfo; } internal static ConstructorInfo GetConstructor(Type type, Type[] parameterTypes, bool nonPublic) { return type.GetConstructor(nonPublic ? (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : (BindingFlags.Instance | BindingFlags.Public), null, parameterTypes, null); } internal static ConstructorInfo[] GetConstructors(Type type, bool nonPublic) { return type.GetConstructors(nonPublic ? (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : (BindingFlags.Instance | BindingFlags.Public)); } internal static void GetBuffer(MemoryStream stream, out ArraySegment<byte> segment) { if (stream == null || !stream.TryGetBuffer(out segment)) { ThrowHelper.ThrowInvalidOperationException("Unable to obtain buffer from MemoryStream"); segment = default(ArraySegment<byte>); } } internal static PropertyInfo GetProperty(Type type, string name, bool nonPublic) { return type.GetProperty(name, nonPublic ? (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : (BindingFlags.Instance | BindingFlags.Public)); } internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly) { BindingFlags bindingAttr = (publicOnly ? (BindingFlags.Instance | BindingFlags.Public) : (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); PropertyInfo[] properties = type.GetProperties(bindingAttr); FieldInfo[] fields = type.GetFields(bindingAttr); MemberInfo[] array = new MemberInfo[fields.Length + properties.Length]; properties.CopyTo(array, 0); fields.CopyTo(array, properties.Length); return array; } internal static Type GetMemberType(MemberInfo member) { return member.MemberType switch { MemberTypes.Field => ((FieldInfo)member).FieldType, MemberTypes.Property => ((PropertyInfo)member).PropertyType, _ => null, }; } } internal enum ProtoTypeCode { Empty = 0, Unknown = 1, Boolean = 3, Char = 4, SByte = 5, Byte = 6, Int16 = 7, UInt16 = 8, Int32 = 9, UInt32 = 10, Int64 = 11, UInt64 = 12, Single = 13, Double = 14, Decimal = 15, DateTime = 16, String = 18, TimeSpan = 100, ByteArray = 101, Guid = 102, Uri = 103, Type = 104, ByteArraySegment = 105, ByteMemory = 106, ByteReadOnlyMemory = 107, IntPtr = 108, UIntPtr = 109 } public interface IExtensible { IExtension GetExtensionObject(bool createIfMissing); } public interface ITypedExtensible { IExtension GetExtensionObject(Type type, bool createIfMissing); } public interface IExtension { Stream BeginAppend(); void EndAppend(Stream stream, bool commit); Stream BeginQuery(); void EndQuery(Stream stream); int GetLength(); } public interface IExtensionResettable : IExtension { void Reset(); } public enum ImplicitFields { None, AllPublic, AllFields } public interface IProtoInput<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TInput> { T Deserialize<T>(TInput source, T value = default(T), object userState = null); } public interface IProtoOutput<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TOutput> { void Serialize<T>(TOutput destination, T value, object userState = null); } public interface IMeasuredProtoOutput<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] TOutput> : IProtoOutput<TOutput> { MeasureState<T> Measure<T>(T value, object userState = null); void Serialize<T>(MeasureState<T> measured, TOutput destination); } public interface ISerializationContext { TypeModel Model { get; } object UserState { get; } } public struct MeasureState<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] T> : IDisposable { private readonly TypeModel _model; private readonly T _value; private readonly object _userState; private ProtoWriter _writer; public long Length { get; } internal MeasureState(TypeModel model, in T value, object userState, long abortAfter) { _model = model; _value = value; _userState = userState; ProtoWriter.State state = ProtoWriter.NullProtoWriter.CreateNullProtoWriter(_model, userState, abortAfter); try { Length = TypeModel.SerializeImpl(ref state, _value); ProtoWriter.NullProtoWriter.CheckOversized(abortAfter, Length); _writer = state.GetWriter(); } catch { state.Dispose(); throw; } } public void Dispose() { ProtoWriter writer = _writer; _writer = null; writer?.Dispose(); } public long LengthOnly() { long length = Length; Dispose(); return length; } private void SerializeCore(ProtoWriter.State state) { try { ProtoWriter writer = _writer; if (writer == null) { throw new ObjectDisposedException("MeasureState"); } ProtoWriter writer2 = state.GetWriter(); writer2.InitializeFrom(writer); long num = TypeModel.SerializeImpl(ref state, _value); writer2.CopyBack(writer); if (num != Length) { ThrowHelper.ThrowInvalidOperationException($"Invalid length; expected {Length}, actual: {num}"); } } catch (Exception ex) { ex.Data?.Add("ProtoBuf.MeasuredLength", Length); throw; } finally { state.Dispose(); } } internal int GetLengthHits(out int misses) { return _writer.GetLengthHits(out misses); } public void Serialize(Stream stream) { SerializeCore(ProtoWriter.State.Create(stream, _model, _userState)); } public void Serialize(IBufferWriter<byte> writer) { SerializeCore(ProtoWriter.State.Create(writer, _model, _userState)); } } internal sealed class NetObjectCache { [StructLayout(LayoutKind.Auto)] private readonly struct ObjectKey : IEquatable<ObjectKey> { private readonly object _obj; private readonly Type _subTypeLevel; [MethodImpl(MethodImplOptions.AggressiveInlining)] public ObjectKey(object obj, Type subTypeLevel) { _obj = obj; _subTypeLevel = subTypeLevel; } public override string ToString() { return $"{_subTypeLevel}/{_obj}"; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { return RuntimeHelpers.GetHashCode(_obj) ^ (_subTypeLevel?.GetHashCode() ?? 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object obj) { if (obj is ObjectKey other) { return Equals(other); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(ObjectKey other) { return (_obj == other._obj) & (_subTypeLevel == other._subTypeLevel); } } private readonly Dictionary<ObjectKey, long> _knownLengths = new Dictionary<ObjectKey, long>(); private int _hit; private int _miss; internal int LengthHits => _hit; internal int LengthMisses => _miss; [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryGetKnownLength(object obj, Type subTypeLevel, out long length) { if (_knownLengths.TryGetValue(new ObjectKey(obj, subTypeLevel), out length)) { _hit++; return true; } _miss++; length = 0L; return false; } public void SetKnownLength(object obj, Type subTypeLevel, long length) { ObjectKey key = new ObjectKey(obj, subTypeLevel); _knownLengths[key] = length; } internal void Clear() { _knownLengths.Clear(); _hit = (_miss = 0); } internal void InitializeFrom(NetObjectCache obj) { if (obj == null) { return; } _knownLengths.Clear(); foreach (KeyValuePair<ObjectKey, long> knownLength in obj._knownLengths) { _knownLengths.Add(knownLength.Key, knownLength.Value); } } internal void CopyBack(NetObjectCache obj) { if (obj != null) { obj._hit += _hit; obj._miss += _miss; } } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class NullWrappedValueAttribute : Attribute { public bool AsGroup { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class NullWrappedCollectionAttribute : Attribute { public bool AsGroup { get; set; } } public enum PrefixStyle { None, Base128, Fixed32, Fixed32BigEndian } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] public sealed class ProtoContractAttribute : Attribute { [Flags] private enum TypeOptions : ushort { InferTagFromName = 1, InferTagFromNameHasValue = 2, UseProtoMembersOnly = 4, SkipConstructor = 8, IgnoreListHandling = 0x10, IsGroup = 0x100, IgnoreUnknownSubTypes = 0x200 } internal const string ReferenceDynamicDisabled = "Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited"; private int implicitFirstTag; private TypeOptions flags; public string Name { get; set; } public string Origin { get; set; } public int ImplicitFirstTag { get { return implicitFirstTag; } set { if (value < 1) { ThrowHelper.ThrowArgumentOutOfRangeException("ImplicitFirstTag"); } implicitFirstTag = value; } } public bool UseProtoMembersOnly { get { return HasFlag(TypeOptions.UseProtoMembersOnly); } set { SetFlag(TypeOptions.UseProtoMembersOnly, value); } } public bool IgnoreListHandling { get { return HasFlag(TypeOptions.IgnoreListHandling); } set { SetFlag(TypeOptions.IgnoreListHandling, value); } } public ImplicitFields ImplicitFields { get; set; } public bool InferTagFromName { get { return HasFlag(TypeOptions.InferTagFromName); } set { SetFlag(TypeOptions.InferTagFromName, value); SetFlag(TypeOptions.InferTagFromNameHasValue, value: true); } } internal bool InferTagFromNameHasValue => HasFlag(TypeOptions.InferTagFromNameHasValue); public int DataMemberOffset { get; set; } public bool SkipConstructor { get { return HasFlag(TypeOptions.SkipConstructor); } set { SetFlag(TypeOptions.SkipConstructor, value); } } public bool AsReferenceDefault { get { return false; } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] set { if (value != AsReferenceDefault) { ThrowHelper.ThrowNotSupportedException(); } } } public bool IsGroup { get { return HasFlag(TypeOptions.IsGroup); } set { SetFlag(TypeOptions.IsGroup, value); } } public bool IgnoreUnknownSubTypes { get { return HasFlag(TypeOptions.IgnoreUnknownSubTypes); } set { SetFlag(TypeOptions.IgnoreUnknownSubTypes, value); } } [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", true)] public bool EnumPassthru { get { return true; } set { if (!value) { ThrowHelper.ThrowInvalidOperationException("EnumPassthru is not longer supported, and is always considered true"); } } } public Type Surrogate { get; set; } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)] public Type Serializer { get; set; } private bool HasFlag(TypeOptions flag) { return (flags & flag) == flag; } private void SetFlag(TypeOptions flag, bool value) { if (value) { flags |= flag; } else { flags &= (TypeOptions)(ushort)(~(int)flag); } } } [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class ProtoConverterAttribute : Attribute { } [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] public sealed class ProtoEnumAttribute : Attribute { internal const string EnumValueDeprecated = "Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties"; public int Value { [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", false)] get { return 0; } [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", true)] set { ThrowHelper.ThrowNotSupportedException(); } } public string Name { get; set; } [Obsolete("Enum value maps have been deprecated and are no longer supported; all enums are now effectively pass-thru; custom maps should be applied via shadow properties; in C#, lambda-based 'switch expressions' make for very convenient shadow properties", false)] public bool HasValue() { return false; } } [Serializable] public class ProtoException : Exception { public ProtoException() { } public ProtoException(string message) : base(message) { } public ProtoException(string message, Exception innerException) : base(message, innerException) { } protected ProtoException(SerializationInfo info, StreamingContext context) : base(info, context) { } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class ProtoIgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public sealed class ProtoPartialIgnoreAttribute : ProtoIgnoreAttribute { public string MemberName { get; } public ProtoPartialIgnoreAttribute(string memberName) { if (string.IsNullOrEmpty(memberName)) { ThrowHelper.ThrowArgumentNullException("memberName"); } MemberName = memberName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] public sealed class ProtoIncludeAttribute : Attribute { public int Tag { get; } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public string KnownTypeName { get; } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public Type KnownType => TypeModel.ResolveKnownType(KnownTypeName, null); [DefaultValue(DataFormat.Default)] public DataFormat DataFormat { get; set; } public ProtoIncludeAttribute(int tag, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] Type knownType) : this(tag, ((object)knownType == null) ? "" : knownType.AssemblyQualifiedName) { } public ProtoIncludeAttribute(int tag, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] string knownTypeName) { if (tag <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException("tag", "Tags must be positive integers"); } if (string.IsNullOrEmpty(knownTypeName)) { ThrowHelper.ThrowArgumentNullException("knownTypeName", "Known type cannot be blank"); } Tag = tag; KnownTypeName = knownTypeName; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class ProtoMapAttribute : Attribute { public DataFormat KeyFormat { get; set; } public DataFormat ValueFormat { get; set; } public bool DisableMap { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public class ProtoMemberAttribute : Attribute, IComparable, IComparable<ProtoMemberAttribute> { internal MemberInfo Member; internal MemberInfo BackingMember; internal bool TagIsPinned; private string name; private DataFormat dataFormat; private int tag; private MemberSerializationOptions options; public string Name { get { return name; } set { name = value; } } public DataFormat DataFormat { get { return dataFormat; } set { dataFormat = value; } } public int Tag => tag; public bool IsRequired { get { return (options & MemberSerializationOptions.Required) == MemberSerializationOptions.Required; } set { if (value) { options |= MemberSerializationOptions.Required; } else { options &= ~MemberSerializationOptions.Required; } } } public bool IsPacked { get { return (options & MemberSerializationOptions.Packed) == MemberSerializationOptions.Packed; } set { if (value) { options |= MemberSerializationOptions.Packed; } else { options &= ~MemberSerializationOptions.Packed; } } } public bool OverwriteList { get { return (options & MemberSerializationOptions.OverwriteList) == MemberSerializationOptions.OverwriteList; } set { if (value) { options |= MemberSerializationOptions.OverwriteList; } else { options &= ~MemberSerializationOptions.OverwriteList; } } } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] public bool AsReference { get { return (options & MemberSerializationOptions.AsReference) == MemberSerializationOptions.AsReference; } set { if (value) { options |= MemberSerializationOptions.AsReference; } else { options &= ~MemberSerializationOptions.AsReference; } options |= MemberSerializationOptions.AsReferenceHasValue; } } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] internal bool AsReferenceHasValue { get { return (options & MemberSerializationOptions.AsReferenceHasValue) == MemberSerializationOptions.AsReferenceHasValue; } set { if (value) { options |= MemberSerializationOptions.AsReferenceHasValue; } else { options &= ~MemberSerializationOptions.AsReferenceHasValue; } } } [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", true)] public bool DynamicType { get { return (options & MemberSerializationOptions.DynamicType) == MemberSerializationOptions.DynamicType; } set { if (value) { options |= MemberSerializationOptions.DynamicType; } else { options &= ~MemberSerializationOptions.DynamicType; } } } public MemberSerializationOptions Options { get { return options; } set { options = value; } } public int CompareTo(object other) { return CompareTo(other as ProtoMemberAttribute); } public int CompareTo(ProtoMemberAttribute other) { if (other == null) { return -1; } if (this == other) { return 0; } int num = tag.CompareTo(other.tag); if (num == 0) { num = string.CompareOrdinal(name, other.name); } return num; } public ProtoMemberAttribute(int tag) : this(tag, forced: false) { } internal ProtoMemberAttribute(int tag, bool forced) { if (tag <= 0 && !forced) { ThrowHelper.ThrowArgumentOutOfRangeException("tag"); } this.tag = tag; } internal void Rebase(int tag) { this.tag = tag; } } [Flags] public enum MemberSerializationOptions { None = 0, Packed = 1, Required = 2, [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", false)] AsReference = 4, [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", false)] DynamicType = 8, OverwriteList = 0x10, [Obsolete("Reference-tracking and dynamic-type are not currently implemented in this build; they may be reinstated later; this is partly due to doubts over whether the features are adviseable, and partly over confidence in testing all the scenarios (it takes time; that time hasn't get happened); feedback is invited", false)] AsReferenceHasValue = 0x20 } [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public sealed class ProtoPartialMemberAttribute : ProtoMemberAttribute { public string MemberName { get; private set; } public ProtoPartialMemberAttribute(int tag, string memberName) : base(tag) { if (string.IsNullOrEmpty(memberName)) { ThrowHelper.ThrowArgumentNullException("memberName"); } MemberName = memberName; } } public abstract class ProtoReader : IDisposable, ISerializationContext { private protected enum Read32VarintMode { Signed, Unsigned, FieldHeader } [StructLayout(LayoutKind.Auto)] public ref struct State { private ProtoReader _reader; private ReadOnlyMemory<byte> _memory; internal ReadOnlySpan<byte> Span { get; private set; } internal int OffsetInCurrent { get; private set; } internal int RemainingInCurrent { get; private set; } public WireType WireType { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader.WireType; } } public bool InternStrings { get { return _reader.InternStrings; } set { _reader.InternStrings = value; } } public int FieldNumber { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader._fieldNumber; } } internal TypeModel Model { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader?.Model; } private set { _reader.Model = value; } } public ISerializationContext Context { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _reader; } } public static State Create(ReadOnlySequence<byte> source, TypeModel model, object userState = null) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) ReadOnlySequenceProtoReader readOnlySequenceProtoReader = Pool<ReadOnlySequenceProtoReader>.TryGet() ?? new ReadOnlySequenceProtoReader(); readOnlySequenceProtoReader.Init(source, model, userState); return new State(readOnlySequenceProtoReader); } public static State Create(ReadOnlyMemory<byte> source, TypeModel model, object userState = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Create(new ReadOnlySequence<byte>(source), model, userState); } public void Dispose() { ProtoReader reader = _reader; this = default(State); reader?.Dispose(); } internal SolidState Solidify() { return new SolidState(_reader, _memory.Slice(OffsetInCurrent, RemainingInCurrent)); } internal State(ProtoReader reader, ReadOnlyMemory<byte> memory) : this(reader) { Init(memory); } internal State(ProtoReader reader) { this = default(State); _reader = reader; } internal void Init(ReadOnlyMemory<byte> memory) { _memory = memory; Span = memory.Span; OffsetInCurrent = 0; RemainingInCurrent = Span.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Skip(int bytes) { OffsetInCurrent += bytes; RemainingInCurrent -= bytes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlySpan<byte> Consume(int bytes) { ReadOnlySpan<byte> result = Span.Slice(OffsetInCurrent, bytes); OffsetInCurrent += bytes; RemainingInCurrent -= bytes; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ReadOnlySpan<byte> Consume(int bytes, out int offset) { offset = OffsetInCurrent; OffsetInCurrent += bytes; RemainingInCurrent -= bytes; return Span; } internal int ReadVarintUInt32(out uint value) { value = Span[OffsetInCurrent]; int num = (((value & 0x80) == 0) ? 1 : ParseVarintUInt32Tail(Span.Slice(OffsetInCurrent), ref value)); OffsetInCurrent += num; RemainingInCurrent -= num; return num; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal int ParseVarintUInt32(ReadOnlySpan<byte> span, out uint value) { value = span[0]; if ((value & 0x80u) != 0) { return ParseVarintUInt32Tail(span, ref value); } return 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal int ParseVarintUInt32(ReadOnlySpan<byte> span, int offset, out uint value) { value = span[offset]; if ((value & 0x80u) != 0) { return ParseVarintUInt32Tail(span.Slice(offset), ref value); } return 1; } private int ParseVarintUInt32Tail(ReadOnlySpan<byte> span, ref uint value) { uint num = span[1]; value = (value & 0x7Fu) | ((num & 0x7F) << 7); if ((num & 0x80) == 0) { return 2; } num = span[2]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0) { return 3; } num = span[3]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0) { return 4; } num = span[4]; value |= num << 28; if ((num & 0xF0) == 0) { return 5; } ThrowOverflow(); return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Advance(long count) { _reader.Advance(count); } internal static int TryParseUInt64Varint(ReadOnlySpan<byte> span, int offset, out ulong value) { if ((uint)offset >= (uint)span.Length) { value = 0uL; return 0; } value = span[offset++]; if ((value & 0x80) == 0L) { return 1; } value &= 127uL; if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } ulong num = span[offset++]; value |= (num & 0x7F) << 7; if ((num & 0x80) == 0L) { return 2; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 14; if ((num & 0x80) == 0L) { return 3; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 21; if ((num & 0x80) == 0L) { return 4; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 28; if ((num & 0x80) == 0L) { return 5; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 35; if ((num & 0x80) == 0L) { return 6; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 42; if ((num & 0x80) == 0L) { return 7; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 49; if ((num & 0x80) == 0L) { return 8; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset++]; value |= (num & 0x7F) << 56; if ((num & 0x80) == 0L) { return 9; } if ((uint)offset >= (uint)span.Length) { NoContextThrowEoF(); } num = span[offset]; value |= num << 63; if ((num & 0xFFFFFFFFFFFFFFFEuL) != 0L) { NoContextThrowOverflow(); } return 10; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal ProtoReader GetReader() { return _reader; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ushort ReadUInt16() { return checked((ushort)ReadUInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public short ReadInt16() { return checked((short)ReadInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long GetPosition() { return _reader._longPosition; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte ReadByte() { return checked((byte)ReadUInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public sbyte ReadSByte() { return checked((sbyte)ReadInt32()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public IntPtr ReadIntPtr() { return new IntPtr(ReadInt64()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public UIntPtr ReadUIntPtr() { return new UIntPtr(ReadUInt64()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ReadUInt32() { switch (_reader.WireType) { case WireType.Variant: return ReadUInt32Varint(Read32VarintMode.Signed); case WireType.Fixed32: return _reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: { ulong num = _reader.ImplReadUInt64Fixed(ref this); return checked((uint)num); } default: ThrowWireTypeException(); return 0u; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ReadInt32() { switch (_reader.WireType) { case WireType.Variant: return (int)ReadUInt32Varint(Read32VarintMode.Signed); case WireType.Fixed32: return (int)_reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: { long num = ReadInt64(); return checked((int)num); } case WireType.SignedVariant: return Zag(ReadUInt32Varint(Read32VarintMode.Signed)); default: ThrowWireTypeException(); return 0; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ReadInt64() { switch (_reader.WireType) { case WireType.Variant: return (long)ReadUInt64Varint(); case WireType.Fixed32: return (int)_reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: return (long)_reader.ImplReadUInt64Fixed(ref this); case WireType.SignedVariant: return Zag(ReadUInt64Varint()); default: ThrowWireTypeException(); return 0L; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe double ReadDouble() { switch (_reader.WireType) { case WireType.Fixed32: return ReadSingle(); case WireType.Fixed64: { long num = ReadInt64(); return *(double*)(&num); } default: ThrowWireTypeException(); return 0.0; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe float ReadSingle() { switch (_reader.WireType) { case WireType.Fixed32: { int num3 = ReadInt32(); return *(float*)(&num3); } case WireType.Fixed64: { double num = ReadDouble(); float num2 = (float)num; if (float.IsInfinity(num2) && !double.IsInfinity(num)) { ThrowOverflow(); } return num2; } default: ThrowWireTypeException(); return 0f; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void PrepareToReadRepeated<T>(ref SerializerFeatures features, SerializerFeatures serializerFeatures, out SerializerFeatures category, out bool packed) { if (serializerFeatures.IsRepeated()) { TypeModel.ThrowNestedListsNotSupported(typeof(T)); } features.InheritFrom(serializerFeatures); category = serializerFeatures.GetCategory(); packed = false; if (TypeHelper<T>.CanBePacked && WireType == WireType.String && !features.HasAny(SerializerFeatures.OptionWrappedValue)) { if (category != SerializerFeatures.CategoryScalar) { ThrowInvalidOperationException("Packed data expected a scalar serializer"); } packed = true; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ReadRepeatedCore<TSerializer, TList, T>(ref TList values, SerializerFeatures category, WireType wireType, in TSerializer serializer, SerializerFeatures features) where TSerializer : ISerializer<T> where TList : ICollection<T> { int fieldNumber = FieldNumber; bool flag = features.HasAny(SerializerFeatures.OptionWrappedValue); T value = features.DefaultFor<T>(); do { T item; if (flag) { item = ReadWrapped(features, value, serializer); } else { switch (category) { case SerializerFeatures.CategoryScalar: Hint(wireType); item = serializer.Read(ref this, value); break; case SerializerFeatures.CategoryMessage: case SerializerFeatures.CategoryMessageWrappedAtRoot: item = ReadMessage(SerializerFeatures.CategoryRepeated, value, in serializer); break; default: category.ThrowInvalidCategory(); item = default(T); break; } } values.Add(item); } while (TryReadFieldHeader(fieldNumber)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ReadPackedScalar<TSerializer, TList, T>(ref TList list, WireType wireType, in TSerializer serializer) where TSerializer : ISerializer<T> where TList : ICollection<T> { int num = (int)ReadUInt32Varint(Read32VarintMode.Unsigned); if (num == 0) { return; } if (num < 0) { ThrowInvalidLength(num); } int num2; if (wireType <= WireType.Fixed64) { if (wireType == WireType.Variant) { goto IL_00ff; } if (wireType == WireType.Fixed64) { if (num % 8 != 0) { ThrowHelper.ThrowInvalidOperationException("packed length should be multiple of 8"); } num2 = num / 8; goto IL_0065; } } else { if (wireType == WireType.Fixed32) { if (num % 4 != 0) { ThrowHelper.ThrowInvalidOperationException("packed length should be multiple of 4"); } num2 = num / 4; goto IL_0065; } if (wireType == WireType.SignedVariant) { goto IL_00ff; } } ThrowHelper.ThrowInvalidPackedOperationException(WireType, typeof(T)); return; IL_00ff: long num3 = GetPosition() + num; TList val; TSerializer val2; do { _reader.WireType = wireType; ref TList reference = ref list; val = default(TList); if (val == null) { val = reference; reference = ref val; } val2 = serializer; reference.Add(val2.Read(ref this, default(T))); } while (GetPosition() < num3); if (GetPosition() != num3) { ThrowHelper.ThrowInvalidOperationException("over-read packed data"); } return; IL_0065: if ((object)list is List<T> list2) { list2.Capacity = Math.Max(list2.Capacity, list2.Count + Math.Min(num2, 8192)); } for (int i = 0; i < num2; i++) { _reader.WireType = wireType; ref TList reference2 = ref list; val = default(TList); if (val == null) { val = reference2; reference2 = ref val; } val2 = serializer; reference2.Add(val2.Read(ref this, default(T))); } } internal ReadBuffer<T> FillBuffer<TSerializer, T>(SerializerFeatures features, in TSerializer serializer, T initialValue) where TSerializer : ISerializer<T> { PrepareToReadRepeated<T>(ref features, serializer.Features, out var category, out var packed); ReadBuffer<T> list = ReadBuffer<T>.Create(); try { WireType wireType = features.GetWireType(); if (packed) { ReadPackedScalar<TSerializer, ReadBuffer<T>, T>(ref list, wireType, in serializer); } else { ReadRepeatedCore<TSerializer, ReadBuffer<T>, T>(ref list, category, wireType, in serializer, features); } return list; } catch { try { list.Dispose(); } catch { } throw; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ReadBoolean() { return ReadUInt32() != 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ReadUInt64() { switch (_reader.WireType) { case WireType.Variant: return ReadUInt64Varint(); case WireType.Fixed32: return _reader.ImplReadUInt32Fixed(ref this); case WireType.Fixed64: return _reader.ImplReadUInt64Fixed(ref this); default: ThrowWireTypeException(); return 0uL; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte[] AppendBytes(byte[] value) { return AppendBytesImpl(value, DefaultMemoryConverter<byte>.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory<byte> AppendBytes(ReadOnlyMemory<byte> value) { return AppendBytesImpl(value, DefaultMemoryConverter<byte>.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Memory<byte> AppendBytes(Memory<byte> value) { return AppendBytesImpl(value, DefaultMemoryConverter<byte>.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ArraySegment<byte> AppendBytes(ArraySegment<byte> value) { return AppendBytesImpl(value, DefaultMemoryConverter<byte>.Instance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public TStorage AppendBytes<TStorage>(TStorage value, IMemoryConverter<TStorage, byte> converter = null) { return AppendBytesImpl(value, converter ?? DefaultMemoryConverter<byte>.GetFor<TStorage>(Model)); } private TStorage AppendBytesImpl<TStorage>(TStorage value, IMemoryConverter<TStorage, byte> converter) { WireType wireType = _reader.WireType; if (wireType == WireType.String) { int num = (int)ReadUInt32Varint(Read32VarintMode.Signed); _reader.WireType = WireType.None; if (num == 0) { return converter.NonNull(in value); } if (num < 0) { ThrowInvalidLength(num); } Memory<byte> memory = converter.Expand(Context, ref value, num); _reader.ImplReadBytes(ref this, memory.Span); return value; } ThrowWireTypeException(); return default(TStorage); } [Browsable(false)] public Span<byte> ReadBytes(Span<byte> destination) { ReadBytes(destination, out var length); return destination.Slice(0, length); } public void ReadBytes(Span<byte> destination, out int length) { WireType wireType = _reader.WireType; if (wireType == WireType.String) { length = (int)ReadUInt32Varint(Read32VarintMode.Signed); if (length < 0) { ThrowInvalidLength(length); } if (length > destination.Length) { ThrowHelper.ThrowInvalidOperationException($"Insufficient space in the target span to read a string/bytes value; {destination.Length} vs {length} bytes"); } _reader.WireType = WireType.None; destination = destination.Slice(0, length); _reader.ImplReadBytes(ref this, destination); } else { length = 0; ThrowWireTypeException(); } } [MethodImpl(MethodImplOptions.NoInlining)] public SubItemToken StartSubItem() { ProtoReader reader = _reader; switch (_reader.WireType) { case WireType.StartGroup: reader.WireType = WireType.None; if (reader.IncrDepth()) { ThrowTooDeep(); } return new SubItemToken(-reader._fieldNumber); case WireType.String: { long num = (long)ReadUInt64Varint(); if (num < 0) { ThrowInvalidOperationException(); } long blockEnd = reader.blockEnd64; reader.blockEnd64 = reader._longPosition + num; if (reader.IncrDepth()) { ThrowTooDeep(); } return new SubItemToken(blockEnd); } default: ThrowWireTypeException(); return default(SubItemToken); } } [MethodImpl(MethodImplOptions.NoInlining)] public void EndSubItem(SubItemToken token) { long value = token.value64; ProtoReader reader = _reader; WireType wireType = reader.WireType; if (wireType == WireType.EndGroup) { if (value >= 0) { ThrowProtoException("A length-based message was terminated via end-group; this indicates data corruption"); } if (-(int)value != reader._fieldNumber) { ThrowProtoException("Wrong group was ended"); } reader.WireType = WireType.None; reader.DecrDepth(); return; } long longPosition = reader._longPosition; if (value < longPosition) { ThrowProtoException($"Sub-message not read entirely; expected {value}, was {longPosition}"); } if (reader.blockEnd64 != longPosition && reader.blockEnd64 != long.MaxValue) { ThrowProtoException($"Sub-message not read correctly (end {reader.blockEnd64} vs {longPosition})"); } reader.blockEnd64 = value; reader.DecrDepth(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal object ReadObject(object value, Type type) { return ReadTypedObject(value, type); } [MethodImpl(MethodImplOptions.NoInlining)] internal object ReadTypedObject(object value, Type type) { TypeModel model = Model; if (model == null) { ThrowInvalidOperationException("Cannot deserialize sub-objects unless a model is provided"); } if (DynamicStub.TryDeserialize(ObjectScope.WrappedMessage, type, model, ref this, ref value)) { return value; } SubItemToken token = StartSubItem(); if ((object)type == null || !model.TryDeserializeAuxiliaryType(ref this, DataFormat.Default, 1, type, ref value, skipOtherFields: true, asListItem: false, autoCreate: true, insideList: false, null, isRoot: false)) { TypeModel.ThrowUnexpectedType(type, Model); } EndSubItem(token); return value; } internal void SkipAllFields() { while (ReadFieldHeader() > 0) { SkipField(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ReadString(StringMap map = null) { if (_reader.WireType == WireType.String) { int num = (int)ReadUInt32Varint(Read32VarintMode.Unsigned); if (num == 0) { return ""; } if (num < 0) { ThrowInvalidLength(num); } string text = _reader.ImplReadString(ref this, num); if (_reader.InternStrings) { text = _reader.Intern(text); } return text; } ThrowWireTypeException(); return null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private uint ReadUInt32Varint(Read32VarintMode mode) { uint value; int num = _reader.ImplTryReadUInt32VarintWithoutMoving(ref this, mode, out value); if (num <= 0) { if (mode == Read32VarintMode.FieldHeader) { return 0u; } ThrowEoF(); } _reader.ImplSkipBytes(ref this, num); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ulong ReadUInt64Varint() { ulong value; int num = _reader.ImplTryReadUInt64VarintWithoutMoving(ref this, out value); if (num <= 0) { ThrowEoF(); } _reader.ImplSkipBytes(ref this, num); return value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Assert