public void WriteAndReadDouble()
        {
            // Arrange
            const double originalValue = 3.141592;
            LocalUnmanagedMemory local;
            double ret;

            // Act
            using (local = new LocalUnmanagedMemory(MarshalType<double>.Size))
            {
                local.Write(originalValue);
                ret = local.Read<double>();
            }

            // Assert
            Assert.AreEqual(originalValue, ret, "Both values aren't equal.");
            Assert.AreEqual(IntPtr.Zero, local.Address);
        }
Example #2
0
        public void WriteAndReadCustomStruct()
        {
            // Arrange
            var customStruct = Resources.CustomStruct;
            LocalUnmanagedMemory local;
            Point ret;

            // Act
            using (local = new LocalUnmanagedMemory(MarshalType <Point> .Size))
            {
                local.Write(customStruct);
                ret = local.Read <Point>();
            }

            // Assert
            Assert.AreEqual(customStruct, ret, "Both structures aren't equal.");
            Assert.AreEqual(IntPtr.Zero, local.Address);
        }
        public void WriteAndReadCustomStruct()
        {
            // Arrange
            var customStruct = Resources.CustomStruct;
            LocalUnmanagedMemory local;
            Point ret;

            // Act
            using (local = new LocalUnmanagedMemory(MarshalType<Point>.Size))
            {
                local.Write(customStruct);
                ret = local.Read<Point>();
            }

            // Assert
            Assert.AreEqual(customStruct, ret, "Both structures aren't equal.");
            Assert.AreEqual(IntPtr.Zero, local.Address);
        }
Example #4
0
        public void WriteAndReadDouble()
        {
            // Arrange
            const double         originalValue = 3.141592;
            LocalUnmanagedMemory local;
            double ret;

            // Act
            using (local = new LocalUnmanagedMemory(MarshalType <double> .Size))
            {
                local.Write(originalValue);
                ret = local.Read <double>();
            }

            // Assert
            Assert.AreEqual(originalValue, ret, "Both values aren't equal.");
            Assert.AreEqual(IntPtr.Zero, local.Address);
        }
Example #5
0
        /// <summary>
        /// Marshals an array of byte to a managed object.
        /// </summary>
        /// <param name="byteArray">The array of bytes corresponding to a managed object.</param>
        /// <param name="index">[Optional] Where to start the conversion of bytes to the managed object.</param>
        /// <returns>A managed object.</returns>
        public static T ByteArrayToObject(byte[] byteArray, int index = 0)
        {
            // We'll tried to avoid marshalling as it really slows the process
            // First, check if the type can be converted without marshalling
            switch (TypeCode)
            {
            case TypeCode.Object:
                if (IsIntPtr)
                {
                    switch (byteArray.Length)
                    {
                    case 1:
                        return((T)(object)new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[index], 0x0, 0x0, 0x0 }, index)));

                    case 2:
                        return((T)(object)new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[index], byteArray[index + 1], 0x0, 0x0 }, index)));

                    case 4:
                        return((T)(object)new IntPtr(BitConverter.ToInt32(byteArray, index)));

                    case 8:
                        return((T)(object)new IntPtr(BitConverter.ToInt64(byteArray, index)));
                    }
                }
                break;

            case TypeCode.Boolean:
                return((T)(object)BitConverter.ToBoolean(byteArray, index));

            case TypeCode.Byte:
                return((T)(object)byteArray[index]);

            case TypeCode.Char:
                return((T)(object)Encoding.UTF8.GetChars(byteArray)[index]);

            case TypeCode.Double:
                return((T)(object)BitConverter.ToDouble(byteArray, index));

            case TypeCode.Int16:
                return((T)(object)BitConverter.ToInt16(byteArray, index));

            case TypeCode.Int32:
                return((T)(object)BitConverter.ToInt32(byteArray, index));

            case TypeCode.Int64:
                return((T)(object)BitConverter.ToInt64(byteArray, index));

            case TypeCode.Single:
                return((T)(object)BitConverter.ToSingle(byteArray, index));

            case TypeCode.String:
                throw new InvalidCastException("This method doesn't support string conversion.");

            case TypeCode.UInt16:
                return((T)(object)BitConverter.ToUInt16(byteArray, index));

            case TypeCode.UInt32:
                return((T)(object)BitConverter.ToUInt32(byteArray, index));

            case TypeCode.UInt64:
                return((T)(object)BitConverter.ToUInt64(byteArray, index));
            }

            // Allocate a block of unmanaged memory
            using (var unmanaged = new LocalUnmanagedMemory(Size))
            {
                // Write the array of bytes inside the unmanaged memory
                unmanaged.Write(byteArray, index);

                // Return a managed object created from the block of unmanaged memory
                return(unmanaged.Read <T>());
            }
        }
