using System; using System.IO; using System.IO.Compression; using System.Runtime.InteropServices; namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum { /// /// Abtract class that represents all Media Converters /// public abstract class MediaConverter { /// /// The type of serializer /// public abstract MediaConverterType FormatType { get; } /// /// Signs whether this class can be used to read the data format /// public virtual bool IsReader { get { return false; } } /// /// Signs whether this class can be used to write the data format /// public virtual bool IsWriter { get { return false; } } /// /// Serialization method /// /// public virtual void Read(byte[] data) { throw new NotImplementedException(this.GetType().ToString() + "Read operation is not implemented for this converter"); } /// /// DeSerialization method /// /// public virtual void Write(byte[] data) { throw new NotImplementedException(this.GetType().ToString() + "Write operation is not implemented for this converter"); } /// /// Serializer does a quick check, returns TRUE if file is detected as this type /// /// public virtual bool CheckType(byte[] data) { throw new NotImplementedException(this.GetType().ToString() + "Check type operation is not implemented for this converter"); } #region Static Tools /// /// Converts an int32 value into a byte array /// /// /// public static byte[] GetBytes(int value) { byte[] buf = new byte[4]; buf[0] = (byte)value; buf[1] = (byte)(value >> 8); buf[2] = (byte)(value >> 16); buf[3] = (byte)(value >> 24); return buf; } /// /// Returns an int32 from a byte array based on offset /// /// /// /// public static int GetInt32(byte[] buf, int offsetIndex) { return buf[offsetIndex] | buf[offsetIndex + 1] << 8 | buf[offsetIndex + 2] << 16 | buf[offsetIndex + 3] << 24; } /// /// Returns an int32 from a byte array based on offset /// /// /// /// public static uint GetUInt32(byte[] buf, int offsetIndex) { return (uint)(buf[offsetIndex] | buf[offsetIndex + 1] << 8 | buf[offsetIndex + 2] << 16 | buf[offsetIndex + 3] << 24); } /// /// Returns an uint16 from a byte array based on offset /// /// /// /// public static ushort GetWordValue(byte[] buf, int offsetIndex) { return (ushort)(buf[offsetIndex] | buf[offsetIndex + 1] << 8); } /// /// Updates a byte array with a uint16 value based on offset /// /// /// /// public static void SetWordValue(byte[] buf, int offsetIndex, ushort value) { buf[offsetIndex] = (byte)value; buf[offsetIndex + 1] = (byte)(value >> 8); } /// /// Takes a PauseInMilliseconds value and returns the value in T-States /// /// /// public static int TranslatePause(int pauseInMS) { // t-states per millisecond var tspms = (69888 * 50) / 1000; // get value int res = pauseInMS * tspms; return res; } /// /// Decompresses a byte array that is Z-RLE compressed /// /// /// public static void DecompressZRLE(byte[] sourceBuffer, ref byte[] destBuffer) { MemoryStream stream = new MemoryStream(); stream.Write(sourceBuffer, 0, sourceBuffer.Length); stream.Position = 0; stream.ReadByte(); stream.ReadByte(); DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress, false); ds.Read(destBuffer, 0, destBuffer.Length); } public static byte[] SerializeRaw(object obj) { int rSize = Marshal.SizeOf(obj); IntPtr buff = Marshal.AllocHGlobal(rSize); Marshal.StructureToPtr(obj, buff, false); byte[] rData = new byte[rSize]; Marshal.Copy(buff, rData, 0, rSize); return rData; } public static T DeserializeRaw(byte[] rData, int pos) { int rSize = Marshal.SizeOf(typeof(T)); if (rSize > rData.Length - pos) throw new Exception(); IntPtr buff = Marshal.AllocHGlobal(rSize); Marshal.Copy(rData, pos, buff, rSize); T rObj = (T)Marshal.PtrToStructure(buff, typeof(T)); Marshal.FreeHGlobal(buff); return rObj; } #endregion } }