using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using BurnOutSharp.Matching; namespace BurnOutSharp.Tools { internal static class Extensions { // TODO: Add extensions for BitConverter.ToX(); offset += x; #region Byte Arrays /// /// Find all positions of one array in another, if possible, if possible /// public static List FindAllPositions(this byte[] stack, byte?[] needle, int start = 0, int end = -1) { // Get the outgoing list List positions = new List(); // Initialize the loop variables bool found = true; int lastPosition = start; var matcher = new ContentMatch(needle, end: end); // Loop over and get all positions while (found) { matcher.Start = lastPosition; (found, lastPosition) = matcher.Match(stack, false); if (found) positions.Add(lastPosition); } return positions; } /// /// Find the first position of one array in another, if possible /// public static bool FirstPosition(this byte[] stack, byte?[] needle, out int position, int start = 0, int end = -1) { var matcher = new ContentMatch(needle, start, end); (bool found, int foundPosition) = matcher.Match(stack, false); position = foundPosition; return found; } /// /// Find the last position of one array in another, if possible /// public static bool LastPosition(this byte[] stack, byte?[] needle, out int position, int start = 0, int end = -1) { var matcher = new ContentMatch(needle, start, end); (bool found, int foundPosition) = matcher.Match(stack, true); position = foundPosition; return found; } /// /// See if a byte array starts with another /// public static bool StartsWith(this byte[] stack, byte?[] needle) { return stack.FirstPosition(needle, out int _, start: 0, end: 1); } /// /// See if a byte array ends with another /// public static bool EndsWith(this byte[] stack, byte?[] needle) { return stack.FirstPosition(needle, out int _, start: stack.Length - needle.Length); } #endregion #region Streams /// /// Read a byte from the stream /// public static byte ReadByteValue(this Stream stream) { byte[] buffer = new byte[1]; stream.Read(buffer, 0, 1); return buffer[0]; } /// /// Read a byte array from the stream /// public static byte[] ReadBytes(this Stream stream, int count) { byte[] buffer = new byte[count]; stream.Read(buffer, 0, count); return buffer; } /// /// Read a character from the stream /// public static char ReadChar(this Stream stream) { byte[] buffer = new byte[1]; stream.Read(buffer, 0, 1); return (char)buffer[0]; } /// /// Read a character array from the stream /// public static char[] ReadChars(this Stream stream, int count) => stream.ReadChars(count, Encoding.Default); /// /// Read a character array from the stream /// public static char[] ReadChars(this Stream stream, int count, Encoding encoding) { byte[] buffer = new byte[count]; stream.Read(buffer, 0, count); return encoding.GetString(buffer).ToCharArray(); } /// /// Read a short from the stream /// public static short ReadInt16(this Stream stream) { byte[] buffer = new byte[2]; stream.Read(buffer, 0, 2); return BitConverter.ToInt16(buffer, 0); } /// /// Read a ushort from the stream /// public static ushort ReadUInt16(this Stream stream) { byte[] buffer = new byte[2]; stream.Read(buffer, 0, 2); return BitConverter.ToUInt16(buffer, 0); } /// /// Read an int from the stream /// public static int ReadInt32(this Stream stream) { byte[] buffer = new byte[4]; stream.Read(buffer, 0, 4); return BitConverter.ToInt32(buffer, 0); } /// /// Read a uint from the stream /// public static uint ReadUInt32(this Stream stream) { byte[] buffer = new byte[4]; stream.Read(buffer, 0, 4); return BitConverter.ToUInt32(buffer, 0); } /// /// Read a long from the stream /// public static long ReadInt64(this Stream stream) { byte[] buffer = new byte[8]; stream.Read(buffer, 0, 8); return BitConverter.ToInt64(buffer, 0); } /// /// Read a ulong from the stream /// public static ulong ReadUInt64(this Stream stream) { byte[] buffer = new byte[8]; stream.Read(buffer, 0, 8); return BitConverter.ToUInt64(buffer, 0); } /// /// Read a null-terminated string from the stream /// public static string ReadString(this Stream stream) => stream.ReadString(Encoding.Default); /// /// Read a null-terminated string from the stream /// public static string ReadString(this Stream stream, Encoding encoding) { byte[] nullTerminator = encoding.GetBytes(new char[] { '\0' }); int charWidth = nullTerminator.Length; List tempBuffer = new List(); byte[] buffer = new byte[charWidth]; while (stream.Read(buffer, 0, charWidth) != 0 && buffer.SequenceEqual(nullTerminator)) { tempBuffer.AddRange(buffer); } return encoding.GetString(tempBuffer.ToArray()); } #endregion } }