Example #1
0
		private T ReadInternal<T>(IntPtr address) where T : struct
		{
			var type = MarshalCache<T>.RealType;

			if (!MarshalCache<T>.TypeRequiresMarshal)
			{
				var val = default(T);
				// If the (value) type doesn't require marshalling, we can simply use MoveMemory to move the entire
				// thing in one swoop. This is significantly faster than having it go through the Marshal.
				var ptr = MarshalCache<T>.GetUnsafePtr(ref val);
				MoveMemory(ptr, (void*) address, MarshalCache<T>.Size);

				return val;
			}

			// Have the marshal deal with it for now.
			return Marshal.PtrToStructure<T>(address);

			// Scrapped until it can be properly unit tested.

			//object ret = null;
			//var typeCode = Type.GetTypeCode(type);

			//// Special case simple value types:
			//// - Boolean
			//// - Byte, SByte
			//// - Char
			//// - Decimal
			//// - Int32, UInt32
			//// - Int64, UInt64
			//// - Int16, UInt16
			//// - IntPtr, UIntPtr
			//// As of .NET 4.5, the (Type)(object)result pattern used below
			//// is recognized and optimized by both 32-bit and 64-bit JITs.
			//// Therefore, do not change this to a switch - JIT won't apply same optimization (it won't box!).
			//if (typeCode == TypeCode.Boolean)
			//	ret = *(byte*)address != 0;
			//if (typeCode == TypeCode.Byte)
			//	ret = *(byte*)address;
			//if (typeCode == TypeCode.SByte)
			//	ret = *(sbyte*)address;
			//if (typeCode == TypeCode.Char)
			//	ret = *(char*)address;
			//if (typeCode == TypeCode.Decimal)
			//	ret = *(decimal*)address;
			//if (typeCode == TypeCode.Int32)
			//	ret = *(int*)address;
			//if (typeCode == TypeCode.UInt32)
			//	ret = *(uint*)address;
			//if (typeCode == TypeCode.Int64)
			//	ret = *(long*)address;
			//if (typeCode == TypeCode.UInt64)
			//	ret = *(ulong*)address;
			//if (typeCode == TypeCode.Int16)
			//	ret = *(short*)address;
			//if (typeCode == TypeCode.UInt16)
			//	ret = *(ushort*)address;

			//return (T)ret;
		}
Example #2
0
        public static unsafe T Read <T>(this IntPtr address)
        {
            try
            {
                if (address == IntPtr.Zero)
                {
                    throw new InvalidOperationException("Cannot retrieve a value at address 0");
                }
                object ptrToStructure;
                switch (MarshalCache <T> .TypeCode)
                {
                case TypeCode.Object:
                    if (MarshalCache <T> .RealType == typeof(IntPtr))
                    {
                        return((T)(object)*(IntPtr *)address);
                    }
                    if (!MarshalCache <T> .TypeRequiresMarshal)
                    {
                        T     obj = default(T);
                        void *ptr = MarshalCache <T> .GetUnsafePtr(ref obj);

                        Kernel32.MoveMemory(ptr, (void *)address, MarshalCache <T> .Size);
                        return(obj);
                    }
                    ptrToStructure = Marshal.PtrToStructure(address, typeof(T));
                    break;

                case TypeCode.Boolean: ptrToStructure = *(byte *)address != 0; break;

                case TypeCode.Char: ptrToStructure = *(char *)address; break;

                case TypeCode.SByte: ptrToStructure = *(sbyte *)address; break;

                case TypeCode.Byte: ptrToStructure = *(byte *)address; break;

                case TypeCode.Int16: ptrToStructure = *(short *)address; break;

                case TypeCode.UInt16: ptrToStructure = *(ushort *)address; break;

                case TypeCode.Int32: ptrToStructure = *(int *)address; break;

                case TypeCode.UInt32: ptrToStructure = *(uint *)address; break;

                case TypeCode.Int64: ptrToStructure = *(long *)address; break;

                case TypeCode.UInt64: ptrToStructure = *(ulong *)address; break;

                case TypeCode.Single: ptrToStructure = *(float *)address; break;

                case TypeCode.Double: ptrToStructure = *(double *)address; break;

                default: throw new ArgumentOutOfRangeException();
                }
                return((T)ptrToStructure);
            }
            catch (AccessViolationException) { return(default(T)); }
        }
Example #3
0
        private T ReadInternal <T>(IntPtr address) where T : struct
        {
            var type = MarshalCache <T> .RealType;

            if (!MarshalCache <T> .TypeRequiresMarshal)
            {
                var val = default(T);
                // If the (value) type doesn't require marshalling, we can simply use MoveMemory to move the entire
                // thing in one swoop. This is significantly faster than having it go through the Marshal.
                var ptr = MarshalCache <T> .GetUnsafePtr(ref val);

                MoveMemory(ptr, (void *)address, MarshalCache <T> .Size);

                return(val);
            }

            return(Marshal.PtrToStructure <T>(address));
        }