Example #6
0
        /// <summary>
        /// Marshals a managed object to an array of bytes.
        /// </summary>
        /// <param name="obj">The object to marshal.</param>
        /// <returns>A array of bytes corresponding to the managed object.</returns>
        public static byte[] ObjectToByteArray(T obj)
        {
            // We'll tried to avoid marshalling as it really slows the process
            // First, check if the type can be converted without marhsalling
            switch (TypeCode)
            {
            case TypeCode.Object:
                if (IsIntPtr)
                {
                    switch (Size)
                    {
                    case 4:
                        return(BitConverter.GetBytes(((IntPtr)(object)obj).ToInt32()));

                    case 8:
                        return(BitConverter.GetBytes(((IntPtr)(object)obj).ToInt64()));
                    }
                }
                break;

            case TypeCode.Boolean:
                return(BitConverter.GetBytes((bool)(object)obj));

            case TypeCode.Char:
                return(Encoding.UTF8.GetBytes(new[] { (char)(object)obj }));

            case TypeCode.Double:
                return(BitConverter.GetBytes((double)(object)obj));

            case TypeCode.Int16:
                return(BitConverter.GetBytes((short)(object)obj));

            case TypeCode.Int32:
                return(BitConverter.GetBytes((int)(object)obj));

            case TypeCode.Int64:
                return(BitConverter.GetBytes((long)(object)obj));

            case TypeCode.Single:
                return(BitConverter.GetBytes((float)(object)obj));

            case TypeCode.String:
                throw new InvalidCastException("This method doesn't support string conversion.");

            case TypeCode.UInt16:
                return(BitConverter.GetBytes((ushort)(object)obj));

            case TypeCode.UInt32:
                return(BitConverter.GetBytes((uint)(object)obj));

            case TypeCode.UInt64:
                return(BitConverter.GetBytes((ulong)(object)obj));
            }
            // Check if it's not a common type
            // Allocate a block of unmanaged memory
            using (var unmanaged = new LocalUnmanagedMemory(Size))
            {
                // Write the object inside the unmanaged memory
                unmanaged.Write(obj);
                // Return the content of the block of unmanaged memory
                return(unmanaged.Read());
            }
        }
Example #7
0
        /// <summary>
        ///     Marshals an array of byte to a managed object.
        /// </summary>
        /// <param name="byteArray">The array of bytes corresponding to a managed object.</param>
        /// <returns>A managed object.</returns>
        public unsafe static T ByteArrayToObject(byte[] byteArray)
        {
            var requiresMarshal = MarshalCache <T> .TypeRequiresMarshal;
            var size            = requiresMarshal ? MarshalCache <T> .Size : Unsafe.SizeOf <T>();

            fixed(byte *b = byteArray)
            {
                if (requiresMarshal)
                {
                    return(Marshal.PtrToStructure <T>(new IntPtr(b)));
                }

                return(Unsafe.Read <T>(b));
            }

#if false
            // We'll tried to avoid marshalling as it really slows the process
            // First, check if the type can be converted without marhsalling
            switch (TypeCode)
            {
            case TypeCode.Object:
                if (IsIntPtr)
                {
                    switch (byteArray.Length)
                    {
                    case 1:
                        return
                            ((T)
                             (object)
                             new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[0], 0x0, 0x0, 0x0 }, 0)));

                    case 2:
                        return
                            ((T)
                             (object)
                             new IntPtr(
                                 BitConverter.ToInt32(new byte[] { byteArray[0], byteArray[1], 0x0, 0x0 },
                                                      0)));

                    case 4:
                        return((T)(object)new IntPtr(BitConverter.ToInt32(byteArray, 0)));

                    case 8:
                        return((T)(object)new IntPtr(BitConverter.ToInt64(byteArray, 0)));
                    }
                }
                break;

            case TypeCode.Boolean:
                return((T)(object)BitConverter.ToBoolean(byteArray, 0));

            case TypeCode.Byte:
                return((T)(object)byteArray[0]);

            case TypeCode.Char:
                return((T)(object)Encoding.UTF8.GetChars(byteArray)[0]);      //BitConverter.ToChar(byteArray, 0);

            case TypeCode.Double:
                return((T)(object)BitConverter.ToDouble(byteArray, 0));

            case TypeCode.Int16:
                return((T)(object)BitConverter.ToInt16(byteArray, 0));

            case TypeCode.Int32:
                return((T)(object)BitConverter.ToInt32(byteArray, 0));

            case TypeCode.Int64:
                return((T)(object)BitConverter.ToInt64(byteArray, 0));

            case TypeCode.Single:
                return((T)(object)BitConverter.ToSingle(byteArray, 0));

            case TypeCode.String:
                throw new InvalidCastException("This method doesn't support string conversion.");

            case TypeCode.UInt16:
                return((T)(object)BitConverter.ToUInt16(byteArray, 0));

            case TypeCode.UInt32:
                return((T)(object)BitConverter.ToUInt32(byteArray, 0));

            case TypeCode.UInt64:
                return((T)(object)BitConverter.ToUInt64(byteArray, 0));
            }
            // Check if it's not a common type
            // Allocate a block of unmanaged memory
            using (var unmanaged = new LocalUnmanagedMemory(Size))
            {
                // Write the array of bytes inside the unmanaged memory
                unmanaged.Write(byteArray);
                // Return a managed object created from the block of unmanaged memory
                return(unmanaged.Read <T>());
            }
