summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs')
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs252
1 files changed, 0 insertions, 252 deletions
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
deleted file mode 100644
index 3ea781252f..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
+++ /dev/null
@@ -1,252 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
-
-#if !ES_BUILD_AGAINST_DOTNET_V35
-using Contract = System.Diagnostics.Contracts.Contract;
-#else
-using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
-#endif
-
-namespace System.Diagnostics.Tracing
-{
- /// <summary>
- /// Holds property values of any type. For common value types, we have inline storage so that we don't need
- /// to box the values. For all other types, we store the value in a single object reference field.
- ///
- /// To get the value of a property quickly, use a delegate produced by <see cref="PropertyValue.GetPropertyGetter(PropertyInfo)"/>.
- /// </summary>
- internal unsafe struct PropertyValue
- {
- /// <summary>
- /// Union of well-known value types, to avoid boxing those types.
- /// </summary>
- [StructLayout(LayoutKind.Explicit)]
- public struct Scalar
- {
- [FieldOffset(0)]
- public Boolean AsBoolean;
- [FieldOffset(0)]
- public Byte AsByte;
- [FieldOffset(0)]
- public SByte AsSByte;
- [FieldOffset(0)]
- public Char AsChar;
- [FieldOffset(0)]
- public Int16 AsInt16;
- [FieldOffset(0)]
- public UInt16 AsUInt16;
- [FieldOffset(0)]
- public Int32 AsInt32;
- [FieldOffset(0)]
- public UInt32 AsUInt32;
- [FieldOffset(0)]
- public Int64 AsInt64;
- [FieldOffset(0)]
- public UInt64 AsUInt64;
- [FieldOffset(0)]
- public IntPtr AsIntPtr;
- [FieldOffset(0)]
- public UIntPtr AsUIntPtr;
- [FieldOffset(0)]
- public Single AsSingle;
- [FieldOffset(0)]
- public Double AsDouble;
- [FieldOffset(0)]
- public Guid AsGuid;
- [FieldOffset(0)]
- public DateTime AsDateTime;
- [FieldOffset(0)]
- public DateTimeOffset AsDateTimeOffset;
- [FieldOffset(0)]
- public TimeSpan AsTimeSpan;
- [FieldOffset(0)]
- public Decimal AsDecimal;
- }
-
- // Anything not covered by the Scalar union gets stored in this reference.
- readonly object _reference;
- readonly Scalar _scalar;
- readonly int _scalarLength;
-
- private PropertyValue(object value)
- {
- _reference = value;
- _scalar = default(Scalar);
- _scalarLength = 0;
- }
-
- private PropertyValue(Scalar scalar, int scalarLength)
- {
- _reference = null;
- _scalar = scalar;
- _scalarLength = scalarLength;
- }
-
- private PropertyValue(Boolean value) : this(new Scalar() { AsBoolean = value }, sizeof(Boolean)) { }
- private PropertyValue(Byte value) : this(new Scalar() { AsByte = value }, sizeof(Byte)) { }
- private PropertyValue(SByte value) : this(new Scalar() { AsSByte = value }, sizeof(SByte)) { }
- private PropertyValue(Char value) : this(new Scalar() { AsChar = value }, sizeof(Char)) { }
- private PropertyValue(Int16 value) : this(new Scalar() { AsInt16 = value }, sizeof(Int16)) { }
- private PropertyValue(UInt16 value) : this(new Scalar() { AsUInt16 = value }, sizeof(UInt16)) { }
- private PropertyValue(Int32 value) : this(new Scalar() { AsInt32 = value }, sizeof(Int32)) { }
- private PropertyValue(UInt32 value) : this(new Scalar() { AsUInt32 = value }, sizeof(UInt32)) { }
- private PropertyValue(Int64 value) : this(new Scalar() { AsInt64 = value }, sizeof(Int64)) { }
- private PropertyValue(UInt64 value) : this(new Scalar() { AsUInt64 = value }, sizeof(UInt64)) { }
- private PropertyValue(IntPtr value) : this(new Scalar() { AsIntPtr = value }, sizeof(IntPtr)) { }
- private PropertyValue(UIntPtr value) : this(new Scalar() { AsUIntPtr = value }, sizeof(UIntPtr)) { }
- private PropertyValue(Single value) : this(new Scalar() { AsSingle = value }, sizeof(Single)) { }
- private PropertyValue(Double value) : this(new Scalar() { AsDouble = value }, sizeof(Double)) { }
- private PropertyValue(Guid value) : this(new Scalar() { AsGuid = value }, sizeof(Guid)) { }
- private PropertyValue(DateTime value) : this(new Scalar() { AsDateTime = value }, sizeof(DateTime)) { }
- private PropertyValue(DateTimeOffset value) : this(new Scalar() { AsDateTimeOffset = value }, sizeof(DateTimeOffset)) { }
- private PropertyValue(TimeSpan value) : this(new Scalar() { AsTimeSpan = value }, sizeof(TimeSpan)) { }
- private PropertyValue(Decimal value) : this(new Scalar() { AsDecimal = value }, sizeof(Decimal)) { }
-
- public static Func<object, PropertyValue> GetFactory(Type type)
- {
- if (type == typeof(Boolean)) return value => new PropertyValue((Boolean)value);
- if (type == typeof(Byte)) return value => new PropertyValue((Byte)value);
- if (type == typeof(SByte)) return value => new PropertyValue((SByte)value);
- if (type == typeof(Char)) return value => new PropertyValue((Char)value);
- if (type == typeof(Int16)) return value => new PropertyValue((Int16)value);
- if (type == typeof(UInt16)) return value => new PropertyValue((UInt16)value);
- if (type == typeof(Int32)) return value => new PropertyValue((Int32)value);
- if (type == typeof(UInt32)) return value => new PropertyValue((UInt32)value);
- if (type == typeof(Int64)) return value => new PropertyValue((Int64)value);
- if (type == typeof(UInt64)) return value => new PropertyValue((UInt64)value);
- if (type == typeof(IntPtr)) return value => new PropertyValue((IntPtr)value);
- if (type == typeof(UIntPtr)) return value => new PropertyValue((UIntPtr)value);
- if (type == typeof(Single)) return value => new PropertyValue((Single)value);
- if (type == typeof(Double)) return value => new PropertyValue((Double)value);
- if (type == typeof(Guid)) return value => new PropertyValue((Guid)value);
- if (type == typeof(DateTime)) return value => new PropertyValue((DateTime)value);
- if (type == typeof(DateTimeOffset)) return value => new PropertyValue((DateTimeOffset)value);
- if (type == typeof(TimeSpan)) return value => new PropertyValue((TimeSpan)value);
- if (type == typeof(Decimal)) return value => new PropertyValue((Decimal)value);
-
- return value => new PropertyValue(value);
- }
-
-
- public object ReferenceValue
- {
- get
- {
- Debug.Assert(_scalarLength == 0, "This ReflectedValue refers to an unboxed value type, not a reference type or boxed value type.");
- return _reference;
- }
- }
-
- public Scalar ScalarValue
- {
- get
- {
- Debug.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
- return _scalar;
- }
- }
-
- public int ScalarLength
- {
- get
- {
- Debug.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
- return _scalarLength;
- }
- }
-
- /// <summary>
- /// Gets a delegate that gets the value of a given property.
- /// </summary>
- public static Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
- {
- if (property.DeclaringType.GetTypeInfo().IsValueType)
- return GetBoxedValueTypePropertyGetter(property);
- else
- return GetReferenceTypePropertyGetter(property);
- }
-
- /// <summary>
- /// Gets a delegate that gets the value of a property of a value type. We unfortunately cannot avoid boxing the value type,
- /// without making this generic over the value type. That would result in a large number of generic instantiations, and furthermore
- /// does not work correctly on .Net Native (we cannot express the needed instantiations in an rd.xml file). We expect that user-defined
- /// value types will be rare, and in any case the boxing only happens for events that are actually enabled.
- /// </summary>
- private static Func<PropertyValue, PropertyValue> GetBoxedValueTypePropertyGetter(PropertyInfo property)
- {
- var type = property.PropertyType;
-
- if (type.GetTypeInfo().IsEnum)
- type = Enum.GetUnderlyingType(type);
-
- var factory = GetFactory(type);
-
- return container => factory(property.GetValue(container.ReferenceValue));
- }
-
- /// <summary>
- /// For properties of reference types, we use a generic helper class to get the value. This enables us to use MethodInfo.CreateDelegate
- /// to build a fast getter. We can get away with this on .Net Native, because we really only need one runtime instantiation of the
- /// generic type, since it's only instantiated over reference types (and thus all instances are shared).
- /// </summary>
- /// <param name="property"></param>
- /// <returns></returns>
- private static Func<PropertyValue, PropertyValue> GetReferenceTypePropertyGetter(PropertyInfo property)
- {
- var helper = (TypeHelper)Activator.CreateInstance(typeof(ReferenceTypeHelper<>).MakeGenericType(property.DeclaringType));
- return helper.GetPropertyGetter(property);
- }
-
- private abstract class TypeHelper
- {
- public abstract Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property);
-
- protected Delegate GetGetMethod(PropertyInfo property, Type propertyType)
- {
- return property.GetMethod.CreateDelegate(typeof(Func<,>).MakeGenericType(property.DeclaringType, propertyType));
- }
- }
-
- private sealed class ReferenceTypeHelper<TContainer> : TypeHelper where TContainer : class
- {
- public override Func<PropertyValue, PropertyValue> GetPropertyGetter(PropertyInfo property)
- {
- var type = property.PropertyType;
-
- if (!Statics.IsValueType(type))
- {
- var getter = (Func<TContainer, object>)GetGetMethod(property, type);
- return container => new PropertyValue(getter((TContainer)container.ReferenceValue));
- }
- else
- {
- if (type.GetTypeInfo().IsEnum)
- type = Enum.GetUnderlyingType(type);
-
- if (type == typeof(Boolean)) { var f = (Func<TContainer, Boolean>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Byte)) { var f = (Func<TContainer, Byte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(SByte)) { var f = (Func<TContainer, SByte>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Char)) { var f = (Func<TContainer, Char>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Int16)) { var f = (Func<TContainer, Int16>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(UInt16)) { var f = (Func<TContainer, UInt16>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Int32)) { var f = (Func<TContainer, Int32>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(UInt32)) { var f = (Func<TContainer, UInt32>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Int64)) { var f = (Func<TContainer, Int64>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(UInt64)) { var f = (Func<TContainer, UInt64>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(IntPtr)) { var f = (Func<TContainer, IntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(UIntPtr)) { var f = (Func<TContainer, UIntPtr>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Single)) { var f = (Func<TContainer, Single>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Double)) { var f = (Func<TContainer, Double>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Guid)) { var f = (Func<TContainer, Guid>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(DateTime)) { var f = (Func<TContainer, DateTime>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(DateTimeOffset)) { var f = (Func<TContainer, DateTimeOffset>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(TimeSpan)) { var f = (Func<TContainer, TimeSpan>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
- if (type == typeof(Decimal)) { var f = (Func<TContainer, Decimal>)GetGetMethod(property, type); return container => new PropertyValue(f((TContainer)container.ReferenceValue)); }
-
- return container => new PropertyValue(property.GetValue(container.ReferenceValue));
- }
- }
- }
- }
-}