Example #4
0
        public static unsafe T Read <T>(this IntPtr address)
        {
            try
            {
                // It may be worth it to simply use memcpy to avoid it, but I doubt thats going to give any noticeable increase in speed.
                if (address == IntPtr.Zero)
                {
                    throw new InvalidOperationException("Cannot retrieve a value at address 0");
                }

                object ptrToStructure;
                // ReSharper disable once SwitchStatementMissingSomeCases
                switch (MarshalCache <T> .TypeCode)
                {
                case TypeCode.Object:

                    if (MarshalCache <T> .RealType == typeof(IntPtr))
                    {
                        return((T)(object)*(IntPtr *)address);
                    }

                    // If the type doesn't require an explicit Marshal call, then ignore it and memcpy the thing.
                    if (!MarshalCache <T> .TypeRequiresMarshal)
                    {
                        var o   = default(T);
                        var ptr = MarshalCache <T> .GetUnsafePtr(ref o);

                        Kernel32.MoveMemory(ptr, (void *)address, MarshalCache <T> .Size);

                        return(o);
                    }

                    // All System.Object's require marshaling!
                    ptrToStructure = Marshal.PtrToStructure(address, typeof(T));
                    break;

                case TypeCode.Boolean:
                    ptrToStructure = *(byte *)address != 0;
                    break;

                case TypeCode.Char:
                    ptrToStructure = *(char *)address;
                    break;

                case TypeCode.SByte:
                    ptrToStructure = *(sbyte *)address;
                    break;

                case TypeCode.Byte:
                    ptrToStructure = *(byte *)address;
                    break;

                case TypeCode.Int16:
                    ptrToStructure = *(short *)address;
                    break;

                case TypeCode.UInt16:
                    ptrToStructure = *(ushort *)address;
                    break;

                case TypeCode.Int32:
                    ptrToStructure = *(int *)address;
                    break;

                case TypeCode.UInt32:
                    ptrToStructure = *(uint *)address;
                    break;

                case TypeCode.Int64:
                    ptrToStructure = *(long *)address;
                    break;

                case TypeCode.UInt64:
                    ptrToStructure = *(ulong *)address;
                    break;

                case TypeCode.Single:
                    ptrToStructure = *(float *)address;
                    break;

                case TypeCode.Double:
                    ptrToStructure = *(double *)address;
                    break;

                case TypeCode.Decimal:
                    // Probably safe to remove this. I'm unaware of anything that actually uses "decimal" that would require memory reading...
                    ptrToStructure = *(decimal *)address;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                return((T)ptrToStructure);
            }
            catch (AccessViolationException ex)
            {
                Trace.WriteLine("Access Violation on " + address + " with type " + typeof(T).Name +
                                Environment.NewLine +
                                ex);
                return(default);
Example #5
0
        private T InternalRead <T>(IntPtr address) where T : struct
        {
            try
            {
                if (address == IntPtr.Zero)
                {
                    throw new InvalidOperationException("Cannot retrieve a value at address 0");
                }

                object returnValue;
                switch (MarshalCache <T> .TypeCode)
                {
                case TypeCode.Object:

                    if (MarshalCache <T> .RealType == typeof(IntPtr))
                    {
                        return((T)(object)*(IntPtr *)address);
                    }

                    if (!MarshalCache <T> .TypeRequiresMarshal)
                    {
                        T     o   = default(T);
                        void *ptr = MarshalCache <T> .GetUnsafePtr(ref o);

                        NativeMethods.MoveMemory(ptr, (void *)address, MarshalCache <T> .Size);
                        return(o);
                    }
                    // All System.Object's require marshaling!
                    returnValue = Marshal.PtrToStructure(address, typeof(T));
                    break;

                case TypeCode.SByte:
                    returnValue = *(sbyte *)address;
                    break;

                case TypeCode.Byte:
                    returnValue = *(byte *)address;
                    break;

                case TypeCode.Int16:
                    returnValue = *(short *)address;
                    break;

                case TypeCode.UInt16:
                    returnValue = *(ushort *)address;
                    break;

                case TypeCode.Int32:
                    returnValue = *(int *)address;
                    break;

                case TypeCode.UInt32:
                    returnValue = *(uint *)address;
                    break;

                case TypeCode.Int64:
                    returnValue = *(long *)address;
                    break;

                case TypeCode.UInt64:
                    returnValue = *(ulong *)address;
                    break;

                case TypeCode.Single:
                    returnValue = *(float *)address;
                    break;

                case TypeCode.Double:
                    returnValue = *(double *)address;
                    break;

                case TypeCode.Decimal:
                    returnValue = *(decimal *)address;
                    break;

                case TypeCode.Boolean:
                    returnValue = *(byte *)address != 0;
                    break;

                case TypeCode.Char:
                    returnValue = *(char *)address;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                return((T)returnValue);
            }
            catch (AccessViolationException)
            {
                return(default(T));
            }
        }