예제 #1
0
 public static DdsHeader FromFileStream(Stream input)
 {
     byte[] buff = new byte[128];
     using (SafeGCHandle handle = new SafeGCHandle(buff, GCHandleType.Pinned))
     {
         input.EnsureRead(buff, 0, buff.Length);
         return (DdsHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject() + 4, TypeCache<DdsHeader>.Type);
     }
 }
예제 #2
0
        public static void ToFileStream(DdsHeader header, Stream output)
        {
            byte[] buff = new byte[128];
            using (SafeGCHandle handle = new SafeGCHandle(buff, GCHandleType.Pinned))
            {
                IntPtr ptr = handle.AddrOfPinnedObject();

                Marshal.WriteInt32(ptr, DdsHeader.MagicHeader);
                Marshal.StructureToPtr(header, ptr + 4, false);

                output.Write(buff, 0, buff.Length);
            }
        }
예제 #3
0
        public static unsafe IDisposable ChangeArrayType(Array array, Int32 oldElementSize, out void *pointer)
        {
            if (array.Length < 1)
            {
                throw new NotSupportedException();
            }

            SafeGCHandle handle = new SafeGCHandle(array, GCHandleType.Pinned);

            try
            {
                pointer = handle.AddrOfPinnedObject().ToPointer();
                UIntPtr *arrayPointer = (UIntPtr *)pointer;
                UIntPtr  arrayLength  = *(arrayPointer - 1);
                UIntPtr  arrayType    = *(arrayPointer - 2);
                UInt64   arraySize    = ((UInt64)arrayLength * (UInt64)oldElementSize);

                if (arraySize % (UInt64)UnsafeSize != 0)
                {
                    throw new InvalidCastException();
                }

                try
                {
                    *(arrayPointer - 1) = new UIntPtr(arraySize / (UInt64)UnsafeSize);
                    *(arrayPointer - 2) = ArrayTypePointer;

                    return(new DisposableAction(() =>
                    {
                        *(arrayPointer - 1) = arrayLength;
                        *(arrayPointer - 2) = arrayType;
                        handle.Dispose();
                    }));
                }
                catch
                {
                    *(arrayPointer - 1) = arrayLength;
                    *(arrayPointer - 2) = arrayType;
                    throw;
                }
            }
            catch
            {
                handle.SafeDispose();
                throw;
            }
        }
예제 #4
0
        public static void WriteStruct(this Stream output, object pack)
        {
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            int size = Marshal.SizeOf(pack);

            byte[] buff = new byte[size];

            using (SafeGCHandle handle = new SafeGCHandle(buff, GCHandleType.Pinned))
            {
                Marshal.StructureToPtr(pack, handle.AddrOfPinnedObject(), false);
                output.Write(buff, 0, size);
            }
        }
예제 #5
0
        public static T[] ReadStructs <T>(this Stream input, int count) where T : new()
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }

            T[] result = new T[count];

            int size = Marshal.SizeOf(TypeCache <T> .Type);

            byte[] buff = new byte[size];
            using (SafeGCHandle handle = new SafeGCHandle(buff, GCHandleType.Pinned))
            {
                for (int i = 0; i < result.Length; i++)
                {
                    input.EnsureRead(buff, 0, size);
                    result[i] = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), TypeCache <T> .Type);
                }
            }

            return(result);
        }
예제 #6
0
 private static unsafe UIntPtr GetArrayTypePointer()
 {
     T[] result = new T[1];
     using (SafeGCHandle handle = new SafeGCHandle(result, GCHandleType.Pinned))
         return(*(((UIntPtr *)handle.AddrOfPinnedObject().ToPointer()) - 2));
 }