395 lines
14 KiB
C#
395 lines
14 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Collections;
|
|
using System.Xml.Schema;
|
|
namespace ln.type
|
|
{
|
|
public static class Extensions
|
|
{
|
|
public static T[] Concat<T>(this T[] me, T[] other)
|
|
{
|
|
T[] combined = new T[me.Length + other.Length];
|
|
Array.Copy(me, 0, combined, 0, me.Length);
|
|
Array.Copy(other, 0, combined, me.Length, combined.Length);
|
|
return combined;
|
|
}
|
|
|
|
|
|
public static T[] Combine<T>(this T[] me, IEnumerable<T> other)
|
|
{
|
|
HashSet<T> elements = new HashSet<T>(me);
|
|
foreach (T e in other)
|
|
elements.Add(e);
|
|
return elements.ToArray();
|
|
}
|
|
public static T[] Remove<T>(this T[] me, IEnumerable<T> remove)
|
|
{
|
|
HashSet<T> elements = new HashSet<T>(me);
|
|
foreach (T e in remove)
|
|
elements.Remove(e);
|
|
return elements.ToArray();
|
|
}
|
|
|
|
|
|
public static bool AreEqual<T>(this T[] me, T[] you)
|
|
{
|
|
if (me.Length != you.Length)
|
|
return false;
|
|
|
|
for (int n = 0; n < me.Length; n++)
|
|
if (!me[n].Equals(you[n]))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
public static byte[] BigEndian(this byte[] bytes)
|
|
{
|
|
if (BitConverter.IsLittleEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
}
|
|
|
|
public static int ReadInteger(this Stream stream)
|
|
{
|
|
byte[] b = new byte[4];
|
|
stream.Read(b, 0, 4);
|
|
return BitConverter.ToInt32(b, 0);
|
|
}
|
|
public static void WriteInteger(this Stream stream, int i)
|
|
{
|
|
stream.Write(BitConverter.GetBytes(i), 0, 4);
|
|
}
|
|
public static uint ReadUInteger(this Stream stream)
|
|
{
|
|
byte[] b = new byte[4];
|
|
stream.Read(b, 0, 4);
|
|
return BitConverter.ToUInt32(b.BigEndian(), 0);
|
|
}
|
|
public static void WriteUInteger(this Stream stream, uint i)
|
|
{
|
|
stream.Write(BitConverter.GetBytes(i).BigEndian(), 0, 4);
|
|
}
|
|
|
|
public static long ReadLong(this Stream stream)
|
|
{
|
|
byte[] b = new byte[8];
|
|
stream.Read(b, 0, 8);
|
|
return BitConverter.ToInt64(b, 0);
|
|
}
|
|
public static void WriteLong(this Stream stream, long i)
|
|
{
|
|
stream.Write(BitConverter.GetBytes(i), 0, 8);
|
|
}
|
|
public static ulong ReadULong(this Stream stream)
|
|
{
|
|
byte[] b = new byte[8];
|
|
stream.Read(b, 0, 8);
|
|
return BitConverter.ToUInt64(b.BigEndian(), 0);
|
|
}
|
|
public static void WriteULong(this Stream stream, ulong i)
|
|
{
|
|
stream.Write(BitConverter.GetBytes(i).BigEndian(), 0, 8);
|
|
}
|
|
|
|
|
|
public static byte[] ReadToEnd(this Stream stream)
|
|
{
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
stream.CopyTo(memoryStream);
|
|
return memoryStream.ToArray();
|
|
}
|
|
|
|
public static void WriteByte(this Stream stream, char ch)
|
|
{
|
|
if (ch > 255)
|
|
throw new ArgumentOutOfRangeException(nameof(ch));
|
|
stream.WriteByte((byte)ch);
|
|
}
|
|
public static void WriteBytes(this Stream stream, byte[] bytes)
|
|
{
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static byte[] ReadBytes(this Stream stream, int length)
|
|
{
|
|
byte[] bytes = new byte[length];
|
|
stream.Read(bytes, 0, length);
|
|
return bytes;
|
|
}
|
|
|
|
public static void WriteShort(this Stream stream, short value, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(value);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static short ReadShort(this Stream stream, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = stream.ReadBytes(2);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return BitConverter.ToInt16(bytes, 0);
|
|
}
|
|
public static void WriteUShort(this Stream stream, ushort value, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(value);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static ushort ReadUShort(this Stream stream, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = stream.ReadBytes(2);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return BitConverter.ToUInt16(bytes, 0);
|
|
}
|
|
|
|
public static void WriteLong(this Stream stream, long value, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(value);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static long ReadLong(this Stream stream, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = stream.ReadBytes(8);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return BitConverter.ToInt64(bytes, 0);
|
|
}
|
|
|
|
public static void WriteULong(this Stream stream, ulong value, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(value);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static ulong ReadULong(this Stream stream, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = stream.ReadBytes(8);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return BitConverter.ToUInt64(bytes, 0);
|
|
}
|
|
|
|
public static void WriteFloat(this Stream stream, float value, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(value);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static float ReadFloat(this Stream stream, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = stream.ReadBytes(4);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return BitConverter.ToSingle(bytes, 0);
|
|
}
|
|
|
|
public static void WriteDouble(this Stream stream, double value, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(value);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
public static double ReadDouble(this Stream stream, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = stream.ReadBytes(8);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return BitConverter.ToDouble(bytes, 0);
|
|
}
|
|
|
|
|
|
|
|
|
|
public static byte[] GetBytes(this int v, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(v);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
}
|
|
public static byte[] GetBytes(this uint v, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(v);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
|
|
}
|
|
public static int GetInt(this byte[] bytes, bool bigEndian = false) => GetInt(bytes, 0, bigEndian);
|
|
public static int GetInt(this byte[] bytes, int offset, bool bigEndian = false)
|
|
{
|
|
byte[] ib = bytes.Slice(offset, 4).BigEndian();
|
|
return BitConverter.ToInt32(ib, 0);
|
|
}
|
|
public static uint GetUInt(this byte[] bytes, bool bigEndian = false) => GetUInt(bytes, 0, bigEndian);
|
|
public static uint GetUInt(this byte[] bytes, int offset, bool bigEndian = false)
|
|
{
|
|
byte[] ib = bytes.Slice(offset, 4).BigEndian();
|
|
return BitConverter.ToUInt32(ib, 0);
|
|
}
|
|
|
|
public static byte[] GetBytes(this short v, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(v);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
}
|
|
public static byte[] GetBytes(this ushort v, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(v);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
}
|
|
|
|
public static short GetShort(this byte[] bytes, bool bigEndian = false) => GetShort(bytes, 0, bigEndian);
|
|
public static short GetShort(this byte[] bytes, int offset, bool bigEndian = false)
|
|
{
|
|
byte[] ib = bytes.Slice(offset, 2).BigEndian();
|
|
return BitConverter.ToInt16(ib, 0);
|
|
}
|
|
public static ushort GetUShort(this byte[] bytes, bool bigEndian = false) => GetUShort(bytes, 0, bigEndian);
|
|
public static ushort GetUShort(this byte[] bytes, int offset, bool bigEndian = false)
|
|
{
|
|
byte[] ib = bytes.Slice(offset, 2).BigEndian();
|
|
return BitConverter.ToUInt16(ib, 0);
|
|
}
|
|
|
|
public static byte[] GetBytes(this long v, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(v);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
}
|
|
public static byte[] GetBytes(this ulong v, bool bigEndian = false)
|
|
{
|
|
byte[] bytes = BitConverter.GetBytes(v);
|
|
if (BitConverter.IsLittleEndian == bigEndian)
|
|
Array.Reverse(bytes);
|
|
return bytes;
|
|
}
|
|
|
|
|
|
public static T[] Slice<T>(this T[] me, int offset) => Slice(me, offset, me.Length - offset);
|
|
public static T[] Slice<T>(this T[] me, ref int offset) => Slice(me, ref offset, me.Length - offset);
|
|
public static T[] Slice<T>(this T[] me, int offset, int length) => Slice(me, ref offset, length);
|
|
public static T[] Slice<T>(this T[] me, ref int offset, int length)
|
|
{
|
|
if (offset < 0)
|
|
offset = me.Length + offset;
|
|
if (length < 0)
|
|
length = me.Length - offset + length;
|
|
|
|
T[] slice = new T[length];
|
|
Array.Copy(me, offset, slice, 0, length);
|
|
offset += length;
|
|
return slice;
|
|
}
|
|
|
|
public static byte[] BytesFromHexString(string hexString)
|
|
{
|
|
int NumberChars = hexString.Length;
|
|
byte[] bytes = new byte[NumberChars / 2];
|
|
for (int i = 0; i < NumberChars; i += 2)
|
|
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
|
|
return bytes;
|
|
}
|
|
|
|
public static string ToHexString(this byte[] bytes)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
for (int n = 0; n < bytes.Length; n ++)
|
|
{
|
|
stringBuilder.AppendFormat("{0:X2}", bytes[n]);
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public static string HexDump(this byte[] bytes)
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
for (int n = 0; n < bytes.Length; n += 16)
|
|
{
|
|
int len = bytes.Length - n;
|
|
if (len > 16)
|
|
len = 16;
|
|
|
|
byte[] section = bytes.Slice(n, len);
|
|
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
if (i < section.Length)
|
|
stringBuilder.AppendFormat("{0:X2} ", section[i]);
|
|
else
|
|
stringBuilder.Append(" ");
|
|
}
|
|
|
|
stringBuilder.Append(" ");
|
|
|
|
foreach (byte b in section)
|
|
{
|
|
if (b < 32)
|
|
stringBuilder.Append('.');
|
|
else
|
|
stringBuilder.Append((char)b);
|
|
}
|
|
stringBuilder.AppendLine();
|
|
}
|
|
|
|
return stringBuilder.ToString();
|
|
}
|
|
|
|
public static Decimal ToDecimal(this double v)
|
|
{
|
|
if (v <= (double)Decimal.MinValue)
|
|
return decimal.MinValue;
|
|
if (v >= (double)Decimal.MaxValue)
|
|
return decimal.MaxValue;
|
|
|
|
return new Decimal(v);
|
|
}
|
|
|
|
public static string GetSimpleQualifiedName(this Type type) => string.Format("{0}, {1}", type.FullName, type.Assembly.GetName().Name);
|
|
|
|
}
|
|
public static class DateTimeExtensions
|
|
{
|
|
public static DateTime EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
|
|
|
|
public static DateTime FromUnixTimeSeconds(double seconds)
|
|
{
|
|
return EPOCH.AddSeconds(seconds);
|
|
}
|
|
public static DateTime FromUnixTimeMilliseconds(double milliseconds)
|
|
{
|
|
return EPOCH.AddMilliseconds(milliseconds);
|
|
}
|
|
|
|
public static double ToUnixTimeSeconds(this DateTime dateTime)
|
|
{
|
|
return (dateTime - EPOCH).TotalSeconds;
|
|
}
|
|
public static double ToUnixTimeMilliseconds(this DateTime dateTime)
|
|
{
|
|
return (dateTime - EPOCH).TotalMilliseconds;
|
|
}
|
|
}
|
|
}
|