Пример #1
0
        private static IntPtr PrepareIOStruct(IPhysFSStream ioStream)
        {
            PHYSFS_Io ioStruct = new PHYSFS_Io {
                Version = ioStream.Version,
                Opaque  = IntPtr.Zero,
                Seek    = (IntPtr io, ulong offset) => {
                    return(ioStream.Seek(offset) ? 1 : 0);
                },
                Tell = (IntPtr io) => {
                    return(ioStream.Tell());
                },
                Length = (IntPtr io) => {
                    return(ioStream.Length());
                },
                Duplicate = (IntPtr io) => {
                    IPhysFSStream ioStreamClone    = ioStream.Duplicate();
                    IntPtr        ioStructClonePtr = PrepareIOStruct(ioStreamClone);
                    return(ioStructClonePtr);
                },
                Flush = (IntPtr io) => {
                    return(ioStream.Flush() ? 1 : 0);
                }
            };

            if (ioStream.CanRead)
            {
                ioStruct.Read = (IntPtr io, IntPtr buf, ulong len) => {
                    byte[] buffer    = new byte[len];
                    long   bytesRead = ioStream.Read(buffer, len);

                    if (bytesRead > 0L)
                    {
                        Helper.MarshalCopy(buffer, 0UL, buf, len);
                    }

                    return(bytesRead);
                };
            }

            if (ioStream.CanWrite)
            {
                ioStruct.Write = (IntPtr io, IntPtr buf, ulong len) => {
                    byte[] buffer = new byte[len];
                    Helper.MarshalCopy(buf, buffer, 0UL, len);
                    long bytesWritten = ioStream.Write(buffer, len);
                    return(bytesWritten);
                };
            }

            IntPtr ioPtr = Marshal.AllocHGlobal(Marshal.SizeOf <PHYSFS_Io>());

            ioStruct.Destroy = (IntPtr io) => {
                ioStream.Destroy();
                Marshal.FreeHGlobal(ioPtr); // we must free this, otherwise no one will do
            };

            Marshal.StructureToPtr(ioStruct, ioPtr, fDeleteOld: false);

            return(ioPtr);
        }
Пример #2
0
        private static IPhysFSStream PrepareIOStream(IntPtr io)
        {
            PHYSFS_Io physfsIo = Marshal.PtrToStructure <PHYSFS_Io>(io);

            PhysFSInternalStream internalStream = new PhysFSInternalStream {
                ReadFunction = (byte[] buffer, ulong len) => {
                    IntPtr buf       = Marshal.AllocHGlobal(buffer.Length * Marshal.SizeOf <byte>());
                    long   bytesRead = physfsIo.Read(io, buf, len);
                    Helper.MarshalCopy(buf, buffer, 0UL, len);
                    Marshal.FreeHGlobal(buf);
                    return(bytesRead);
                },
                WriteFunction = (byte[] buffer, ulong len) => {
                    IntPtr buf = Marshal.AllocHGlobal(buffer.Length * Marshal.SizeOf <byte>());
                    Helper.MarshalCopy(buffer, 0UL, buf, len);
                    long bytesWritten = physfsIo.Write(io, buf, len);
                    Marshal.FreeHGlobal(buf);
                    return(bytesWritten);
                },
                SeekFunction = (ulong offset) => {
                    int seekRet = physfsIo.Seek(io, offset);
                    return(seekRet != 0);
                },
                TellFunction = () => {
                    return(physfsIo.Tell(io));
                },
                LengthFunction = () => {
                    return(physfsIo.Length(io));
                },
                DuplicateFunction = () => {
                    IntPtr ioClone = physfsIo.Duplicate(io);
                    return(PrepareIOStream(ioClone));
                },
                FlushFunction = () => {
                    return(physfsIo.Flush(io) != 0);
                },
                DestroyFunction = () => {
                    physfsIo.Destroy(io);
                }
            };

            return(internalStream);
        }