using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; namespace BizHawk { public struct Tuple : IEquatable> { private readonly T1 first; private readonly T2 second; public T1 First { get { return first; } } public T2 Second { get { return second; } } public Tuple(T1 o1, T2 o2) { first = o1; second = o2; } public bool Equals(Tuple other) { return first.Equals(other.first) && second.Equals(other.second); } public override bool Equals(object obj) { if (obj is Tuple) return this.Equals((Tuple)obj); else return false; } public override int GetHashCode() { return first.GetHashCode() ^ second.GetHashCode(); } } public static class Extensions { public static bool IsBinary(this string str) { for (int i = 0; i < str.Length; i++) { char c = str[i]; if (c == '0' || c == '1') continue; return false; } return true; } public static bool In(this string str, params string[] options) { foreach (string opt in options) { if (opt.Equals(str, StringComparison.CurrentCultureIgnoreCase)) return true; } return false; } public static bool In(this string str, IEnumerable options) { foreach (string opt in options) { if (opt.Equals(str,StringComparison.CurrentCultureIgnoreCase)) return true; } return false; } public static bool In(this string str, IEnumerable options, Func eval) { foreach (T opt in options) { if (eval(opt, str) == true) return true; } return false; } public static bool NotIn(this string str, params string[] options) { foreach (string opt in options) { if (opt.ToLower() == str.ToLower()) return false; } return true; } public static bool NotIn(this string str, IEnumerable options) { foreach (string opt in options) { if (opt.ToLower() == str.ToLower()) return false; } return true; } public static bool In(this int i, params int[] options) { foreach (int j in options) { if (i == j) return true; } return false; } public static bool In(this int i, IEnumerable options) { foreach (int j in options) { if (i == j) return true; } return false; } public static bool ContainsStartsWith(this IEnumerable options, string str) { foreach (string opt in options) { if (opt.StartsWith(str)) return true; } return false; } public static string GetOptionValue(this IEnumerable options, string str) { try { foreach (string opt in options) { if (opt.StartsWith(str)) { return opt.Split('=')[1]; } } } catch (Exception) { } return null; } public static bool IsValidRomExtentsion(this string str, params string[] romExtensions) { string strUpper = str.ToUpper(); foreach (string ext in romExtensions) { if (strUpper.EndsWith(ext.ToUpper())) return true; } return false; } public static string ToCommaSeparated(this List list) { var sb = new StringBuilder(); for (int i = 0; i < list.Count; i++) { if (i > 0) sb.Append(","); sb.Append(list[i]); } return sb.ToString(); } public static void SaveAsHex(this byte[] buffer, TextWriter writer) { for (int i=0; i= 0; j--) if (SaveRAM[j] != 0) return j + 1; return 0; } /// /// conerts bytes to an uppercase string of hex numbers in upper case without any spacing or anything /// //could be extension method /// public static string BytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); foreach (byte b in bytes) sb.AppendFormat("{0:X2}", b); return sb.ToString(); } //could be extension method public static byte[] HexStringToBytes(string str) { MemoryStream ms = new MemoryStream(); if (str.Length % 2 != 0) throw new ArgumentException(); int len = str.Length/2; for (int i = 0; i < len; i++) { int d = 0; for (int j = 0; j < 2; j++) { char c = char.ToLower(str[i * 2 + j]); if (c >= '0' && c <= '9') d += (c - '0'); else if (c >= 'a' && c <= 'f') d += (c - 'a') + 10; else throw new ArgumentException(); if (j == 0) d <<= 4; } ms.WriteByte((byte)d); } return ms.ToArray(); } //could be extension method public static void WriteByteBuffer(BinaryWriter bw, byte[] data) { if (data == null) bw.Write(0); else { bw.Write(data.Length); bw.Write(data); } } //could be extension method public static byte[] ReadByteBuffer(BinaryReader br, bool return_null) { int len = br.ReadInt32(); if (len == 0 && return_null) return null; byte[] ret = new byte[len]; int ofs = 0; while (len > 0) { int done = br.Read(ret, ofs, len); ofs += done; len -= done; } return ret; } public static unsafe int memcmp(void* a, string b, int len) { fixed (byte* bp = System.Text.Encoding.ASCII.GetBytes(b)) return memcmp(a, bp, len); } public static unsafe int memcmp(void* a, void* b, int len) { byte* ba = (byte*)a; byte* bb = (byte*)b; for (int i = 0; i < len; i++) { byte _a = ba[i]; byte _b = bb[i]; int c = _a - _b; if (c != 0) return c; } return 0; } public static unsafe void memset(void* ptr, int val, int len) { byte* bptr = (byte*)ptr; for (int i = 0; i < len; i++) bptr[i] = (byte)val; } public static byte[] ReadAllBytes(Stream stream) { const int BUFF_SIZE = 4096; byte[] buffer = new byte[BUFF_SIZE]; int bytesRead = 0; var inStream = new BufferedStream(stream); var outStream = new MemoryStream(); while ((bytesRead = inStream.Read(buffer, 0, BUFF_SIZE)) > 0) { outStream.Write(buffer, 0, bytesRead); } return outStream.ToArray(); } public static string FormatFileSize(long filesize) { Decimal size = (Decimal)filesize; Decimal OneKiloByte = 1024M; Decimal OneMegaByte = OneKiloByte * 1024M; Decimal OneGigaByte = OneMegaByte * 1024M; string suffix; if (size > 1024*1024*1024) { size /= 1024*1024*1024; suffix = "GB"; } else if (size > 1024*1024) { size /= 1024*1024; suffix = "MB"; } else if (size > 1024) { size /= 1024; suffix = "KB"; } else { suffix = " B"; } string precision = "2"; return String.Format("{0:N" + precision + "}{1}", size, suffix); } } public static class BITREV { public static byte[] byte_8; static BITREV() { make_byte_8(); } static void make_byte_8() { int bits = 8; int n = 1 << 8; byte_8 = new byte[n]; int m = 1; int a = n >> 1; int j = 2; byte_8[0] = 0; byte_8[1] = (byte)a; while ((--bits) != 0) { m <<= 1; a >>= 1; for (int i = 0; i < m; i++) byte_8[j++] = (byte)(byte_8[i] + a); } } } /// /// a Dictionary-of-lists with key K and values List<V> /// [Serializable] public class Bag : BagBase>, List> { } /// /// a Dictionary-of-lists with key K and values List<V> /// [Serializable] public class SortedBag : BagBase>, List> { } /// /// A dictionary that creates new values on the fly as necessary so that any key you need will be defined. /// /// dictionary keys /// dictionary values public class WorkingDictionary : Dictionary where V : new() { public new V this[K key] { get { V temp; if (!TryGetValue(key, out temp)) temp = this[key] = new V(); return temp; } set { base[key] = value; } } } /// /// base class for Bag and SortedBag /// /// dictionary keys /// list values /// dictionary type /// list type [Serializable] public class BagBase : IEnumerable where D : IDictionary, new() where L : IList, IEnumerable, new() { D dictionary = new D(); public void Add(K key, V val) { this[key].Add(val); } public bool ContainsKey(K key) { return dictionary.ContainsKey(key); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerator GetEnumerator() { foreach (L lv in dictionary.Values) foreach (V v in lv) yield return v; } public IEnumerable KeyValuePairEnumerator { get { return dictionary; } } /// /// the list of keys contained herein /// public IList Keys { get { return new List(dictionary.Keys); } } public L this[K key] { get { L slot; if (!dictionary.TryGetValue(key, out slot)) dictionary[key] = slot = new L(); return slot; } set { dictionary[key] = value; } } } }