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); }
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); }