using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace RomCheater.Core { public static class BitTools { const byte BitsPerByte = 8; #region SizeOf Members public static T SizeOf() where T : IConvertible { Type t = typeof(T); string name = t.Name.ToLower(); switch (name) { case "byte": // unsigned byte return (T)Convert.ChangeType(sizeof(byte), typeof(T)); case "sbyte": // signed byte return (T)Convert.ChangeType(sizeof(sbyte), typeof(T)); case "int16": // short return (T)Convert.ChangeType(sizeof(short), typeof(T)); case "uint16": // ushort return (T)Convert.ChangeType(sizeof(ushort), typeof(T)); case "int32": // int return (T)Convert.ChangeType(sizeof(int), typeof(T)); case "uint32": // uint return (T)Convert.ChangeType(sizeof(uint), typeof(T)); case "int64": // long return (T)Convert.ChangeType(sizeof(long), typeof(T)); case "uint64": // ulong return (T)Convert.ChangeType(sizeof(ulong), typeof(T)); default: throw new InvalidOperationException("Encountered invalid type when converting byte array", new TypeLoadException(string.Format("Type: '{0}' was unexpected.", name))); } } public static T SizeOf(SearchDataTypes sdt) where T : IConvertible { if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } return (T)Convert.ChangeType(((int)sdt / BitsPerByte), typeof(T)); } #region sbyte/byte output public static void SizeOf(SearchDataTypes sdt, out sbyte size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToSByte((sbyte)sdt / BitsPerByte); } public static void SizeOf(SearchDataTypes sdt, out byte size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToByte((byte)sdt / BitsPerByte); } #endregion #region short/ushort output public static void SizeOf(SearchDataTypes sdt, out short size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToInt16((short)sdt / BitsPerByte); } public static void SizeOf(SearchDataTypes sdt, out ushort size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToUInt16((ushort)sdt / BitsPerByte); } #endregion #region int/uint output public static void SizeOf(SearchDataTypes sdt, out int size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToInt32((int)sdt / BitsPerByte); } public static void SizeOf(SearchDataTypes sdt, out uint size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToUInt32((uint)sdt / BitsPerByte); } #endregion #region long/ulong output public static void SizeOf(SearchDataTypes sdt, out long size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToInt64((uint)sdt / BitsPerByte); } public static void SizeOf(SearchDataTypes sdt, out ulong size) { size = 0; if (!Enum.IsDefined(typeof(SearchDataTypes), sdt)) { throw new ArgumentException(string.Format("DataType: 0x{0} has not been defined", ((int)sdt).ToString("X")), "sdt"); } size = Convert.ToUInt64((uint)sdt / BitsPerByte); } #endregion #endregion #region Structure Support public static T[] ConvertByteArray(byte[] data, Func cancelmethod) where T : IConvertible { Type t = typeof(T); string name = t.Name.ToLower(); List list = new List(); switch (name) { case "byte": // unsigned byte //list = new List(); //using (MemoryStream ms = new MemoryStream(data)) //{ // using (BinaryReader br = new BinaryReader(ms)) // { // while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadByte(), typeof(T))); if (cancelmethod.Invoke()) { break; } } // } //} //break; throw new NotSupportedException("Conversion from byte[] to byte[] is not supported because the data can be used without conversion."); case "sbyte": // signed byte //list = new List(); //using (MemoryStream ms = new MemoryStream(data)) //{ // using (BinaryReader br = new BinaryReader(ms)) // { // while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadSByte(), typeof(T))); if (cancelmethod.Invoke()) { break; } } // } //} //break; throw new NotSupportedException("Conversion from byte[] to sbyte[] is not supported because the data can be used without conversion."); case "int16": // short list = new List(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadInt16(), typeof(T))); if (cancelmethod.Invoke()) { break; } } } } break; case "uint16": // ushort list = new List(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadUInt16(), typeof(T))); if (cancelmethod.Invoke()) { break; } } } } break; case "int32": // int list = new List(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadInt32(), typeof(T))); if (cancelmethod.Invoke()) { break; } } } } break; case "uint32": // uint list = new List(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadUInt32(), typeof(T))); if (cancelmethod.Invoke()) { break; } } } } break; case "int64": // long list = new List(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (br.BaseStream.Position < br.BaseStream.Length) {list.Add((T)Convert.ChangeType(br.ReadInt64(), typeof(T))); if (cancelmethod.Invoke()) { break; } } } } break; case "uint64": // ulong list = new List(); using (MemoryStream ms = new MemoryStream(data)) { using (BinaryReader br = new BinaryReader(ms)) { while (br.BaseStream.Position < br.BaseStream.Length) { list.Add((T)Convert.ChangeType(br.ReadUInt64(), typeof(T))); if (cancelmethod.Invoke()) { break; } } } } break; default: throw new InvalidOperationException("Encountered invalid type when converting byte array", new TypeLoadException(string.Format("Type: '{0}' was unexpected.", name))); } return list.ToArray(); } #endregion } }