Files
cuetools.net/CUETools.Codecs.MACLib/StreamIO.cs

97 lines
2.7 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace CUETools.Codecs.MACLib
{
internal unsafe class StreamIO : IDisposable
{
public StreamIO(Stream stream)
{
m_stream = stream;
2018-03-31 19:12:58 -04:00
// We keep the references to those callbacks to
// prevent them from being garbage collected.
m_read_bytes = ReadCallback;
m_write_bytes = WriteCallback;
m_get_pos = TellCallback;
m_get_size = GetSizeCallback;
m_seek = SeekRelativeCallback;
2018-03-31 19:12:58 -04:00
m_hCIO = MACLibDll.c_APECIO_Create(null, m_read_bytes, m_write_bytes, m_seek, m_get_pos, m_get_size);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
m_stream = null;
_readBuffer = null;
}
2018-03-31 19:12:58 -04:00
MACLibDll.c_APECIO_Destroy(m_hCIO);
m_hCIO = IntPtr.Zero;
}
~StreamIO()
{
Dispose(false);
}
2018-03-31 19:12:58 -04:00
private int ReadCallback(void* id, void* data, int bcount, out int pBytesRead)
{
if (_readBuffer == null || _readBuffer.Length < bcount)
_readBuffer = new byte[Math.Max(bcount, 0x4000)];
int len = m_stream.Read(_readBuffer, 0, bcount);
if (len > 0) Marshal.Copy(_readBuffer, 0, (IntPtr)data, len);
pBytesRead = len;
return 0;
}
2018-03-31 19:12:58 -04:00
private int WriteCallback(void* id, void* data, int bcount, out int pBytesWritten)
{
if (_readBuffer == null || _readBuffer.Length < bcount)
_readBuffer = new byte[Math.Max(bcount, 0x4000)];
Marshal.Copy((IntPtr)data, _readBuffer, 0, bcount);
m_stream.Write(_readBuffer, 0, bcount);
pBytesWritten = bcount;
return 0;
}
2018-03-31 19:12:58 -04:00
int TellCallback(void* id)
{
return (int)m_stream.Position;
}
2018-03-31 19:12:58 -04:00
uint GetSizeCallback(void* id)
{
return (uint)m_stream.Length;
}
2018-03-31 19:12:58 -04:00
int SeekRelativeCallback(void* id, IntPtr delta, int mode)
{
m_stream.Seek((long)delta, (SeekOrigin)(mode));
return 0;
}
2018-03-31 19:12:58 -04:00
internal IntPtr CIO => m_hCIO;
Stream m_stream;
byte[] _readBuffer;
CIO_ReadDelegate m_read_bytes;
CIO_WriteDelegate m_write_bytes;
CIO_GetPositionDelegate m_get_pos;
CIO_GetSizeDelegate m_get_size;
CIO_SeekDelegate m_seek;
2018-03-31 19:12:58 -04:00
internal IntPtr m_hCIO;
}
}