Ejemplo n.º 1
0
        private static uint OffsetOfByDynamic(FieldInfo fieldInfo)
        {
            if (fieldOffsetCache == null)
            {
                lock (lockObject)
                {
                    if (fieldOffsetCache == null)
                    {
                        fieldOffsetCache     = new IdCache <uint>();
                        fieldOffsetCacheLock = new object();
                    }
                }
            }

            var fieldId = (long)fieldInfo.FieldHandle.Value;

            if (fieldOffsetCache.TryGetValue(fieldId, out uint offset))
            {
                return(offset);
            }

            lock (fieldOffsetCacheLock)
            {
                if (fieldOffsetCache.TryGetValue(fieldId, out offset))
                {
                    return(offset);
                }

                GetAllFieldOffsetByDynamic(fieldInfo.DeclaringType);

                return(fieldOffsetCache[fieldId]);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 获取类型的静态内存地址位置。
        /// </summary>
        /// <param name="type">类型信息</param>
        /// <returns>返回内存地址。</returns>
        public static IntPtr GetTypeStaticMemoryAddress(Type type)
        {
            if (StaticFieldAddressCache == null)
            {
                lock (typeof(TypeHelper))
                {
                    if (StaticFieldAddressCache == null)
                    {
                        StaticFieldAddressCache     = new IdCache <IntPtr>();
                        StaticFieldAddressCacheLock = new object();
                    }
                }
            }

            var typeId = (long)GetTypeHandle(type);

            if (StaticFieldAddressCache.TryGetValue(typeId, out var value))
            {
                return(value);
            }

            lock (StaticFieldAddressCacheLock)
            {
                if (StaticFieldAddressCache.TryGetValue(typeId, out value))
                {
                    return(value);
                }

                value = GetTypeStaticMemoryAddressByDynamic(type);

                StaticFieldAddressCache.Add(typeId, value);

                return(value);
            }
        }
Ejemplo n.º 3
0
        public static bool IsEmptyValue(object value)
        {
            if (value == null)
            {
                return(true);
            }

            if (defaultValues == null)
            {
                lock (lockObject)
                {
                    if (defaultValues == null)
                    {
                        defaultValues = new IdCache <object>();
                    }
                }
            }

            if (defaultValues.TryGetValue((long)Pointer.GetTypeHandle(value), out var default_value))
            {
                return(RuntimeHelpers.Equals(value, default_value));
            }

            lock (defaultValues)
            {
                var objectHandle = (long)Pointer.GetTypeHandle(value);

                if (!defaultValues.TryGetValue(objectHandle, out default_value))
                {
                    var type = value.GetType();

                    if (type.IsValueType)
                    {
                        default_value = Activator.CreateInstance(type);
                    }
                    else
                    {
                        default_value = null;
                    }

                    defaultValues.DirectAdd(objectHandle, default_value);
                }
            }

            return(RuntimeHelpers.Equals(value, default_value));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 获取一个类型占用的内存大小。如果是 Class 则不包括 ObjectHandle 的大小。
        /// </summary>
        /// <param name="type">类型信息</param>
        /// <returns>返回内存大小。</returns>
        public unsafe static uint SizeOf(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (type is TypeBuilder)
            {
                throw new ArgumentException("Unable get size of a TypeBuilder.", nameof(type));
            }

            if (type.IsGenericTypeDefinition)
            {
                throw new ArgumentException("Unable get size of a generic definition type.", nameof(type));
            }

            if (type.IsGenericTypeDefinition)
            {
                return(0);
            }

            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Boolean:
                return(sizeof(bool));

            case TypeCode.Char:
                return(sizeof(char));

            case TypeCode.SByte:
                return(sizeof(sbyte));

            case TypeCode.Byte:
                return(sizeof(byte));

            case TypeCode.Int16:
                return(sizeof(short));

            case TypeCode.UInt16:
                return(sizeof(ushort));

            case TypeCode.Int32:
                return(sizeof(int));

            case TypeCode.UInt32:
                return(sizeof(uint));

            case TypeCode.Int64:
                return(sizeof(long));

            case TypeCode.UInt64:
                return(sizeof(ulong));

            case TypeCode.Single:
                return(sizeof(float));

            case TypeCode.Double:
                return(sizeof(double));

            case TypeCode.Decimal:
                return(sizeof(decimal));

            case TypeCode.DateTime:
                return((uint)sizeof(DateTime));
            }

            if (type.IsPointer ||
                type.IsInterface ||
                type.IsByRef ||
                typeof(object) == type ||
                typeof(IntPtr) == type)
            {
                return((uint)IntPtr.Size);
            }

            if (typeSizeCache == null)
            {
                lock (lockObject)
                {
                    if (typeSizeCache == null)
                    {
                        typeSizeCache     = new IdCache <uint>();
                        typeSizeCacheLock = new object();
                    }

                    var sizeOfHelperMethod = typeof(Marshal).GetMethod(MarshalSizeOfHelperName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

                    if (sizeOfHelperMethod != null)
                    {
                        sizeOfHelper = MethodHelper.CreateDelegate <SizeOfHelperDelegate>(sizeOfHelperMethod, SignatureLevels.Cast);
                    }

                    pointerSizeOfMethod = typeof(Pointer).GetMethod(nameof(Pointer.SizeOf), Type.EmptyTypes);
                }
            }

            if (type.IsValueType)
            {
                if (sizeOfHelper != null)
                {
                    return((uint)sizeOfHelper(type, false));
                }

                try
                {
                    return((uint)Marshal.SizeOf(type));
                }
                catch (Exception)
                {
                }
            }

            var typeId = (long)type.TypeHandle.Value;

            if (typeSizeCache.TryGetValue(typeId, out uint size))
            {
                return(size);
            }

            lock (typeSizeCacheLock)
            {
                if (typeSizeCache.TryGetValue(typeId, out size))
                {
                    return(size);
                }

                if (type.IsValueType)
                {
                    size = (uint)pointerSizeOfMethod.MakeGenericMethod(type).Invoke(null, null);
                }
                else
                {
                    var fields = type.GetFields(BindingFlags.NonPublic |
                                                BindingFlags.Public |
                                                BindingFlags.Instance |
                                                BindingFlags.DeclaredOnly);

                    if (fields.Length == 0)
                    {
                        size = (uint)IntPtr.Size;
                    }
                    else
                    {
                        int right              = fields.Length - 1;
                        var maxOffset          = OffsetOf(fields[right]);
                        var maxOffsetFieldType = fields[right].FieldType;

                        while (right > 0)
                        {
                            --right;

                            var offset = OffsetOf(fields[right]);

                            if (offset > maxOffset)
                            {
                                maxOffset          = offset;
                                maxOffsetFieldType = fields[right].FieldType;
                            }
                        }

                        // = last field offset + last field size + type handle size;
                        size = maxOffset + (maxOffsetFieldType.IsValueType ? SizeOf(maxOffsetFieldType) : (uint)IntPtr.Size) + ((uint)IntPtr.Size);
                    }
                }

                typeSizeCache[typeId] = size;
            }

            return(size);
        }
Ejemplo n.º 5
0
        static SConvert()
        {
            Cache = new IdCache <ISConvert <TSource> >();

            CacheLock = new object();
        }
Ejemplo n.º 6
0
        static DConvert()
        {
            Cache = new IdCache <IDConvert <TDestination> >();

            CacheLock = new object();
        }