using System; using System.Runtime.InteropServices; using Decal.Interop.Dat; namespace Decal.DecalDat { [ComVisible(true)] [Guid("9F7F6CD9-D164-418D-8CB5-3B9ACD70BEAF")] [ClassInterface(ClassInterfaceType.None)] [ProgId("DecalDat.DatStream")] public class DatStreamImpl : IDatStream { private DatFileEntry _file; internal void Load(DatFileEntry file) { _file = file; } public int Size => _file?.Size ?? 0; public int Tell => _file?.Tell ?? 0; public void Skip(int Bytes) { _file?.Skip(Bytes); } public void Restart() { _file?.Reset(); } public void ReadBinary(int Bytes, ref byte Buffer) { if (_file == null) return; var buf = new byte[Bytes]; _file.Read(buf, 0, Bytes); // Copy to unmanaged buffer starting at ref Buffer Marshal.Copy(buf, 0, GetBufferPtr(ref Buffer), Bytes); } public string Read(int Bytes) { if (_file == null) return string.Empty; var buf = new byte[Bytes]; int read = _file.Read(buf, 0, Bytes); // Return as binary BSTR (same as SysAllocStringByteLen in C++) unsafe { fixed (byte* p = buf) { return Marshal.PtrToStringAnsi(new IntPtr(p), read); } } } private static unsafe IntPtr GetBufferPtr(ref byte buffer) { fixed (byte* p = &buffer) { return new IntPtr(p); } } } }