using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IPA.Utilities { /// /// A class providing static utility functions that in any other language would just *exist*. /// public static class LoneFunctions { /// /// Converts a hex string to a byte array. /// /// the hex stream /// the corresponding byte array public static byte[] StringToByteArray(string hex) { int NumberChars = hex.Length; byte[] bytes = new byte[NumberChars / 2]; for (int i = 0; i < NumberChars; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return bytes; } /// /// /// /// /// public static string ByteArrayToString(byte[] ba) { StringBuilder hex = new StringBuilder(ba.Length * 2); foreach (byte b in ba) hex.AppendFormat("{0:x2}", b); return hex.ToString(); } // Copyright (c) 2008-2013 Hafthor Stefansson // Distributed under the MIT/X11 software license // Ref: http://www.opensource.org/licenses/mit-license.php. // From: https://stackoverflow.com/a/8808245/3117125 /// /// Uses unsafe code to compare 2 byte arrays quickly. /// /// array 1 /// array 2 /// whether or not they are byte-for-byte equal public static unsafe bool UnsafeCompare(byte[] a1, byte[] a2) { if (a1 == a2) return true; if (a1 == null || a2 == null || a1.Length != a2.Length) return false; fixed (byte* p1 = a1, p2 = a2) { byte* x1 = p1, x2 = p2; int l = a1.Length; for (int i = 0; i < l / 8; i++, x1 += 8, x2 += 8) if (*((long*)x1) != *((long*)x2)) return false; if ((l & 4) != 0) { if (*((int*)x1) != *((int*)x2)) return false; x1 += 4; x2 += 4; } if ((l & 2) != 0) { if (*((short*)x1) != *((short*)x2)) return false; x1 += 2; x2 += 2; } if ((l & 1) != 0) if (*((byte*)x1) != *((byte*)x2)) return false; return true; } } /// /// Gets a path relative to the provided folder. /// /// the file to relativize /// the source folder /// a path to get from to public static string GetRelativePath(string file, string folder) { Uri pathUri = new Uri(file); // Folders must end in a slash if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString())) { folder += Path.DirectorySeparatorChar; } Uri folderUri = new Uri(folder); return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', Path.DirectorySeparatorChar)); } /// /// Copies all files from to . /// /// the source directory /// the destination directory /// public static void CopyAll(DirectoryInfo source, DirectoryInfo target, string appendFileName = "") { if (source.FullName.ToLower() == target.FullName.ToLower()) { return; } // Check if the target directory exists, if not, create it. if (Directory.Exists(target.FullName) == false) { Directory.CreateDirectory(target.FullName); } // Copy each file into it's new directory. foreach (FileInfo fi in source.GetFiles()) { if (fi.Name == appendFileName) File.AppendAllLines(Path.Combine(target.ToString(), fi.Name), File.ReadAllLines(fi.FullName)); else fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true); } // Copy each subdirectory using recursion. foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) { DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name); CopyAll(diSourceSubDir, nextTargetSubDir, appendFileName); } } } }