901 lines
24 KiB
C#
901 lines
24 KiB
C#
//
|
||
// ExtensionMethods.cs - various useful (maybe?) extension methods
|
||
//
|
||
// Author:
|
||
// Michael Becker <alcexhim@gmail.com>
|
||
//
|
||
// Copyright (c) 2019
|
||
//
|
||
// This program is free software: you can redistribute it and/or modify
|
||
// it under the terms of the GNU Lesser General Public License as published by
|
||
// the Free Software Foundation, either version 3 of the License, or
|
||
// (at your option) any later version.
|
||
//
|
||
// This program is distributed in the hope that it will be useful,
|
||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
// GNU General Public License for more details.
|
||
//
|
||
// You should have received a copy of the GNU Lesser General Public License
|
||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
|
||
namespace UniversalEditor
|
||
{
|
||
public static class ExtensionMethods
|
||
{
|
||
public static long GetItemOffset(this List<string> list, int index, int additionalPadding = 0)
|
||
{
|
||
long offset = 0;
|
||
for (int i = 0; i < index; i++)
|
||
{
|
||
if (list[i] == null)
|
||
{
|
||
offset += additionalPadding;
|
||
}
|
||
else
|
||
{
|
||
offset += list[i].Length + additionalPadding;
|
||
}
|
||
}
|
||
return offset;
|
||
}
|
||
|
||
public static bool get_EndOfStream(this System.IO.Stream stream)
|
||
{
|
||
return (stream.Position == stream.Length);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets an int value representing the subset of bits from a single Byte.
|
||
/// </summary>
|
||
/// <param name="b">The Byte used to get the subset of bits from.</param>
|
||
/// <param name="offset">The offset of bits starting from the right.</param>
|
||
/// <param name="count">The number of bits to read.</param>
|
||
/// <returns>
|
||
/// An int value representing the subset of bits.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// Given -> b = 00110101
|
||
/// A call to GetBits(b, 2, 4)
|
||
/// GetBits looks at the following bits in the byte -> 00{1101}00
|
||
/// Returns 1101 as an int (13)
|
||
/// </remarks>
|
||
public static int GetBits(this byte value, int offset, int count)
|
||
{
|
||
return (value >> offset) & ((1 << count) - 1);
|
||
}
|
||
public static int GetBits(this short value, int offset, int count)
|
||
{
|
||
return (value >> offset) & ((1 << count) - 1);
|
||
}
|
||
public static int GetBits(this int value, int offset, int count)
|
||
{
|
||
return (value >> offset) & ((1 << count) - 1);
|
||
}
|
||
|
||
[CLSCompliant(false)]
|
||
public static int GetBits(this ushort value, int offset, int count)
|
||
{
|
||
return (value >> offset) & ((1 << count) - 1);
|
||
}
|
||
|
||
public static void AddRange(this System.Collections.Specialized.StringCollection coll, params string[] values)
|
||
{
|
||
coll.AddRange(values);
|
||
}
|
||
|
||
public static bool Match(this Array array1, Array array2)
|
||
{
|
||
if (array1.Length != array2.Length)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
System.Collections.IEnumerator en1 = array1.GetEnumerator();
|
||
System.Collections.IEnumerator en2 = array2.GetEnumerator();
|
||
|
||
en1.MoveNext();
|
||
en2.MoveNext();
|
||
|
||
try
|
||
{
|
||
while (en1.Current != null)
|
||
{
|
||
if (en2.Current == null) return false;
|
||
if (!en1.Current.Equals(en2.Current)) return false;
|
||
|
||
en1.MoveNext();
|
||
en2.MoveNext();
|
||
}
|
||
}
|
||
catch (InvalidOperationException)
|
||
{
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public static bool ContainsAny(this string value, params string[] anyOf)
|
||
{
|
||
bool result;
|
||
for (int i = 0; i < anyOf.Length; i++)
|
||
{
|
||
string any = anyOf[i];
|
||
if (value.Contains(any))
|
||
{
|
||
result = true;
|
||
return result;
|
||
}
|
||
}
|
||
result = false;
|
||
return result;
|
||
}
|
||
public static bool ContainsAny(this string value, params char[] anyOf)
|
||
{
|
||
bool result;
|
||
for (int i = 0; i < anyOf.Length; i++)
|
||
{
|
||
char any = anyOf[i];
|
||
if (value.Contains(any.ToString()))
|
||
{
|
||
result = true;
|
||
return result;
|
||
}
|
||
}
|
||
result = false;
|
||
return result;
|
||
}
|
||
|
||
public static int IndexOfAny(this string value, params string[] anyOf)
|
||
{
|
||
int result;
|
||
for (int i = 0; i < anyOf.Length; i++)
|
||
{
|
||
string any = anyOf[i];
|
||
int index = value.IndexOf(any);
|
||
if (index > -1)
|
||
{
|
||
result = index;
|
||
return result;
|
||
}
|
||
}
|
||
result = -1;
|
||
return result;
|
||
}
|
||
public static string Capitalize(this string value)
|
||
{
|
||
string result;
|
||
if (string.IsNullOrEmpty(value))
|
||
{
|
||
result = value;
|
||
}
|
||
else
|
||
{
|
||
if (value.Length == 1)
|
||
{
|
||
result = value.ToUpper();
|
||
}
|
||
else
|
||
{
|
||
result = value.Substring(0, 1).ToUpper() + value.Substring(1);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
#region Splitting
|
||
public static T[] Split<T>(this string value, params char[] separator)
|
||
{
|
||
return value.Split<T>(separator, -1, StringSplitOptions.None);
|
||
}
|
||
public static T[] Split<T>(this string value, char[] separator, int count)
|
||
{
|
||
return value.Split<T>(separator, count, StringSplitOptions.None);
|
||
}
|
||
public static T[] Split<T>(this string value, char[] separator, int count, StringSplitOptions options)
|
||
{
|
||
string[] separators = new string[separator.Length];
|
||
for (int i = 0; i < separator.Length; i++)
|
||
{
|
||
separators[i] = separator[i].ToString();
|
||
}
|
||
return value.Split<T>(separators, count, options);
|
||
}
|
||
public static T[] Split<T>(this string value, params string[] separator)
|
||
{
|
||
return value.Split<T>(separator, -1, StringSplitOptions.None);
|
||
}
|
||
public static T[] Split<T>(this string value, string[] separator, int count)
|
||
{
|
||
return value.Split<T>(separator, count, StringSplitOptions.None);
|
||
}
|
||
public static T[] Split<T>(this string value, string[] separator, int count, StringSplitOptions options)
|
||
{
|
||
string[] splitt = null;
|
||
if (count < 0)
|
||
{
|
||
splitt = value.Split(separator, options);
|
||
}
|
||
else
|
||
{
|
||
splitt = value.Split(separator, count, options);
|
||
}
|
||
T[] values = new T[splitt.Length];
|
||
for (int i = 0; i < splitt.Length; i++)
|
||
{
|
||
if (!string.IsNullOrEmpty(splitt[i]))
|
||
{
|
||
values[i] = (T)Convert.ChangeType(splitt[i], typeof(T));
|
||
}
|
||
}
|
||
return values;
|
||
}
|
||
public static string[] Split(this string value, string separator)
|
||
{
|
||
return value.Split(new string[] { separator });
|
||
}
|
||
public static string[] Split(this string value, string[] separator)
|
||
{
|
||
return value.Split(separator, StringSplitOptions.None);
|
||
}
|
||
public static string[] Split(this string value, string[] separator, string ignore)
|
||
{
|
||
return value.Split(separator, ignore, ignore);
|
||
}
|
||
public static string[] Split(this string value, string[] separator, string ignoreBegin, string ignoreEnd)
|
||
{
|
||
return value.Split(separator, ignoreBegin, ignoreEnd, StringSplitOptions.None, -1);
|
||
}
|
||
public static string[] Split(this string value, string[] separator, StringSplitOptions options, int count, string ignore)
|
||
{
|
||
return value.Split(separator, ignore, ignore, options, count);
|
||
}
|
||
public static string[] Split(this string value, char[] separator, string ignore)
|
||
{
|
||
return value.Split(separator, ignore, ignore);
|
||
}
|
||
public static string[] Split(this string value, char[] separator, string ignoreBegin, string ignoreEnd)
|
||
{
|
||
return value.Split(separator, ignoreBegin, ignoreEnd, StringSplitOptions.None, -1);
|
||
}
|
||
public static string[] Split(this string value, char[] separator, string ignore, StringSplitOptions options, int count)
|
||
{
|
||
return value.Split(separator, ignore, ignore, options, count);
|
||
}
|
||
public static string[] Split(this string value, char[] separator, string ignoreBegin, string ignoreEnd, StringSplitOptions options, int count)
|
||
{
|
||
List<string> entries = new List<string>();
|
||
for (int i = 0; i < separator.Length; i++)
|
||
{
|
||
char sep = separator[i];
|
||
entries.Add(sep.ToString());
|
||
}
|
||
return value.Split(entries.ToArray(), ignoreBegin, ignoreEnd, options, count);
|
||
}
|
||
public static string[] Split(this string value, string[] separator, string ignoreBegin, string ignoreEnd, StringSplitOptions options, int count)
|
||
{
|
||
return value.Split(separator, ignoreBegin, ignoreEnd, options, count, true);
|
||
}
|
||
public static string[] Split(this string value, string[] separator, string ignoreBegin, string ignoreEnd, StringSplitOptions options, int count, bool discardIgnoreString)
|
||
{
|
||
List<string> entries = new List<string>();
|
||
bool ignoring = false;
|
||
bool continueOutside = false;
|
||
string next = string.Empty;
|
||
int i = 0;
|
||
while (i < value.Length)
|
||
{
|
||
if (i + ignoreBegin.Length > value.Length)
|
||
{
|
||
goto IL_70;
|
||
}
|
||
if (ignoring || !(value.Substring(i, ignoreBegin.Length) == ignoreBegin))
|
||
{
|
||
goto IL_70;
|
||
}
|
||
ignoring = true;
|
||
if (!discardIgnoreString)
|
||
{
|
||
next += ignoreBegin;
|
||
}
|
||
IL_16F:
|
||
i++;
|
||
continue;
|
||
IL_70:
|
||
if (i + ignoreEnd.Length <= value.Length)
|
||
{
|
||
if (ignoring && value.Substring(i, ignoreEnd.Length) == ignoreEnd)
|
||
{
|
||
ignoring = false;
|
||
if (!discardIgnoreString)
|
||
{
|
||
next += ignoreEnd;
|
||
}
|
||
goto IL_16F;
|
||
}
|
||
}
|
||
if (!ignoring)
|
||
{
|
||
int j = 0;
|
||
while (j < separator.Length)
|
||
{
|
||
if (i + separator[j].Length <= value.Length)
|
||
{
|
||
if (value.Substring(i, separator[j].Length) == separator[j])
|
||
{
|
||
if (count > -1 && (entries.Count >= count - 1))
|
||
{
|
||
next = value.Substring(i - next.Length);
|
||
entries.Add(next);
|
||
i = value.Length - 1;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
entries.Add(next);
|
||
next = string.Empty;
|
||
i += separator[j].Length - 1;
|
||
continueOutside = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
j++;
|
||
continue;
|
||
}
|
||
}
|
||
if (continueOutside)
|
||
{
|
||
continueOutside = false;
|
||
goto IL_16F;
|
||
}
|
||
next += value[i];
|
||
goto IL_16F;
|
||
}
|
||
if (!string.IsNullOrEmpty(next))
|
||
{
|
||
entries.Add(next);
|
||
next = null;
|
||
}
|
||
return entries.ToArray();
|
||
}
|
||
#endregion
|
||
|
||
#region Endianness
|
||
[CLSCompliant(false)]
|
||
public static ushort SwapEndian(this ushort x)
|
||
{
|
||
return (ushort)(x >> 8 | (int)x << 8);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ushort SwapEndian(this short x)
|
||
{
|
||
return ((ushort)x).SwapEndian();
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint SwapEndian(this uint x)
|
||
{
|
||
return x >> 24 | (x << 8 & 16711680u) | (x >> 8 & 65280u) | x << 24;
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint SwapEndian(this int x)
|
||
{
|
||
return ((uint)x).SwapEndian();
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ushort Swap(short x)
|
||
{
|
||
return x.SwapEndian();
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ushort Swap(ushort x)
|
||
{
|
||
return x.SwapEndian();
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint Swap(int x)
|
||
{
|
||
return x.SwapEndian();
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint Swap(uint x)
|
||
{
|
||
return x.SwapEndian();
|
||
}
|
||
#endregion
|
||
#region Number
|
||
[CLSCompliant(false)]
|
||
public static uint RoundUp(this uint number, int multiple)
|
||
{
|
||
uint result;
|
||
if ((ulong)number % (ulong)((long)multiple) == 0uL)
|
||
{
|
||
result = number;
|
||
}
|
||
else
|
||
{
|
||
result = (uint)((ulong)number + (ulong)((long)multiple - (long)((ulong)number % (ulong)((long)multiple))));
|
||
}
|
||
return result;
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ulong RoundUp(this ulong number, int multiple)
|
||
{
|
||
ulong result;
|
||
if ((ulong)number % (ulong)((long)multiple) == 0uL)
|
||
{
|
||
result = number;
|
||
}
|
||
else
|
||
{
|
||
result = (ulong)((ulong)number + (ulong)((long)multiple - (long)((ulong)number % (ulong)((long)multiple))));
|
||
}
|
||
return result;
|
||
}
|
||
public static int RoundUp(this int number, int multiple)
|
||
{
|
||
int result;
|
||
if (number % multiple == 0)
|
||
{
|
||
result = number;
|
||
}
|
||
else
|
||
{
|
||
result = number + (multiple - number % multiple);
|
||
}
|
||
return result;
|
||
}
|
||
public static int Digits(this int number)
|
||
{
|
||
return number.ToString().Length;
|
||
}
|
||
public static int Digits(this long number)
|
||
{
|
||
return number.ToString().Length;
|
||
}
|
||
|
||
public static short UpperWord(this short number)
|
||
{
|
||
return (short)(number >> 16);
|
||
}
|
||
public static short LowerWord(this short number)
|
||
{
|
||
return (short)(number & 0xFFFF);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ushort UpperWord(this ushort number)
|
||
{
|
||
return (ushort)(number >> 16);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ushort LowerWord(this ushort number)
|
||
{
|
||
return (ushort)(number & 0xFFFF);
|
||
}
|
||
public static int UpperWord(this int number)
|
||
{
|
||
return (int)(number >> 16);
|
||
}
|
||
public static int LowerWord(this int number)
|
||
{
|
||
return (int)(number & 0xFFFF);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint UpperWord(this uint number)
|
||
{
|
||
return (uint)(number >> 16);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint LowerWord(this uint number)
|
||
{
|
||
return (uint)(number & 0xFFFF);
|
||
}
|
||
public static long UpperWord(this long number)
|
||
{
|
||
return (long)(number >> 16);
|
||
}
|
||
public static long LowerWord(this long number)
|
||
{
|
||
return (long)(number & 0xFFFF);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ulong UpperWord(this ulong number)
|
||
{
|
||
return (ulong)(number >> 16);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ulong LowerWord(this ulong number)
|
||
{
|
||
return (ulong)(number & 0xFFFF);
|
||
}
|
||
#endregion
|
||
#region StreamReader Extensions
|
||
|
||
public static byte ReadByte(this System.IO.Stream stream, long offset)
|
||
{
|
||
stream.Position = offset;
|
||
return (byte)stream.ReadByte();
|
||
}
|
||
public static byte[] ReadBytes(this System.IO.Stream stream, long offset, int length)
|
||
{
|
||
byte[] array = new byte[length];
|
||
stream.Position = offset;
|
||
stream.Read(array, 0, length);
|
||
return array;
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static byte[] ReadBytes(this System.IO.Stream stream, long offset, uint length)
|
||
{
|
||
return stream.ReadBytes(offset, (int)length);
|
||
}
|
||
public static short ReadShort(this System.IO.Stream stream, long offset)
|
||
{
|
||
byte[] array = new byte[2];
|
||
stream.Position = offset;
|
||
stream.Read(array, 0, 2);
|
||
return BitConverter.ToInt16(array, 0);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ushort ReadUShort(this System.IO.Stream stream, long offset)
|
||
{
|
||
byte[] array = new byte[2];
|
||
stream.Position = offset;
|
||
stream.Read(array, 0, 2);
|
||
return BitConverter.ToUInt16(array, 0);
|
||
}
|
||
public static int ReadInt(this System.IO.Stream stream, long offset)
|
||
{
|
||
byte[] array = new byte[4];
|
||
stream.Position = offset;
|
||
stream.Read(array, 0, 4);
|
||
return BitConverter.ToInt32(array, 0);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static uint ReadUInt(this System.IO.Stream stream, long offset)
|
||
{
|
||
byte[] array = new byte[4];
|
||
stream.Position = offset;
|
||
stream.Read(array, 0, 4);
|
||
return BitConverter.ToUInt32(array, 0);
|
||
}
|
||
public static string ReadString(this System.IO.Stream stream, long offset, int maxLength, bool nullTerminator)
|
||
{
|
||
string text = string.Empty;
|
||
stream.Position = offset;
|
||
for (int i = 0; i < maxLength; i++)
|
||
{
|
||
char c = (char)stream.ReadByte();
|
||
if (c == '\0' && nullTerminator)
|
||
{
|
||
break;
|
||
}
|
||
text += c;
|
||
}
|
||
return text;
|
||
}
|
||
public static string ReadString(this System.IO.Stream stream, long offset, int maxLength)
|
||
{
|
||
return stream.ReadString(offset, maxLength, true);
|
||
}
|
||
public static string ReadString(this System.IO.Stream stream, long offset, int maxLength, Encoding encoding, bool nullTerminator)
|
||
{
|
||
stream.Position = offset;
|
||
byte[] array = new byte[maxLength];
|
||
stream.Read(array, 0, maxLength);
|
||
string text = encoding.GetString(array);
|
||
if (nullTerminator)
|
||
{
|
||
string arg_2D_0 = text;
|
||
char[] trimChars = new char[1];
|
||
text = arg_2D_0.TrimEnd(trimChars);
|
||
}
|
||
return text;
|
||
}
|
||
public static string ReadString(this System.IO.Stream stream, long offset, int maxLength, Encoding encoding)
|
||
{
|
||
return stream.ReadString(offset, maxLength, encoding, true);
|
||
}
|
||
public static byte[] ToByteArray(this System.IO.Stream stream)
|
||
{
|
||
long oldpos = stream.Position;
|
||
|
||
byte[] array = new byte[(int)((IntPtr)stream.Length)];
|
||
stream.Position = 0L;
|
||
stream.Read(array, 0, array.Length);
|
||
|
||
stream.Position = oldpos;
|
||
return array;
|
||
}
|
||
#endregion
|
||
#region StreamWriter Extensions
|
||
|
||
public static void Write(this System.IO.Stream stream, byte value)
|
||
{
|
||
stream.WriteByte(value);
|
||
}
|
||
public static void Write(this System.IO.Stream stream, short value)
|
||
{
|
||
stream.Write(BitConverter.GetBytes(value), 0, 2);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static void Write(this System.IO.Stream stream, ushort value)
|
||
{
|
||
stream.Write(BitConverter.GetBytes(value), 0, 2);
|
||
}
|
||
public static void Write(this System.IO.Stream stream, int value)
|
||
{
|
||
stream.Write(BitConverter.GetBytes(value), 0, 4);
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static void Write(this System.IO.Stream stream, uint value)
|
||
{
|
||
stream.Write(BitConverter.GetBytes(value), 0, 4);
|
||
}
|
||
public static void Write(this System.IO.Stream stream, byte[] values)
|
||
{
|
||
stream.Write(values, 0, values.Length);
|
||
}
|
||
public static void Write(this System.IO.Stream stream, string value)
|
||
{
|
||
for (int i = 0; i < value.Length; i++)
|
||
{
|
||
stream.WriteByte((byte)value[i]);
|
||
}
|
||
}
|
||
public static void Write(this System.IO.Stream stream, string value, int length)
|
||
{
|
||
for (int i = 0; i < length; i++)
|
||
{
|
||
if (i < value.Length)
|
||
{
|
||
stream.WriteByte((byte)value[i]);
|
||
}
|
||
else
|
||
{
|
||
stream.WriteByte(0);
|
||
}
|
||
}
|
||
}
|
||
public static void Write(this System.IO.Stream stream, string value, int strLength, int length)
|
||
{
|
||
for (int i = 0; i < length; i++)
|
||
{
|
||
if (i < value.Length && i < strLength)
|
||
{
|
||
stream.WriteByte((byte)value[i]);
|
||
}
|
||
else
|
||
{
|
||
stream.WriteByte(0);
|
||
}
|
||
}
|
||
}
|
||
public static void Write(this System.IO.Stream stream, string value, int strLength, int length, Encoding encoding)
|
||
{
|
||
byte[] bytes = encoding.GetBytes(value);
|
||
int num = 0;
|
||
while (bytes.Length > strLength)
|
||
{
|
||
num++;
|
||
bytes = encoding.GetBytes(value.Substring(0, value.Length - num));
|
||
}
|
||
for (int i = 0; i < length; i++)
|
||
{
|
||
if (i < bytes.Length && i < strLength)
|
||
{
|
||
stream.WriteByte(bytes[i]);
|
||
}
|
||
else
|
||
{
|
||
stream.WriteByte(0);
|
||
}
|
||
}
|
||
}
|
||
public static void Write(this System.IO.Stream output, System.IO.Stream input)
|
||
{
|
||
byte[] array = new byte[4096];
|
||
input.Position = 0L;
|
||
int count;
|
||
while ((count = input.Read(array, 0, array.Length)) > 0)
|
||
{
|
||
output.Write(array, 0, count);
|
||
}
|
||
}
|
||
public static void Write(this System.IO.Stream output, System.IO.MemoryStream input)
|
||
{
|
||
input.Position = 0L;
|
||
input.WriteTo(output);
|
||
}
|
||
public static void Write(this System.IO.Stream output, System.IO.Stream input, long offset, long length)
|
||
{
|
||
byte[] array = new byte[4096];
|
||
input.Position = offset;
|
||
int count;
|
||
while ((count = input.Read(array, 0, (input.Position + (long)array.Length > offset + length) ? ((int)(offset + length - input.Position)) : ((int)((long)array.Length)))) > 0)
|
||
{
|
||
output.Write(array, 0, count);
|
||
}
|
||
}
|
||
public static System.IO.MemoryStream Copy(this System.IO.Stream input)
|
||
{
|
||
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream((int)input.Length);
|
||
byte[] array = new byte[4096];
|
||
input.Position = 0L;
|
||
int count;
|
||
while ((count = input.Read(array, 0, array.Length)) > 0)
|
||
{
|
||
memoryStream.Write(array, 0, count);
|
||
}
|
||
return memoryStream;
|
||
}
|
||
public static System.IO.MemoryStream Copy(this System.IO.Stream input, long offset, int length)
|
||
{
|
||
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(length);
|
||
byte[] array = new byte[4096];
|
||
input.Position = offset;
|
||
int count;
|
||
while ((count = input.Read(array, 0, (input.Position + (long)array.Length > offset + (long)length) ? ((int)(offset + (long)length - input.Position)) : ((int)((long)array.Length)))) > 0)
|
||
{
|
||
memoryStream.Write(array, 0, count);
|
||
}
|
||
return memoryStream;
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static System.IO.MemoryStream Copy(this System.IO.Stream input, long offset, uint length)
|
||
{
|
||
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream((int)length);
|
||
byte[] array = new byte[4096];
|
||
input.Position = offset;
|
||
int count;
|
||
while ((count = input.Read(array, 0, (input.Position + (long)array.Length > offset + (long)((ulong)length)) ? ((int)(offset + (long)((ulong)length) - input.Position)) : ((int)((long)array.Length)))) > 0)
|
||
{
|
||
memoryStream.Write(array, 0, count);
|
||
}
|
||
return memoryStream;
|
||
}
|
||
#endregion
|
||
#region Strings
|
||
public static bool IsAllUpperCase(this string str)
|
||
{
|
||
return (!(new System.Text.RegularExpressions.Regex("[a-z]")).IsMatch(str));
|
||
}
|
||
public static string UrlEncode(this string value)
|
||
{
|
||
return value;
|
||
}
|
||
public static string UrlDecode(this string input)
|
||
{
|
||
StringBuilder output = new StringBuilder();
|
||
for (int i = 0; i < input.Length; i++)
|
||
{
|
||
if (input[i] == '%')
|
||
{
|
||
char c = input[i + 1];
|
||
string arg_45_0 = c.ToString();
|
||
c = input[i + 2];
|
||
string numeric = arg_45_0 + c.ToString();
|
||
int hexcode = int.Parse(numeric, System.Globalization.NumberStyles.HexNumber);
|
||
i += 2;
|
||
output.Append((char)hexcode);
|
||
}
|
||
else
|
||
{
|
||
output.Append(input[i]);
|
||
}
|
||
}
|
||
return output.ToString();
|
||
}
|
||
public static bool Match(this string input, params string[] filters)
|
||
{
|
||
foreach (string filter in filters)
|
||
{
|
||
if (input.Match(filter)) return true;
|
||
}
|
||
return false;
|
||
}
|
||
public static bool Match(this string input, string filter)
|
||
{
|
||
string wildcardToRegex = "^" + System.Text.RegularExpressions.Regex.Escape(filter).Replace("\\*", ".*").Replace("\\?", ".") + "$";
|
||
return new System.Text.RegularExpressions.Regex(wildcardToRegex).IsMatch(input);
|
||
}
|
||
public static string TrimNull(this string value)
|
||
{
|
||
int i = value.IndexOf('\0');
|
||
if (i > -1) return value.Substring(0, i);
|
||
return value;
|
||
}
|
||
public static string Format(this string input, Dictionary<string, string> formatWhat)
|
||
{
|
||
return Format(input, formatWhat, "$(", ")");
|
||
}
|
||
public static string Format(this string input, Dictionary<string, string> formatWhat, string formatBegin, string formatEnd)
|
||
{
|
||
string val = input;
|
||
foreach (KeyValuePair<string, string> kvp in formatWhat)
|
||
{
|
||
val = val.Replace(formatBegin + kvp.Key + formatEnd, kvp.Value);
|
||
}
|
||
return val;
|
||
}
|
||
/// <summary>
|
||
/// Inserts the specified value "count" times, with "spacing" characters between.
|
||
/// </summary>
|
||
/// <param name="count">The number of times to insert value.</param>
|
||
/// <param name="spacing">The amount of characters to leave between insertions.</param>
|
||
/// <param name="value">The value to insert.</param>
|
||
/// <returns></returns>
|
||
public static string Insert(this string input, int count, int spacing, string value)
|
||
{
|
||
int j = 0;
|
||
string retval = String.Empty;
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
retval += input.Substring(j, spacing) + value;
|
||
j += spacing;
|
||
}
|
||
retval += input.Substring(j);
|
||
return retval;
|
||
}
|
||
#endregion
|
||
|
||
#region Dictionary
|
||
public static KeyValuePair<TKey, TValue>[] ToArray<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
|
||
{
|
||
System.Collections.Generic.List<KeyValuePair<TKey, TValue>> list = new List<KeyValuePair<TKey, TValue>>();
|
||
foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
|
||
{
|
||
list.Add(kvp);
|
||
}
|
||
return list.ToArray();
|
||
}
|
||
public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value = default(TValue))
|
||
{
|
||
if (dictionary.ContainsKey(key))
|
||
{
|
||
return dictionary[key];
|
||
}
|
||
return value;
|
||
}
|
||
#endregion
|
||
|
||
#region Arrays
|
||
public static void Fill<T>(this T[] data, T value)
|
||
{
|
||
for (int i = 0; i < data.Length; i++)
|
||
{
|
||
data[i] = value;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
public static long RoundToNearestPowerOf2(this long input)
|
||
{
|
||
long v = input;
|
||
v--;
|
||
v |= v >> 1;
|
||
v |= v >> 2;
|
||
v |= v >> 4;
|
||
v |= v >> 8;
|
||
v |= v >> 16;
|
||
v++;
|
||
return v;
|
||
}
|
||
[CLSCompliant(false)]
|
||
public static ulong RoundToNearestPowerOf2(this ulong input)
|
||
{
|
||
ulong v = input;
|
||
v--;
|
||
v |= v >> 1;
|
||
v |= v >> 2;
|
||
v |= v >> 4;
|
||
v |= v >> 8;
|
||
v |= v >> 16;
|
||
v++;
|
||
return v;
|
||
}
|
||
}
|
||
}
|