public DowncastingMemoryBlockAccess(MemoryBlock <T> array)
        {
            _array = array;

            if (!PointerHelpers.IsPrimitiveIntegerType(typeof(T)))
            {
                throw new ArgumentException("DowncastingMemoryBlockAccess can only cast to primitive integer types");
            }

            _elemSize = PointerHelpers.GetElementSize(typeof(T));
        }
示例#2
0
        public UpcastingMemoryBlockAccess(MemoryBlock <byte> array, int absoluteByteOffset = 0)
        {
            _array      = array;
            _byteOffset = absoluteByteOffset;

            if (!PointerHelpers.IsPrimitiveIntegerType(typeof(T)))
            {
                throw new ArgumentException("UpcastingMemoryBlockAccess can only cast to primitive integer types");
            }

            _elemSize = PointerHelpers.GetElementSize(typeof(T));
        }
示例#3
0
        public Pointer <E> ReinterpretCast <E>() where E : struct
        {
            Type currentType = typeof(T);
            Type targetType  = typeof(E);

            if (!PointerHelpers.IsPrimitiveIntegerType(currentType))
            {
                throw new InvalidOperationException("Cannot cast a pointer from a non-primitive type");
            }
            if (!PointerHelpers.IsPrimitiveIntegerType(targetType))
            {
                throw new InvalidOperationException("Cannot cast a pointer to a non-primitive type");
            }

            if (currentType == targetType)
            {
                return((Pointer <E>)(object) this);
            }

            if (!(this._memory is BasicMemoryBlockAccess <T>))
            {
                throw new InvalidOperationException("Cannot cast a pointer that has already been cast from another type");
            }

            // Upcasting - accessing a byte array as a sequence of wide integers
            if (currentType == typeof(byte) &&
                (targetType == typeof(sbyte) ||
                 targetType == typeof(short) ||
                 targetType == typeof(ushort) ||
                 targetType == typeof(int) ||
                 targetType == typeof(uint) ||
                 targetType == typeof(long) ||
                 targetType == typeof(ulong) ||
                 targetType == typeof(float) ||
                 targetType == typeof(double)))
            {
                MemoryBlock <byte> block = (this._memory as BasicMemoryBlockAccess <byte>).Block;
                int targetElemSize       = PointerHelpers.GetElementSize(targetType);
                return(new Pointer <E>(new UpcastingMemoryBlockAccess <E>(block, _elementsOffset % targetElemSize), _elementsOffset / targetElemSize));
            }

            // Downcasting - accessing an integer array as a sequence of bytes
            if (targetType == typeof(byte) &&
                (currentType == typeof(sbyte) ||
                 currentType == typeof(short) ||
                 currentType == typeof(ushort) ||
                 currentType == typeof(int) ||
                 currentType == typeof(uint) ||
                 currentType == typeof(long) ||
                 currentType == typeof(ulong) ||
                 currentType == typeof(float) ||
                 currentType == typeof(double)))
            {
                throw new NotImplementedException("Cannot cast a pointer in this way");
                //MemoryBlock<T> block = (this._memory as BasicMemoryBlockAccess<T>).Block;
                //int sourceElemSize = PointerHelpers.GetElementSize(currentType);
                //return (Pointer<E>)(object)(new Pointer<byte>(new DowncastingMemoryBlockAccess<T>(block), _elementsOffset * sourceElemSize));
            }

            throw new InvalidOperationException("Cannot cast a pointer from " + currentType.ToString() + " to " + targetType.ToString());
        }