Files
mirror-processhacker/trunk/ProcessHacker.Common/Utils.cs
T
wj32 6ad1ea536a * eliminated all architecture dependent IntPtr.ToStrings
* deleted old API logger code

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1682 21ef857c-d57f-4fe0-8362-d861dc6d29cd
2009-08-09 11:20:31 +00:00

1184 lines
40 KiB
C#

/*
* Process Hacker -
* misc. functions
*
* Copyright (C) 2008-2009 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker 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 General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace ProcessHacker.Common
{
/// <summary>
/// Provides methods for manipulating various types of data.
/// </summary>
public static class Utils
{
#region Constants
public static string[] SizeUnitNames = { "B", "kB", "MB", "GB", "TB", "PB", "EB" };
public static string[] PrivilegeNames =
{
"SeCreateTokenPrivilege",
"SeAssignPrimaryTokenPrivilege",
"SeLockMemoryPrivilege",
"SeIncreaseQuotaPrivilege",
"SeUnsolicitedInputPrivilege",
"SeMachineAccountPrivilege",
"SeTcbPrivilege",
"SeSecurityPrivilege",
"SeTakeOwnershipPrivilege",
"SeLoadDriverPrivilege",
"SeSystemProfilePrivilege",
"SeSystemtimePrivilege",
"SeProfileSingleProcessPrivilege",
"SeIncreaseBasePriorityPrivilege",
"SeCreatePagefilePrivilege",
"SeCreatePermanentPrivilege",
"SeBackupPrivilege",
"SeRestorePrivilege",
"SeShutdownPrivilege",
"SeDebugPrivilege",
"SeAuditPrivilege",
"SeSystemEnvironmentPrivilege",
"SeChangeNotifyPrivilege",
"SeRemoteShutdownPrivilege",
"SeUndockPrivilege",
"SeSyncAgentPrivilege",
"SeEnableDelegationPrivilege",
"SeManageVolumePrivilege",
"SeImpersonatePrivilege",
"SeCreateGlobalPrivilege",
"SeTrustedCredManAccessPrivilege",
"SeRelabelPrivilege",
"SeIncreaseWorkingSetPrivilege",
"SeTimeZonePrivilege",
"SeCreateSymbolicLinkPrivilege"
};
#endregion
/// <summary>
/// The maximum unit specifier to use when formatting sizes.
/// </summary>
public static int UnitSpecifier = 4;
/// <summary>
/// Flattens an array of arrays into a single array.
/// </summary>
/// <typeparam name="T">The type of each element in the arrays.</typeparam>
/// <param name="ap">
/// An array of arrays. If an array in the array is null, it will be ignored.
/// </param>
/// <returns>An array containing elements from each array.</returns>
public static T[] Concat<T>(params T[][] ap)
{
int tl = 0;
foreach (var array in ap)
if (array != null)
tl += array.Length;
T[] na = new T[tl];
int i = 0;
foreach (var array in ap)
{
if (array != null)
{
Array.Copy(array, 0, na, i, array.Length);
i += array.Length;
}
}
return na;
}
/// <summary>
/// Counts the number of bits in the specified number.
/// </summary>
/// <param name="value">The number to process.</param>
/// <returns>The number of bits in the specified number.</returns>
public static int CountBits(this long value)
{
int count = 0;
while (value != 0)
{
count++;
value &= value - 1;
}
return count;
}
/// <summary>
/// Creates an array of bytes from the specified byte pointer.
/// </summary>
/// <param name="ptr">A pointer to an array of bytes.</param>
/// <param name="length">The length of the array.</param>
/// <returns>A new byte array.</returns>
public unsafe static byte[] Create(byte* ptr, int length)
{
byte[] array = new byte[length];
for (int i = 0; i < length; i++)
array[i] = ptr[i];
return array;
}
/// <summary>
/// Adds an ellipsis to a string if it is longer than the specified length.
/// </summary>
/// <param name="s">The string.</param>
/// <param name="len">The maximum length.</param>
/// <returns>The modified string.</returns>
public static string CreateEllipsis(string s, int len)
{
if (s.Length <= len)
return s;
else
return s.Substring(0, len - 4) + " ...";
}
/// <summary>
/// Creates a string containing random uppercase characters.
/// </summary>
/// <param name="length">The number of characters to generate.</param>
/// <returns>The generated string.</returns>
public static string CreateRandomString(int length)
{
Random r = new Random((int)(DateTime.Now.ToFileTime() & 0xffffffff));
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++)
sb.Append((char)('A' + r.Next(25)));
return sb.ToString();
}
/// <summary>
/// Clears and cleans up resources held by the menu items.
/// </summary>
public static void DisposeAndClear(this Menu.MenuItemCollection items)
{
//foreach (MenuItem item in items)
//{
// item.Dispose();
//}
items.Clear();
}
/// <summary>
/// Disables the menu items contained in the specified menu.
/// </summary>
/// <param name="menu">The menu.</param>
public static void DisableAllMenuItems(Menu menu)
{
foreach (MenuItem item in menu.MenuItems)
item.Enabled = false;
}
/// <summary>
/// Disables all menu items.
/// </summary>
public static void DisableAll(this Menu menu)
{
DisableAllMenuItems(menu);
}
/// <summary>
/// Duplicates the specified array.
/// </summary>
/// <typeparam name="T">The type of array to duplicate.</typeparam>
/// <param name="array">The array to duplicate.</param>
/// <returns>A copy of the specified array.</returns>
public static T[] Duplicate<T>(this T[] array)
{
T[] newArray = new T[array.Length];
array.CopyTo(newArray, 0);
return newArray;
}
/// <summary>
/// Enables the menu items contained in the specified menu.
/// </summary>
/// <param name="menu">The menu.</param>
public static void EnableAllMenuItems(Menu menu)
{
foreach (MenuItem item in menu.MenuItems)
item.Enabled = true;
}
/// <summary>
/// Enables all menu items.
/// </summary>
public static void EnableAll(this Menu menu)
{
EnableAllMenuItems(menu);
}
/// <summary>
/// Compares two arrays and determines whether they are equal.
/// </summary>
/// <typeparam name="T">The type of each element in the arrays.</typeparam>
/// <param name="array">The first array.</param>
/// <param name="other">The second array.</param>
/// <returns>Whether the two arrays are considered to be equal.</returns>
public static bool Equals<T>(T[] array, T[] other)
{
return Equals(array, other, 0);
}
/// <summary>
/// Compares two arrays and determines whether they are equal.
/// </summary>
/// <typeparam name="T">The type of each element in the arrays.</typeparam>
/// <param name="array">The first array.</param>
/// <param name="other">The second array.</param>
/// <param name="startIndex">The index from which to begin comparing.</param>
/// <returns>Whether the two arrays are considered to be equal.</returns>
public static bool Equals<T>(T[] array, T[] other, int startIndex)
{
return Equals(array, other, startIndex, array.Length);
}
/// <summary>
/// Compares two arrays and determines whether they are equal.
/// </summary>
/// <typeparam name="T">The type of each element in the arrays.</typeparam>
/// <param name="array">The first array.</param>
/// <param name="other">The second array.</param>
/// <param name="startIndex">The index from which to begin comparing.</param>
/// <param name="length">The number of elements to compare.</param>
/// <returns>Whether the two arrays are considered to be equal.</returns>
public static bool Equals<T>(T[] array, T[] other, int startIndex, int length)
{
for (int i = startIndex; i < startIndex + length; i++)
if (!array[i].Equals(other[i]))
return false;
return true;
}
/// <summary>
/// Escapes a string using C-style escaping.
/// </summary>
/// <param name="str">The string to escape.</param>
/// <returns>The escaped string.</returns>
public static string EscapeString(string str)
{
str = str.Replace("\\", "\\\\");
str = str.Replace("\"", "\\\"");
return str;
}
/// <summary>
/// Fills a combobox with enum value names.
/// </summary>
/// <param name="box">The combobox to modify.</param>
/// <param name="t">The type of the enum.</param>
public static void Fill(this ComboBox box, Type t)
{
foreach (string s in Enum.GetNames(t))
box.Items.Add(s);
}
/// <summary>
/// Moves the specified rectangle to fit inside the working area
/// of the display containing the specified control.
/// </summary>
/// <param name="rect">The rectangle to process.</param>
/// <param name="c">The control from which to get the display.</param>
/// <returns>A new rectangle with its location modified.</returns>
public static Rectangle FitRectangle(Rectangle rect, Control c)
{
return FitRectangle(rect, Screen.GetWorkingArea(c));
}
/// <summary>
/// Moves the specified rectangle to fit inside the specified bounds.
/// </summary>
/// <param name="rect">The rectangle to process.</param>
/// <param name="bounds">The bounds in which the rectangle should be.</param>
/// <returns>A new rectangle with its location modified.</returns>
public static Rectangle FitRectangle(Rectangle rect, Rectangle bounds)
{
if (rect.X < bounds.Left)
rect.X = bounds.Left;
if (rect.Y < bounds.Top)
rect.Y = bounds.Top;
if (rect.X + rect.Width > bounds.Width)
rect.X = bounds.Width - rect.Width;
if (rect.Y + rect.Height > bounds.Height)
rect.Y = bounds.Height - rect.Height;
return rect;
}
/// <summary>
/// Gets a string representation for an address.
/// </summary>
/// <param name="address">An address.</param>
/// <returns>A string representation of the specified address.</returns>
public static string FormatAddress(int address)
{
return "0x" + address.ToString("x");
}
/// <summary>
/// Gets a string representation for an address.
/// </summary>
/// <param name="address">An address.</param>
/// <returns>A string representation of the specified address.</returns>
public static string FormatAddress(uint address)
{
return "0x" + address.ToString("x");
}
/// <summary>
/// Gets a string representation for an address.
/// </summary>
/// <param name="address">An address.</param>
/// <returns>A string representation of the specified address.</returns>
public static string FormatAddress(long address)
{
return "0x" + address.ToString("x");
}
/// <summary>
/// Gets a string representation for an address.
/// </summary>
/// <param name="address">An address.</param>
/// <returns>A string representation of the specified address.</returns>
public static string FormatAddress(ulong address)
{
return "0x" + address.ToString("x");
}
/// <summary>
/// Gets a string representation for an address.
/// </summary>
/// <param name="address">An address.</param>
/// <returns>A string representation of the specified address.</returns>
public static string FormatAddress(IntPtr address)
{
return "0x" + address.ToString("x");
}
/// <summary>
/// Gets the string representation of a priority number.
/// </summary>
/// <param name="priority">A priority number.</param>
/// <returns>A string.</returns>
public static string FormatPriority(int priority)
{
if (priority >= 24)
return "Realtime";
else if (priority >= 13)
return "High";
else if (priority >= 10)
return "Above Normal";
else if (priority >= 8)
return "Normal";
else if (priority >= 6)
return "Below Normal";
else
return "Idle";
}
/// <summary>
/// Gets the relative time in nice English.
/// </summary>
/// <param name="time">A DateTime.</param>
/// <returns>A string.</returns>
public static string FormatRelativeDateTime(DateTime time)
{
// Get the time span from the time to now.
TimeSpan span = DateTime.Now.Subtract(time);
// The partial number of weeks.
double weeks = span.TotalDays / 7;
// The partial number of fortnights.
double fortnights = weeks / 2;
// ...
double months = span.TotalDays * 12 / 365;
double years = months / 12;
double centuries = years / 100;
string str = "";
// Start from the most general time unit and see if they can be used
// without any fractional component.
// x centur(y|ies)
if (centuries >= 1)
str = (int)centuries + " " + ((int)centuries == 1 ? "century" : "centuries");
// x year(s)
else if (years >= 1)
str = (int)years + " " + ((int)years == 1 ? "year" : "years");
// x month(s)
else if (months >= 1)
str = (int)months + " " + ((int)months == 1 ? "month" : "months");
// x fortnight(s)
else if (fortnights >= 1)
str = (int)fortnights + " " + ((int)fortnights == 1 ? "fortnight" : "fortnights");
// x week(s)
else if (weeks >= 1)
str = (int)weeks + " " + ((int)weeks == 1 ? "week" : "weeks");
// x day(s) (and y hour(s))
else if (span.TotalDays >= 1)
{
str = (int)span.TotalDays + " " + ((int)span.TotalDays == 1 ? "day" : "days");
if (span.Hours >= 1)
str += " and " + span.Hours + " " +
(span.Hours == 1 ? "hour" : "hours");
}
// x hour(s) (and y minute(s))
else if (span.Hours >= 1)
{
str = span.Hours + " " + (span.Hours == 1 ? "hour" : "hours");
if (span.Minutes >= 1)
str += " and " + span.Minutes + " " +
(span.Minutes == 1 ? "minute" : "minutes");
}
// x minute(s) (and y second(s))
else if (span.Minutes >= 1)
{
str = span.Minutes + " " + (span.Minutes == 1 ? "minute" : "minutes");
if (span.Seconds >= 1)
str += " and " + span.Seconds + " " +
(span.Seconds == 1 ? "second" : "seconds");
}
// x second(s)
else if (span.Seconds >= 1)
str = span.Seconds + " " + (span.Seconds == 1 ? "second" : "seconds");
// x millisecond(s)
else if (span.Milliseconds >= 1)
str = span.Milliseconds + " " + (span.Milliseconds == 1 ? "millisecond" : "milliseconds");
else
str = "a very short time";
// Turn 1 into "a", e.g. 1 minute -> a minute
if (str.StartsWith("1 "))
{
// Special vowel case: a hour -> an hour
if (str[2] != 'h')
str = "a " + str.Substring(2);
else
str = "an " + str.Substring(2);
}
return str + " ago";
}
/// <summary>
/// Formats a size into a string representation, postfixing it with the correct unit.
/// </summary>
/// <param name="size">The size to format.</param>
public static string FormatSize(int size)
{
return FormatSize((uint)size);
}
/// <summary>
/// Formats a size into a string representation, postfixing it with the correct unit.
/// </summary>
/// <param name="size">The size to format.</param>
public static string FormatSize(uint size)
{
int i = 0;
double s = (double)size;
while (s > 1024 && i < SizeUnitNames.Length && i < UnitSpecifier)
{
s /= 1024;
i++;
}
return (s == 0 ? "0" : s.ToString("#,#.##")) + " " + SizeUnitNames[i];
}
/// <summary>
/// Formats a size into a string representation, postfixing it with the correct unit.
/// </summary>
/// <param name="size">The size to format.</param>
public static string FormatSize(IntPtr size)
{
unchecked
{
return FormatSize((ulong)size.ToInt64());
}
}
/// <summary>
/// Formats a size into a string representation, postfixing it with the correct unit.
/// </summary>
/// <param name="size">The size to format.</param>
public static string FormatSize(long size)
{
return FormatSize((ulong)size);
}
/// <summary>
/// Formats a size into a string representation, postfixing it with the correct unit.
/// </summary>
/// <param name="size">The size to format.</param>
public static string FormatSize(ulong size)
{
int i = 0;
double s = (double)size;
while (s > 1024 && i < SizeUnitNames.Length && i < UnitSpecifier)
{
s /= 1024;
i++;
}
return (s == 0 ? "0" : s.ToString("#,#.##")) + " " + SizeUnitNames[i];
}
/// <summary>
/// Formats a <see cref="TimeSpan"/> object into a string representation.
/// </summary>
/// <param name="time">The <see cref="TimeSpan"/> to format.</param>
/// <returns></returns>
public static string FormatTimeSpan(TimeSpan time)
{
return String.Format("{0:d2}:{1:d2}:{2:d2}.{3:d3}",
time.Hours,
time.Minutes,
time.Seconds,
time.Milliseconds);
}
/// <summary>
/// Converts a 64-bit Windows time value to a DateTime object.
/// </summary>
/// <param name="time">The Windows time value.</param>
public static DateTime GetDateTimeFromLongTime(long time)
{
return (new DateTime(1601, 1, 1)).AddTicks(time).ToLocalTime();
}
/// <summary>
/// Converts a 32-bit Unix time value into a DateTime object.
/// </summary>
/// <param name="time">The Unix time value.</param>
public static DateTime GetDateTimeFromUnixTime(uint time)
{
return (new DateTime(1970, 1, 1, 0, 0, 0)).Add(new TimeSpan(0, 0, 0, (int)time));
}
/// <summary>
/// Parses a string and produces a rectangle.
/// </summary>
/// <param name="s">
/// A string describing a rectangle in the following format:
/// x,y,width,height (with no spaces).
/// </param>
/// <returns>A rectangle.</returns>
public static Rectangle GetRectangle(string s)
{
var split = s.Split(',');
return new Rectangle(int.Parse(split[0]), int.Parse(split[1]),
int.Parse(split[2]), int.Parse(split[3]));
}
/// <summary>
/// Returns a <see cref="ProcessThread"/> object of the specified thread ID.
/// </summary>
/// <param name="p">The process which the thread belongs to.</param>
/// <param name="id">The ID of the thread.</param>
/// <returns></returns>
public static ProcessThread GetThreadFromId(Process p, int id)
{
foreach (ProcessThread t in p.Threads)
if (t.Id == id)
return t;
return null;
}
/// <summary>
/// Determines whether the array is empty (all 0's).
/// </summary>
/// <param name="array">The array to search.</param>
/// <returns>True if the array is empty; otherwise false.</returns>
public static bool IsEmpty(byte[] array)
{
bool empty = true;
foreach (byte b in array)
{
if (b != 0)
{
empty = false;
break;
}
}
return empty;
}
/// <summary>
/// Makes a character printable by converting unprintable characters to a dot ('.').
/// </summary>
/// <param name="c">The character to convert.</param>
/// <returns></returns>
public static char MakePrintable(char c)
{
if (c >= ' ' && c <= '~')
return c;
else
return '.';
}
/// <summary>
/// Makes a string printable by converting unprintable characters to a dot ('.').
/// </summary>
/// <param name="s">The string to convert.</param>
/// <returns></returns>
public static string MakePrintable(string s)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.Length; i++)
sb.Append(MakePrintable(s[i]));
return sb.ToString();
}
public static System.Diagnostics.ProcessPriorityClass NativeToWindowsBasePriority(int priority)
{
if (priority >= 24)
return ProcessPriorityClass.RealTime;
else if (priority >= 13)
return ProcessPriorityClass.High;
else if (priority >= 10)
return ProcessPriorityClass.AboveNormal;
else if (priority >= 8)
return ProcessPriorityClass.Normal;
else if (priority >= 6)
return ProcessPriorityClass.BelowNormal;
else
return ProcessPriorityClass.Idle;
}
/// <summary>
/// Reads a null-terminated string from a stream.
/// </summary>
/// <param name="s">The stream to read from.</param>
/// <returns>The read string.</returns>
public static string ReadString(Stream s)
{
StringBuilder str = new StringBuilder();
while (true)
{
int b = s.ReadByte();
if (b == 0 || b == -1)
break;
str.Append((char)(byte)b);
}
return str.ToString();
}
/// <summary>
/// Reads a null-terminated Unicode string from a stream.
/// </summary>
/// <param name="s">The stream to read from.</param>
/// <returns>The read string.</returns>
public static string ReadUnicodeString(Stream s)
{
StringBuilder str = new StringBuilder();
while (true)
{
int b = s.ReadByte();
if (b == -1)
break;
int b2 = s.ReadByte();
if (b2 == -1)
break;
if (b == 0 && b2 == 0)
break;
str.Append(UnicodeEncoding.Unicode.GetChars(new byte[] { (byte)b, (byte)b2 }));
}
return str.ToString();
}
/// <summary>
/// Reads a Unicode string from a stream.
/// </summary>
/// <param name="s">The stream to read from.</param>
/// <param name="length">The length, in bytes, of the string.</param>
/// <returns>The read string.</returns>
public static string ReadUnicodeString(Stream s, int length)
{
StringBuilder str = new StringBuilder();
int i = 0;
while (i < length)
{
int b = s.ReadByte();
if (b == -1)
break;
int b2 = s.ReadByte();
if (b2 == -1)
break;
str.Append(UnicodeEncoding.Unicode.GetChars(new byte[] { (byte)b, (byte)b2 }));
i += 2;
}
return str.ToString();
}
/// <summary>
/// Selects all of the specified items.
/// </summary>
/// <param name="items">The items.</param>
public static void SelectAll(this ListView.ListViewItemCollection items)
{
foreach (ListViewItem item in items)
item.Selected = true;
}
/// <summary>
/// Selects all of the items in the specified ListView.
/// </summary>
/// <param name="items">The ListView to process.</param>
public static void SelectAll(this ListView items)
{
for (int i = 0; i < items.VirtualListSize; i++)
if (!items.SelectedIndices.Contains(i))
items.SelectedIndices.Add(i);
}
/// <summary>
/// Enables or disables double buffering for a control.
/// </summary>
/// <param name="c">The control.</param>
/// <param name="t">The type of the control.</param>
/// <param name="value">The new setting.</param>
public static void SetDoubleBuffered(Control c, Type t, bool value)
{
PropertyInfo property = t.GetProperty("DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance);
property.SetValue(c, value, null);
}
/// <summary>
/// Enables or disables double buffering for a control.
/// </summary>
/// <param name="c">The control to set the property on.</param>
/// <param name="value">The new value.</param>
public static void SetDoubleBuffered(this Control c, bool value)
{
SetDoubleBuffered(c, c.GetType(), value);
}
/// <summary>
/// Shows a file in Windows Explorer.
/// </summary>
/// <param name="fileName">The file to show.</param>
public static void ShowFileInExplorer(string fileName)
{
Process.Start("explorer.exe", "/select," + fileName);
}
/// <summary>
/// Returns a sorted list of the names in a given enum type.
/// </summary>
/// <param name="enumType">The enum type to process.</param>
/// <returns>A list of key-value pairs, sorted based on the number of bits in the value.</returns>
public static List<KeyValuePair<string, long>> SortFlagNames(Type enumType)
{
List<KeyValuePair<string, long>> nameList = new List<KeyValuePair<string, long>>();
foreach (string name in Enum.GetNames(enumType))
{
long nameLong = Convert.ToInt64(Enum.Parse(enumType, name));
nameList.Add(new KeyValuePair<string, long>(name, nameLong));
}
nameList.Sort((kvp1, kvp2) => kvp2.Value.CountBits().CompareTo(kvp1.Value.CountBits()));
return nameList;
}
/// <summary>
/// Swaps the order of the bytes.
/// </summary>
/// <param name="v">The number to change.</param>
/// <returns>A number.</returns>
public static int SwapBytes(this int v)
{
byte b1 = (byte)v;
byte b2 = (byte)(v >> 8);
byte b3 = (byte)(v >> 16);
byte b4 = (byte)(v >> 24);
return b4 | (b3 << 8) | (b2 << 16) | (b1 << 24);
}
/// <summary>
/// Swaps the order of the bytes.
/// </summary>
/// <param name="v">The number to change.</param>
/// <returns>A number.</returns>
public static uint SwapBytes(this uint v)
{
byte b1 = (byte)v;
byte b2 = (byte)(v >> 8);
byte b3 = (byte)(v >> 16);
byte b4 = (byte)(v >> 24);
return (uint)(b4 | (b3 << 8) | (b2 << 16) | (b1 << 24));
}
/// <summary>
/// Swaps the order of the bytes.
/// </summary>
/// <param name="v">The number to change.</param>
/// <returns>A number.</returns>
public static ushort SwapBytes(this ushort v)
{
byte b1 = (byte)v;
byte b2 = (byte)(v >> 8);
return (ushort)(b2 | (b1 << 8));
}
public static int WindowsToNativeBasePriority(System.Diagnostics.ProcessPriorityClass priority)
{
switch (priority)
{
case ProcessPriorityClass.RealTime:
return 24;
case ProcessPriorityClass.High:
return 13;
case ProcessPriorityClass.AboveNormal:
return 10;
case ProcessPriorityClass.Normal:
return 8;
case ProcessPriorityClass.BelowNormal:
return 6;
case ProcessPriorityClass.Idle:
return 4;
default:
return 8;
}
}
#region Stuff from PNG.Net
public enum Endianness
{
Little, Big
}
public static bool ArrayContains<T>(T[] array, T element)
{
foreach (T e in array)
if (e.Equals(element))
return true;
return false;
}
public static bool BytesEqual(byte[] b1, byte[] b2)
{
for (int i = 0; i < b1.Length; i++)
if (b1[i] != b2[i])
return false;
return true;
}
public static int BytesToInt(byte[] data, Endianness type)
{
if (type == Endianness.Little)
{
return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
else if (type == Endianness.Big)
{
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
}
else
{
throw new ArgumentException();
}
}
public static long BytesToLong(byte[] data, Endianness type)
{
if (type == Endianness.Little)
{
return (data[0]) | (data[1] << 8) | (data[2] << 16) | (data[3] << 24) |
(data[4] << 32) | (data[5] << 40) | (data[6] << 48) | (data[7] << 56);
}
else if (type == Endianness.Big)
{
return (data[0] << 56) | (data[1] << 48) | (data[2] << 40) | (data[3] << 32) |
(data[4] << 24) | (data[5] << 16) | (data[6] << 8) | (data[7]);
}
else
{
throw new ArgumentException();
}
}
public static uint BytesToUInt(byte[] data, Endianness type)
{
return BytesToUInt(data, 0, type);
}
public static uint BytesToUInt(byte[] data, int offset, Endianness type)
{
if (type == Endianness.Little)
{
return (uint)(data[offset]) | (uint)(data[offset + 1] << 8) |
(uint)(data[offset + 2] << 16) | (uint)(data[offset + 3] << 24);
}
else if (type == Endianness.Big)
{
return (uint)(data[offset] << 24) | (uint)(data[offset + 1] << 16) |
(uint)(data[offset + 2] << 8) | (uint)(data[offset + 3]);
}
else
{
throw new ArgumentException();
}
}
public static ushort BytesToUShort(byte[] data, Endianness type)
{
return BytesToUShort(data, 0, type);
}
public static ushort BytesToUShort(byte[] data, int offset, Endianness type)
{
if (type == Endianness.Little)
{
return (ushort)(data[offset] | (data[offset + 1] << 8));
}
else if (type == Endianness.Big)
{
return (ushort)((data[offset] << 8) | data[offset + 1]);
}
else
{
throw new ArgumentException();
}
}
public static string FlagsToString(Type e, long value)
{
string r = "";
for (int i = 0; i < 32; i++)
{
long fv = 1 << i;
if ((value & fv) == fv)
{
r += Enum.GetName(e, fv) + ", ";
}
}
if (r.EndsWith(", "))
r = r.Remove(r.Length - 2, 2);
return r;
}
public static int IntCeilDiv(int a, int b)
{
return (int)Math.Ceiling(((double)a / b));
}
public static byte[] IntToBytes(int n, Endianness type)
{
byte[] data = new byte[4];
if (type == Endianness.Little)
{
data[0] = (byte)(n & 0xff);
data[1] = (byte)((n >> 8) & 0xff);
data[2] = (byte)((n >> 16) & 0xff);
data[3] = (byte)((n >> 24) & 0xff);
}
else if (type == Endianness.Big)
{
data[0] = (byte)((n >> 24) & 0xff);
data[1] = (byte)((n >> 16) & 0xff);
data[2] = (byte)((n >> 8) & 0xff);
data[3] = (byte)(n & 0xff);
}
else
{
throw new ArgumentException();
}
return data;
}
public static byte[] ReverseBytes(byte[] data)
{
byte[] newdata = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
newdata[i] = data[data.Length - i - 1];
return newdata;
}
public static uint ReverseEndian(uint n)
{
uint b0 = n & 0xff;
uint b1 = (n >> 8) & 0xff;
uint b2 = (n >> 16) & 0xff;
uint b3 = (n >> 24) & 0xff;
b0 <<= 24;
b1 <<= 16;
b2 <<= 8;
return b0 | b1 | b2 | b3;
}
public static int ReadInt(Stream s, Endianness type)
{
byte[] buffer = new byte[4];
if (s.Read(buffer, 0, 4) == 0)
throw new EndOfStreamException();
return BytesToInt(buffer, type);
}
public static string ReadString(Stream s, int length)
{
byte[] buffer = new byte[length];
if (s.Read(buffer, 0, length) == 0)
throw new EndOfStreamException();
return System.Text.ASCIIEncoding.ASCII.GetString(buffer);
}
public static uint ReadUInt(Stream s, Endianness type)
{
byte[] buffer = new byte[4];
if (s.Read(buffer, 0, 4) == 0)
throw new EndOfStreamException();
return BytesToUInt(buffer, type);
}
public static uint RoundUpAddress(uint address, uint align)
{
uint t = (uint)Math.Ceiling((double)address / align);
return t * align;
}
public static byte[] UIntToBytes(uint n, Endianness type)
{
byte[] data = new byte[4];
if (type == Endianness.Little)
{
data[0] = (byte)(n & 0xff);
data[1] = (byte)((n >> 8) & 0xff);
data[2] = (byte)((n >> 16) & 0xff);
data[3] = (byte)((n >> 24) & 0xff);
}
else if (type == Endianness.Big)
{
data[0] = (byte)((n >> 24) & 0xff);
data[1] = (byte)((n >> 16) & 0xff);
data[2] = (byte)((n >> 8) & 0xff);
data[3] = (byte)(n & 0xff);
}
else
{
throw new ArgumentException();
}
return data;
}
public static byte[] UShortToBytes(ushort n, Endianness type)
{
byte[] data = new byte[2];
if (type == Endianness.Little)
{
data[0] = (byte)(n & 0xff);
data[1] = (byte)((n >> 8) & 0xff);
}
else if (type == Endianness.Big)
{
data[0] = (byte)((n >> 8) & 0xff);
data[1] = (byte)(n & 0xff);
}
else
{
throw new ArgumentException();
}
return data;
}
#endregion
}
}