#endif
        }
Example #8
0
        /// <summary>
        ///     Marshals an array of byte to a managed object.
        /// </summary>
        /// <param name="byteArray">The array of bytes corresponding to a managed object.</param>
        /// <returns>A managed object.</returns>
        public static T ByteArrayToObject(byte[] byteArray)
        {
            // We'll tried to avoid marshalling as it really slows the process
            // First, check if the type can be converted without marshalling
            switch (TypeCode)
            {
            case TypeCode.Object:
                if (IsIntPtr)
                {
                    switch (byteArray.Length)
                    {
                    case 1:
                        return
                            ((T)
                             (object)
                             new IntPtr(BitConverter.ToInt32(new byte[] { byteArray[0], 0x0, 0x0, 0x0 }, 0)));

                    case 2:
                        return
                            ((T)
                             (object)
                             new IntPtr(
                                 BitConverter.ToInt32(new byte[] { byteArray[0], byteArray[1], 0x0, 0x0 },
                                                      0)));

                    case 4:
                        return((T)(object)new IntPtr(BitConverter.ToInt32(byteArray, 0)));

                    case 8:
                        return((T)(object)new IntPtr(BitConverter.ToInt64(byteArray, 0)));
                    }
                }

                break;

            case TypeCode.Boolean:
                return((T)(object)BitConverter.ToBoolean(byteArray, 0));

            case TypeCode.Byte:
                return((T)(object)byteArray[0]);

            case TypeCode.Char:
                return((T)(object)Encoding.UTF8.GetChars(byteArray)[0]);      //BitConverter.ToChar(byteArray, 0);

            case TypeCode.Double:
                return((T)(object)BitConverter.ToDouble(byteArray, 0));

            case TypeCode.Int16:
                return((T)(object)BitConverter.ToInt16(byteArray, 0));

            case TypeCode.Int32:
                return((T)(object)BitConverter.ToInt32(byteArray, 0));

            case TypeCode.Int64:
                return((T)(object)BitConverter.ToInt64(byteArray, 0));

            case TypeCode.Single:
                return((T)(object)BitConverter.ToSingle(byteArray, 0));

            case TypeCode.String:
                throw new InvalidCastException("This method doesn't support string conversion.");

            case TypeCode.UInt16:
                return((T)(object)BitConverter.ToUInt16(byteArray, 0));

            case TypeCode.UInt32:
                return((T)(object)BitConverter.ToUInt32(byteArray, 0));

            case TypeCode.UInt64:
                return((T)(object)BitConverter.ToUInt64(byteArray, 0));

            case TypeCode.Decimal:
                return((T)(object)BitConverter.ToDouble(byteArray, 0));

            case TypeCode.SByte:
                return((T)(object)BitConverter.ToChar(byteArray, 0));

            case TypeCode.DateTime:
                throw new InvalidCastException(
                          "This method doesn't support DateTime conversion. Use .ToBinary() to store as Int64.");

            case TypeCode.DBNull:
                throw new InvalidCastException("This method doesn't support null conversion.");

            case TypeCode.Empty:
                throw new InvalidCastException("This method doesn't support empty object conversion.");

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Check if it's not a common type
            // Allocate a block of unmanaged memory
            using var unmanaged = new LocalUnmanagedMemory(Size);

            // Write the array of bytes inside the unmanaged memory
            unmanaged.Write(byteArray);
            // Return a managed object created from the block of unmanaged memory
            return(unmanaged.Read <T>());
        }