//******************************************************************************************************
// Common.cs - Gbtc
//
// Copyright © 2010, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 04/03/2006 - J. Ritchie Carroll
// Generated original version of source code.
// 12/13/2007 - Darrell Zuercher
// Edited code comments.
// 09/08/2008 - J. Ritchie Carroll
// Converted to C#.
// 02/13/2009 - Josh L. Patterson
// Edited Code Comments.
// 09/14/2009 - Stephen C. Wills
// Added new header and license agreement.
// 09/17/2009 - Pinal C. Patel
// Modified GetApplicationType() to remove dependency on HttpContext.Current.
// 09/28/2010 - Pinal C. Patel
// Cached the current ApplicationType returned by GetApplicationType() for better performance.
// 12/05/2010 - Pinal C. Patel
// Added an overload for TypeConvertToString() that takes CultureInfo as a parameter.
// 12/07/2010 - Pinal C. Patel
// Updated TypeConvertToString() to return an empty string if the passed in value is null.
// 03/09/2011 - Pinal C. Patel
// Moved UpdateType enumeration from GSF.Services.ServiceProcess namespace for broader usage.
// 04/07/2011 - J. Ritchie Carroll
// Added ToNonNullNorEmptyString() and ToNonNullNorWhiteSpace() extensions.
// 10/8/2012 - Danyelle Gilliam
// Modified Header
//
//******************************************************************************************************
#region [ Contributor License Agreements ]
//******************************************************************************************************
//
// Copyright © 2011, Grid Protection Alliance. All Rights Reserved.
//
// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain a copy of the License at:
//
// http://www.opensource.org/licenses/eclipse-1.0.php
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
//******************************************************************************************************
#endregion
using GSF.Reflection;
using System;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
//using System.Web.Hosting;
namespace GSF
{
#region [ Enumerations ]
/// Specifies the type of the application.
public enum ApplicationType
{
///
/// Application is of unknown type.
///
Unknown = 0,
///
/// Application doesn't require a subsystem.
///
Native = 1,
///
/// Application runs in the Windows GUI subsystem.
///
WindowsGui = 2,
///
/// Application runs in the Windows character subsystem.
///
WindowsCui = 3,
///
/// Application runs in the OS/2 character subsystem.
///
OS2Cui = 5,
///
/// Application runs in the Posix character subsystem.
///
PosixCui = 7,
///
/// Application is a native Win9x driver.
///
NativeWindows = 8,
///
/// Application runs in the Windows CE subsystem.
///
WindowsCEGui = 9,
///
/// The application is a web site or web application.
///
Web = 100
}
///
/// Indicates the type of update.
///
public enum UpdateType
{
///
/// Update is informational.
///
Information,
///
/// Update is a warning.
///
Warning,
///
/// Update is an alarm.
///
Alarm
}
#endregion
// This is the location for handy miscellaneous functions that are difficult to categorize elsewhere. For the most
// part these functions may have the most value in a Visual Basic application which supports importing functions
// down to a class level, e.g.: Imports GSF.Common
///
/// Defines common global functions.
///
public static class Common
{
private static Nullable s_applicationType;
///
/// Attempts to parse a from given string .
///
/// String value to attempt to parse as a .
/// Parsed value.
/// true if was successfully parsed as a ; otherwise, false.
public static bool TryParseGuid(string value, out Guid result)
{
try
{
result = new Guid(value);
return true;
}
catch
{
result = Guid.Empty;
return false;
}
}
/// Returns one of two strongly-typed objects.
/// One of two objects, depending on the evaluation of given expression.
/// The expression you want to evaluate.
/// Returned if expression evaluates to True.
/// Returned if expression evaluates to False.
/// Return type used for immediate expression
///
/// This function acts as a strongly-typed immediate if (a.k.a. inline if).
/// It is expected that this function will only be used in Visual Basic.NET as a strongly-typed IIf replacement.
///
public static T IIf(bool expression, T truePart, T falsePart)
{
return (expression ? truePart : falsePart);
}
/// Creates a strongly-typed Array.
/// New array of specified type.
/// Desired length of new array.
/// Return type for new array.
///
/// It is expected that this function will only be used in Visual Basic.NET.
///
/// The Array.CreateInstance provides better performance and more direct CLR access for array creation (not to
/// mention less confusion on the matter of array lengths) in VB.NET, however the returned System.Array is not
/// typed properly. This function properly casts the return array based on the the type specification helping
/// when Option Strict is enabled.
///
///
///
///
/// Dim buffer As Byte() = CreateArray(Of Byte)(12)
/// Dim matrix As Integer()() = CreateArray(Of Integer())(10)
///
///
public static T[] CreateArray(int length)
{
// The following provides better performance than "Return New T(length) {}".
return (T[])Array.CreateInstance(typeof(T), length);
}
/// Creates a strongly-typed Array with an initial value parameter.
/// New array of specified type.
/// Desired length of new array.
/// Value used to initialize all array elements.
/// Return type for new array.
///
/// It is expected that this function will only be used in Visual Basic.NET.
///
///
///
/// Dim elements As Integer() = CreateArray(12, -1)
/// Dim names As String() = CreateArray(100, "undefined")
///
///
public static T[] CreateArray(int length, T initialValue)
{
T[] typedArray = CreateArray(length);
// Initializes all elements with the default value.
for (int x = 0; x < typedArray.Length; x++)
{
typedArray[x] = initialValue;
}
return typedArray;
}
///
/// Gets the type of the currently executing application.
///
/// One of the values.
public static ApplicationType GetApplicationType()
{
if ((object)s_applicationType != null)
return s_applicationType.Value;
//if ((object)HostingEnvironment.ApplicationVirtualPath != null)
//{
// s_applicationType = ApplicationType.Web;
//}
//else
//{
try
{
// References:
// - http://support.microsoft.com/kb/65122
// - http://support.microsoft.com/kb/90493/en-us
// - http://www.codeguru.com/cpp/w-p/system/misc/article.php/c2897/
// We will always have an entry assembly for windows application.
FileStream exe = new FileStream(AssemblyInfo.EntryAssembly.Location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
byte[] dosHeader = new byte[64];
byte[] exeHeader = new byte[248];
byte[] subSystem = new byte[2];
exe.Read(dosHeader, 0, dosHeader.Length);
exe.Seek(BitConverter.ToInt16(dosHeader, 60), SeekOrigin.Begin);
exe.Read(exeHeader, 0, exeHeader.Length);
exe.Close();
Buffer.BlockCopy(exeHeader, 92, subSystem, 0, 2);
s_applicationType = ((ApplicationType)(BitConverter.ToInt16(subSystem, 0)));
}
catch
{
// We are unable to determine the application type.
s_applicationType = ApplicationType.Unknown;
}
//}
return s_applicationType.Value;
}
// The following "ToNonNullString" methods extend all class based objects. Note that these extension methods can be
// called even if the base object is null, hence the value of these methods. Our philosophy for this project has been
// "not" to apply extensions to all objects (this to avoid general namespace pollution) and make sure extensions are
// grouped together in their own source file (e.g., StringExtensions.cs); however these items do apply to all items
// and are essentially type-less hence their location in the "Common" class. These extension methods are at least
// limited to classes and won't show up on native types and custom structs.
///
/// Converts value to string; null objects (or DBNull objects) will return an empty string ("").
///
/// of to convert to string.
/// Value to convert to string.
/// as a string; if is null, empty string ("") will be returned.
public static string ToNonNullString(this T value) where T : class
{
return ((object)value == null || value == DBNull.Value ? "" : value.ToString());
}
///
/// Converts value to string; null objects (or DBNull objects) will return specified .
///
/// of to convert to string.
/// Value to convert to string.
/// to return if is null.
/// as a string; if is null, will be returned.
/// cannot be null.
public static string ToNonNullString(this T value, string nonNullValue) where T : class
{
if ((object)nonNullValue == null)
throw new ArgumentNullException("nonNullValue");
return ((object)value == null || value == DBNull.Value ? nonNullValue : value.ToString());
}
// We handle strings as a special version of the ToNullNullString extension to handle documentation a little differently
///
/// Makes sure returned string value is not null; if this string is null, empty string ("") will be returned.
///
/// to verify is not null.
/// value; if is null, empty string ("") will be returned.
public static string ToNonNullString(this string value)
{
return ((object)value == null ? "" : value);
}
///
/// Converts value to string; null objects, DBNull objects or empty strings will return specified .
///
/// of to convert to string.
/// Value to convert to string.
/// to return if is null.
/// as a string; if is null, DBNull or an empty string will be returned.
/// must not be null or an empty string.
public static string ToNonNullNorEmptyString(this T value, string nonNullNorEmptyValue) where T : class
{
if (string.IsNullOrEmpty(nonNullNorEmptyValue))
throw new ArgumentException("Must not be null or an empty string", "nonNullNorEmptyValue");
if ((object)value == null || value == DBNull.Value)
return nonNullNorEmptyValue;
string valueAsString = value.ToString();
return (string.IsNullOrEmpty(valueAsString) ? nonNullNorEmptyValue : valueAsString);
}
///
/// Converts value to string; null objects, DBNull objects, empty strings or all white space strings will return specified .
///
/// of to convert to string.
/// Value to convert to string.
/// to return if is null.
/// as a string; if is null, DBNull, empty or all white space, will be returned.
/// must not be null, an empty string or white space.
public static string ToNonNullNorWhiteSpace(this T value, string nonNullNorWhiteSpaceValue) where T : class
{
if (nonNullNorWhiteSpaceValue.IsNullOrWhiteSpace())
throw new ArgumentException("Must not be null, an empty string or white space", "nonNullNorWhiteSpaceValue");
if ((object)value == null || value == DBNull.Value)
return nonNullNorWhiteSpaceValue;
string valueAsString = value.ToString();
return (valueAsString.IsNullOrWhiteSpace() ? nonNullNorWhiteSpaceValue : valueAsString);
}
///
/// Converts to a using an appropriate .
///
/// Value to convert to a .
/// converted to a .
///
///
/// If fails, the value's ToString() value will be returned.
/// Returned value will never be null, if no value exists an empty string ("") will be returned.
///
///
/// You can use the string extension method to
/// convert the string back to its original .
///
///
public static string TypeConvertToString(object value)
{
return TypeConvertToString(value, null);
}
///
/// Converts to a using an appropriate .
///
/// Value to convert to a .
/// to use for the conversion.
/// converted to a .
///
///
/// If fails, the value's ToString() value will be returned.
/// Returned value will never be null, if no value exists an empty string ("") will be returned.
///
///
/// You can use the string extension method to
/// convert the string back to its original .
///
///
public static string TypeConvertToString(object value, CultureInfo culture)
{
// Don't proceed further if value is null.
if ((object)value == null)
return string.Empty;
// If value is already a string, no need to attempt conversion
if (value is string)
return value as string;
// Initialize culture info if not specified.
if ((object)culture == null)
culture = CultureInfo.InvariantCulture;
try
{
// Attempt to use type converter to set field value
TypeConverter converter = TypeDescriptor.GetConverter(value);
return converter.ConvertToString(null, culture, value).ToNonNullString();
}
catch
{
// Otherwise just call object's ToString method
return value.ToNonNullString();
}
}
/// Gets a high-resolution number of seconds, including fractional seconds, that have
/// elapsed since 12:00:00 midnight, January 1, 0001.
public static double SystemTimer
{
get
{
return Ticks.ToSeconds(PrecisionTimer.Now.Ticks);
}
}
/// Determines if given item is equal to its default value (e.g., null or 0.0).
/// Object to evaluate.
/// Result of evaluation as a .
///
/// Native types default to zero, not null, therefore this can be used to evaulate if an item is its default (i.e., uninitialized) value.
///
public static bool IsDefaultValue(object item)
{
// Only reference types can be null, therefore null is its default value
if ((object)item == null)
return true;
Type itemType = item.GetType();
if (itemType.IsValueType)
{
// Handle common types
IConvertible convertible = item as IConvertible;
if ((object)convertible != null)
{
switch (convertible.GetTypeCode())
{
case TypeCode.Boolean:
return ((bool)item == default(bool));
case TypeCode.SByte:
return ((sbyte)item == default(sbyte));
case TypeCode.Byte:
return ((byte)item == default(byte));
case TypeCode.Int16:
return ((short)item == default(short));
case TypeCode.UInt16:
return ((ushort)item == default(ushort));
case TypeCode.Int32:
return ((int)item == default(int));
case TypeCode.UInt32:
return ((uint)item == default(uint));
case TypeCode.Int64:
return ((long)item == default(long));
case TypeCode.UInt64:
return ((ulong)item == default(ulong));
case TypeCode.Single:
return ((float)item == default(float));
case TypeCode.Double:
return ((double)item == default(double));
case TypeCode.Decimal:
return ((decimal)item == default(decimal));
case TypeCode.Char:
return ((char)item == default(char));
case TypeCode.DateTime:
return ((DateTime)item == default(DateTime));
}
}
// Handle custom value types
return ((ValueType)item).Equals(Activator.CreateInstance(itemType));
}
return ((object)item == null);
}
/// Determines if given item is a reference type.
/// Object to evaluate.
/// Result of evaluation as a .
public static bool IsReference(object item)
{
return !(item is ValueType);
}
/// Determines if given item is a reference type but not a string.
/// Object to evaluate.
/// Result of evaluation as a .
public static bool IsNonStringReference(object item)
{
return (IsReference(item) && !(item is string));
}
/// Determines if given item is numeric.
/// Object to evaluate.
/// Result of evaluation as a .
public static bool IsNumeric(object item)
{
IConvertible convertible = item as IConvertible;
if ((object)convertible != null)
{
switch (convertible.GetTypeCode())
{
case TypeCode.Boolean:
case TypeCode.SByte:
case TypeCode.Byte:
case TypeCode.Int16:
case TypeCode.UInt16:
case TypeCode.Int32:
case TypeCode.UInt32:
case TypeCode.Int64:
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
return true;
case TypeCode.Char:
case TypeCode.String:
double result;
return double.TryParse(convertible.ToString(null), out result);
}
}
return false;
}
/// Returns the smallest item from a list of parameters.
/// Return type that is the minimum value in the .
/// A variable number of parameters of the specified type.
/// Result is the minimum value of type in the .
public static T Min(params T[] itemList)
{
return itemList.Min();
}
/// Returns the largest item from a list of parameters.
/// Return type that is the maximum value in the .
/// A variable number of parameters of the specified type .
/// Result is the maximum value of type in the .
public static T Max(params T[] itemList)
{
return itemList.Max();
}
#region [ Old Code ]
///// Returns the smallest item from a list of parameters.
///// A variable number of parameters of type
///// Result is the minimum value of type in the .
//public static object Min(params object[] itemList)
//{
// return itemList.Min