History

Added more code to GSF shared code project - moved PathHelper path validation function into FilePath

J. Ritchie Carroll committed 10 years ago

Commit e16ec441 parent 612a09672 files · +1523 −1481Browse files

Unified · Split

72 files
  1. Source/Libraries/GSF.Core.Shared/Common.cs +355 −0
  2. Source/Libraries/GSF.Core.Shared/Diagnostics/Utilities/LogFileReader.cs +1 −1
  3. Source/Libraries/GSF.Core.Shared/Diagnostics/Utilities/LogFileWriter.cs +1 −1
  4. Source/Libraries/GSF.Core.Shared/Diagnostics/Utilities/LogSubscriptionFileWriter.cs +2 −2
  5. Source/Libraries/GSF.Core.Shared/GSF.Core.Shared.projitems +11 −1
  6. Source/Libraries/GSF.Core.Shared/IO/Checksums/Adler32.cs +0 −0
  7. Source/Libraries/GSF.Core.Shared/IO/Checksums/ChecksumExtensions.cs +0 −0
  8. Source/Libraries/GSF.Core.Shared/IO/Checksums/Crc16.cs +4 −4
  9. Source/Libraries/GSF.Core.Shared/IO/Checksums/Crc32.cs +4 −4
  10. Source/Libraries/GSF.Core.Shared/IO/Checksums/CrcCCITT.cs +4 −4
  11. Source/Libraries/GSF.Core.Shared/IO/Checksums/NamespaceDoc.cs +0 −0
  12. Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor16.cs +6 −6
  13. Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor32.cs +6 −6
  14. Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor64.cs +6 −6
  15. Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor8.cs +6 −6
  16. Source/Libraries/GSF.Core.Shared/IO/FilePath.cs +830 −0
  17. Source/Libraries/GSF.Core.Shared/PathHelpers.cs +0 −56
  18. Source/Libraries/GSF.Core/Adapters/Adapter.cs +1 −1
  19. Source/Libraries/GSF.Core/Adapters/AdapterLoader.cs +7 −7
  20. Source/Libraries/GSF.Core/BinaryCodedDecimal.cs +4 −4
  21. Source/Libraries/GSF.Core/BinaryValueBase.cs +5 −5
  22. Source/Libraries/GSF.Core/BitExtensions.cs +1 −1
  23. Source/Libraries/GSF.Core/ByteEncoding.cs +13 −13
  24. Source/Libraries/GSF.Core/Collections/AsyncQueue.cs +1 −1
  25. Source/Libraries/GSF.Core/Collections/CollectionExtensions.cs +6 −6
  26. Source/Libraries/GSF.Core/Collections/DoubleBufferedQueueManager.cs +2 −2
  27. Source/Libraries/GSF.Core/Collections/FileBackedDictionary.cs +2 −2
  28. Source/Libraries/GSF.Core/Collections/FileBackedHashSet.cs +13 −13
  29. Source/Libraries/GSF.Core/Collections/FileBackedLookupTable.cs +10 −10
  30. Source/Libraries/GSF.Core/Collections/PriorityQueue.cs +9 −9
  31. Source/Libraries/GSF.Core/Collections/RollingWindow.cs +6 −6
  32. Source/Libraries/GSF.Core/Common.cs +0 −350
  33. Source/Libraries/GSF.Core/Configuration/CategorizedSettingsSection.cs +1 −1
  34. Source/Libraries/GSF.Core/Configuration/ConfigurationFile.cs +3 −3
  35. Source/Libraries/GSF.Core/Configuration/ConnectionStringParser.cs +1 −1
  36. Source/Libraries/GSF.Core/Console/Command.cs +2 −2
  37. Source/Libraries/GSF.Core/Data/DataSetEqualityComparer.cs +1 −1
  38. Source/Libraries/GSF.Core/Data/DataSetExtensions.cs +3 −3
  39. Source/Libraries/GSF.Core/DateTimeExtensions.cs +8 −8
  40. Source/Libraries/GSF.Core/Diagnostics/PerformanceCounter.cs +6 −6
  41. Source/Libraries/GSF.Core/Diagnostics/PerformanceMonitor.cs +1 −1
  42. Source/Libraries/GSF.Core/EndianOrder.cs +18 −18
  43. Source/Libraries/GSF.Core/ErrorManagement/ErrorLogger.cs +5 −5
  44. Source/Libraries/GSF.Core/GSF.Core.csproj +0 −10
  45. Source/Libraries/GSF.Core/IO/CachedFileStream.cs +10 −10
  46. Source/Libraries/GSF.Core/IO/Compression/PatternCompressor.cs +13 −13
  47. Source/Libraries/GSF.Core/IO/Compression/PatternDecompressor.cs +11 −11
  48. Source/Libraries/GSF.Core/IO/FilePath.cs +41 −778
  49. Source/Libraries/GSF.Core/IO/IsamDataFileBase.cs +3 −3
  50. Source/Libraries/GSF.Core/IO/LogFile.cs +3 −3
  51. Source/Libraries/GSF.Core/IO/MultipleDestinationExporter.cs +1 −1
  52. Source/Libraries/GSF.Core/IO/OutageLog.cs +1 −1
  53. Source/Libraries/GSF.Core/IO/RunTimeLog.cs +1 −1
  54. Source/Libraries/GSF.Core/Identity/UnixUserInfo.cs +3 −3
  55. Source/Libraries/GSF.Core/Identity/UserInfo.cs +35 −35
  56. Source/Libraries/GSF.Core/Identity/WindowsUserInfo.cs +3 −3
  57. Source/Libraries/GSF.Core/Net/Smtp/Mail.cs +2 −2
  58. Source/Libraries/GSF.Core/NumericalAnalysis/CurveFit.cs +3 −3
  59. Source/Libraries/GSF.Core/ObjectState.cs +1 −1
  60. Source/Libraries/GSF.Core/Parsing/ISupportBinaryImage.cs +3 −3
  61. Source/Libraries/GSF.Core/Parsing/MultiSourceFrameImageParserBase.cs +1 −1
  62. Source/Libraries/GSF.Core/PrecisionTimer.cs +2 −2
  63. Source/Libraries/GSF.Core/ReusableObjectPool.cs +2 −2
  64. Source/Libraries/GSF.Core/Scheduling/Schedule.cs +2 −2
  65. Source/Libraries/GSF.Core/Scheduling/ScheduleManager.cs +1 −1
  66. Source/Libraries/GSF.Core/Security/Cryptography/Cipher.cs +4 −4
  67. Source/Libraries/GSF.Core/Serialization.cs +4 −4
  68. Source/Libraries/GSF.Core/Threading/ManagedThreadPool.cs +3 −3
  69. Source/Libraries/GSF.Core/Threading/ManagedThreads.cs +1 −1
  70. Source/Libraries/GSF.Core/Threading/SynchronizedOperationBase.cs +1 −1
  71. Source/Libraries/GSF.Core/TransformEqualityComparer.cs +1 −1
  72. Source/Libraries/GSF.Core/Validation/ValidationService.cs +2 −2
Source/Libraries/GSF.Core.Shared/Common.cs+355−0
@@ -44,6 +44,10 @@ · 43 unmodified lines
4444 //******************************************************************************************************
4545
4646 using System;
47+using System.ComponentModel;
48+using System.Globalization;
49+using System.IO;
50+using System.Linq;
4751 using System.Runtime.CompilerServices;
4852
4953 namespace GSF
@@ -57,6 +61,105 @@ namespace GSF · 7 unmodified lines
5761 /// </summary>
5862 public static partial class Common
5963 {
64+ /// <summary>
65+ /// Determines if the current system is a POSIX style environment.
66+ /// </summary>
67+ /// <remarks>
68+ /// <para>
69+ /// Since a .NET application compiled under Mono can run under both Windows and Unix style platforms,
70+ /// you can use this property to easily determine the current operating environment.
71+ /// </para>
72+ /// <para>
73+ /// This property will return <c>true</c> for both MacOSX and Unix environments. Use the Platform property
74+ /// of the <see cref="System.Environment.OSVersion"/> to determine more specific platform type, e.g.,
75+ /// MacOSX or Unix. Note that all flavors of Linux will show up as <see cref="PlatformID.Unix"/>.
76+ /// </para>
77+ /// </remarks>
78+ public static readonly bool IsPosixEnvironment = (Path.DirectorySeparatorChar == '/'); // This is how Mono source often checks this
79+
80+ /// <summary>
81+ /// Determines if the code base is currently running under Mono.
82+ /// </summary>
83+ /// <remarks>
84+ /// This property can be used to make a run-time determination if Windows or Mono based .NET is being used. However, it is
85+ /// highly recommended to use the MONO compiler directive wherever possible instead of determining this at run-time.
86+ /// </remarks>
87+ public static bool IsMono = ((object)Type.GetType("Mono.Runtime") != null);
88+
89+ /// <summary>Returns one of two strongly-typed objects.</summary>
90+ /// <returns>One of two objects, depending on the evaluation of given expression.</returns>
91+ /// <param name="expression">The expression you want to evaluate.</param>
92+ /// <param name="truePart">Returned if expression evaluates to True.</param>
93+ /// <param name="falsePart">Returned if expression evaluates to False.</param>
94+ /// <typeparam name="T">Return type used for immediate expression</typeparam>
95+ /// <remarks>
96+ /// <para>This function acts as a strongly-typed immediate if (a.k.a. inline if).</para>
97+ /// <para>
98+ /// It is expected that this function will only be used in languages that do not support ?: conditional operations, e.g., Visual Basic.NET.
99+ /// In Visual Basic this function can be used as a strongly-typed IIf replacement by specifying "Imports GSF.Common".
100+ /// </para>
101+ /// </remarks>
102+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
103+ public static T IIf<T>(bool expression, T truePart, T falsePart)
104+ {
105+ return (expression ? truePart : falsePart);
106+ }
107+
108+ /// <summary>Creates a strongly-typed Array.</summary>
109+ /// <returns>New array of specified type.</returns>
110+ /// <param name="length">Desired length of new array.</param>
111+ /// <typeparam name="T">Return type for new array.</typeparam>
112+ /// <remarks>
113+ /// <para>It is expected that this function will only be used in Visual Basic.NET.</para>
114+ /// <para>
115+ /// The Array.CreateInstance provides better performance and more direct CLR access for array creation (not to
116+ /// mention less confusion on the matter of array lengths) in VB.NET, however the returned System.Array is not
117+ /// typed properly. This function properly casts the return array based on the type specification helping
118+ /// when Option Strict is enabled.
119+ /// </para>
120+ /// </remarks>
121+ /// <example>
122+ /// <code language="VB">
123+ /// Dim buffer As Byte() = CreateArray(Of Byte)(12)
124+ /// Dim matrix As Integer()() = CreateArray(Of Integer())(10)
125+ /// </code>
126+ /// </example>
127+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
128+ public static T[] CreateArray<T>(int length)
129+ {
130+ // The following provides better performance than "Return New T(length) {}".
131+ // ReSharper disable once UseArrayCreationExpression.1
132+ return (T[])Array.CreateInstance(typeof(T), length);
133+ }
134+
135+ /// <summary>Creates a strongly-typed Array with an initial value parameter.</summary>
136+ /// <returns>New array of specified type.</returns>
137+ /// <param name="length">Desired length of new array.</param>
138+ /// <param name="initialValue">Value used to initialize all array elements.</param>
139+ /// <typeparam name="T">Return type for new array.</typeparam>
140+ /// <remarks>
141+ /// It is expected that this function will only be used in Visual Basic.NET.
142+ /// </remarks>
143+ /// <example>
144+ /// <code language="VB">
145+ /// Dim elements As Integer() = CreateArray(12, -1)
146+ /// Dim names As String() = CreateArray(100, "undefined")
147+ /// </code>
148+ /// </example>
149+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
150+ public static T[] CreateArray<T>(int length, T initialValue)
151+ {
152+ T[] typedArray = CreateArray<T>(length);
153+
154+ // Initializes all elements with the default value.
155+ for (int x = 0; x < typedArray.Length; x++)
156+ {
157+ typedArray[x] = initialValue;
158+ }
159+
160+ return typedArray;
161+ }
162+
60163 // The following "ToNonNullString" methods extend all class based objects. Note that these extension methods can be
61164 // called even if the base object is null, hence the value of these methods. Our philosophy for this project has been
62165 // "not" to apply extensions to all objects (this to avoid general namespace pollution) and make sure extensions are
@@ -146,5 +249,257 @@ namespace GSF · 83 unmodified lines
146249
147250 return (string.IsNullOrWhiteSpace(valueAsString) ? nonNullNorWhiteSpaceValue : valueAsString);
148251 }
252+
253+ /// <summary>
254+ /// Converts <paramref name="value"/> to a <see cref="String"/> using an appropriate <see cref="TypeConverter"/>.
255+ /// </summary>
256+ /// <param name="value">Value to convert to a <see cref="String"/>.</param>
257+ /// <returns><paramref name="value"/> converted to a <see cref="String"/>.</returns>
258+ /// <remarks>
259+ /// <para>
260+ /// If <see cref="TypeConverter"/> fails, the value's <c>ToString()</c> value will be returned.
261+ /// Returned value will never be null, if no value exists an empty string ("") will be returned.
262+ /// </para>
263+ /// <para>
264+ /// You can use the <see cref="StringExtensions.ConvertToType{T}(string)"/> string extension method to
265+ /// convert the string back to its original <see cref="Type"/>.
266+ /// </para>
267+ /// </remarks>
268+ public static string TypeConvertToString(object value)
269+ {
270+ return TypeConvertToString(value, null);
271+ }
272+
273+ /// <summary>
274+ /// Converts <paramref name="value"/> to a <see cref="String"/> using an appropriate <see cref="TypeConverter"/>.
275+ /// </summary>
276+ /// <param name="value">Value to convert to a <see cref="String"/>.</param>
277+ /// <param name="culture"><see cref="CultureInfo"/> to use for the conversion.</param>
278+ /// <returns><paramref name="value"/> converted to a <see cref="String"/>.</returns>
279+ /// <remarks>
280+ /// <para>
281+ /// If <see cref="TypeConverter"/> fails, the value's <c>ToString()</c> value will be returned.
282+ /// Returned value will never be null, if no value exists an empty string ("") will be returned.
283+ /// </para>
284+ /// <para>
285+ /// You can use the <see cref="StringExtensions.ConvertToType{T}(string)"/> string extension method to
286+ /// convert the string back to its original <see cref="Type"/>.
287+ /// </para>
288+ /// </remarks>
289+ public static string TypeConvertToString(object value, CultureInfo culture)
290+ {
291+ // Don't proceed further if value is null.
292+ if ((object)value == null)
293+ return string.Empty;
294+
295+ // If value is already a string, no need to attempt conversion
296+ string valueAsString = value as string;
297+
298+ if ((object)valueAsString != null)
299+ return valueAsString;
300+
301+ // Initialize culture info if not specified.
302+ if ((object)culture == null)
303+ culture = CultureInfo.InvariantCulture;
304+
305+ try
306+ {
307+ // Attempt to use type converter to set field value
308+ TypeConverter converter = TypeDescriptor.GetConverter(value);
309+
310+ // ReSharper disable once AssignNullToNotNullAttribute
311+ return converter.ConvertToString(null, culture, value).ToNonNullString();
312+ }
313+ catch
314+ {
315+ // Otherwise just call object's ToString method
316+ return value.ToNonNullString();
317+ }
318+ }
319+
320+ /// <summary>Gets a high-resolution number of seconds, including fractional seconds, that have
321+ /// elapsed since 12:00:00 midnight, January 1, 0001.</summary>
322+ public static double SystemTimer
323+ {
324+ get
325+ {
326+ return Ticks.ToSeconds(DateTime.UtcNow.Ticks);
327+ }
328+ }
329+
330+ /// <summary>Determines if given item is equal to its default value (e.g., null or 0.0).</summary>
331+ /// <param name="item">Object to evaluate.</param>
332+ /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
333+ /// <remarks>
334+ /// Native types default to zero, not null, therefore this can be used to evaluate if an item is its default (i.e., uninitialized) value.
335+ /// </remarks>
336+ public static bool IsDefaultValue(object item)
337+ {
338+ // Only reference types can be null, therefore null is its default value
339+ if ((object)item == null)
340+ return true;
341+
342+ Type itemType = item.GetType();
343+
344+ if (!itemType.IsValueType)
345+ return false;
346+
347+ // Handle common types
348+ IConvertible convertible = item as IConvertible;
349+
350+ if ((object)convertible != null)
351+ {
352+ try
353+ {
354+ switch (convertible.GetTypeCode())
355+ {
356+ case TypeCode.Boolean:
357+ return ((bool)item == default(bool));
358+ case TypeCode.SByte:
359+ return ((sbyte)item == default(sbyte));
360+ case TypeCode.Byte:
361+ return ((byte)item == default(byte));
362+ case TypeCode.Int16:
363+ return ((short)item == default(short));
364+ case TypeCode.UInt16:
365+ return ((ushort)item == default(ushort));
366+ case TypeCode.Int32:
367+ return ((int)item == default(int));
368+ case TypeCode.UInt32:
369+ return ((uint)item == default(uint));
370+ case TypeCode.Int64:
371+ return ((long)item == default(long));
372+ case TypeCode.UInt64:
373+ return ((ulong)item == default(ulong));
374+ case TypeCode.Single:
375+ return ((float)item == default(float));
376+ case TypeCode.Double:
377+ return ((double)item == default(double));
378+ case TypeCode.Decimal:
379+ return ((decimal)item == default(decimal));
380+ case TypeCode.Char:
381+ return ((char)item == default(char));
382+ case TypeCode.DateTime:
383+ return ((DateTime)item == default(DateTime));
384+ }
385+ }
386+ catch (InvalidCastException)
387+ {
388+ // An exception here indicates that the item is a custom type that
389+ // lied about its type code. The type should still be instantiable,
390+ // so we can ignore this exception
391+ }
392+ }
393+
394+ // Handle custom value types
395+ return ((ValueType)item).Equals(Activator.CreateInstance(itemType));
396+ }
397+
398+ /// <summary>Determines if given item is a reference type.</summary>
399+ /// <param name="item">Object to evaluate.</param>
400+ /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
401+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
402+ public static bool IsReference(object item)
403+ {
404+ return !(item is ValueType);
405+ }
406+
407+ /// <summary>Determines if given item is a reference type but not a string.</summary>
408+ /// <param name="item">Object to evaluate.</param>
409+ /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
410+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
411+ public static bool IsNonStringReference(object item)
412+ {
413+ return (IsReference(item) && !(item is string));
414+ }
415+
416+ /// <summary>Determines if given item is numeric.</summary>
417+ /// <param name="item">Object to evaluate.</param>
418+ /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
419+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
420+ public static bool IsNumeric(object item)
421+ {
422+ IConvertible convertible = item as IConvertible;
423+
424+ if ((object)convertible != null)
425+ {
426+ switch (convertible.GetTypeCode())
427+ {
428+ case TypeCode.Boolean:
429+ case TypeCode.SByte:
430+ case TypeCode.Byte:
431+ case TypeCode.Int16:
432+ case TypeCode.UInt16:
433+ case TypeCode.Int32:
434+ case TypeCode.UInt32:
435+ case TypeCode.Int64:
436+ case TypeCode.UInt64:
437+ case TypeCode.Single:
438+ case TypeCode.Double:
439+ case TypeCode.Decimal:
440+ return true;
441+ case TypeCode.Char:
442+ case TypeCode.String:
443+ double result;
444+ return double.TryParse(convertible.ToString(null), out result);
445+ }
446+ }
447+
448+ return false;
449+ }
450+
451+ /// <summary>Returns the smallest item from a list of parameters.</summary>
452+ /// <typeparam name="T">Return type <see cref="Type"/> that is the minimum value in the <paramref name="itemList"/>.</typeparam>
453+ /// <param name="itemList">A variable number of parameters of the specified type.</param>
454+ /// <returns>Result is the minimum value of type <see cref="Type"/> in the <paramref name="itemList"/>.</returns>
455+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
456+ public static T Min<T>(params T[] itemList)
457+ {
458+ return itemList.Min();
459+ }
460+
461+ /// <summary>Returns the largest item from a list of parameters.</summary>
462+ /// <typeparam name="T">Return type <see cref="Type"/> that is the maximum value in the <paramref name="itemList"/>.</typeparam>
463+ /// <param name="itemList">A variable number of parameters of the specified type .</param>
464+ /// <returns>Result is the maximum value of type <see cref="Type"/> in the <paramref name="itemList"/>.</returns>
465+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
466+ public static T Max<T>(params T[] itemList)
467+ {
468+ return itemList.Max();
469+ }
470+
471+ /// <summary>Returns the value that is neither the largest nor the smallest.</summary>
472+ /// <typeparam name="T"><see cref="Type"/> of the objects passed to and returned from this method.</typeparam>
473+ /// <param name="value1">Value 1.</param>
474+ /// <param name="value2">Value 2.</param>
475+ /// <param name="value3">Value 3.</param>
476+ /// <returns>Result is the value that is neither the largest nor the smallest.</returns>
477+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
478+ public static T Mid<T>(T value1, T value2, T value3) where T : IComparable<T>
479+ {
480+ if ((object)value1 == null)
481+ throw new ArgumentNullException(nameof(value1));
482+
483+ if ((object)value2 == null)
484+ throw new ArgumentNullException(nameof(value2));
485+
486+ if ((object)value3 == null)
487+ throw new ArgumentNullException(nameof(value3));
488+
489+ int comp1to2 = value1.CompareTo(value2);
490+ int comp1to3 = value1.CompareTo(value3);
491+ int comp2to3 = value2.CompareTo(value3);
492+
493+ // If 3 is the smallest, pick the smaller of 1 and 2
494+ if (comp1to3 >= 0 && comp2to3 >= 0)
495+ return (comp1to2 <= 0) ? value1 : value2;
496+
497+ // If 2 is the smallest, pick the smaller of 1 and 3
498+ if (comp1to2 >= 0 && comp2to3 <= 0)
499+ return (comp1to3 <= 0) ? value1 : value3;
500+
501+ // 1 is the smallest so pick the smaller of 2 and 3
502+ return (comp2to3 <= 0) ? value2 : value3;
503+ }
149504 }
150505 }
Source/Libraries/GSF.Core.Shared/Diagnostics/Utilities/LogFileReader.cs+1−1
@@ -41,7 +41,7 @@ namespace GSF.Diagnostics · 40 unmodified lines
4141 public static List<LogMessage> Read(string logFileName)
4242 {
4343 List<LogMessage> lst = new List<LogMessage>();
44− PathHelpers.ValidatePathName(logFileName);
44+ FilePath.ValidatePathName(logFileName);
4545 using (var stream = new FileStream(logFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
4646 {
4747 try
Source/Libraries/GSF.Core.Shared/Diagnostics/Utilities/LogFileWriter.cs+1−1
@@ -58,7 +58,7 @@ namespace GSF.Diagnostics · 57 unmodified lines
5858 FileName = logFileName;
5959 m_saveHelper = LogMessageSaveHelper.Create();
6060
61− PathHelpers.ValidatePathName(logFileName);
61+ FilePath.ValidatePathName(logFileName);
6262 m_stream = new FileStream(logFileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read);
6363 m_stream.Write(282497); //VersionNumber: Compressed. With LogSaveHelper
6464
Source/Libraries/GSF.Core.Shared/Diagnostics/Utilities/LogSubscriptionFileWriter.cs+2−2
@@ -125,7 +125,7 @@ namespace GSF.Diagnostics · 124 unmodified lines
125125 /// <param name="logDirectory"></param>
126126 public void SetPath(string logDirectory)
127127 {
128− PathHelpers.ValidatePathName(logDirectory);
128+ FilePath.ValidatePathName(logDirectory);
129129 lock (m_syncRoot)
130130 {
131131 m_path = logDirectory;
@@ -138,7 +138,7 @@ namespace GSF.Diagnostics · 6 unmodified lines
138138 /// </summary>
139139 public void SetPath(string logDirectory, VerboseLevel level)
140140 {
141− PathHelpers.ValidatePathName(logDirectory);
141+ FilePath.ValidatePathName(logDirectory);
142142 lock (m_syncRoot)
143143 {
144144 Verbose = level;
Source/Libraries/GSF.Core.Shared/GSF.Core.Shared.projitems+11−1
@@ -76,6 +76,17 @@ · 75 unmodified lines
7676 <Compile Include="$(MSBuildThisFileDirectory)Ionic.Zlib\ZlibConstants.cs" />
7777 <Compile Include="$(MSBuildThisFileDirectory)Ionic.Zlib\ZlibStream.cs" />
7878 <Compile Include="$(MSBuildThisFileDirectory)IO\BlockAllocatedMemoryStream.cs" />
79+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Adler32.cs" />
80+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\ChecksumExtensions.cs" />
81+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Crc16.cs" />
82+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Crc32.cs" />
83+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\CrcCCITT.cs" />
84+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\NamespaceDoc.cs" />
85+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Xor16.cs" />
86+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Xor32.cs" />
87+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Xor64.cs" />
88+ <Compile Include="$(MSBuildThisFileDirectory)IO\Checksums\Xor8.cs" />
89+ <Compile Include="$(MSBuildThisFileDirectory)IO\FilePath.cs" />
7990 <Compile Include="$(MSBuildThisFileDirectory)IO\StreamExtensions.cs" />
8091 <Compile Include="$(MSBuildThisFileDirectory)LittleEndian.cs" />
8192 <Compile Include="$(MSBuildThisFileDirectory)NtpTimeTag.cs" />
@@ -85,7 +96,6 @@ · 3 unmodified lines
8596 <Compile Include="$(MSBuildThisFileDirectory)NumericalAnalysis\Interpolation\PiecewiseLinearFunction.cs" />
8697 <Compile Include="$(MSBuildThisFileDirectory)NumericalAnalysis\NamespaceDoc.cs" />
8798 <Compile Include="$(MSBuildThisFileDirectory)NumericalAnalysis\NumericalAnalysisExtensions.cs" />
88− <Compile Include="$(MSBuildThisFileDirectory)PathHelpers.cs" />
8999 <Compile Include="$(MSBuildThisFileDirectory)Reflection\AssemblyExtensions.cs" />
90100 <Compile Include="$(MSBuildThisFileDirectory)Reflection\AssemblyInfo.cs" />
91101 <Compile Include="$(MSBuildThisFileDirectory)Reflection\MemberInfoExtensions.cs" />
Source/Libraries/GSF.Core.Shared/IO/Checksums/Adler32.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Adler32.cs+0−0

File mode changed from 100755 to 100644.

Source/Libraries/GSF.Core.Shared/IO/Checksums/ChecksumExtensions.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/ChecksumExtensions.cs+0−0

File mode changed from 100755 to 100644.

Source/Libraries/GSF.Core.Shared/IO/Checksums/Crc16.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Crc16.cs+4−4
@@ -158,7 +158,7 @@ namespace GSF.IO.Checksums · 157 unmodified lines
158158 public void Update(byte[] buffer)
159159 {
160160 if ((object)buffer == null)
161− throw new ArgumentNullException("buffer");
161+ throw new ArgumentNullException(nameof(buffer));
162162
163163 Update(buffer, 0, buffer.Length);
164164 }
@@ -172,13 +172,13 @@ namespace GSF.IO.Checksums · 7 unmodified lines
172172 public void Update(byte[] buffer, int offset, int count)
173173 {
174174 if ((object)buffer == null)
175− throw new ArgumentNullException("buffer");
175+ throw new ArgumentNullException(nameof(buffer));
176176
177177 if (count < 0)
178− throw new ArgumentOutOfRangeException("count", "Count cannot be less than zero");
178+ throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be less than zero");
179179
180180 if (offset < 0 || offset + count > buffer.Length)
181− throw new ArgumentOutOfRangeException("offset");
181+ throw new ArgumentOutOfRangeException(nameof(offset));
182182
183183 ushort temp;
184184 for (int i = 0; i < count; i++)
Source/Libraries/GSF.Core.Shared/IO/Checksums/Crc32.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Crc32.cs+4−4
@@ -91,7 +91,7 @@ namespace GSF.IO.Checksums · 90 unmodified lines
9191 public void Update(byte[] buffer)
9292 {
9393 if ((object)buffer == null)
94− throw new ArgumentNullException("buffer");
94+ throw new ArgumentNullException(nameof(buffer));
9595
9696 Update(buffer, 0, buffer.Length);
9797 }
@@ -105,13 +105,13 @@ namespace GSF.IO.Checksums · 7 unmodified lines
105105 public void Update(byte[] buffer, int offset, int count)
106106 {
107107 if ((object)buffer == null)
108− throw new ArgumentNullException("buffer");
108+ throw new ArgumentNullException(nameof(buffer));
109109
110110 if (count < 0)
111− throw new ArgumentOutOfRangeException("count", "Count cannot be less than zero");
111+ throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be less than zero");
112112
113113 if (offset < 0 || offset + count > buffer.Length)
114− throw new ArgumentOutOfRangeException("offset");
114+ throw new ArgumentOutOfRangeException(nameof(offset));
115115
116116 crc ^= CrcSeed;
117117
Source/Libraries/GSF.Core.Shared/IO/Checksums/CrcCCITT.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/CrcCCITT.cs+4−4
@@ -108,7 +108,7 @@ namespace GSF.IO.Checksums · 107 unmodified lines
108108 public void Update(byte[] buffer)
109109 {
110110 if ((object)buffer == null)
111− throw new ArgumentNullException("buffer");
111+ throw new ArgumentNullException(nameof(buffer));
112112
113113 Update(buffer, 0, buffer.Length);
114114 }
@@ -122,13 +122,13 @@ namespace GSF.IO.Checksums · 7 unmodified lines
122122 public void Update(byte[] buffer, int offset, int count)
123123 {
124124 if ((object)buffer == null)
125− throw new ArgumentNullException("buffer");
125+ throw new ArgumentNullException(nameof(buffer));
126126
127127 if (count < 0)
128− throw new ArgumentOutOfRangeException("count", "Count cannot be less than zero");
128+ throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be less than zero");
129129
130130 if (offset < 0 || offset + count > buffer.Length)
131− throw new ArgumentOutOfRangeException("offset");
131+ throw new ArgumentOutOfRangeException(nameof(offset));
132132
133133 while (--count >= 0)
134134 {
Source/Libraries/GSF.Core.Shared/IO/Checksums/NamespaceDoc.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/NamespaceDoc.cs+0−0

File mode changed from 100755 to 100644.

Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor16.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Xor16.cs+6−6
@@ -97,7 +97,7 @@ namespace GSF.IO.Checksums · 96 unmodified lines
9797 public void Update(byte[] buffer)
9898 {
9999 if ((object)buffer == null)
100− throw new ArgumentNullException("buffer");
100+ throw new ArgumentNullException(nameof(buffer));
101101
102102 Update(buffer, 0, buffer.Length);
103103 }
@@ -117,19 +117,19 @@ namespace GSF.IO.Checksums · 13 unmodified lines
117117 public void Update(byte[] buffer, int offset, int count)
118118 {
119119 if ((object)buffer == null)
120− throw new ArgumentNullException("buffer");
120+ throw new ArgumentNullException(nameof(buffer));
121121
122122 if (offset < 0)
123− throw new ArgumentOutOfRangeException("offset", "cannot be negative");
123+ throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative");
124124
125125 if (count < 0)
126− throw new ArgumentOutOfRangeException("count", "cannot be negative");
126+ throw new ArgumentOutOfRangeException(nameof(count), "cannot be negative");
127127
128128 if (offset >= buffer.Length)
129− throw new ArgumentOutOfRangeException("offset", "not a valid index into buffer");
129+ throw new ArgumentOutOfRangeException(nameof(offset), "not a valid index into buffer");
130130
131131 if (offset + count > buffer.Length)
132− throw new ArgumentOutOfRangeException("count", "exceeds buffer size");
132+ throw new ArgumentOutOfRangeException(nameof(count), "exceeds buffer size");
133133
134134 for (int x = 0; x < count; x += 2)
135135 {
Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor32.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Xor32.cs+6−6
@@ -97,7 +97,7 @@ namespace GSF.IO.Checksums · 96 unmodified lines
9797 public void Update(byte[] buffer)
9898 {
9999 if ((object)buffer == null)
100− throw new ArgumentNullException("buffer");
100+ throw new ArgumentNullException(nameof(buffer));
101101
102102 Update(buffer, 0, buffer.Length);
103103 }
@@ -117,19 +117,19 @@ namespace GSF.IO.Checksums · 13 unmodified lines
117117 public void Update(byte[] buffer, int offset, int count)
118118 {
119119 if ((object)buffer == null)
120− throw new ArgumentNullException("buffer");
120+ throw new ArgumentNullException(nameof(buffer));
121121
122122 if (offset < 0)
123− throw new ArgumentOutOfRangeException("offset", "cannot be negative");
123+ throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative");
124124
125125 if (count < 0)
126− throw new ArgumentOutOfRangeException("count", "cannot be negative");
126+ throw new ArgumentOutOfRangeException(nameof(count), "cannot be negative");
127127
128128 if (offset >= buffer.Length)
129− throw new ArgumentOutOfRangeException("offset", "not a valid index into buffer");
129+ throw new ArgumentOutOfRangeException(nameof(offset), "not a valid index into buffer");
130130
131131 if (offset + count > buffer.Length)
132− throw new ArgumentOutOfRangeException("count", "exceeds buffer size");
132+ throw new ArgumentOutOfRangeException(nameof(count), "exceeds buffer size");
133133
134134 for (int x = 0; x < count; x += 4)
135135 {
Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor64.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Xor64.cs+6−6
@@ -97,7 +97,7 @@ namespace GSF.IO.Checksums · 96 unmodified lines
9797 public void Update(byte[] buffer)
9898 {
9999 if ((object)buffer == null)
100− throw new ArgumentNullException("buffer");
100+ throw new ArgumentNullException(nameof(buffer));
101101
102102 Update(buffer, 0, buffer.Length);
103103 }
@@ -117,19 +117,19 @@ namespace GSF.IO.Checksums · 13 unmodified lines
117117 public void Update(byte[] buffer, int offset, int count)
118118 {
119119 if ((object)buffer == null)
120− throw new ArgumentNullException("buffer");
120+ throw new ArgumentNullException(nameof(buffer));
121121
122122 if (offset < 0)
123− throw new ArgumentOutOfRangeException("offset", "cannot be negative");
123+ throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative");
124124
125125 if (count < 0)
126− throw new ArgumentOutOfRangeException("count", "cannot be negative");
126+ throw new ArgumentOutOfRangeException(nameof(count), "cannot be negative");
127127
128128 if (offset >= buffer.Length)
129− throw new ArgumentOutOfRangeException("offset", "not a valid index into buffer");
129+ throw new ArgumentOutOfRangeException(nameof(offset), "not a valid index into buffer");
130130
131131 if (offset + count > buffer.Length)
132− throw new ArgumentOutOfRangeException("count", "exceeds buffer size");
132+ throw new ArgumentOutOfRangeException(nameof(count), "exceeds buffer size");
133133
134134 for (int x = 0; x < count; x += 8)
135135 {
Source/Libraries/GSF.Core.Shared/IO/Checksums/Xor8.csrenamed from Source/Libraries/GSF.Core/IO/Checksums/Xor8.cs+6−6
@@ -97,7 +97,7 @@ namespace GSF.IO.Checksums · 96 unmodified lines
9797 public void Update(byte[] buffer)
9898 {
9999 if ((object)buffer == null)
100− throw new ArgumentNullException("buffer");
100+ throw new ArgumentNullException(nameof(buffer));
101101
102102 Update(buffer, 0, buffer.Length);
103103 }
@@ -117,19 +117,19 @@ namespace GSF.IO.Checksums · 13 unmodified lines
117117 public void Update(byte[] buffer, int offset, int count)
118118 {
119119 if ((object)buffer == null)
120− throw new ArgumentNullException("buffer");
120+ throw new ArgumentNullException(nameof(buffer));
121121
122122 if (offset < 0)
123− throw new ArgumentOutOfRangeException("offset", "cannot be negative");
123+ throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative");
124124
125125 if (count < 0)
126− throw new ArgumentOutOfRangeException("count", "cannot be negative");
126+ throw new ArgumentOutOfRangeException(nameof(count), "cannot be negative");
127127
128128 if (offset >= buffer.Length)
129− throw new ArgumentOutOfRangeException("offset", "not a valid index into buffer");
129+ throw new ArgumentOutOfRangeException(nameof(offset), "not a valid index into buffer");
130130
131131 if (offset + count > buffer.Length)
132− throw new ArgumentOutOfRangeException("count", "exceeds buffer size");
132+ throw new ArgumentOutOfRangeException(nameof(count), "exceeds buffer size");
133133
134134 for (int x = 0; x < count; x++)
135135 {
Source/Libraries/GSF.Core.Shared/IO/FilePath.cs+830−0
@@ -0,0 +1,830 @@
1+//******************************************************************************************************
2+// FilePath.cs - Gbtc
3+//
4+// Copyright © 2012, Grid Protection Alliance. All Rights Reserved.
5+//
6+// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7+// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8+// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may
9+// not use this file except in compliance with the License. You may obtain a copy of the License at:
10+//
11+// http://www.opensource.org/licenses/MIT
12+//
13+// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14+// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15+// License for the specific language governing permissions and limitations.
16+//
17+// Code Modification History:
18+// ----------------------------------------------------------------------------------------------------
19+// 02/05/2003 - J. Ritchie Carroll
20+// Generated original version of source code.
21+// 12/29/2005 - Pinal C. Patel
22+// Migrated 2.0 version of source code from 1.1 source (GSF.Shared.FilePath).
23+// 08/22/2007 - Darrell Zuercher
24+// Edited code comments.
25+// 09/19/2008 - J. Ritchie Carroll
26+// Converted to C#.
27+// 10/24/2008 - Pinal C. Patel
28+// Edited code comments.
29+// 12/17/2008 - F. Russell Robertson
30+// Fixed issue in GetFilePatternRegularExpression().
31+// 06/30/2009 - Pinal C. Patel
32+// Removed FilePathHasFileName() since the result was error prone.
33+// 09/14/2009 - Stephen C. Wills
34+// Added new header and license agreement.
35+// 09/17/2009 - Pinal C. Patel
36+// Modified GetAbsolutePath() to remove dependency on HttpContext.Current.
37+// 04/19/2010 - Pinal C. Patel
38+// Added GetApplicationDataFolder() method.
39+// 04/21/2010 - Pinal C. Patel
40+// Updated GetApplicationDataFolder() to include the company name if available.
41+// 01/28/2011 - J. Ritchie Carroll
42+// Added IsValidFileName function.
43+// 02/14/2011 - J. Ritchie Carroll
44+// Fixed issue in GetDirectoryName where last directory was being truncated as a file name.
45+// 06/06/2011 - Stephen C. Wills
46+// Fixed issue in GetFileName where path suffix was being removed before extracting the file name.
47+// 07/29/2011 - Pinal C. Patel
48+// Updated GetApplicationDataFolder() to use the TEMP directory for web applications.
49+// 12/14/2012 - Starlynn Danyelle Gilliam
50+// Modified Header.
51+//
52+//******************************************************************************************************
53+
54+using System;
55+using System.Collections.Generic;
56+using System.IO;
57+using System.Linq;
58+using System.Text;
59+using System.Text.RegularExpressions;
60+using System.Threading;
61+
62+namespace GSF.IO
63+{
64+ /// <summary>
65+ /// Contains File and Path manipulation methods.
66+ /// </summary>
67+ public static partial class FilePath
68+ {
69+ #region [ Members ]
70+
71+ // Fields
72+ private static readonly string s_directorySeparatorCharPattern;
73+ private static readonly string s_fileNameCharPattern;
74+
75+ #endregion
76+
77+ #region [ Constructor ]
78+
79+ static FilePath()
80+ {
81+ char[] directorySeparatorChars =
82+ {
83+ Path.DirectorySeparatorChar,
84+ Path.AltDirectorySeparatorChar
85+ };
86+
87+ char[] encodedInvalidFileNameChars = Path.GetInvalidFileNameChars()
88+ .SelectMany(c => c.RegexEncode())
89+ .ToArray();
90+
91+ char[] encodedDirectorySeparatorChars = directorySeparatorChars
92+ .Distinct()
93+ .SelectMany(c => c.RegexEncode())
94+ .ToArray();
95+
96+ // Defines a regular expression pattern for a valid directory separator character.
97+ s_directorySeparatorCharPattern = $"[{new string(encodedDirectorySeparatorChars)}]";
98+
99+ // Defines a regular expression pattern for a valid file name character. We do this by
100+ // allowing any characters except those that would not be valid as part of a filename.
101+ // This essentially builds the "?" wildcard pattern match.
102+ s_fileNameCharPattern = $"[^{new string(encodedInvalidFileNameChars)}]";
103+ }
104+
105+ #endregion
106+
107+ #region [ Methods ]
108+
109+ /// <summary>
110+ /// Ensures the supplied path name is valid.
111+ /// </summary>
112+ /// <param name="filePath">The file path to be validated.</param>
113+ /// <remarks>
114+ /// Throws argument exceptions if the <see param="pathName"/> is invalid.
115+ /// </remarks>
116+ public static void ValidatePathName(string filePath)
117+ {
118+ if (filePath.IsNullOrWhiteSpace())
119+ throw new ArgumentNullException(nameof(filePath), "Path cannot be null or empty space");
120+
121+ if (filePath.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
122+ throw new ArgumentException("Path has invalid characters.", nameof(filePath));
123+ }
124+
125+ /// <summary>
126+ /// Determines whether the specified file name matches any of the given file specs (wildcards are defined as '*' or '?' characters).
127+ /// </summary>
128+ /// <param name="fileSpecs">The file specs used for matching the specified file name.</param>
129+ /// <param name="filePath">The file path to be tested against the specified file specs for a match.</param>
130+ /// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param>
131+ /// <returns><c>true</c> if the specified file name matches any of the given file specs; otherwise <c>false</c>.</returns>
132+ /// <exception cref="ArgumentException"><paramref name="filePath"/> contains one or more of the invalid characters defined in <see cref="Path.GetInvalidPathChars"/>.</exception>
133+ /// <remarks>
134+ /// The syntax for <paramref name="fileSpecs"/> adheres to the following rules:
135+ ///
136+ /// <ul>
137+ /// <li>Either '\' or '/' (as defined by <see cref="Path.DirectorySeparatorChar"/> and <see cref="Path.AltDirectorySeparatorChar"/>) can match the other.</li>
138+ /// <li>A single '\' or '/' at the beginning of the pattern matches any valid path root (such as "C:\" or "\\server\share").</li>
139+ /// <li>A '?' matches a single character which would be valid in a file name (as defined by <see cref="Path.GetInvalidFileNameChars"/>).</li>
140+ /// <li>A '*' matches any number of characters which would be valid in a file name.</li>
141+ /// <li>A sequence of "**\" or "**/" matches any number of sequential directories.</li>
142+ /// <li>Any other character matches itself.</li>
143+ /// </ul>
144+ /// </remarks>
145+ public static bool IsFilePatternMatch(string[] fileSpecs, string filePath, bool ignoreCase)
146+ {
147+ foreach (string fileSpec in fileSpecs)
148+ {
149+ if (IsFilePatternMatch(fileSpec, filePath, ignoreCase))
150+ return true;
151+ }
152+
153+ return false;
154+ }
155+
156+ /// <summary>
157+ /// Determines whether the specified file name matches the given file spec (wildcards are defined as '*' or '?' characters).
158+ /// </summary>
159+ /// <param name="fileSpec">The file spec used for matching the specified file name.</param>
160+ /// <param name="filePath">The file path to be tested against the specified file spec for a match.</param>
161+ /// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param>
162+ /// <returns><c>true</c> if the specified file name matches the given file spec; otherwise <c>false</c>.</returns>
163+ /// <exception cref="ArgumentException"><paramref name="filePath"/> contains one or more of the invalid characters defined in <see cref="Path.GetInvalidPathChars"/>.</exception>
164+ /// <remarks>
165+ /// The syntax for <paramref name="fileSpec"/> adheres to the following rules:
166+ ///
167+ /// <ul>
168+ /// <li>Either '\' or '/' (as defined by <see cref="Path.DirectorySeparatorChar"/> and <see cref="Path.AltDirectorySeparatorChar"/>) can match the other.</li>
169+ /// <li>A single '\' or '/' at the beginning of the pattern matches any valid path root (such as "C:\" or "\\server\share").</li>
170+ /// <li>A '?' matches a single character which would be valid in a file name (as defined by <see cref="Path.GetInvalidFileNameChars"/>).</li>
171+ /// <li>A '*' matches any number of characters which would be valid in a file name.</li>
172+ /// <li>A sequence of "**\" or "**/" matches any number of sequential directories.</li>
173+ /// <li>Any other character matches itself.</li>
174+ /// </ul>
175+ /// </remarks>
176+ public static bool IsFilePatternMatch(string fileSpec, string filePath, bool ignoreCase)
177+ {
178+ if (string.IsNullOrWhiteSpace(filePath))
179+ return false;
180+
181+ // Define regular expression patterns for the three possible sequences that can match the path root.
182+ string recursiveDirPattern = $"{(Regex.Escape("**"))}{s_directorySeparatorCharPattern}";
183+ string pathRootPattern = string.Format("({0}[^{0}]|{0}$)", Regex.Escape(Path.DirectorySeparatorChar.ToString()));
184+ string altPathRootPattern = string.Format("({0}[^{0}]|{0}$)", Regex.Escape(Path.AltDirectorySeparatorChar.ToString()));
185+
186+ // If any of the three patterns are found at the start of fileSpec and the fileName refers to a rooted path,
187+ // remove the path root from fileName and then remove all leading directory separator chars from both fileSpec and fileName.
188+ if (Regex.IsMatch(fileSpec, $"^({recursiveDirPattern}|{pathRootPattern}|{altPathRootPattern})") && Path.IsPathRooted(filePath))
189+ {
190+ fileSpec = fileSpec.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
191+ filePath = Regex.Replace(filePath, $"^{Regex.Escape(Path.GetPathRoot(filePath))}", "").TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
192+ }
193+
194+ // Use regular expression matching to determine whether fileSpec matches fileName.
195+ return new Regex(GetFilePatternRegularExpression(fileSpec), (ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None)).IsMatch(filePath);
196+ }
197+
198+ /// <summary>
199+ /// Determines if the specified file name and path is valid.
200+ /// </summary>
201+ /// <param name="filePath">The file name with optional path to test for validity.</param>
202+ /// <returns><c>true</c> if the specified <paramref name="filePath"/> is a valid name; otherwise <c>false</c>.</returns>
203+ public static bool IsValidFileName(string filePath)
204+ {
205+ if (string.IsNullOrWhiteSpace(filePath))
206+ return false;
207+
208+ try
209+ {
210+ // Attempt to parse directory and file name - this will catch most issues
211+ string directory = Path.GetDirectoryName(filePath);
212+ string filename = Path.GetFileName(filePath);
213+
214+ // Check for invalid directory characters
215+ if (!string.IsNullOrWhiteSpace(directory) && directory.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
216+ return false;
217+
218+ // Check for invalid file name characters
219+ if (string.IsNullOrWhiteSpace(filename) || filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
220+ return false;
221+
222+ // Recurse in to check validity of each directory name
223+ if (!string.IsNullOrWhiteSpace(directory) && !string.IsNullOrWhiteSpace(Path.GetFileName(directory)))
224+ return IsValidFileName(directory);
225+ }
226+ catch
227+ {
228+ // If you can't parse a file name or directory, file path is definitely not valid
229+ return false;
230+ }
231+
232+ return true;
233+ }
234+
235+ /// <summary>
236+ /// Gets a valid file name by replacing invalid file name characters with <paramref name="replaceWithCharacter"/>.
237+ /// </summary>
238+ /// <param name="fileName">File name to validate.</param>
239+ /// <param name="replaceWithCharacter">Character to replace invalid file name characters with. Set to '\0' to remove invalid file name characters.</param>
240+ /// <returns>A valid file name with no invalid file name characters.</returns>
241+ /// <remarks>
242+ /// This function expects a file name, not a file name with a path. To properly get a valid file path, where all directory
243+ /// names and the file name are validated, use the <see cref="GetValidFilePath"/>. Calling the <see cref="GetValidFileName"/>
244+ /// function will a full path will yield all directory separators replaced with the <paramref name="replaceWithCharacter"/>.
245+ /// </remarks>
246+ public static string GetValidFileName(string fileName, char replaceWithCharacter = '_')
247+ {
248+ if (replaceWithCharacter == '\0')
249+ return fileName.RemoveInvalidFileNameCharacters();
250+
251+ return fileName.ReplaceInvalidFileNameCharacters(replaceWithCharacter);
252+ }
253+
254+ /// <summary>
255+ /// Gets a valid file path by replacing invalid file or directory name characters with <paramref name="replaceWithCharacter"/>.
256+ /// </summary>
257+ /// <param name="filePath">File path to validate.</param>
258+ /// <param name="replaceWithCharacter">Character to replace invalid file or directory name characters with. Set to '\0' to remove invalid file or directory name characters.</param>
259+ /// <returns>A valid file path with no invalid file or directory name characters.</returns>
260+ public static string GetValidFilePath(string filePath, char replaceWithCharacter = '_')
261+ {
262+ string[] fileParts = filePath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
263+
264+ for (int i = 0; i < fileParts.Length; i++)
265+ {
266+ // Leave any volume specification alone
267+ if (i == 0 &&
268+ Path.VolumeSeparatorChar != Path.DirectorySeparatorChar &&
269+ Path.VolumeSeparatorChar != Path.AltDirectorySeparatorChar &&
270+ fileParts[0].IndexOfAny(new[] { Path.VolumeSeparatorChar }) > 0)
271+ continue;
272+
273+ fileParts[i] = GetValidFileName(fileParts[i], replaceWithCharacter);
274+ }
275+
276+ return string.Join(Path.DirectorySeparatorChar.ToString(), fileParts);
277+ }
278+
279+ /// <summary>
280+ /// Gets the file name and extension from the specified file path.
281+ /// </summary>
282+ /// <param name="filePath">The file path from which the file name and extension is to be obtained.</param>
283+ /// <returns>File name and extension if the file path has it; otherwise empty string.</returns>
284+ public static string GetFileName(string filePath)
285+ {
286+ return Path.GetFileName(filePath);
287+ }
288+
289+ /// <summary>
290+ /// Gets the extension from the specified file path.
291+ /// </summary>
292+ /// <param name="filePath">The file path from which the extension is to be obtained.</param>
293+ /// <returns>File extension.</returns>
294+ public static string GetExtension(string filePath)
295+ {
296+ return Path.GetExtension(RemovePathSuffix(filePath));
297+ }
298+
299+ /// <summary>
300+ /// Gets the file name without extension from the specified file path.
301+ /// </summary>
302+ /// <param name="filePath">The file path from which the file name is to be obtained.</param>
303+ /// <returns>File name without the extension if the file path has it; otherwise empty string.</returns>
304+ public static string GetFileNameWithoutExtension(string filePath)
305+ {
306+ return Path.GetFileNameWithoutExtension(RemovePathSuffix(filePath));
307+ }
308+
309+ /// <summary>
310+ /// Gets the size of the specified file.
311+ /// </summary>
312+ /// <param name="fileName">Name of file whose size is to be retrieved.</param>
313+ /// <returns>The size of the specified file.</returns>
314+ public static long GetFileLength(string fileName)
315+ {
316+ try
317+ {
318+ return (new FileInfo(fileName)).Length;
319+ }
320+ catch
321+ {
322+ return -1;
323+ }
324+ }
325+
326+ /// <summary>
327+ /// Gets a list of files under the specified path. Search wildcard pattern (c:\Data\*.dat) can be used for
328+ /// including only the files matching the pattern or path wildcard pattern (c:\Data\*\*.dat) to indicate the
329+ /// inclusion of files under all subdirectories in the list.
330+ /// </summary>
331+ /// <param name="path">The path for which a list of files is to be returned.</param>
332+ /// <returns>A list of files under the given path.</returns>
333+ public static string[] GetFileList(string path)
334+ {
335+ string directory = GetDirectoryName(path);
336+ string filePattern = GetFileName(path);
337+ SearchOption options = SearchOption.TopDirectoryOnly;
338+
339+ if (string.IsNullOrEmpty(filePattern))
340+ {
341+ // No wildcard pattern was specified, so get a listing of all files.
342+ filePattern = "*.*";
343+ }
344+
345+ if (GetLastDirectoryName(directory) == "*")
346+ {
347+ // Path wildcard pattern is used to specify the option to include subdirectories.
348+ options = SearchOption.AllDirectories;
349+ directory = directory.Remove(directory.LastIndexOf("*", StringComparison.OrdinalIgnoreCase));
350+ }
351+
352+ return Directory.GetFiles(directory, filePattern, options);
353+ }
354+
355+ /// <summary>
356+ /// Gets a regular expression pattern that simulates wildcard matching for filenames (wildcards are defined as '*' or '?' characters).
357+ /// </summary>
358+ /// <param name="fileSpec">The file spec for which the regular expression pattern if to be generated.</param>
359+ /// <returns>Regular expression pattern that simulates wildcard matching for filenames.</returns>
360+ public static string GetFilePatternRegularExpression(string fileSpec)
361+ {
362+ List<Tuple<string, string>> replacements = new List<Tuple<string, string>>()
363+ {
364+ // Replaces directory separator characters with their equivalent regular expressions.
365+ Tuple.Create($"{s_directorySeparatorCharPattern}+", $"{s_directorySeparatorCharPattern}+"),
366+
367+ // Replaces wildcard file patterns with their equivalent regular expression.
368+ Tuple.Create(Regex.Escape("?"), s_fileNameCharPattern),
369+ Tuple.Create(Regex.Escape("**") + s_directorySeparatorCharPattern, $"({s_fileNameCharPattern}*{s_directorySeparatorCharPattern})*"),
370+ Tuple.Create(Regex.Escape("*"), $"{s_fileNameCharPattern}*")
371+ };
372+
373+ StringBuilder input;
374+ StringBuilder output;
375+ Tuple<string, string> replacement;
376+ Match match;
377+
378+ input = new StringBuilder(fileSpec);
379+ output = new StringBuilder();
380+
381+ while (input.Length > 0)
382+ {
383+ // Determine if any of the replacement patterns match the input.
384+ replacement = replacements.FirstOrDefault(r => Regex.IsMatch(input.ToString(), $"^{r.Item1}"));
385+
386+ if ((object)replacement != null)
387+ {
388+ // If one of the replacement patterns matches the input,
389+ // apply that replacement and write it to the output.
390+ match = Regex.Match(input.ToString(), $"^{replacement.Item1}");
391+ output.Append(Regex.Replace(match.Value, replacement.Item1, replacement.Item2));
392+ input.Remove(0, match.Length);
393+ }
394+ else
395+ {
396+ // If not, move a single character as-is from input to the output.
397+ output.Append(Regex.Escape(input[0].ToString()));
398+ input.Remove(0, 1);
399+ }
400+ }
401+
402+ // Return the output string as the regular expression pattern.
403+ return "^" + output + "$";
404+ }
405+
406+ /// <summary>
407+ /// Gets the directory information from the specified file path.
408+ /// </summary>
409+ /// <param name="filePath">The file path from which the directory information is to be obtained.</param>
410+ /// <returns>Directory information.</returns>
411+ /// <remarks>
412+ /// This differs from <see cref="Path.GetDirectoryName"/> in that it will see if last name in path is
413+ /// a directory and, if it exists, will properly treat that part of path as a directory. The .NET path
414+ /// function always assumes last entry is a file name if path is not suffixed with a slash. For example:
415+ /// Path.GetDirectoryName(@"C:\Music") will return "C:\", however,
416+ /// FilePath.GetDirectoryName(@"C:\Music") will return "C:\Music\", so long as Music directory exists.
417+ /// </remarks>
418+ public static string GetDirectoryName(string filePath)
419+ {
420+ // Test for case where valid path does not end in directory separator, Path.GetDirectoryName assumes
421+ // this is a file name - whether is exists or not :-(
422+ string directoryName = AddPathSuffix(filePath);
423+
424+ if (Directory.Exists(directoryName))
425+ return directoryName;
426+
427+ return AddPathSuffix(Path.GetDirectoryName(filePath) ?? filePath);
428+ }
429+
430+ /// <summary>
431+ /// Gets the last directory name from a file path.
432+ /// </summary>
433+ /// <param name="filePath">The file path from where the last directory name is to be retrieved.</param>
434+ /// <returns>The last directory name from a file path.</returns>
435+ /// <remarks>
436+ /// <see cref="GetLastDirectoryName(string)"/> would return sub2 from c:\windows\sub2\filename.ext.
437+ /// </remarks>
438+ public static string GetLastDirectoryName(string filePath)
439+ {
440+ // Test case should verify the following:
441+ // FilePath.GetLastDirectoryName(@"C:\Test\sub") == "Test" <-- sub assumed to be filename
442+ // FilePath.GetLastDirectoryName(@"C:\Test\sub\") == "sub" <-- sub assumed to be directory
443+
444+ if (!string.IsNullOrEmpty(filePath))
445+ {
446+ int index;
447+ char[] dirVolChars = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar };
448+
449+ // Remove file name and trailing directory separator character from the file path.
450+ filePath = RemovePathSuffix(GetDirectoryName(filePath));
451+
452+ // Keep going through the file path until all directory separator characters are removed.
453+ while ((index = filePath.IndexOfAny(dirVolChars)) > -1)
454+ filePath = filePath.Substring(index + 1);
455+
456+ return filePath;
457+ }
458+
459+ throw new ArgumentNullException(nameof(filePath));
460+ }
461+
462+ /// <summary>
463+ /// Makes sure path is suffixed with standard <see cref="Path.DirectorySeparatorChar"/>.
464+ /// </summary>
465+ /// <param name="filePath">The file path to be suffixed.</param>
466+ /// <returns>Suffixed path.</returns>
467+ public static string AddPathSuffix(string filePath)
468+ {
469+ if (string.IsNullOrEmpty(filePath))
470+ {
471+ filePath = Path.DirectorySeparatorChar.ToString();
472+ }
473+ else
474+ {
475+ char suffixChar = filePath[filePath.Length - 1];
476+
477+ if (suffixChar != Path.DirectorySeparatorChar && suffixChar != Path.AltDirectorySeparatorChar)
478+ filePath += Path.DirectorySeparatorChar;
479+ }
480+
481+ return filePath;
482+ }
483+
484+ /// <summary>
485+ /// Makes sure path is not suffixed with <see cref="Path.DirectorySeparatorChar"/> or <see cref="Path.AltDirectorySeparatorChar"/>.
486+ /// </summary>
487+ /// <param name="filePath">The file path to be unsuffixed.</param>
488+ /// <returns>Unsuffixed path.</returns>
489+ public static string RemovePathSuffix(string filePath)
490+ {
491+ if (string.IsNullOrEmpty(filePath))
492+ {
493+ filePath = "";
494+ }
495+ else
496+ {
497+ char suffixChar = filePath[filePath.Length - 1];
498+
499+ while ((suffixChar == Path.DirectorySeparatorChar || suffixChar == Path.AltDirectorySeparatorChar) && filePath.Length > 0)
500+ {
501+ filePath = filePath.Substring(0, filePath.Length - 1);
502+
503+ if (filePath.Length > 0)
504+ suffixChar = filePath[filePath.Length - 1];
505+ }
506+ }
507+
508+ return filePath;
509+ }
510+
511+ /// <summary>
512+ /// Remove any path root present in the path.
513+ /// </summary>
514+ /// <param name="filePath">The file path whose root is to be removed.</param>
515+ /// <returns>The path with the root removed if it was present.</returns>
516+ public static string DropPathRoot(string filePath)
517+ {
518+ // JRC: Changed this to the following more simple algorithm
519+ if (string.IsNullOrEmpty(filePath))
520+ return "";
521+
522+ return filePath.Remove(0, Path.GetPathRoot(filePath).Length);
523+
524+ #region [ Original Code ]
525+
526+ //string result = filePath;
527+
528+ //if (!string.IsNullOrEmpty(filePath))
529+ //{
530+ // if ((filePath[0] == '\\') || (filePath[0] == '/'))
531+ // {
532+ // // UNC name ?
533+ // if ((filePath.Length > 1) && ((filePath[1] == '\\') || (filePath[1] == '/')))
534+ // {
535+ // int index = 2;
536+ // int elements = 2;
537+
538+ // // Scan for two separate elements \\machine\share\restofpath
539+ // while ((index <= filePath.Length) &&
540+ // (((filePath[index] != '\\') && (filePath[index] != '/')) || (--elements > 0)))
541+ // {
542+ // index++;
543+ // }
544+
545+ // index++;
546+
547+ // if (index < filePath.Length)
548+ // {
549+ // result = filePath.Substring(index);
550+ // }
551+ // else
552+ // {
553+ // result = "";
554+ // }
555+ // }
556+ // }
557+ // else if ((filePath.Length > 1) && (filePath[1] == ':'))
558+ // {
559+ // int dropCount = 2;
560+ // if ((filePath.Length > 2) && ((filePath[2] == '\\') || (filePath[2] == '/')))
561+ // {
562+ // dropCount = 3;
563+ // }
564+ // result = result.Remove(0, dropCount);
565+ // }
566+ //}
567+
568+ //return result;
569+
570+ #endregion
571+ }
572+
573+ /// <summary>
574+ /// Returns a file name, for display purposes, of the specified length using "..." to indicate a longer name.
575+ /// </summary>
576+ /// <param name="filePath">The file path to be trimmed.</param>
577+ /// <param name="length">The maximum length of the trimmed file path.</param>
578+ /// <returns>Trimmed file path.</returns>
579+ /// <remarks>
580+ /// Minimum value for the <paramref name="length" /> parameter is 12. 12 will be used for any value
581+ /// specified as less than 12.
582+ /// </remarks>
583+ public static string TrimFileName(string filePath, int length)
584+ {
585+ if (string.IsNullOrEmpty(filePath))
586+ filePath = "";
587+ else
588+ filePath = filePath.Trim();
589+
590+ if (length < 12)
591+ length = 12;
592+
593+ if (filePath.Length > length)
594+ {
595+ string justName = GetFileName(filePath);
596+
597+ if (justName.Length == filePath.Length)
598+ {
599+ // This is just a file name. Make sure extension shows.
600+ string justExtension = GetExtension(filePath);
601+ string trimName = GetFileNameWithoutExtension(filePath);
602+
603+ if (trimName.Length > 8)
604+ {
605+ if (justExtension.Length > length - 8)
606+ justExtension = justExtension.Substring(0, length - 8);
607+
608+ double offsetLen = (length - justExtension.Length - 3) / 2.0D;
609+
610+ return trimName.Substring(0, (int)(Math.Ceiling(offsetLen))) + "..." +
611+ trimName.Substring((int)Math.Round(trimName.Length - Math.Floor(offsetLen) + 1.0D)) + justExtension;
612+ }
613+
614+ // We can not trim file names less than 8 with a "...", so we truncate long extension.
615+ return trimName + justExtension.Substring(0, length - trimName.Length);
616+ }
617+
618+ // File name alone exceeds length - recurses into function without path.
619+ if (justName.Length > length)
620+ return TrimFileName(justName, length);
621+
622+ // File name contains path. Trims path before file name.
623+ string justFilePath = GetDirectoryName(filePath);
624+ int offset = length - justName.Length - 4;
625+
626+ if (justFilePath.Length > offset && offset > 0)
627+ return justFilePath.Substring(0, offset) + "..." + Path.DirectorySeparatorChar + justName;
628+
629+ // Can not fit path. Trims file name.
630+ return TrimFileName(justName, length);
631+ }
632+
633+ // Full file name fits within requested length.
634+ return filePath;
635+ }
636+
637+ /// <summary>
638+ /// Attempts to get read access on a file.
639+ /// </summary>
640+ /// <param name="fileName">The file to check for read access.</param>
641+ /// <returns>True if read access is obtained; false otherwise.</returns>
642+ public static bool TryGetReadLock(string fileName)
643+ {
644+ try
645+ {
646+ using (File.OpenRead(fileName))
647+ return true;
648+ }
649+ catch
650+ {
651+ return false;
652+ }
653+ }
654+
655+ /// <summary>
656+ /// Attempts to get read access on a file.
657+ /// </summary>
658+ /// <param name="fileName">The file to check for read access.</param>
659+ /// <returns>True if read access is obtained; false otherwise.</returns>
660+ public static bool TryGetReadLockExclusive(string fileName)
661+ {
662+ try
663+ {
664+ using (new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
665+ return true;
666+ }
667+ catch
668+ {
669+ return false;
670+ }
671+ }
672+
673+ /// <summary>
674+ /// Attempts to get write access on a file.
675+ /// </summary>
676+ /// <param name="fileName">The file to check for write access.</param>
677+ /// <returns>True if write access is obtained; false otherwise.</returns>
678+ public static bool TryGetWriteLock(string fileName)
679+ {
680+ try
681+ {
682+ using (File.OpenWrite(fileName))
683+ return true;
684+ }
685+ catch
686+ {
687+ return false;
688+ }
689+ }
690+
691+ /// <summary>
692+ /// Waits for the default duration (5 seconds) for read access on a file.
693+ /// </summary>
694+ /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
695+ public static void WaitForReadLock(string fileName)
696+ {
697+ WaitForReadLock(fileName, 5);
698+ }
699+
700+ /// <summary>
701+ /// Waits for read access on a file for the specified number of seconds.
702+ /// </summary>
703+ /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
704+ /// <param name="secondsToWait">The time to wait for in seconds to obtain read access on a file. Set to zero to wait infinitely.</param>
705+ public static void WaitForReadLock(string fileName, double secondsToWait)
706+ {
707+ if (!File.Exists(fileName))
708+ throw new FileNotFoundException("Could not test file lock for \"" + fileName + "\", file does not exist", fileName);
709+
710+ // Keeps trying for a file lock.
711+ double startTime = Common.SystemTimer;
712+
713+ while (!TryGetReadLock(fileName))
714+ {
715+ if (secondsToWait > 0)
716+ {
717+ if (Common.SystemTimer > startTime + secondsToWait)
718+ throw new IOException("Could not open \"" + fileName + "\" for read access, tried for " + secondsToWait + " seconds");
719+ }
720+
721+ // Yields to all other system threads.
722+ Thread.Sleep(250);
723+ }
724+ }
725+
726+ /// <summary>
727+ /// Waits for the default duration (5 seconds) for read access on a file.
728+ /// </summary>
729+ /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
730+ public static void WaitForReadLockExclusive(string fileName)
731+ {
732+ WaitForReadLockExclusive(fileName, 5);
733+ }
734+
735+ /// <summary>
736+ /// Waits for read access on a file for the specified number of seconds.
737+ /// </summary>
738+ /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
739+ /// <param name="secondsToWait">The time to wait for in seconds to obtain read access on a file. Set to zero to wait infinitely.</param>
740+ public static void WaitForReadLockExclusive(string fileName, double secondsToWait)
741+ {
742+ if (!File.Exists(fileName))
743+ throw new FileNotFoundException("Could not test file lock for \"" + fileName + "\", file does not exist", fileName);
744+
745+ // Keeps trying for a file lock.
746+ double startTime = Common.SystemTimer;
747+
748+ while (!TryGetReadLockExclusive(fileName))
749+ {
750+ if (secondsToWait > 0)
751+ {
752+ if (Common.SystemTimer > startTime + secondsToWait)
753+ throw new IOException("Could not open \"" + fileName + "\" for read access, tried for " + secondsToWait + " seconds");
754+ }
755+
756+ // Yields to all other system threads.
757+ Thread.Sleep(250);
758+ }
759+ }
760+
761+ /// <summary>
762+ /// Waits for the default duration (5 seconds) for write access on a file.
763+ /// </summary>
764+ /// <param name="fileName">The name of the file to wait for to obtain write access.</param>
765+ public static void WaitForWriteLock(string fileName)
766+ {
767+ WaitForWriteLock(fileName, 5);
768+ }
769+
770+ /// <summary>
771+ /// Waits for write access on a file for the specified number of seconds.
772+ /// </summary>
773+ /// <param name="fileName">The name of the file to wait for to obtain write access.</param>
774+ /// <param name="secondsToWait">The time to wait for in seconds to obtain write access on a file. Set to zero to wait infinitely.</param>
775+ public static void WaitForWriteLock(string fileName, double secondsToWait)
776+ {
777+ if (!File.Exists(fileName))
778+ throw new FileNotFoundException("Could not test file lock for \"" + fileName + "\", file does not exist", fileName);
779+
780+ // Keeps trying for a file lock.
781+ double startTime = Common.SystemTimer;
782+
783+ while (!TryGetWriteLock(fileName))
784+ {
785+ if (secondsToWait > 0)
786+ {
787+ if (Common.SystemTimer > startTime + secondsToWait)
788+ throw new IOException("Could not open \"" + fileName + "\" for write access, tried for " + secondsToWait + " seconds");
789+ }
790+
791+ // Yields to all other system threads.
792+ Thread.Sleep(250);
793+ }
794+ }
795+
796+ /// <summary>
797+ /// Waits for the default duration (5 seconds) for a file to exist.
798+ /// </summary>
799+ /// <param name="fileName">The name of the file to wait for until it is created.</param>
800+ public static void WaitTillExists(string fileName)
801+ {
802+ WaitTillExists(fileName, 5);
803+ }
804+
805+ /// <summary>
806+ /// Waits for a file to exist for the specified number of seconds.
807+ /// </summary>
808+ /// <param name="fileName">The name of the file to wait for until it is created.</param>
809+ /// <param name="secondsToWait">The time to wait for in seconds for the file to be created. Set to zero to wait infinitely.</param>
810+ public static void WaitTillExists(string fileName, double secondsToWait)
811+ {
812+ // Keeps waiting for a file to be created.
813+ double startTime = Common.SystemTimer;
814+
815+ while (!File.Exists(fileName))
816+ {
817+ if (secondsToWait > 0)
818+ {
819+ if (Common.SystemTimer > startTime + secondsToWait)
820+ throw new IOException("Waited for \"" + fileName + "\" to exist for " + secondsToWait + " seconds, but it was never created");
821+ }
822+
823+ // Yields to all other system threads.
824+ Thread.Sleep(250);
825+ }
826+ }
827+
828+ #endregion
829+ }
830+}
Source/Libraries/GSF.Core.Shared/PathHelpers.cs+0−56
@@ -1,56 +0,0 @@
1−//******************************************************************************************************
2−// PathHelpers.cs - Gbtc
3−//
4−// Copyright © 2016, Grid Protection Alliance. All Rights Reserved.
5−//
6−// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7−// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8−// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
9−// not use this file except in compliance with the License. You may obtain a copy of the License at:
10−//
11−// http://www.opensource.org/licenses/eclipse-1.0.php
12−//
13−// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14−// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15−// License for the specific language governing permissions and limitations.
16−//
17−// Code Modification History:
18−// ----------------------------------------------------------------------------------------------------
19−// 10/24/2016 - Steven E. Chisholm
20−// Generated original version of source code.
21−//
22−//
23−//******************************************************************************************************
24−
25−using System;
26−using System.IO;
27−
28−namespace GSF.IO
29−{
30− /// <summary>
31− /// Helper methods for path strings.
32− /// </summary>
33− public static class PathHelpers
34− {
35−
36− /// <summary>
37− /// Ensures the supplied path name is valid.
38− /// </summary>
39− /// <param name="pathName">any path.</param>
40− /// <remarks>
41− /// throws a series of exceptions if the <see param="pathName"/> is invalid.
42− /// </remarks>
43− public static void ValidatePathName(string pathName)
44− {
45− if (pathName.IsNullOrWhiteSpace())
46− {
47− throw new ArgumentNullException(nameof(pathName), "Extension cannot be null or empty space");
48− }
49−
50− if (pathName.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
51− throw new ArgumentException("filename has invalid characters.", "value");
52− }
53−
54−
55− }
56−}
Source/Libraries/GSF.Core/Adapters/Adapter.cs+1−1
@@ -229,7 +229,7 @@ namespace GSF.Adapters · 228 unmodified lines
229229 set
230230 {
231231 if (string.IsNullOrEmpty(value))
232− throw new ArgumentNullException("value");
232+ throw new ArgumentNullException(nameof(value));
233233
234234 m_settingsCategory = value;
235235 }
Source/Libraries/GSF.Core/Adapters/AdapterLoader.cs+7−7
@@ -471,7 +471,7 @@ namespace GSF.Adapters · 470 unmodified lines
471471 set
472472 {
473473 if ((object)value == null)
474− throw new ArgumentNullException("value");
474+ throw new ArgumentNullException(nameof(value));
475475
476476 m_adapterDirectory = value;
477477 }
@@ -490,7 +490,7 @@ namespace GSF.Adapters · 12 unmodified lines
490490 set
491491 {
492492 if (string.IsNullOrEmpty(value))
493− throw new ArgumentNullException("value");
493+ throw new ArgumentNullException(nameof(value));
494494
495495 m_adapterFileExtension = value;
496496 }
@@ -578,7 +578,7 @@ namespace GSF.Adapters · 81 unmodified lines
578578 set
579579 {
580580 if (value < 0)
581− throw new ArgumentOutOfRangeException("value");
581+ throw new ArgumentOutOfRangeException(nameof(value));
582582
583583 m_allowableProcessMemoryUsage = value;
584584 }
@@ -597,7 +597,7 @@ namespace GSF.Adapters · 12 unmodified lines
597597 set
598598 {
599599 if (value < 0)
600− throw new ArgumentOutOfRangeException("value");
600+ throw new ArgumentOutOfRangeException(nameof(value));
601601
602602 m_allowableProcessProcessorUsage = value;
603603 }
@@ -616,7 +616,7 @@ namespace GSF.Adapters · 12 unmodified lines
616616 set
617617 {
618618 if (value < 0)
619− throw new ArgumentOutOfRangeException("value");
619+ throw new ArgumentOutOfRangeException(nameof(value));
620620
621621 m_allowableAdapterMemoryUsage = value;
622622 }
@@ -635,7 +635,7 @@ namespace GSF.Adapters · 12 unmodified lines
635635 set
636636 {
637637 if (value < 0)
638− throw new ArgumentOutOfRangeException("value");
638+ throw new ArgumentOutOfRangeException(nameof(value));
639639
640640 m_allowableAdapterProcessorUsage = value;
641641 }
@@ -669,7 +669,7 @@ namespace GSF.Adapters · 27 unmodified lines
669669 set
670670 {
671671 if (string.IsNullOrEmpty(value))
672− throw new ArgumentNullException("value");
672+ throw new ArgumentNullException(nameof(value));
673673
674674 m_settingsCategory = value;
675675 }
Source/Libraries/GSF.Core/BinaryCodedDecimal.cs+4−4
@@ -131,7 +131,7 @@ namespace GSF · 130 unmodified lines
131131 public static byte Encode(byte value)
132132 {
133133 if (value > (byte)99)
134− throw new ArgumentOutOfRangeException("value", "A binary-coded decimal has a maximum value of 99 for a single byte");
134+ throw new ArgumentOutOfRangeException(nameof(value), "A binary-coded decimal has a maximum value of 99 for a single byte");
135135
136136 byte high = (byte)((value / TenP1) & 0x0F);
137137 byte low = (byte)((value % TenP1) & 0x0F);
@@ -149,7 +149,7 @@ namespace GSF · 11 unmodified lines
149149 public static ushort Encode(ushort value)
150150 {
151151 if (value > (ushort)9999)
152− throw new ArgumentOutOfRangeException("value", "A binary-coded decimal has a maximum value of 9,999 for two bytes");
152+ throw new ArgumentOutOfRangeException(nameof(value), "A binary-coded decimal has a maximum value of 9,999 for two bytes");
153153
154154 byte high = Encode((byte)(value / TenP2));
155155 byte low = Encode((byte)(value % TenP2));
@@ -167,7 +167,7 @@ namespace GSF · 11 unmodified lines
167167 public static uint Encode(uint value)
168168 {
169169 if (value > (uint)99999999)
170− throw new ArgumentOutOfRangeException("value", "A binary-coded decimal has a maximum value of 99,999,999 for four bytes");
170+ throw new ArgumentOutOfRangeException(nameof(value), "A binary-coded decimal has a maximum value of 99,999,999 for four bytes");
171171
172172 ushort high = Encode((ushort)(value / TenP4));
173173 ushort low = Encode((ushort)(value % TenP4));
@@ -185,7 +185,7 @@ namespace GSF · 11 unmodified lines
185185 public static ulong Encode(ulong value)
186186 {
187187 if (value > (ulong)9999999999999999)
188− throw new ArgumentOutOfRangeException("value", "A binary-coded decimal has a maximum value of 9,999,999,999,999,999 for eight bytes");
188+ throw new ArgumentOutOfRangeException(nameof(value), "A binary-coded decimal has a maximum value of 9,999,999,999,999,999 for eight bytes");
189189
190190 uint high = Encode((uint)(value / TenP8));
191191 uint low = Encode((uint)(value % TenP8));
Source/Libraries/GSF.Core/BinaryValueBase.cs+5−5
@@ -93,19 +93,19 @@ namespace GSF · 92 unmodified lines
9393 protected BinaryValueBase(TypeCode typeCode, byte[] buffer, int startIndex, int length)
9494 {
9595 if ((object)buffer == null)
96− throw new ArgumentNullException("buffer");
96+ throw new ArgumentNullException(nameof(buffer));
9797
9898 if (startIndex < 0)
99− throw new ArgumentOutOfRangeException("startIndex", "cannot be negative");
99+ throw new ArgumentOutOfRangeException(nameof(startIndex), "cannot be negative");
100100
101101 if (length < 0)
102− throw new ArgumentOutOfRangeException("length", "cannot be negative");
102+ throw new ArgumentOutOfRangeException(nameof(length), "cannot be negative");
103103
104104 if (startIndex >= buffer.Length)
105− throw new ArgumentOutOfRangeException("startIndex", "not a valid index in buffer");
105+ throw new ArgumentOutOfRangeException(nameof(startIndex), "not a valid index in buffer");
106106
107107 if (startIndex + length > buffer.Length)
108− throw new ArgumentOutOfRangeException("length", "exceeds buffer size");
108+ throw new ArgumentOutOfRangeException(nameof(length), "exceeds buffer size");
109109
110110 m_typeCode = typeCode;
111111 m_buffer = new byte[length];
Source/Libraries/GSF.Core/BitExtensions.cs+1−1
@@ -436,7 +436,7 @@ namespace GSF · 435 unmodified lines
436436 #endregion
437437
438438 default:
439− throw new ArgumentOutOfRangeException("bit", "Parameter must be between 0 and 63");
439+ throw new ArgumentOutOfRangeException(nameof(bit), "Parameter must be between 0 and 63");
440440 }
441441 }
442442
Source/Libraries/GSF.Core/ByteEncoding.cs+13−13
@@ -121,10 +121,10 @@ namespace GSF · 120 unmodified lines
121121 return bytes;
122122 }
123123
124− throw new ArgumentException("Input string is not a valid hex encoded string - invalid characters encountered", "hexData");
124+ throw new ArgumentException("Input string is not a valid hex encoded string - invalid characters encountered", nameof(hexData));
125125 }
126126
127− throw new ArgumentNullException("hexData", "Input string cannot be null or empty");
127+ throw new ArgumentNullException(nameof(hexData), "Input string cannot be null or empty");
128128 }
129129
130130 /// <summary>Encodes given buffer into a user presentable representation.</summary>
@@ -187,10 +187,10 @@ namespace GSF · 56 unmodified lines
187187 return bytes;
188188 }
189189
190− throw new ArgumentException("Input string is not a valid decimal encoded string - invalid characters encountered", "decData");
190+ throw new ArgumentException("Input string is not a valid decimal encoded string - invalid characters encountered", nameof(decData));
191191 }
192192
193− throw new ArgumentNullException("decData", "Input string cannot be null or empty");
193+ throw new ArgumentNullException(nameof(decData), "Input string cannot be null or empty");
194194 }
195195
196196 /// <summary>Encodes given buffer into a user presentable representation.</summary>
@@ -322,10 +322,10 @@ namespace GSF · 125 unmodified lines
322322 return bytes;
323323 }
324324
325− throw new ArgumentException("Input string is not a valid binary encoded string - invalid characters encountered", "binaryData");
325+ throw new ArgumentException("Input string is not a valid binary encoded string - invalid characters encountered", nameof(binaryData));
326326 }
327327
328− throw new ArgumentNullException("binaryData", "Input string cannot be null or empty");
328+ throw new ArgumentNullException(nameof(binaryData), "Input string cannot be null or empty");
329329 }
330330
331331 /// <summary>Encodes given buffer into a user presentable representation.</summary>
@@ -337,7 +337,7 @@ namespace GSF · 5 unmodified lines
337337 public override string GetString(byte[] bytes, int offset, int length, char spacingCharacter)
338338 {
339339 if ((object)bytes == null)
340− throw new ArgumentNullException("bytes", "Input buffer cannot be null");
340+ throw new ArgumentNullException(nameof(bytes), "Input buffer cannot be null");
341341
342342 // Initializes byte image array on first call for speed in future calls.
343343 if ((object)m_byteImages == null)
@@ -475,7 +475,7 @@ namespace GSF · 131 unmodified lines
475475 public override string GetString(byte[] bytes, int offset, int length, char spacingCharacter)
476476 {
477477 if ((object)bytes == null)
478− throw new ArgumentNullException("bytes", "Input buffer cannot be null");
478+ throw new ArgumentNullException(nameof(bytes), "Input buffer cannot be null");
479479
480480 string base64String = Convert.ToBase64String(bytes, offset, length);
481481
@@ -532,7 +532,7 @@ namespace GSF · 50 unmodified lines
532532 public override string GetString(byte[] bytes, int offset, int length, char spacingCharacter)
533533 {
534534 if ((object)bytes == null)
535− throw new ArgumentNullException("bytes", "Input buffer cannot be null");
535+ throw new ArgumentNullException(nameof(bytes), "Input buffer cannot be null");
536536
537537 string asciiString = Encoding.ASCII.GetString(bytes, offset, length);
538538
@@ -578,7 +578,7 @@ namespace GSF · 39 unmodified lines
578578 public virtual string GetString(byte[] bytes, char spacingCharacter)
579579 {
580580 if ((object)bytes == null)
581− throw new ArgumentNullException("bytes", "Input buffer cannot be null");
581+ throw new ArgumentNullException(nameof(bytes), "Input buffer cannot be null");
582582
583583 return GetString(bytes, 0, bytes.Length, spacingCharacter);
584584 }
@@ -591,7 +591,7 @@ namespace GSF · 6 unmodified lines
591591 public virtual string GetString(byte[] bytes, int offset, int length)
592592 {
593593 if ((object)bytes == null)
594− throw new ArgumentNullException("bytes", "Input buffer cannot be null");
594+ throw new ArgumentNullException(nameof(bytes), "Input buffer cannot be null");
595595
596596 return GetString(bytes, offset, length, NoSpacing);
597597 }
@@ -610,7 +610,7 @@ namespace GSF · 12 unmodified lines
610610 public virtual byte[] GetBytes(string value)
611611 {
612612 if (string.IsNullOrEmpty(value))
613− throw new ArgumentNullException("value", "Input string cannot be null");
613+ throw new ArgumentNullException(nameof(value), "Input string cannot be null");
614614 return GetBytes(value, NoSpacing);
615615 }
616616
@@ -726,7 +726,7 @@ namespace GSF · 109 unmodified lines
726726 internal static string BytesToString(byte[] bytes, int offset, int length, char spacingCharacter, string format)
727727 {
728728 if ((object)bytes == null)
729− throw new ArgumentNullException("bytes", "Input buffer cannot be null");
729+ throw new ArgumentNullException(nameof(bytes), "Input buffer cannot be null");
730730
731731 StringBuilder byteString = new StringBuilder();
732732
Source/Libraries/GSF.Core/Collections/AsyncQueue.cs+1−1
@@ -106,7 +106,7 @@ namespace GSF.Collections · 105 unmodified lines
106106 break;
107107
108108 default:
109− throw new ArgumentOutOfRangeException("synchronizedOperationType");
109+ throw new ArgumentOutOfRangeException(nameof(synchronizedOperationType));
110110 }
111111 }
112112
Source/Libraries/GSF.Core/Collections/CollectionExtensions.cs+6−6
@@ -533,7 +533,7 @@ namespace GSF.Collections · 532 unmodified lines
533533 return new T[length];
534534
535535 if (startIndex >= source.Length)
536− throw new ArgumentOutOfRangeException("startIndex", "Not a valid index into source buffer");
536+ throw new ArgumentOutOfRangeException(nameof(startIndex), "Not a valid index into source buffer");
537537
538538 // Create a new array that will be returned with the specified array elements.
539539 T[] copyOfSource = new T[source.Length - startIndex < length ? source.Length - startIndex : length];
@@ -737,7 +737,7 @@ namespace GSF.Collections · 197 unmodified lines
737737 private static string ToDelimitedString<TSource, TDelimiter>(IEnumerable<TSource> source, TDelimiter delimiter)
738738 {
739739 if (Common.IsReference(delimiter) && (object)delimiter == null)
740− throw new ArgumentNullException("delimiter", "delimiter cannot be null");
740+ throw new ArgumentNullException(nameof(delimiter), "delimiter cannot be null");
741741
742742 StringBuilder delimitedString = new StringBuilder();
743743
@@ -774,7 +774,7 @@ namespace GSF.Collections · 30 unmodified lines
774774 public static void LoadDelimitedString<TSource>(this IList<TSource> destination, string delimitedString, char delimiter, Func<string, TSource> convertFromString)
775775 {
776776 if ((object)delimitedString == null)
777− throw new ArgumentNullException("delimitedString", "delimitedString cannot be null");
777+ throw new ArgumentNullException(nameof(delimitedString), "delimitedString cannot be null");
778778
779779 if (destination.IsReadOnly)
780780 throw new ArgumentException("Cannot add items to a read only list");
@@ -795,10 +795,10 @@ namespace GSF.Collections · 14 unmodified lines
795795 public static void LoadDelimitedString<TSource>(this IList<TSource> destination, string delimitedString, string[] delimiters, Func<string, TSource> convertFromString)
796796 {
797797 if ((object)delimiters == null)
798− throw new ArgumentNullException("delimiters", "delimiters cannot be null");
798+ throw new ArgumentNullException(nameof(delimiters), "delimiters cannot be null");
799799
800800 if ((object)delimitedString == null)
801− throw new ArgumentNullException("delimitedString", "delimitedString cannot be null");
801+ throw new ArgumentNullException(nameof(delimitedString), "delimitedString cannot be null");
802802
803803 if (destination.IsReadOnly)
804804 throw new ArgumentException("Cannot add items to a read only list");
@@ -932,7 +932,7 @@ namespace GSF.Collections · 127 unmodified lines
932932 private static int CompareTo(this Array array1, Array array2, IComparer comparer, bool orderIsImportant = true)
933933 {
934934 if ((object)comparer == null)
935− throw new ArgumentNullException("comparer");
935+ throw new ArgumentNullException(nameof(comparer));
936936
937937 if ((object)array1 == null && (object)array2 == null)
938938 return 0;
Source/Libraries/GSF.Core/Collections/DoubleBufferedQueueManager.cs+2−2
@@ -54,10 +54,10 @@ namespace GSF.Collections · 53 unmodified lines
5454 internal DoubleBufferedQueueProducer(DoubleBufferedQueueManager<T> manager, DoubleBufferedQueue<T> queue)
5555 {
5656 if ((object)manager == null)
57− throw new ArgumentNullException("manager");
57+ throw new ArgumentNullException(nameof(manager));
5858
5959 if ((object)queue == null)
60− throw new ArgumentNullException("queue");
60+ throw new ArgumentNullException(nameof(queue));
6161
6262 m_manager = manager;
6363 m_queue = queue;
Source/Libraries/GSF.Core/Collections/FileBackedDictionary.cs+2−2
@@ -432,10 +432,10 @@ namespace GSF.Collections · 431 unmodified lines
432432 public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
433433 {
434434 if ((object)array == null)
435− throw new ArgumentNullException("array");
435+ throw new ArgumentNullException(nameof(array));
436436
437437 if (arrayIndex < 0)
438− throw new ArgumentOutOfRangeException("arrayIndex");
438+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
439439
440440 if (m_lookupTable.Count > array.Length - arrayIndex)
441441 throw new ArgumentException("Not enough available space in array to copy elements from dictionary");
Source/Libraries/GSF.Core/Collections/FileBackedHashSet.cs+13−13
@@ -306,7 +306,7 @@ namespace GSF.Collections · 305 unmodified lines
306306 int removedCount;
307307
308308 if ((object)match == null)
309− throw new ArgumentNullException("match");
309+ throw new ArgumentNullException(nameof(match));
310310
311311 removedCount = 0;
312312 m_lookupTable.UnmarkAll();
@@ -346,7 +346,7 @@ namespace GSF.Collections · 33 unmodified lines
346346 public void UnionWith(IEnumerable<T> other)
347347 {
348348 if ((object)other == null)
349− throw new ArgumentNullException("other");
349+ throw new ArgumentNullException(nameof(other));
350350
351351 foreach (T item in other)
352352 Add(item);
@@ -361,7 +361,7 @@ namespace GSF.Collections · 8 unmodified lines
361361 public void IntersectWith(IEnumerable<T> other)
362362 {
363363 if ((object)other == null)
364− throw new ArgumentNullException("other");
364+ throw new ArgumentNullException(nameof(other));
365365
366366 m_lookupTable.UnmarkAll();
367367
@@ -380,7 +380,7 @@ namespace GSF.Collections · 12 unmodified lines
380380 public void ExceptWith(IEnumerable<T> other)
381381 {
382382 if ((object)other == null)
383− throw new ArgumentNullException("other");
383+ throw new ArgumentNullException(nameof(other));
384384
385385 foreach (T item in other)
386386 m_lookupTable.Remove(item);
@@ -398,7 +398,7 @@ namespace GSF.Collections · 11 unmodified lines
398398 List<T> list;
399399
400400 if ((object)other == null)
401− throw new ArgumentNullException("other");
401+ throw new ArgumentNullException(nameof(other));
402402
403403 list = new List<T>();
404404 m_lookupTable.UnmarkAll();
@@ -427,7 +427,7 @@ namespace GSF.Collections · 22 unmodified lines
427427 public bool IsSubsetOf(IEnumerable<T> other)
428428 {
429429 if ((object)other == null)
430− throw new ArgumentNullException("other");
430+ throw new ArgumentNullException(nameof(other));
431431
432432 m_lookupTable.UnmarkAll();
433433
@@ -448,7 +448,7 @@ namespace GSF.Collections · 14 unmodified lines
448448 public bool IsSupersetOf(IEnumerable<T> other)
449449 {
450450 if ((object)other == null)
451− throw new ArgumentNullException("other");
451+ throw new ArgumentNullException(nameof(other));
452452
453453 foreach (T item in other)
454454 {
@@ -471,7 +471,7 @@ namespace GSF.Collections · 16 unmodified lines
471471 public bool IsProperSupersetOf(IEnumerable<T> other)
472472 {
473473 if ((object)other == null)
474− throw new ArgumentNullException("other");
474+ throw new ArgumentNullException(nameof(other));
475475
476476 m_lookupTable.UnmarkAll();
477477
@@ -498,7 +498,7 @@ namespace GSF.Collections · 20 unmodified lines
498498 bool canBeProperSubset;
499499
500500 if ((object)other == null)
501− throw new ArgumentNullException("other");
501+ throw new ArgumentNullException(nameof(other));
502502
503503 canBeProperSubset = false;
504504 m_lookupTable.UnmarkAll();
@@ -523,7 +523,7 @@ namespace GSF.Collections · 18 unmodified lines
523523 public bool Overlaps(IEnumerable<T> other)
524524 {
525525 if ((object)other == null)
526− throw new ArgumentNullException("other");
526+ throw new ArgumentNullException(nameof(other));
527527
528528 foreach (T item in other)
529529 {
@@ -546,7 +546,7 @@ namespace GSF.Collections · 16 unmodified lines
546546 public bool SetEquals(IEnumerable<T> other)
547547 {
548548 if ((object)other == null)
549− throw new ArgumentNullException("other");
549+ throw new ArgumentNullException(nameof(other));
550550
551551 m_lookupTable.UnmarkAll();
552552
@@ -579,10 +579,10 @@ namespace GSF.Collections · 26 unmodified lines
579579 public void CopyTo(T[] array, int arrayIndex)
580580 {
581581 if ((object)array == null)
582− throw new ArgumentNullException("array");
582+ throw new ArgumentNullException(nameof(array));
583583
584584 if (arrayIndex < 0)
585− throw new ArgumentOutOfRangeException("arrayIndex");
585+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
586586
587587 if (m_lookupTable.Count > array.Length - arrayIndex)
588588 throw new ArgumentException("Not enough available space in array to copy elements from hash set");
Source/Libraries/GSF.Core/Collections/FileBackedLookupTable.cs+10−10
@@ -208,10 +208,10 @@ namespace GSF.Collections · 207 unmodified lines
208208 throw new InvalidOperationException("Unable to create FileBackedLookupTable with values that are not serializable");
209209
210210 if ((object)filePath == null)
211− throw new ArgumentNullException("filePath");
211+ throw new ArgumentNullException(nameof(filePath));
212212
213213 if (string.IsNullOrWhiteSpace(filePath))
214− throw new ArgumentException("Path is zero-length or contains only whitespace", "filePath");
214+ throw new ArgumentException("Path is zero-length or contains only whitespace", nameof(filePath));
215215
216216 m_lookupTableType = lookupTableType;
217217
@@ -252,7 +252,7 @@ namespace GSF.Collections · 34 unmodified lines
252252 invalidPathChars = Path.GetInvalidPathChars();
253253
254254 if (value.Any(invalidPathChars.Contains))
255− throw new ArgumentException("Path contains one or more invalid characters", "value");
255+ throw new ArgumentException("Path contains one or more invalid characters", nameof(value));
256256 }
257257
258258 Close();
@@ -317,7 +317,7 @@ namespace GSF.Collections · 58 unmodified lines
317317 set
318318 {
319319 if ((object)value == null)
320− throw new ArgumentNullException("value");
320+ throw new ArgumentNullException(nameof(value));
321321
322322 if (value.Length > HeaderNode.SignatureSize)
323323 throw new ArgumentException("Attempt was made to set signature to a value larger than the maximum signature size of " + HeaderNode.SignatureSize);
@@ -348,7 +348,7 @@ namespace GSF.Collections · 24 unmodified lines
348348 TValue value;
349349
350350 if ((object)key == null)
351− throw new ArgumentNullException("key");
351+ throw new ArgumentNullException(nameof(key));
352352
353353 if (!TryGetValue(key, out value))
354354 throw new KeyNotFoundException("Item with the given key was not found in the lookup table");
@@ -364,7 +364,7 @@ namespace GSF.Collections · 9 unmodified lines
364364 long count;
365365
366366 if ((object)key == null)
367− throw new ArgumentNullException("key");
367+ throw new ArgumentNullException(nameof(key));
368368
369369 if (IsReadOnly)
370370 throw new NotSupportedException("Unable to modify read-only lookup table");
@@ -555,7 +555,7 @@ namespace GSF.Collections · 184 unmodified lines
555555 ItemNode itemNode;
556556
557557 if ((object)key == null)
558− throw new ArgumentNullException("key");
558+ throw new ArgumentNullException(nameof(key));
559559
560560 if (IsReadOnly)
561561 throw new NotSupportedException("Unable to modify read-only lookup table");
@@ -641,7 +641,7 @@ namespace GSF.Collections · 79 unmodified lines
641641 long itemPointer;
642642
643643 if ((object)key == null)
644− throw new ArgumentNullException("key");
644+ throw new ArgumentNullException(nameof(key));
645645
646646 if (IsReadOnly)
647647 throw new NotSupportedException("Unable to modify read-only lookup table");
@@ -823,7 +823,7 @@ namespace GSF.Collections · 175 unmodified lines
823823 long itemPointer;
824824
825825 if ((object)key == null)
826− throw new ArgumentNullException("key");
826+ throw new ArgumentNullException(nameof(key));
827827
828828 if ((object)m_fileStream == null)
829829 Open();
@@ -848,7 +848,7 @@ namespace GSF.Collections · 18 unmodified lines
848848 long itemPointer;
849849
850850 if ((object)key == null)
851− throw new ArgumentNullException("key");
851+ throw new ArgumentNullException(nameof(key));
852852
853853 if ((object)m_fileStream == null)
854854 Open();
Source/Libraries/GSF.Core/Collections/PriorityQueue.cs+9−9
@@ -98,7 +98,7 @@ namespace GSF.Collections · 97 unmodified lines
9898 public PriorityQueue(int capacity)
9999 {
100100 if (capacity < 0)
101− throw new ArgumentOutOfRangeException("capacity");
101+ throw new ArgumentOutOfRangeException(nameof(capacity));
102102
103103 if (capacity == 0)
104104 m_heap = EmptyHeap;
@@ -135,14 +135,14 @@ namespace GSF.Collections · 30 unmodified lines
135135 get
136136 {
137137 if (index < 0 || index >= m_count)
138− throw new ArgumentOutOfRangeException("index");
138+ throw new ArgumentOutOfRangeException(nameof(index));
139139
140140 return m_heap[index].Item;
141141 }
142142 set
143143 {
144144 if (index < 0 || index >= m_count)
145− throw new ArgumentOutOfRangeException("index");
145+ throw new ArgumentOutOfRangeException(nameof(index));
146146
147147 m_heap[index].Item = value;
148148 m_version++;
@@ -257,7 +257,7 @@ namespace GSF.Collections · 108 unmodified lines
257257 public int GetPriority(int index)
258258 {
259259 if (index < 0 || index >= m_count)
260− throw new ArgumentOutOfRangeException("index");
260+ throw new ArgumentOutOfRangeException(nameof(index));
261261
262262 return m_heap[index].Priority;
263263 }
@@ -278,7 +278,7 @@ namespace GSF.Collections · 14 unmodified lines
278278 int oldPriority;
279279
280280 if (index < 0 || index >= m_count)
281− throw new ArgumentOutOfRangeException("index");
281+ throw new ArgumentOutOfRangeException(nameof(index));
282282
283283 oldPriority = m_heap[index].Priority;
284284 m_heap[index].Priority = priority;
@@ -391,13 +391,13 @@ namespace GSF.Collections · 106 unmodified lines
391391 public void CopyTo(T[] array, int arrayIndex)
392392 {
393393 if ((object)array == null)
394− throw new ArgumentNullException("array");
394+ throw new ArgumentNullException(nameof(array));
395395
396396 if (arrayIndex < 0)
397− throw new ArgumentOutOfRangeException("arrayIndex");
397+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
398398
399399 if (array.Length - arrayIndex < m_count)
400− throw new ArgumentException("Not enough space in destination.", "array");
400+ throw new ArgumentException("Not enough space in destination.", nameof(array));
401401
402402 foreach (T item in this)
403403 array[arrayIndex++] = item;
@@ -418,7 +418,7 @@ namespace GSF.Collections · 14 unmodified lines
418418 PriorityQueueNode swappedNode;
419419
420420 if (index < 0 || index >= m_count)
421− throw new ArgumentOutOfRangeException("index");
421+ throw new ArgumentOutOfRangeException(nameof(index));
422422
423423 m_count--;
424424 m_version++;
Source/Libraries/GSF.Core/Collections/RollingWindow.cs+6−6
@@ -56,7 +56,7 @@ namespace GSF.Collections · 55 unmodified lines
5656 public RollingWindow(int windowSize)
5757 {
5858 if (windowSize <= 0)
59− throw new ArgumentOutOfRangeException("windowSize", "windowSize must be at least 1");
59+ throw new ArgumentOutOfRangeException(nameof(windowSize), "windowSize must be at least 1");
6060
6161 m_windowSize = windowSize;
6262 m_window = new T[windowSize];
@@ -112,14 +112,14 @@ namespace GSF.Collections · 49 unmodified lines
112112 get
113113 {
114114 if (index < 0 || index >= m_count)
115− throw new ArgumentOutOfRangeException("index", "index must be greater than zero and less than the size of the collection");
115+ throw new ArgumentOutOfRangeException(nameof(index), "index must be greater than zero and less than the size of the collection");
116116
117117 return m_window[WrapIndex(m_start + index)];
118118 }
119119 set
120120 {
121121 if (index < 0 || index >= m_count)
122− throw new ArgumentOutOfRangeException("index", "index must be greater than zero and less than the size of the collection");
122+ throw new ArgumentOutOfRangeException(nameof(index), "index must be greater than zero and less than the size of the collection");
123123
124124 m_window[WrapIndex(m_start + index)] = value;
125125 }
@@ -155,7 +155,7 @@ namespace GSF.Collections · 29 unmodified lines
155155 public void Insert(int index, T item)
156156 {
157157 if (index < 0 || index > m_count)
158− throw new ArgumentOutOfRangeException("index", "index must be greater than zero and less than or equal to the size of the collection");
158+ throw new ArgumentOutOfRangeException(nameof(index), "index must be greater than zero and less than or equal to the size of the collection");
159159
160160 if (m_count >= m_windowSize)
161161 throw new InvalidOperationException("Unable to insert item; rolling window is full");
@@ -293,10 +293,10 @@ namespace GSF.Collections · 131 unmodified lines
293293 int i;
294294
295295 if ((object)array == null)
296− throw new ArgumentNullException("array");
296+ throw new ArgumentNullException(nameof(array));
297297
298298 if (arrayIndex < 0)
299− throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex must be greater than zero");
299+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), "arrayIndex must be greater than zero");
300300
301301 if (m_count > array.Length - arrayIndex)
302302 throw new ArgumentException("Not enough available space in array to copy elements from rolling window");
Source/Libraries/GSF.Core/Common.cs+0−350
@@ -139,106 +139,6 @@ namespace GSF · 138 unmodified lines
139139 private static string s_osPlatformName;
140140 private static PlatformID s_osPlatformID = PlatformID.Win32S;
141141
142− /// <summary>
143− /// Determines if the current system is a POSIX style environment.
144− /// </summary>
145− /// <remarks>
146− /// <para>
147− /// Since a .NET application compiled under Mono can run under both Windows and Unix style platforms,
148− /// you can use this property to easily determine the current operating environment.
149− /// </para>
150− /// <para>
151− /// This property will return <c>true</c> for both MacOSX and Unix environments. Use the Platform property
152− /// of the <see cref="System.Environment.OSVersion"/> to determine more specific platform type, e.g.,
153− /// MacOSX or Unix. Note that all flavors of Linux will show up as <see cref="PlatformID.Unix"/>.
154− /// </para>
155− /// </remarks>
156− public static readonly bool IsPosixEnvironment = (Path.DirectorySeparatorChar == '/'); // This is how Mono source often checks this
157−
158− /// <summary>
159− /// Determines if the code base is currently running under Mono.
160− /// </summary>
161− /// <remarks>
162− /// This property can be used to make a run-time determination if Windows or Mono based .NET is being used. However, it is
163− /// highly recommended to use the MONO compiler directive wherever possible instead of determining this at run-time.
164− /// </remarks>
165− public static bool IsMono = ((object)Type.GetType("Mono.Runtime") != null);
166−
167− /// <summary>Returns one of two strongly-typed objects.</summary>
168− /// <returns>One of two objects, depending on the evaluation of given expression.</returns>
169− /// <param name="expression">The expression you want to evaluate.</param>
170− /// <param name="truePart">Returned if expression evaluates to True.</param>
171− /// <param name="falsePart">Returned if expression evaluates to False.</param>
172− /// <typeparam name="T">Return type used for immediate expression</typeparam>
173− /// <remarks>
174− /// <para>This function acts as a strongly-typed immediate if (a.k.a. inline if).</para>
175− /// <para>
176− /// It is expected that this function will only be used in languages that do not support ?: conditional operations, e.g., Visual Basic.NET.
177− /// In Visual Basic this function can be used as a strongly-typed IIf replacement by specifying "Imports GSF.Common".
178− /// </para>
179− /// </remarks>
180− [MethodImpl(MethodImplOptions.AggressiveInlining)]
181− public static T IIf<T>(bool expression, T truePart, T falsePart)
182− {
183− return (expression ? truePart : falsePart);
184− }
185−
186− /// <summary>Creates a strongly-typed Array.</summary>
187− /// <returns>New array of specified type.</returns>
188− /// <param name="length">Desired length of new array.</param>
189− /// <typeparam name="T">Return type for new array.</typeparam>
190− /// <remarks>
191− /// <para>It is expected that this function will only be used in Visual Basic.NET.</para>
192− /// <para>
193− /// The Array.CreateInstance provides better performance and more direct CLR access for array creation (not to
194− /// mention less confusion on the matter of array lengths) in VB.NET, however the returned System.Array is not
195− /// typed properly. This function properly casts the return array based on the type specification helping
196− /// when Option Strict is enabled.
197− /// </para>
198− /// </remarks>
199− /// <example>
200− /// <code language="VB">
201− /// Dim buffer As Byte() = CreateArray(Of Byte)(12)
202− /// Dim matrix As Integer()() = CreateArray(Of Integer())(10)
203− /// </code>
204− /// </example>
205− [MethodImpl(MethodImplOptions.AggressiveInlining)]
206− public static T[] CreateArray<T>(int length)
207− {
208− // The following provides better performance than "Return New T(length) {}".
209− // ReSharper disable once UseArrayCreationExpression.1
210− return (T[])Array.CreateInstance(typeof(T), length);
211− }
212−
213− /// <summary>Creates a strongly-typed Array with an initial value parameter.</summary>
214− /// <returns>New array of specified type.</returns>
215− /// <param name="length">Desired length of new array.</param>
216− /// <param name="initialValue">Value used to initialize all array elements.</param>
217− /// <typeparam name="T">Return type for new array.</typeparam>
218− /// <remarks>
219− /// It is expected that this function will only be used in Visual Basic.NET.
220− /// </remarks>
221− /// <example>
222− /// <code language="VB">
223− /// Dim elements As Integer() = CreateArray(12, -1)
224− /// Dim names As String() = CreateArray(100, "undefined")
225− /// </code>
226− /// </example>
227− [MethodImpl(MethodImplOptions.AggressiveInlining)]
228− public static T[] CreateArray<T>(int length, T initialValue)
229− {
230− T[] typedArray = CreateArray<T>(length);
231−
232− // Initializes all elements with the default value.
233− for (int x = 0; x < typedArray.Length; x++)
234− {
235− typedArray[x] = initialValue;
236− }
237−
238− return typedArray;
239− }
240−
241−
242142 /// <summary>
243143 /// Gets the type of the currently executing application.
244144 /// </summary>
@@ -448,256 +348,6 @@ namespace GSF · 203 unmodified lines
448348 return processMemory;
449349 }
450350
451− /// <summary>
452− /// Converts <paramref name="value"/> to a <see cref="String"/> using an appropriate <see cref="TypeConverter"/>.
453− /// </summary>
454− /// <param name="value">Value to convert to a <see cref="String"/>.</param>
455− /// <returns><paramref name="value"/> converted to a <see cref="String"/>.</returns>
456− /// <remarks>
457− /// <para>
458− /// If <see cref="TypeConverter"/> fails, the value's <c>ToString()</c> value will be returned.
459− /// Returned value will never be null, if no value exists an empty string ("") will be returned.
460− /// </para>
461− /// <para>
462− /// You can use the <see cref="StringExtensions.ConvertToType{T}(string)"/> string extension method to
463− /// convert the string back to its original <see cref="Type"/>.
464− /// </para>
465− /// </remarks>
466− public static string TypeConvertToString(object value)
467− {
468− return TypeConvertToString(value, null);
469− }
470−
471− /// <summary>
472− /// Converts <paramref name="value"/> to a <see cref="String"/> using an appropriate <see cref="TypeConverter"/>.
473− /// </summary>
474− /// <param name="value">Value to convert to a <see cref="String"/>.</param>
475− /// <param name="culture"><see cref="CultureInfo"/> to use for the conversion.</param>
476− /// <returns><paramref name="value"/> converted to a <see cref="String"/>.</returns>
477− /// <remarks>
478− /// <para>
479− /// If <see cref="TypeConverter"/> fails, the value's <c>ToString()</c> value will be returned.
480− /// Returned value will never be null, if no value exists an empty string ("") will be returned.
481− /// </para>
482− /// <para>
483− /// You can use the <see cref="StringExtensions.ConvertToType{T}(string)"/> string extension method to
484− /// convert the string back to its original <see cref="Type"/>.
485− /// </para>
486− /// </remarks>
487− public static string TypeConvertToString(object value, CultureInfo culture)
488− {
489− // Don't proceed further if value is null.
490− if ((object)value == null)
491− return string.Empty;
492−
493− // If value is already a string, no need to attempt conversion
494− string valueAsString = value as string;
495−
496− if ((object)valueAsString != null)
497− return valueAsString;
498−
499− // Initialize culture info if not specified.
500− if ((object)culture == null)
501− culture = CultureInfo.InvariantCulture;
502−
503− try
504− {
505− // Attempt to use type converter to set field value
506− TypeConverter converter = TypeDescriptor.GetConverter(value);
507− return converter.ConvertToString(null, culture, value).ToNonNullString();
508− }
509− catch
510− {
511− // Otherwise just call object's ToString method
512− return value.ToNonNullString();
513− }
514− }
515−
516− /// <summary>Gets a high-resolution number of seconds, including fractional seconds, that have
517− /// elapsed since 12:00:00 midnight, January 1, 0001.</summary>
518− public static double SystemTimer
519− {
520− get
521− {
522− return Ticks.ToSeconds(DateTime.UtcNow.Ticks);
523− }
524− }
525−
526− /// <summary>Determines if given item is equal to its default value (e.g., null or 0.0).</summary>
527− /// <param name="item">Object to evaluate.</param>
528− /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
529− /// <remarks>
530− /// Native types default to zero, not null, therefore this can be used to evaluate if an item is its default (i.e., uninitialized) value.
531− /// </remarks>
532− public static bool IsDefaultValue(object item)
533− {
534− // Only reference types can be null, therefore null is its default value
535− if ((object)item == null)
536− return true;
537−
538− Type itemType = item.GetType();
539−
540− if (!itemType.IsValueType)
541− return false;
542−
543− // Handle common types
544− IConvertible convertible = item as IConvertible;
545−
546− if ((object)convertible != null)
547− {
548− try
549− {
550− switch (convertible.GetTypeCode())
551− {
552− case TypeCode.Boolean:
553− return ((bool)item == default(bool));
554− case TypeCode.SByte:
555− return ((sbyte)item == default(sbyte));
556− case TypeCode.Byte:
557− return ((byte)item == default(byte));
558− case TypeCode.Int16:
559− return ((short)item == default(short));
560− case TypeCode.UInt16:
561− return ((ushort)item == default(ushort));
562− case TypeCode.Int32:
563− return ((int)item == default(int));
564− case TypeCode.UInt32:
565− return ((uint)item == default(uint));
566− case TypeCode.Int64:
567− return ((long)item == default(long));
568− case TypeCode.UInt64:
569− return ((ulong)item == default(ulong));
570− case TypeCode.Single:
571− return ((float)item == default(float));
572− case TypeCode.Double:
573− return ((double)item == default(double));
574− case TypeCode.Decimal:
575− return ((decimal)item == default(decimal));
576− case TypeCode.Char:
577− return ((char)item == default(char));
578− case TypeCode.DateTime:
579− return ((DateTime)item == default(DateTime));
580− }
581− }
582− catch (InvalidCastException)
583− {
584− // An exception here indicates that the item is a custom type that
585− // lied about its type code. The type should still be instantiable,
586− // so we can ignore this exception
587− }
588− }
589−
590− // Handle custom value types
591− return ((ValueType)item).Equals(Activator.CreateInstance(itemType));
592− }
593−
594− /// <summary>Determines if given item is a reference type.</summary>
595− /// <param name="item">Object to evaluate.</param>
596− /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
597− [MethodImpl(MethodImplOptions.AggressiveInlining)]
598− public static bool IsReference(object item)
599− {
600− return !(item is ValueType);
601− }
602−
603− /// <summary>Determines if given item is a reference type but not a string.</summary>
604− /// <param name="item">Object to evaluate.</param>
605− /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
606− [MethodImpl(MethodImplOptions.AggressiveInlining)]
607− public static bool IsNonStringReference(object item)
608− {
609− return (IsReference(item) && !(item is string));
610− }
611−
612− /// <summary>Determines if given item is numeric.</summary>
613− /// <param name="item">Object to evaluate.</param>
614− /// <returns>Result of evaluation as a <see cref="bool"/>.</returns>
615− [MethodImpl(MethodImplOptions.AggressiveInlining)]
616− public static bool IsNumeric(object item)
617− {
618− IConvertible convertible = item as IConvertible;
619−
620− if ((object)convertible != null)
621− {
622− switch (convertible.GetTypeCode())
623− {
624− case TypeCode.Boolean:
625− case TypeCode.SByte:
626− case TypeCode.Byte:
627− case TypeCode.Int16:
628− case TypeCode.UInt16:
629− case TypeCode.Int32:
630− case TypeCode.UInt32:
631− case TypeCode.Int64:
632− case TypeCode.UInt64:
633− case TypeCode.Single:
634− case TypeCode.Double:
635− case TypeCode.Decimal:
636− return true;
637− case TypeCode.Char:
638− case TypeCode.String:
639− double result;
640− return double.TryParse(convertible.ToString(null), out result);
641− }
642− }
643−
644− return false;
645− }
646−
647− /// <summary>Returns the smallest item from a list of parameters.</summary>
648− /// <typeparam name="T">Return type <see cref="Type"/> that is the minimum value in the <paramref name="itemList"/>.</typeparam>
649− /// <param name="itemList">A variable number of parameters of the specified type.</param>
650− /// <returns>Result is the minimum value of type <see cref="Type"/> in the <paramref name="itemList"/>.</returns>
651− [MethodImpl(MethodImplOptions.AggressiveInlining)]
652− public static T Min<T>(params T[] itemList)
653− {
654− return itemList.Min();
655− }
656−
657− /// <summary>Returns the largest item from a list of parameters.</summary>
658− /// <typeparam name="T">Return type <see cref="Type"/> that is the maximum value in the <paramref name="itemList"/>.</typeparam>
659− /// <param name="itemList">A variable number of parameters of the specified type .</param>
660− /// <returns>Result is the maximum value of type <see cref="Type"/> in the <paramref name="itemList"/>.</returns>
661− [MethodImpl(MethodImplOptions.AggressiveInlining)]
662− public static T Max<T>(params T[] itemList)
663− {
664− return itemList.Max();
665− }
666−
667− /// <summary>Returns the value that is neither the largest nor the smallest.</summary>
668− /// <typeparam name="T"><see cref="Type"/> of the objects passed to and returned from this method.</typeparam>
669− /// <param name="value1">Value 1.</param>
670− /// <param name="value2">Value 2.</param>
671− /// <param name="value3">Value 3.</param>
672− /// <returns>Result is the value that is neither the largest nor the smallest.</returns>
673− [MethodImpl(MethodImplOptions.AggressiveInlining)]
674− public static T Mid<T>(T value1, T value2, T value3) where T : IComparable<T>
675− {
676− if ((object)value1 == null)
677− throw new ArgumentNullException("value1");
678−
679− if ((object)value2 == null)
680− throw new ArgumentNullException("value2");
681−
682− if ((object)value3 == null)
683− throw new ArgumentNullException("value3");
684−
685− int comp1to2 = value1.CompareTo(value2);
686− int comp1to3 = value1.CompareTo(value3);
687− int comp2to3 = value2.CompareTo(value3);
688−
689− // If 3 is the smallest, pick the smaller of 1 and 2
690− if (comp1to3 >= 0 && comp2to3 >= 0)
691− return (comp1to2 <= 0) ? value1 : value2;
692−
693− // If 2 is the smallest, pick the smaller of 1 and 3
694− if (comp1to2 >= 0 && comp2to3 <= 0)
695− return (comp1to3 <= 0) ? value1 : value3;
696−
697− // 1 is the smallest so pick the smaller of 2 and 3
698− return (comp2to3 <= 0) ? value2 : value3;
699− }
700−
701351 #region [ Old Code ]
702352
703353 ///// <summary>Returns the smallest item from a list of parameters.</summary>
Source/Libraries/GSF.Core/Configuration/CategorizedSettingsSection.cs+1−1
@@ -108,7 +108,7 @@ namespace GSF.Configuration · 107 unmodified lines
108108 get
109109 {
110110 if (string.IsNullOrEmpty(name))
111− throw new ArgumentNullException("name");
111+ throw new ArgumentNullException(nameof(name));
112112
113113 // We will add the requested category to the default properties collection, so that when
114114 // the settings are saved off to the config file, all of the categories under which
Source/Libraries/GSF.Core/Configuration/ConfigurationFile.cs+3−3
@@ -508,7 +508,7 @@ namespace GSF.Configuration · 507 unmodified lines
508508 }
509509 else
510510 {
511− throw new ArgumentNullException("configFilePath", "Path of configuration file path cannot be null");
511+ throw new ArgumentNullException(nameof(configFilePath), "Path of configuration file path cannot be null");
512512 }
513513
514514 return configuration;
@@ -535,7 +535,7 @@ namespace GSF.Configuration · 20 unmodified lines
535535 }
536536 else
537537 {
538− throw (new ArgumentNullException("configFilePath", "Path of configuration file path cannot be null"));
538+ throw (new ArgumentNullException(nameof(configFilePath), "Path of configuration file path cannot be null"));
539539 }
540540 }
541541
@@ -592,7 +592,7 @@ namespace GSF.Configuration · 50 unmodified lines
592592 }
593593 else
594594 {
595− throw new ArgumentNullException("configFilePath", "Path of configuration file path cannot be null");
595+ throw new ArgumentNullException(nameof(configFilePath), "Path of configuration file path cannot be null");
596596 }
597597 }
598598
Source/Libraries/GSF.Core/Configuration/ConnectionStringParser.cs+1−1
@@ -310,7 +310,7 @@ namespace GSF.Configuration · 309 unmodified lines
310310
311311 // Null objects don't have properties
312312 if (settingsObject == null)
313− throw new ArgumentNullException("settingsObject", "Unable to parse connection string because settings object is invalid.");
313+ throw new ArgumentNullException(nameof(settingsObject), "Unable to parse connection string because settings object is invalid.");
314314
315315 // Get the set of properties which are part of the connection string
316316 connectionStringProperties = GetConnectionStringProperties(settingsObject.GetType());
Source/Libraries/GSF.Core/Console/Command.cs+2−2
@@ -267,7 +267,7 @@ namespace GSF.Console · 266 unmodified lines
267267 public static string ShellEncode(this string parameter)
268268 {
269269 if ((object)parameter == null)
270− throw new ArgumentNullException("parameter");
270+ throw new ArgumentNullException(nameof(parameter));
271271
272272 return parameter.Replace("\\", "\\\\");
273273 }
@@ -280,7 +280,7 @@ namespace GSF.Console · 6 unmodified lines
280280 public static string ShellDecode(this string parameter)
281281 {
282282 if ((object)parameter == null)
283− throw new ArgumentNullException("parameter");
283+ throw new ArgumentNullException(nameof(parameter));
284284
285285 return parameter.Replace("\\\\", "\\");
286286 }
Source/Libraries/GSF.Core/Data/DataSetEqualityComparer.cs+1−1
@@ -123,7 +123,7 @@ namespace GSF.Data · 122 unmodified lines
123123 object field;
124124
125125 if ((object)obj == null)
126− throw new ArgumentNullException("obj");
126+ throw new ArgumentNullException(nameof(obj));
127127
128128 // This method is required by IEqualityComparer<T> - although the following
129129 // should work, this is not likely the most efficient way to do this...
Source/Libraries/GSF.Core/Data/DataSetExtensions.cs+3−3
@@ -153,10 +153,10 @@ namespace GSF.Data · 152 unmodified lines
153153 public static void SerializeToStream(this DataSet source, Stream destination, bool assumeStringForUnknownTypes = true)
154154 {
155155 if ((object)source == null)
156− throw new ArgumentNullException("source");
156+ throw new ArgumentNullException(nameof(source));
157157
158158 if ((object)destination == null)
159− throw new ArgumentNullException("destination");
159+ throw new ArgumentNullException(nameof(destination));
160160
161161 if (!destination.CanWrite)
162162 throw new InvalidOperationException("Cannot write to a read-only stream");
@@ -299,7 +299,7 @@ namespace GSF.Data · 136 unmodified lines
299299 public static DataSet DeserializeToDataSet(this Stream source)
300300 {
301301 if ((object)source == null)
302− throw new ArgumentNullException("source");
302+ throw new ArgumentNullException(nameof(source));
303303
304304 if (!source.CanRead)
305305 throw new InvalidOperationException("Cannot read from a write-only stream");
Source/Libraries/GSF.Core/DateTimeExtensions.cs+8−8
@@ -208,7 +208,7 @@ namespace GSF · 207 unmodified lines
208208 public static DateTime LocalTimeTo(this DateTime timestamp, string destinationTimeZoneStandardName)
209209 {
210210 if ((object)destinationTimeZoneStandardName == null)
211− throw new ArgumentNullException("destinationTimeZoneStandardName");
211+ throw new ArgumentNullException(nameof(destinationTimeZoneStandardName));
212212
213213 return TimeZoneInfo.ConvertTime(timestamp, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZoneStandardName));
214214 }
@@ -222,7 +222,7 @@ namespace GSF · 7 unmodified lines
222222 public static DateTime LocalTimeTo(this DateTime timestamp, TimeZoneInfo destinationTimeZone)
223223 {
224224 if ((object)destinationTimeZone == null)
225− throw new ArgumentNullException("destinationTimeZone");
225+ throw new ArgumentNullException(nameof(destinationTimeZone));
226226
227227 return TimeZoneInfo.ConvertTime(timestamp, TimeZoneInfo.Local, destinationTimeZone);
228228 }
@@ -277,7 +277,7 @@ namespace GSF · 48 unmodified lines
277277 public static DateTime UniversalTimeTo(this DateTime universalTimestamp, string destinationTimeZoneStandardName)
278278 {
279279 if ((object)destinationTimeZoneStandardName == null)
280− throw new ArgumentNullException("destinationTimeZoneStandardName");
280+ throw new ArgumentNullException(nameof(destinationTimeZoneStandardName));
281281
282282 return TimeZoneInfo.ConvertTime(universalTimestamp, TimeZoneInfo.Utc, TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZoneStandardName));
283283 }
@@ -292,7 +292,7 @@ namespace GSF · 8 unmodified lines
292292 public static DateTime UniversalTimeTo(this DateTime universalTimestamp, TimeZoneInfo destinationTimeZone)
293293 {
294294 if ((object)destinationTimeZone == null)
295− throw new ArgumentNullException("destinationTimeZone");
295+ throw new ArgumentNullException(nameof(destinationTimeZone));
296296
297297 return TimeZoneInfo.ConvertTime(universalTimestamp, TimeZoneInfo.Utc, destinationTimeZone);
298298 }
@@ -308,10 +308,10 @@ namespace GSF · 9 unmodified lines
308308 public static DateTime TimeZoneToTimeZone(this DateTime timestamp, string sourceTimeZoneStandardName, string destinationTimeZoneStandardName)
309309 {
310310 if ((object)sourceTimeZoneStandardName == null)
311− throw new ArgumentNullException("sourceTimeZoneStandardName");
311+ throw new ArgumentNullException(nameof(sourceTimeZoneStandardName));
312312
313313 if ((object)destinationTimeZoneStandardName == null)
314− throw new ArgumentNullException("destinationTimeZoneStandardName");
314+ throw new ArgumentNullException(nameof(destinationTimeZoneStandardName));
315315
316316 return TimeZoneInfo.ConvertTime(timestamp, TimeZoneInfo.FindSystemTimeZoneById(sourceTimeZoneStandardName), TimeZoneInfo.FindSystemTimeZoneById(destinationTimeZoneStandardName));
317317 }
@@ -327,10 +327,10 @@ namespace GSF · 9 unmodified lines
327327 public static DateTime TimeZoneToTimeZone(this DateTime timestamp, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone)
328328 {
329329 if ((object)sourceTimeZone == null)
330− throw new ArgumentNullException("sourceTimeZone");
330+ throw new ArgumentNullException(nameof(sourceTimeZone));
331331
332332 if ((object)destinationTimeZone == null)
333− throw new ArgumentNullException("destinationTimeZone");
333+ throw new ArgumentNullException(nameof(destinationTimeZone));
334334
335335 return TimeZoneInfo.ConvertTime(timestamp, sourceTimeZone, destinationTimeZone);
336336 }
Source/Libraries/GSF.Core/Diagnostics/PerformanceCounter.cs+6−6
@@ -175,10 +175,10 @@ namespace GSF.Diagnostics · 174 unmodified lines
175175 internal PerformanceCounter(PerformanceCounter[] sources)
176176 {
177177 if ((object)sources == null)
178− throw new ArgumentNullException("sources");
178+ throw new ArgumentNullException(nameof(sources));
179179
180180 if (sources.Length < 1)
181− throw new ArgumentOutOfRangeException("sources");
181+ throw new ArgumentOutOfRangeException(nameof(sources));
182182
183183 PerformanceCounter initialCounter = sources[0];
184184
@@ -232,7 +232,7 @@ namespace GSF.Diagnostics · 47 unmodified lines
232232 set
233233 {
234234 if (string.IsNullOrEmpty(value))
235− throw new ArgumentNullException("value");
235+ throw new ArgumentNullException(nameof(value));
236236
237237 m_aliasName = value;
238238 }
@@ -252,7 +252,7 @@ namespace GSF.Diagnostics · 13 unmodified lines
252252 set
253253 {
254254 if (string.IsNullOrEmpty(value))
255− throw new ArgumentNullException("value");
255+ throw new ArgumentNullException(nameof(value));
256256
257257 m_valueUnit = value;
258258 }
@@ -272,7 +272,7 @@ namespace GSF.Diagnostics · 13 unmodified lines
272272 set
273273 {
274274 if (value <= 0)
275− throw new ArgumentOutOfRangeException("value", "Value must be greater than 0");
275+ throw new ArgumentOutOfRangeException(nameof(value), "Value must be greater than 0");
276276
277277 m_valueDivisor = value;
278278 }
@@ -292,7 +292,7 @@ namespace GSF.Diagnostics · 13 unmodified lines
292292 set
293293 {
294294 if (value <= 0)
295− throw new ArgumentOutOfRangeException("value", "Value must be greater than 0");
295+ throw new ArgumentOutOfRangeException(nameof(value), "Value must be greater than 0");
296296
297297 m_samplingWindow = value;
298298 }
Source/Libraries/GSF.Core/Diagnostics/PerformanceMonitor.cs+1−1
@@ -159,7 +159,7 @@ namespace GSF.Diagnostics · 158 unmodified lines
159159 public PerformanceMonitor(string processName, double samplingInterval, bool addDefaultCounters = true)
160160 {
161161 if ((object)processName == null)
162− throw new ArgumentNullException("processName");
162+ throw new ArgumentNullException(nameof(processName));
163163
164164 m_processName = processName;
165165 m_counters = new List<PerformanceCounter>();
Source/Libraries/GSF.Core/EndianOrder.cs+18−18
@@ -390,7 +390,7 @@ namespace GSF · 389 unmodified lines
390390 public bool ToBoolean(byte[] value, int startIndex)
391391 {
392392 if ((object)value == null)
393− throw new ArgumentNullException("value");
393+ throw new ArgumentNullException(nameof(value));
394394
395395 return value[startIndex] != 0;
396396 }
@@ -433,7 +433,7 @@ namespace GSF · 36 unmodified lines
433433 public short ToInt16(byte[] value, int startIndex)
434434 {
435435 if ((object)value == null)
436− throw new ArgumentNullException("value");
436+ throw new ArgumentNullException(nameof(value));
437437
438438 if (m_targetIsLittleEndian)
439439 return (short)((int)value[startIndex] | (int)value[startIndex + 1] << 8);
@@ -469,13 +469,13 @@ namespace GSF · 29 unmodified lines
469469 public unsafe int ToInt32(byte[] value, int startIndex)
470470 {
471471 if ((object)value == null)
472− throw new ArgumentNullException("value");
472+ throw new ArgumentNullException(nameof(value));
473473
474474 if (startIndex < 0)
475− throw new ArgumentOutOfRangeException("startIndex");
475+ throw new ArgumentOutOfRangeException(nameof(startIndex));
476476
477477 if (startIndex > value.Length - sizeof(int))
478− throw new ArgumentOutOfRangeException("startIndex");
478+ throw new ArgumentOutOfRangeException(nameof(startIndex));
479479
480480 fixed (byte* lp = &value[startIndex])
481481 {
@@ -506,13 +506,13 @@ namespace GSF · 24 unmodified lines
506506 public unsafe long ToInt64(byte[] value, int startIndex)
507507 {
508508 if ((object)value == null)
509− throw new ArgumentNullException("value");
509+ throw new ArgumentNullException(nameof(value));
510510
511511 if (startIndex < 0)
512− throw new ArgumentOutOfRangeException("startIndex");
512+ throw new ArgumentOutOfRangeException(nameof(startIndex));
513513
514514 if (startIndex > value.Length - sizeof(long))
515− throw new ArgumentOutOfRangeException("startIndex");
515+ throw new ArgumentOutOfRangeException(nameof(startIndex));
516516
517517 fixed (byte* lp = &value[startIndex])
518518 {
@@ -639,7 +639,7 @@ namespace GSF · 120 unmodified lines
639639 public byte[] GetBytes<T>(T value) where T : struct, IConvertible
640640 {
641641 if (!typeof(T).IsPrimitive)
642− throw new ArgumentException("Value type is not primitive", "value");
642+ throw new ArgumentException("Value type is not primitive", nameof(value));
643643
644644 IConvertible nativeValue = (IConvertible)value;
645645
@@ -873,7 +873,7 @@ namespace GSF · 227 unmodified lines
873873 public int CopyBytes<T>(T value, byte[] destinationArray, int destinationIndex) where T : struct, IConvertible
874874 {
875875 if (!typeof(T).IsPrimitive)
876− throw new ArgumentException("Value type is not primitive", "value");
876+ throw new ArgumentException("Value type is not primitive", nameof(value));
877877
878878 IConvertible nativeValue = (IConvertible)value;
879879
@@ -914,7 +914,7 @@ namespace GSF · 34 unmodified lines
914914 public int CopyBytes(bool value, byte[] destinationArray, int destinationIndex)
915915 {
916916 if ((object)destinationArray == null)
917− throw new ArgumentNullException("destinationArray");
917+ throw new ArgumentNullException(nameof(destinationArray));
918918
919919 if (value)
920920 destinationArray[destinationIndex] = 1;
@@ -958,7 +958,7 @@ namespace GSF · 37 unmodified lines
958958 public int CopyBytes(short value, byte[] destinationArray, int destinationIndex)
959959 {
960960 if ((object)destinationArray == null)
961− throw new ArgumentNullException("destinationArray");
961+ throw new ArgumentNullException(nameof(destinationArray));
962962
963963 if (m_targetIsLittleEndian)
964964 {
@@ -997,13 +997,13 @@ namespace GSF · 32 unmodified lines
997997 public unsafe int CopyBytes(int value, byte[] destinationArray, int destinationIndex)
998998 {
999999 if ((object)destinationArray == null)
1000− throw new ArgumentNullException("destinationArray");
1000+ throw new ArgumentNullException(nameof(destinationArray));
10011001
10021002 if (destinationIndex < 0)
1003− throw new ArgumentOutOfRangeException("destinationIndex");
1003+ throw new ArgumentOutOfRangeException(nameof(destinationIndex));
10041004
10051005 if (destinationIndex > destinationArray.Length - sizeof(int))
1006− throw new ArgumentOutOfRangeException("destinationIndex");
1006+ throw new ArgumentOutOfRangeException(nameof(destinationIndex));
10071007
10081008 fixed (byte* rv = &destinationArray[destinationIndex])
10091009 {
@@ -1040,13 +1040,13 @@ namespace GSF · 30 unmodified lines
10401040 public unsafe int CopyBytes(long value, byte[] destinationArray, int destinationIndex)
10411041 {
10421042 if ((object)destinationArray == null)
1043− throw new ArgumentNullException("destinationArray");
1043+ throw new ArgumentNullException(nameof(destinationArray));
10441044
10451045 if (destinationIndex < 0)
1046− throw new ArgumentOutOfRangeException("destinationIndex");
1046+ throw new ArgumentOutOfRangeException(nameof(destinationIndex));
10471047
10481048 if (destinationIndex > destinationArray.Length - sizeof(long))
1049− throw new ArgumentOutOfRangeException("destinationIndex");
1049+ throw new ArgumentOutOfRangeException(nameof(destinationIndex));
10501050
10511051 fixed (byte* rv = &destinationArray[destinationIndex])
10521052 {
Source/Libraries/GSF.Core/ErrorManagement/ErrorLogger.cs+5−5
@@ -580,7 +580,7 @@ namespace GSF.ErrorManagement · 579 unmodified lines
580580 set
581581 {
582582 if (string.IsNullOrEmpty(value))
583− throw new ArgumentNullException("value");
583+ throw new ArgumentNullException(nameof(value));
584584
585585 m_settingsCategory = value;
586586 }
@@ -696,7 +696,7 @@ namespace GSF.ErrorManagement · 109 unmodified lines
696696 set
697697 {
698698 if ((object)value == null)
699− throw new ArgumentNullException("value");
699+ throw new ArgumentNullException(nameof(value));
700700
701701 m_errorTextMethod = value;
702702 }
@@ -722,7 +722,7 @@ namespace GSF.ErrorManagement · 19 unmodified lines
722722 set
723723 {
724724 if ((object)value == null)
725− throw new ArgumentNullException("value");
725+ throw new ArgumentNullException(nameof(value));
726726
727727 m_scopeTextMethod = value;
728728 }
@@ -748,7 +748,7 @@ namespace GSF.ErrorManagement · 19 unmodified lines
748748 set
749749 {
750750 if ((object)value == null)
751− throw new ArgumentNullException("value");
751+ throw new ArgumentNullException(nameof(value));
752752
753753 m_actionTextMethod = value;
754754 }
@@ -770,7 +770,7 @@ namespace GSF.ErrorManagement · 15 unmodified lines
770770 set
771771 {
772772 if ((object)value == null)
773− throw new ArgumentNullException("value");
773+ throw new ArgumentNullException(nameof(value));
774774
775775 m_moreInfoTextMethod = value;
776776 }
Source/Libraries/GSF.Core/GSF.Core.csproj+0−10
@@ -253,16 +253,6 @@ · 252 unmodified lines
253253 <Compile Include="Interop\VBArrayDescriptor.cs" />
254254 <Compile Include="Interop\WindowsApi.cs" />
255255 <Compile Include="BufferPool.cs" />
256− <Compile Include="IO\Checksums\Adler32.cs" />
257− <Compile Include="IO\Checksums\ChecksumExtensions.cs" />
258− <Compile Include="IO\Checksums\Crc16.cs" />
259− <Compile Include="IO\Checksums\Crc32.cs" />
260− <Compile Include="IO\Checksums\CrcCCITT.cs" />
261− <Compile Include="IO\Checksums\NamespaceDoc.cs" />
262− <Compile Include="IO\Checksums\Xor16.cs" />
263− <Compile Include="IO\Checksums\Xor32.cs" />
264− <Compile Include="IO\Checksums\Xor64.cs" />
265− <Compile Include="IO\Checksums\Xor8.cs" />
266256 <Compile Include="IO\Compression\CompressionExtensions.cs" />
267257 <Compile Include="IO\Compression\FileCompressor.cs" />
268258 <Compile Include="IO\Compression\NamespaceDoc.cs" />
Source/Libraries/GSF.Core/IO/CachedFileStream.cs+10−10
@@ -360,7 +360,7 @@ namespace GSF.IO · 359 unmodified lines
360360 private CachedFileStream(int blockSize)
361361 {
362362 if (blockSize <= 0)
363− throw new ArgumentOutOfRangeException("blockSize");
363+ throw new ArgumentOutOfRangeException(nameof(blockSize));
364364
365365 if (blockSize < 8)
366366 blockSize = 8;
@@ -401,7 +401,7 @@ namespace GSF.IO · 34 unmodified lines
401401 set
402402 {
403403 if (value < 0)
404− throw new ArgumentOutOfRangeException("value");
404+ throw new ArgumentOutOfRangeException(nameof(value));
405405
406406 m_cacheSize = value;
407407 PurgeCache(m_cacheSize);
@@ -476,7 +476,7 @@ namespace GSF.IO · 68 unmodified lines
476476 throw new ObjectDisposedException(GetType().FullName);
477477
478478 if (value < 0)
479− throw new ArgumentOutOfRangeException("value");
479+ throw new ArgumentOutOfRangeException(nameof(value));
480480
481481 m_position = value;
482482 }
@@ -566,16 +566,16 @@ namespace GSF.IO · 83 unmodified lines
566566 throw new NotSupportedException("Stream does not support reading.");
567567
568568 if ((object)buffer == null)
569− throw new ArgumentNullException("buffer");
569+ throw new ArgumentNullException(nameof(buffer));
570570
571571 if (offset + count > buffer.Length)
572572 throw new ArgumentException("Amount to be read exceeds the size of the buffer.");
573573
574574 if (offset < 0)
575− throw new ArgumentOutOfRangeException("offset");
575+ throw new ArgumentOutOfRangeException(nameof(offset));
576576
577577 if (count < 0)
578− throw new ArgumentOutOfRangeException("count");
578+ throw new ArgumentOutOfRangeException(nameof(count));
579579
580580 if (count == 0 || m_position >= Length)
581581 return 0;
@@ -621,16 +621,16 @@ namespace GSF.IO · 39 unmodified lines
621621 throw new NotSupportedException("Stream does not support writing.");
622622
623623 if ((object)buffer == null)
624− throw new ArgumentNullException("buffer");
624+ throw new ArgumentNullException(nameof(buffer));
625625
626626 if (offset + count > buffer.Length)
627627 throw new ArgumentException("Amount to be read exceeds the size of the buffer.");
628628
629629 if (offset < 0)
630− throw new ArgumentOutOfRangeException("offset");
630+ throw new ArgumentOutOfRangeException(nameof(offset));
631631
632632 if (count < 0)
633− throw new ArgumentOutOfRangeException("count");
633+ throw new ArgumentOutOfRangeException(nameof(count));
634634
635635 int bufferOffset = offset;
636636 long end = m_position + count;
@@ -700,7 +700,7 @@ namespace GSF.IO · 63 unmodified lines
700700 throw new NotSupportedException("The stream does not support writing.");
701701
702702 if (value < 0)
703− throw new ArgumentOutOfRangeException("value");
703+ throw new ArgumentOutOfRangeException(nameof(value));
704704
705705 // When decreasing the file size, purge the cache
706706 // of any blocks beyond the new length of the file
Source/Libraries/GSF.Core/IO/Compression/PatternCompressor.cs+13−13
@@ -142,7 +142,7 @@ namespace GSF.IO.Compression · 141 unmodified lines
142142 set
143143 {
144144 if (value > 31)
145− throw new ArgumentOutOfRangeException("value", "Compression strength must be 0 to 31");
145+ throw new ArgumentOutOfRangeException(nameof(value), "Compression strength must be 0 to 31");
146146
147147 if (m_backBuffer == null || m_backBuffer.Length < value + 1)
148148 m_backBuffer = new uint[value + 1];
@@ -173,7 +173,7 @@ namespace GSF.IO.Compression · 24 unmodified lines
173173 byte* iter, end;
174174
175175 if ((object)value == null)
176− throw new ArgumentNullException("value");
176+ throw new ArgumentNullException(nameof(value));
177177
178178 bufferLength = value.BinaryLength.AlignDoubleWord();
179179 buffer = new byte[bufferLength];
@@ -236,19 +236,19 @@ namespace GSF.IO.Compression · 56 unmodified lines
236236 byte* start, iter, end;
237237
238238 if ((object)buffer == null)
239− throw new ArgumentNullException("buffer", "Cannot write data to null buffer");
239+ throw new ArgumentNullException(nameof(buffer), "Cannot write data to null buffer");
240240
241241 if (length % SizeOf32Bits != 0)
242− throw new ArgumentException("Buffer length must be a multiple of four", "length");
242+ throw new ArgumentException("Buffer length must be a multiple of four", nameof(length));
243243
244244 if (offset < 0)
245− throw new ArgumentOutOfRangeException("offset", "offset must be greater than or equal to zero");
245+ throw new ArgumentOutOfRangeException(nameof(offset), "offset must be greater than or equal to zero");
246246
247247 if (length < 0)
248− throw new ArgumentOutOfRangeException("length", "length must be greater than or equal to zero");
248+ throw new ArgumentOutOfRangeException(nameof(length), "length must be greater than or equal to zero");
249249
250250 if (buffer.Length < offset + length)
251− throw new ArgumentOutOfRangeException("length", "length exceeds buffer array boundaries");
251+ throw new ArgumentOutOfRangeException(nameof(length), "length exceeds buffer array boundaries");
252252
253253 fixed (byte* pBuffer = buffer)
254254 {
@@ -564,22 +564,22 @@ namespace GSF.IO.Compression · 309 unmodified lines
564564 // Compression algorithm is best suited for data that differs fractionally over time (e.g., 60.05, 60.08, 60.09, 60.11...)
565565
566566 if ((object)source == null)
567− throw new ArgumentNullException("source");
567+ throw new ArgumentNullException(nameof(source));
568568
569569 if (dataLength < 0)
570− throw new ArgumentOutOfRangeException("dataLength", "Data length must be greater than or equal to zero");
570+ throw new ArgumentOutOfRangeException(nameof(dataLength), "Data length must be greater than or equal to zero");
571571
572572 if (dataLength % SizeOf32Bits != 0)
573− throw new ArgumentException("Data length must be a multiple of 4", "dataLength");
573+ throw new ArgumentException("Data length must be a multiple of 4", nameof(dataLength));
574574
575575 if (bufferLength < dataLength + 1)
576− throw new ArgumentOutOfRangeException("bufferLength", "Buffer length must be at least one byte larger than original data length in case data cannot be compressed");
576+ throw new ArgumentOutOfRangeException(nameof(bufferLength), "Buffer length must be at least one byte larger than original data length in case data cannot be compressed");
577577
578578 if (source.Length < bufferLength)
579− throw new ArgumentOutOfRangeException("source", "Actual length of source buffer is less than specified buffer length");
579+ throw new ArgumentOutOfRangeException(nameof(source), "Actual length of source buffer is less than specified buffer length");
580580
581581 if (compressionStrength > 31)
582− throw new ArgumentOutOfRangeException("compressionStrength", "Compression strength must be 0 to 31");
582+ throw new ArgumentOutOfRangeException(nameof(compressionStrength), "Compression strength must be 0 to 31");
583583
584584 // Special case when there is not enough data to be able to compress
585585 if (dataLength <= 4)
Source/Libraries/GSF.Core/IO/Compression/PatternDecompressor.cs+11−11
@@ -61,7 +61,7 @@ namespace GSF.IO.Compression · 60 unmodified lines
6161 private set
6262 {
6363 if (value > 31)
64− throw new ArgumentOutOfRangeException("value", "Compression strength must be 0 to 31");
64+ throw new ArgumentOutOfRangeException(nameof(value), "Compression strength must be 0 to 31");
6565
6666 if (m_backBuffer == null || m_backBuffer.Length < value + 1)
6767 m_backBuffer = new uint[value + 1];
@@ -211,19 +211,19 @@ namespace GSF.IO.Compression · 143 unmodified lines
211211 byte* start, iter, end;
212212
213213 if ((object)buffer == null)
214− throw new ArgumentNullException("buffer", "Cannot write data to null buffer");
214+ throw new ArgumentNullException(nameof(buffer), "Cannot write data to null buffer");
215215
216216 if (length % SizeOf32Bits != 0)
217− throw new ArgumentException("Buffer length must be a multiple of four", "length");
217+ throw new ArgumentException("Buffer length must be a multiple of four", nameof(length));
218218
219219 if (offset < 0)
220− throw new ArgumentOutOfRangeException("offset", "offset must be greater than or equal to zero");
220+ throw new ArgumentOutOfRangeException(nameof(offset), "offset must be greater than or equal to zero");
221221
222222 if (length < 0)
223− throw new ArgumentOutOfRangeException("length", "length must be greater than or equal to zero");
223+ throw new ArgumentOutOfRangeException(nameof(length), "length must be greater than or equal to zero");
224224
225225 if (buffer.Length < offset + length)
226− throw new ArgumentOutOfRangeException("length", "length exceeds buffer array boundaries");
226+ throw new ArgumentOutOfRangeException(nameof(length), "length exceeds buffer array boundaries");
227227
228228 fixed (byte* pBuffer = buffer)
229229 {
@@ -547,19 +547,19 @@ namespace GSF.IO.Compression · 317 unmodified lines
547547 byte compressionStrength = 5;
548548
549549 if (source == null)
550− throw new ArgumentNullException("source");
550+ throw new ArgumentNullException(nameof(source));
551551
552552 if (dataLength < 1)
553− throw new ArgumentOutOfRangeException("dataLength", "Data length must be greater than or equal to one");
553+ throw new ArgumentOutOfRangeException(nameof(dataLength), "Data length must be greater than or equal to one");
554554
555555 if (bufferLength < dataLength)
556− throw new ArgumentOutOfRangeException("bufferLength", "Buffer length must be at least as large as original data length");
556+ throw new ArgumentOutOfRangeException(nameof(bufferLength), "Buffer length must be at least as large as original data length");
557557
558558 if (bufferLength < maxSize)
559− throw new ArgumentOutOfRangeException("bufferLength", "Buffer length must be at least as large as is necessary to fit the maximum possible size of the decompressed data");
559+ throw new ArgumentOutOfRangeException(nameof(bufferLength), "Buffer length must be at least as large as is necessary to fit the maximum possible size of the decompressed data");
560560
561561 if (source.Length < bufferLength)
562− throw new ArgumentOutOfRangeException("source", "Actual length of source buffer is less than specified buffer length");
562+ throw new ArgumentOutOfRangeException(nameof(source), "Actual length of source buffer is less than specified buffer length");
563563
564564 if (source[0] < 0xE0)
565565 {
Source/Libraries/GSF.Core/IO/FilePath.cs+41−778
@@ -52,13 +52,8 @@ · 51 unmodified lines
5252 //******************************************************************************************************
5353
5454 using System;
55−using System.Collections.Generic;
5655 using System.IO;
57−using System.Linq;
5856 using System.Runtime.InteropServices;
59−using System.Text;
60−using System.Text.RegularExpressions;
61−using System.Threading;
6257 using System.Web.Hosting;
6358 using GSF.Identity;
6459 using GSF.Interop;
@@ -69,7 +64,7 @@ namespace GSF.IO · 4 unmodified lines
6964 /// <summary>
7065 /// Contains File and Path manipulation methods.
7166 /// </summary>
72− public static class FilePath
67+ public static partial class FilePath
7368 {
7469 #region [ Members ]
7570
@@ -92,40 +87,6 @@ namespace GSF.IO · 16 unmodified lines
9287 // Constants
9388 private const int RESOURCETYPE_DISK = 0x1;
9489
95− // Fields
96− private static readonly string s_directorySeparatorCharPattern;
97− private static readonly string s_fileNameCharPattern;
98−
99− #endregion
100−
101− #region [ Constructor ]
102−
103− static FilePath()
104− {
105− char[] directorySeparatorChars =
106− {
107− Path.DirectorySeparatorChar,
108− Path.AltDirectorySeparatorChar
109− };
110−
111− char[] encodedInvalidFileNameChars = Path.GetInvalidFileNameChars()
112− .SelectMany(c => c.RegexEncode())
113− .ToArray();
114−
115− char[] encodedDirectorySeparatorChars = directorySeparatorChars
116− .Distinct()
117− .SelectMany(c => c.RegexEncode())
118− .ToArray();
119−
120− // Defines a regular expression pattern for a valid directory separator character.
121− s_directorySeparatorCharPattern = $"[{new string(encodedDirectorySeparatorChars)}]";
122−
123− // Defines a regular expression pattern for a valid file name character. We do this by
124− // allowing any characters except those that would not be valid as part of a filename.
125− // This essentially builds the "?" wildcard pattern match.
126− s_fileNameCharPattern = $"[^{new string(encodedInvalidFileNameChars)}]";
127− }
128−
12990 #endregion
13091
13192 #region [ Methods ]
@@ -183,380 +144,28 @@ namespace GSF.IO · 51 unmodified lines
183144 }
184145
185146 /// <summary>
186− /// Determines whether the specified file name matches any of the given file specs (wildcards are defined as '*' or '?' characters).
187− /// </summary>
188− /// <param name="fileSpecs">The file specs used for matching the specified file name.</param>
189− /// <param name="filePath">The file path to be tested against the specified file specs for a match.</param>
190− /// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param>
191− /// <returns><c>true</c> if the specified file name matches any of the given file specs; otherwise <c>false</c>.</returns>
192− /// <exception cref="ArgumentException"><paramref name="filePath"/> contains one or more of the invalid characters defined in <see cref="Path.GetInvalidPathChars"/>.</exception>
193− /// <remarks>
194− /// The syntax for <paramref name="fileSpecs"/> adheres to the following rules:
195− ///
196− /// <ul>
197− /// <li>Either '\' or '/' (as defined by <see cref="Path.DirectorySeparatorChar"/> and <see cref="Path.AltDirectorySeparatorChar"/>) can match the other.</li>
198− /// <li>A single '\' or '/' at the beginning of the pattern matches any valid path root (such as "C:\" or "\\server\share").</li>
199− /// <li>A '?' matches a single character which would be valid in a file name (as defined by <see cref="Path.GetInvalidFileNameChars"/>).</li>
200− /// <li>A '*' matches any number of characters which would be valid in a file name.</li>
201− /// <li>A sequence of "**\" or "**/" matches any number of sequential directories.</li>
202− /// <li>Any other character matches itself.</li>
203− /// </ul>
204− /// </remarks>
205− public static bool IsFilePatternMatch(string[] fileSpecs, string filePath, bool ignoreCase)
206− {
207− foreach (string fileSpec in fileSpecs)
208− {
209− if (IsFilePatternMatch(fileSpec, filePath, ignoreCase))
210− return true;
211− }
212−
213− return false;
214− }
215−
216− /// <summary>
217− /// Determines whether the specified file name matches the given file spec (wildcards are defined as '*' or '?' characters).
218− /// </summary>
219− /// <param name="fileSpec">The file spec used for matching the specified file name.</param>
220− /// <param name="filePath">The file path to be tested against the specified file spec for a match.</param>
221− /// <param name="ignoreCase"><c>true</c> to specify a case-insensitive match; otherwise <c>false</c>.</param>
222− /// <returns><c>true</c> if the specified file name matches the given file spec; otherwise <c>false</c>.</returns>
223− /// <exception cref="ArgumentException"><paramref name="filePath"/> contains one or more of the invalid characters defined in <see cref="Path.GetInvalidPathChars"/>.</exception>
224− /// <remarks>
225− /// The syntax for <paramref name="fileSpec"/> adheres to the following rules:
226− ///
227− /// <ul>
228− /// <li>Either '\' or '/' (as defined by <see cref="Path.DirectorySeparatorChar"/> and <see cref="Path.AltDirectorySeparatorChar"/>) can match the other.</li>
229− /// <li>A single '\' or '/' at the beginning of the pattern matches any valid path root (such as "C:\" or "\\server\share").</li>
230− /// <li>A '?' matches a single character which would be valid in a file name (as defined by <see cref="Path.GetInvalidFileNameChars"/>).</li>
231− /// <li>A '*' matches any number of characters which would be valid in a file name.</li>
232− /// <li>A sequence of "**\" or "**/" matches any number of sequential directories.</li>
233− /// <li>Any other character matches itself.</li>
234− /// </ul>
235− /// </remarks>
236− public static bool IsFilePatternMatch(string fileSpec, string filePath, bool ignoreCase)
237− {
238− // Define regular expression patterns for the three possible sequences that can match the path root.
239− string recursiveDirPattern = $"{(Regex.Escape("**"))}{s_directorySeparatorCharPattern}";
240− string pathRootPattern = string.Format("({0}[^{0}]|{0}$)", Regex.Escape(Path.DirectorySeparatorChar.ToString()));
241− string altPathRootPattern = string.Format("({0}[^{0}]|{0}$)", Regex.Escape(Path.AltDirectorySeparatorChar.ToString()));
242−
243− // If any of the three patterns are found at the start of fileSpec and the fileName refers to a rooted path,
244− // remove the path root from fileName and then remove all leading directory separator chars from both fileSpec and fileName.
245− if (Regex.IsMatch(fileSpec, $"^({recursiveDirPattern}|{pathRootPattern}|{altPathRootPattern})") && Path.IsPathRooted(filePath))
246− {
247− fileSpec = fileSpec.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
248− filePath = Regex.Replace(filePath, $"^{Regex.Escape(Path.GetPathRoot(filePath))}", "").TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
249− }
250−
251− // Use regular expression matching to determine whether fileSpec matches fileName.
252− return (new Regex(GetFilePatternRegularExpression(fileSpec), (ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None))).IsMatch(filePath);
253− }
254−
255− /// <summary>
256− /// Determines if the specified file name and path is valid.
257− /// </summary>
258− /// <param name="filePath">The file name with optional path to test for validity.</param>
259− /// <returns><c>true</c> if the specified <paramref name="filePath"/> is a valid name; otherwise <c>false</c>.</returns>
260− public static bool IsValidFileName(string filePath)
261− {
262− if (string.IsNullOrWhiteSpace(filePath))
263− return false;
264−
265− try
266− {
267− // Attempt to parse directory and file name - this will catch most issues
268− string directory = Path.GetDirectoryName(filePath);
269− string filename = Path.GetFileName(filePath);
270−
271− // Check for invalid directory characters
272− if (!string.IsNullOrWhiteSpace(directory) && directory.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
273− return false;
274−
275− // Check for invalid file name characters
276− if (string.IsNullOrWhiteSpace(filename) || filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
277− return false;
278−
279− // Recurse in to check validity of each directory name
280− if (!string.IsNullOrWhiteSpace(directory) && !string.IsNullOrWhiteSpace(Path.GetFileName(directory)))
281− return IsValidFileName(directory);
282− }
283− catch
284− {
285− // If you can't parse a file name or directory, file path is definitely not valid
286− return false;
287− }
288−
289− return true;
290− }
291−
292− /// <summary>
293− /// Gets a valid file name by replacing invalid file name characters with <paramref name="replaceWithCharacter"/>.
294− /// </summary>
295− /// <param name="fileName">File name to validate.</param>
296− /// <param name="replaceWithCharacter">Character to replace invalid file name characters with. Set to '\0' to remove invalid file name characters.</param>
297− /// <returns>A valid file name with no invalid file name characters.</returns>
298− /// <remarks>
299− /// This function expects a file name, not a file name with a path. To properly get a valid file path, where all directory
300− /// names and the file name are validated, use the <see cref="GetValidFilePath"/>. Calling the <see cref="GetValidFileName"/>
301− /// function will a full path will yield all directory separators replaced with the <paramref name="replaceWithCharacter"/>.
302− /// </remarks>
303− public static string GetValidFileName(string fileName, char replaceWithCharacter = '_')
304− {
305− if (replaceWithCharacter == '\0')
306− return fileName.RemoveInvalidFileNameCharacters();
307−
308− return fileName.ReplaceInvalidFileNameCharacters(replaceWithCharacter);
309− }
310−
311− /// <summary>
312− /// Gets a valid file path by replacing invalid file or directory name characters with <paramref name="replaceWithCharacter"/>.
313− /// </summary>
314− /// <param name="filePath">File path to validate.</param>
315− /// <param name="replaceWithCharacter">Character to replace invalid file or directory name characters with. Set to '\0' to remove invalid file or directory name characters.</param>
316− /// <returns>A valid file path with no invalid file or directory name characters.</returns>
317− public static string GetValidFilePath(string filePath, char replaceWithCharacter = '_')
318− {
319− string[] fileParts = filePath.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
320−
321− for (int i = 0; i < fileParts.Length; i++)
322− {
323− // Leave any volume specification alone
324− if (i == 0 &&
325− Path.VolumeSeparatorChar != Path.DirectorySeparatorChar &&
326− Path.VolumeSeparatorChar != Path.AltDirectorySeparatorChar &&
327− fileParts[0].IndexOfAny(new[] { Path.VolumeSeparatorChar }) > 0)
328− continue;
329−
330− fileParts[i] = GetValidFileName(fileParts[i], replaceWithCharacter);
331− }
332−
333− return string.Join(Path.DirectorySeparatorChar.ToString(), fileParts);
334− }
335−
336− /// <summary>
337− /// Gets the file name and extension from the specified file path.
338− /// </summary>
339− /// <param name="filePath">The file path from which the file name and extension is to be obtained.</param>
340− /// <returns>File name and extension if the file path has it; otherwise empty string.</returns>
341− public static string GetFileName(string filePath)
342− {
343− return Path.GetFileName(filePath);
344− }
345−
346− /// <summary>
347− /// Gets the extension from the specified file path.
348− /// </summary>
349− /// <param name="filePath">The file path from which the extension is to be obtained.</param>
350− /// <returns>File extension.</returns>
351− public static string GetExtension(string filePath)
352− {
353− return Path.GetExtension(RemovePathSuffix(filePath));
354− }
355−
356− /// <summary>
357− /// Gets the file name without extension from the specified file path.
358− /// </summary>
359− /// <param name="filePath">The file path from which the file name is to be obtained.</param>
360− /// <returns>File name without the extension if the file path has it; otherwise empty string.</returns>
361− public static string GetFileNameWithoutExtension(string filePath)
362− {
363− return Path.GetFileNameWithoutExtension(RemovePathSuffix(filePath));
364− }
365−
366− /// <summary>
367− /// Gets the size of the specified file.
368− /// </summary>
369− /// <param name="fileName">Name of file whose size is to be retrieved.</param>
370− /// <returns>The size of the specified file.</returns>
371− public static long GetFileLength(string fileName)
372− {
373− try
374− {
375− return (new FileInfo(fileName)).Length;
376− }
377− catch
378− {
379− return -1;
380− }
381− }
382−
383− /// <summary>
384− /// Gets a list of files under the specified path. Search wildcard pattern (c:\Data\*.dat) can be used for
385− /// including only the files matching the pattern or path wildcard pattern (c:\Data\*\*.dat) to indicate the
386− /// inclusion of files under all subdirectories in the list.
387− /// </summary>
388− /// <param name="path">The path for which a list of files is to be returned.</param>
389− /// <returns>A list of files under the given path.</returns>
390− public static string[] GetFileList(string path)
391− {
392− string directory = GetDirectoryName(path);
393− string filePattern = GetFileName(path);
394− SearchOption options = SearchOption.TopDirectoryOnly;
395−
396− if (string.IsNullOrEmpty(filePattern))
397− {
398− // No wildcard pattern was specified, so get a listing of all files.
399− filePattern = "*.*";
400− }
401−
402− if (GetLastDirectoryName(directory) == "*")
403− {
404− // Path wildcard pattern is used to specify the option to include subdirectories.
405− options = SearchOption.AllDirectories;
406− directory = directory.Remove(directory.LastIndexOf("*", StringComparison.OrdinalIgnoreCase));
407− }
408−
409− return Directory.GetFiles(directory, filePattern, options);
410− }
411−
412− /// <summary>
413− /// Gets a regular expression pattern that simulates wildcard matching for filenames (wildcards are defined as '*' or '?' characters).
414− /// </summary>
415− /// <param name="fileSpec">The file spec for which the regular expression pattern if to be generated.</param>
416− /// <returns>Regular expression pattern that simulates wildcard matching for filenames.</returns>
417− public static string GetFilePatternRegularExpression(string fileSpec)
418− {
419− List<Tuple<string, string>> replacements = new List<Tuple<string, string>>()
420− {
421− // Replaces directory separator characters with their equivalent regular expressions.
422− Tuple.Create($"{s_directorySeparatorCharPattern}+", $"{s_directorySeparatorCharPattern}+"),
423−
424− // Replaces wildcard file patterns with their equivalent regular expression.
425− Tuple.Create(Regex.Escape("?"), s_fileNameCharPattern),
426− Tuple.Create(Regex.Escape("**") + s_directorySeparatorCharPattern, $"({s_fileNameCharPattern}*{s_directorySeparatorCharPattern})*"),
427− Tuple.Create(Regex.Escape("*"), $"{s_fileNameCharPattern}*")
428− };
429−
430− StringBuilder input;
431− StringBuilder output;
432− Tuple<string, string> replacement;
433− Match match;
434−
435− input = new StringBuilder(fileSpec);
436− output = new StringBuilder();
437−
438− while (input.Length > 0)
439− {
440− // Determine if any of the replacement patterns match the input.
441− replacement = replacements.FirstOrDefault(r => Regex.IsMatch(input.ToString(), $"^{r.Item1}"));
442−
443− if ((object)replacement != null)
444− {
445− // If one of the replacement patterns matches the input,
446− // apply that replacement and write it to the output.
447− match = Regex.Match(input.ToString(), $"^{replacement.Item1}");
448− output.Append(Regex.Replace(match.Value, replacement.Item1, replacement.Item2));
449− input.Remove(0, match.Length);
450− }
451− else
452− {
453− // If not, move a single character as-is from input to the output.
454− output.Append(Regex.Escape(input[0].ToString()));
455− input.Remove(0, 1);
456− }
457− }
458−
459− // Return the output string as the regular expression pattern.
460− return "^" + output.ToString() + "$";
461− }
462−
463− /// <summary>
464− /// Gets the directory information from the specified file path.
465− /// </summary>
466− /// <param name="filePath">The file path from which the directory information is to be obtained.</param>
467− /// <returns>Directory information.</returns>
468− /// <remarks>
469− /// This differs from <see cref="Path.GetDirectoryName"/> in that it will see if last name in path is
470− /// a directory and, if it exists, will properly treat that part of path as a directory. The .NET path
471− /// function always assumes last entry is a file name if path is not suffixed with a slash. For example:
472− /// Path.GetDirectoryName(@"C:\Music") will return "C:\", however,
473− /// FilePath.GetDirectoryName(@"C:\Music") will return "C:\Music\", so long as Music directory exists.
474− /// </remarks>
475− public static string GetDirectoryName(string filePath)
476− {
477− // Test for case where valid path does not end in directory separator, Path.GetDirectoryName assumes
478− // this is a file name - whether is exists or not :-(
479− string directoryName = AddPathSuffix(filePath);
480−
481− if (Directory.Exists(directoryName))
482− return directoryName;
483−
484− return AddPathSuffix(Path.GetDirectoryName(filePath) ?? filePath);
485− }
486−
487− /// <summary>
488− /// Gets the last directory name from a file path.
147+ /// Determines if the specified <paramref name="filePath"/> is contained with the current executable path.
489148 /// </summary>
490− /// <param name="filePath">The file path from where the last directory name is to be retrieved.</param>
491− /// <returns>The last directory name from a file path.</returns>
492− /// <remarks>
493− /// <see cref="GetLastDirectoryName(string)"/> would return sub2 from c:\windows\sub2\filename.ext.
494− /// </remarks>
495− public static string GetLastDirectoryName(string filePath)
149+ /// <param name="filePath">File name or relative file path.</param>
150+ /// <returns><c>true</c> if the specified <paramref name="filePath"/> is contained with the current executable path; otherwise <c>false</c>.</returns>
151+ public static bool InApplicationPath(string filePath)
496152 {
497− // Test case should verify the following:
498− // FilePath.GetLastDirectoryName(@"C:\Test\sub") == "Test" <-- sub assumed to be filename
499− // FilePath.GetLastDirectoryName(@"C:\Test\sub\") == "sub" <-- sub assumed to be directory
500−
501− if (!string.IsNullOrEmpty(filePath))
502− {
503− int index;
504− char[] dirVolChars = { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar };
505−
506− // Remove file name and trailing directory separator character from the file path.
507− filePath = RemovePathSuffix(GetDirectoryName(filePath));
508−
509− // Keep going through the file path until all directory separator characters are removed.
510− while ((index = filePath.IndexOfAny(dirVolChars)) > -1)
511− filePath = filePath.Substring(index + 1);
512−
513− return filePath;
514− }
515−
516− throw new ArgumentNullException("filePath");
153+ return GetAbsolutePath(filePath).StartsWith(GetAbsolutePath(""), StringComparison.OrdinalIgnoreCase);
517154 }
518155
519156 /// <summary>
520− /// Gets the absolute file path for the specified file name or relative file path.
157+ /// Gets the path to the folder where data related to the current
158+ /// application can be stored as well as shared among different users.
521159 /// </summary>
522− /// <param name="filePath">File name or relative file path.</param>
523− /// <returns>Absolute file path for the specified file name or relative file path.</returns>
524− public static string GetAbsolutePath(string filePath)
160+ /// <returns>Path to the folder where data related to the current application can be stored.</returns>
161+ public static string GetCommonApplicationDataFolder()
525162 {
526− if (!Path.IsPathRooted(filePath))
527− {
528− // The specified path is a relative one since it is not rooted.
529− switch (Common.GetApplicationType())
530− {
531− // Prepends the application's root to the file path.
532− case ApplicationType.Web:
533− filePath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, filePath);
534− break;
535− default:
536− try
537− {
538− filePath = Path.Combine(GetDirectoryName(AssemblyInfo.EntryAssembly.Location), filePath);
539− }
540− catch
541− {
542− // Fall back on executing assembly path if entry assembly is not available
543− filePath = Path.Combine(GetDirectoryName(AssemblyInfo.ExecutingAssembly.Location), filePath);
544− }
545− break;
546− }
547− }
163+ string rootFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
548164
549− return RemovePathSuffix(filePath);
550− }
165+ if (string.IsNullOrEmpty(AssemblyInfo.EntryAssembly.Company))
166+ return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Name);
551167
552− /// <summary>
553− /// Determines if the specified <paramref name="filePath"/> is contained with the current executable path.
554− /// </summary>
555− /// <param name="filePath">File name or relative file path.</param>
556− /// <returns><c>true</c> if the specified <paramref name="filePath"/> is contained with the current executable path; otherwise <c>false</c>.</returns>
557− public static bool InApplicationPath(string filePath)
558− {
559− return GetAbsolutePath(filePath).StartsWith(GetAbsolutePath(""), StringComparison.OrdinalIgnoreCase);
168+ return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Company, AssemblyInfo.EntryAssembly.Name);
560169 }
561170
562171 /// <summary>
@@ -599,191 +208,36 @@ namespace GSF.IO · 36 unmodified lines
599208 }
600209
601210 /// <summary>
602− /// Gets the path to the folder where data related to the current
603− /// application can be stored as well as shared among different users.
604− /// </summary>
605− /// <returns>Path to the folder where data related to the current application can be stored.</returns>
606− public static string GetCommonApplicationDataFolder()
607− {
608− string rootFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
609−
610− if (string.IsNullOrEmpty(AssemblyInfo.EntryAssembly.Company))
611− return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Name);
612−
613− return Path.Combine(rootFolder, AssemblyInfo.EntryAssembly.Company, AssemblyInfo.EntryAssembly.Name);
614− }
615−
616− /// <summary>
617− /// Makes sure path is suffixed with standard <see cref="Path.DirectorySeparatorChar"/>.
618− /// </summary>
619− /// <param name="filePath">The file path to be suffixed.</param>
620− /// <returns>Suffixed path.</returns>
621− public static string AddPathSuffix(string filePath)
622− {
623− if (string.IsNullOrEmpty(filePath))
624− {
625− filePath = Path.DirectorySeparatorChar.ToString();
626− }
627− else
628− {
629− char suffixChar = filePath[filePath.Length - 1];
630−
631− if (suffixChar != Path.DirectorySeparatorChar && suffixChar != Path.AltDirectorySeparatorChar)
632− filePath += Path.DirectorySeparatorChar;
633− }
634−
635− return filePath;
636− }
637−
638− /// <summary>
639− /// Makes sure path is not suffixed with <see cref="Path.DirectorySeparatorChar"/> or <see cref="Path.AltDirectorySeparatorChar"/>.
640− /// </summary>
641− /// <param name="filePath">The file path to be unsuffixed.</param>
642− /// <returns>Unsuffixed path.</returns>
643− public static string RemovePathSuffix(string filePath)
644− {
645− if (string.IsNullOrEmpty(filePath))
646− {
647− filePath = "";
648− }
649− else
650− {
651− char suffixChar = filePath[filePath.Length - 1];
652−
653− while ((suffixChar == Path.DirectorySeparatorChar || suffixChar == Path.AltDirectorySeparatorChar) && filePath.Length > 0)
654− {
655− filePath = filePath.Substring(0, filePath.Length - 1);
656−
657− if (filePath.Length > 0)
658− suffixChar = filePath[filePath.Length - 1];
659− }
660− }
661−
662− return filePath;
663− }
664−
665− /// <summary>
666− /// Remove any path root present in the path.
667− /// </summary>
668− /// <param name="filePath">The file path whose root is to be removed.</param>
669− /// <returns>The path with the root removed if it was present.</returns>
670− public static string DropPathRoot(string filePath)
671− {
672− // JRC: Changed this to the following more simple algorithm
673− if (string.IsNullOrEmpty(filePath))
674− return "";
675−
676− return filePath.Remove(0, Path.GetPathRoot(filePath).Length);
677−
678− #region [ Original Code ]
679− //string result = filePath;
680−
681− //if (!string.IsNullOrEmpty(filePath))
682− //{
683− // if ((filePath[0] == '\\') || (filePath[0] == '/'))
684− // {
685− // // UNC name ?
686− // if ((filePath.Length > 1) && ((filePath[1] == '\\') || (filePath[1] == '/')))
687− // {
688− // int index = 2;
689− // int elements = 2;
690−
691− // // Scan for two separate elements \\machine\share\restofpath
692− // while ((index <= filePath.Length) &&
693− // (((filePath[index] != '\\') && (filePath[index] != '/')) || (--elements > 0)))
694− // {
695− // index++;
696− // }
697−
698− // index++;
699−
700− // if (index < filePath.Length)
701− // {
702− // result = filePath.Substring(index);
703− // }
704− // else
705− // {
706− // result = "";
707− // }
708− // }
709− // }
710− // else if ((filePath.Length > 1) && (filePath[1] == ':'))
711− // {
712− // int dropCount = 2;
713− // if ((filePath.Length > 2) && ((filePath[2] == '\\') || (filePath[2] == '/')))
714− // {
715− // dropCount = 3;
716− // }
717− // result = result.Remove(0, dropCount);
718− // }
719− //}
720−
721− //return result;
722− #endregion
723− }
724−
725− /// <summary>
726− /// Returns a file name, for display purposes, of the specified length using "..." to indicate a longer name.
211+ /// Gets the absolute file path for the specified file name or relative file path.
727212 /// </summary>
728− /// <param name="filePath">The file path to be trimmed.</param>
729− /// <param name="length">The maximum length of the trimmed file path.</param>
730− /// <returns>Trimmed file path.</returns>
731− /// <remarks>
732− /// Minimum value for the <paramref name="length" /> parameter is 12. 12 will be used for any value
733− /// specified as less than 12.
734− /// </remarks>
735− public static string TrimFileName(string filePath, int length)
213+ /// <param name="filePath">File name or relative file path.</param>
214+ /// <returns>Absolute file path for the specified file name or relative file path.</returns>
215+ public static string GetAbsolutePath(string filePath)
736216 {
737− if (string.IsNullOrEmpty(filePath))
738− filePath = "";
739− else
740− filePath = filePath.Trim();
741−
742− if (length < 12)
743− length = 12;
744−
745− if (filePath.Length > length)
217+ if (!Path.IsPathRooted(filePath))
746218 {
747− string justName = GetFileName(filePath);
748−
749− if (justName.Length == filePath.Length)
219+ // The specified path is a relative one since it is not rooted.
220+ switch (Common.GetApplicationType())
750221 {
751− // This is just a file name. Make sure extension shows.
752− string justExtension = GetExtension(filePath);
753− string trimName = GetFileNameWithoutExtension(filePath);
754−
755− if (trimName.Length > 8)
756− {
757− if (justExtension.Length > length - 8)
758− justExtension = justExtension.Substring(0, length - 8);
759−
760− double offsetLen = (length - justExtension.Length - 3) / 2.0D;
761−
762− return trimName.Substring(0, (int)(Math.Ceiling(offsetLen))) + "..." +
763− trimName.Substring((int)Math.Round(trimName.Length - Math.Floor(offsetLen) + 1.0D)) + justExtension;
764− }
765−
766− // We can not trim file names less than 8 with a "...", so we truncate long extension.
767− return trimName + justExtension.Substring(0, length - trimName.Length);
222+ // Prepends the application's root to the file path.
223+ case ApplicationType.Web:
224+ filePath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, filePath);
225+ break;
226+ default:
227+ try
228+ {
229+ filePath = Path.Combine(GetDirectoryName(AssemblyInfo.EntryAssembly.Location), filePath);
230+ }
231+ catch
232+ {
233+ // Fall back on executing assembly path if entry assembly is not available
234+ filePath = Path.Combine(GetDirectoryName(AssemblyInfo.ExecutingAssembly.Location), filePath);
235+ }
236+ break;
768237 }
769−
770− // File name alone exceeds length - recurses into function without path.
771− if (justName.Length > length)
772− return TrimFileName(justName, length);
773−
774− // File name contains path. Trims path before file name.
775− string justFilePath = GetDirectoryName(filePath);
776− int offset = length - justName.Length - 4;
777−
778− if (justFilePath.Length > offset && offset > 0)
779− return justFilePath.Substring(0, offset) + "..." + Path.DirectorySeparatorChar + justName;
780−
781− // Can not fit path. Trims file name.
782− return TrimFileName(justName, length);
783238 }
784239
785− // Full file name fits within requested length.
786− return filePath;
240+ return RemovePathSuffix(filePath);
787241 }
788242
789243 /// <summary>
@@ -818,7 +272,7 @@ namespace GSF.IO · 28 unmodified lines
818272
819273 while (File.Exists(uniqueFilePath))
820274 {
821− uniqueFilePath = Path.Combine(directory, string.Format("{0} ({1}){2}", originalFileRoot, i, fileExtension));
275+ uniqueFilePath = Path.Combine(directory, $"{originalFileRoot} ({i}){fileExtension}");
822276 i++;
823277 }
824278
@@ -864,7 +318,7 @@ namespace GSF.IO · 39 unmodified lines
864318
865319 while (File.Exists(uniqueFilePath))
866320 {
867− uniqueFilePath = Path.Combine(directory, string.Format("{0} ({1}){2}", originalFileRoot, i, fileExtension));
321+ uniqueFilePath = Path.Combine(directory, $"{originalFileRoot} ({i}){fileExtension}");
868322 j = k;
869323 k = i;
870324 i *= 2;
@@ -873,7 +327,7 @@ namespace GSF.IO · 2 unmodified lines
873327 while (j < k)
874328 {
875329 i = (j + k) / 2;
876− uniqueFilePath = Path.Combine(directory, string.Format("{0} ({1}){2}", originalFileRoot, i, fileExtension));
330+ uniqueFilePath = Path.Combine(directory, $"{originalFileRoot} ({i}){fileExtension}");
877331
878332 if (File.Exists(uniqueFilePath))
879333 j = i + 1;
@@ -881,198 +335,7 @@ namespace GSF.IO · 1 unmodified line
881335 k = i;
882336 }
883337
884− return Path.Combine(directory, string.Format("{0} ({1}){2}", originalFileRoot, k, fileExtension));
885− }
886−
887− /// <summary>
888− /// Attempts to get read access on a file.
889− /// </summary>
890− /// <param name="fileName">The file to check for read access.</param>
891− /// <returns>True if read access is obtained; false otherwise.</returns>
892− public static bool TryGetReadLock(string fileName)
893− {
894− try
895− {
896− using (File.OpenRead(fileName))
897− return true;
898− }
899− catch
900− {
901− return false;
902− }
903− }
904−
905− /// <summary>
906− /// Attempts to get read access on a file.
907− /// </summary>
908− /// <param name="fileName">The file to check for read access.</param>
909− /// <returns>True if read access is obtained; false otherwise.</returns>
910− public static bool TryGetReadLockExclusive(string fileName)
911− {
912− try
913− {
914− using (new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
915− return true;
916− }
917− catch
918− {
919− return false;
920− }
921− }
922−
923− /// <summary>
924− /// Attempts to get write access on a file.
925− /// </summary>
926− /// <param name="fileName">The file to check for write access.</param>
927− /// <returns>True if write access is obtained; false otherwise.</returns>
928− public static bool TryGetWriteLock(string fileName)
929− {
930− try
931− {
932− using (File.OpenWrite(fileName))
933− return true;
934− }
935− catch
936− {
937− return false;
938− }
939− }
940−
941− /// <summary>
942− /// Waits for the default duration (5 seconds) for read access on a file.
943− /// </summary>
944− /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
945− public static void WaitForReadLock(string fileName)
946− {
947− WaitForReadLock(fileName, 5);
948− }
949−
950− /// <summary>
951− /// Waits for read access on a file for the specified number of seconds.
952− /// </summary>
953− /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
954− /// <param name="secondsToWait">The time to wait for in seconds to obtain read access on a file. Set to zero to wait infinitely.</param>
955− public static void WaitForReadLock(string fileName, double secondsToWait)
956− {
957− if (!File.Exists(fileName))
958− throw new FileNotFoundException("Could not test file lock for \"" + fileName + "\", file does not exist", fileName);
959−
960− // Keeps trying for a file lock.
961− double startTime = Common.SystemTimer;
962−
963− while (!TryGetReadLock(fileName))
964− {
965− if (secondsToWait > 0)
966− {
967− if (Common.SystemTimer > startTime + secondsToWait)
968− throw new IOException("Could not open \"" + fileName + "\" for read access, tried for " + secondsToWait + " seconds");
969− }
970−
971− // Yields to all other system threads.
972− Thread.Sleep(250);
973− }
974− }
975−
976− /// <summary>
977− /// Waits for the default duration (5 seconds) for read access on a file.
978− /// </summary>
979− /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
980− public static void WaitForReadLockExclusive(string fileName)
981− {
982− WaitForReadLockExclusive(fileName, 5);
983− }
984−
985− /// <summary>
986− /// Waits for read access on a file for the specified number of seconds.
987− /// </summary>
988− /// <param name="fileName">The name of the file to wait for to obtain read access.</param>
989− /// <param name="secondsToWait">The time to wait for in seconds to obtain read access on a file. Set to zero to wait infinitely.</param>
990− public static void WaitForReadLockExclusive(string fileName, double secondsToWait)
991− {
992− if (!File.Exists(fileName))
993− throw new FileNotFoundException("Could not test file lock for \"" + fileName + "\", file does not exist", fileName);
994−
995− // Keeps trying for a file lock.
996− double startTime = Common.SystemTimer;
997−
998− while (!TryGetReadLockExclusive(fileName))
999− {
1000− if (secondsToWait > 0)
1001− {
1002− if (Common.SystemTimer > startTime + secondsToWait)
1003− throw new IOException("Could not open \"" + fileName + "\" for read access, tried for " + secondsToWait + " seconds");
1004− }
1005−
1006− // Yields to all other system threads.
1007− Thread.Sleep(250);
1008− }
1009− }
1010−
1011− /// <summary>
1012− /// Waits for the default duration (5 seconds) for write access on a file.
1013− /// </summary>
1014− /// <param name="fileName">The name of the file to wait for to obtain write access.</param>
1015− public static void WaitForWriteLock(string fileName)
1016− {
1017− WaitForWriteLock(fileName, 5);
1018− }
1019−
1020− /// <summary>
1021− /// Waits for write access on a file for the specified number of seconds.
1022− /// </summary>
1023− /// <param name="fileName">The name of the file to wait for to obtain write access.</param>
1024− /// <param name="secondsToWait">The time to wait for in seconds to obtain write access on a file. Set to zero to wait infinitely.</param>
1025− public static void WaitForWriteLock(string fileName, double secondsToWait)
1026− {
1027− if (!File.Exists(fileName))
1028− throw new FileNotFoundException("Could not test file lock for \"" + fileName + "\", file does not exist", fileName);
1029−
1030− // Keeps trying for a file lock.
1031− double startTime = Common.SystemTimer;
1032−
1033− while (!TryGetWriteLock(fileName))
1034− {
1035− if (secondsToWait > 0)
1036− {
1037− if (Common.SystemTimer > startTime + secondsToWait)
1038− throw new IOException("Could not open \"" + fileName + "\" for write access, tried for " + secondsToWait + " seconds");
1039− }
1040−
1041− // Yields to all other system threads.
1042− Thread.Sleep(250);
1043− }
1044− }
1045−
1046− /// <summary>
1047− /// Waits for the default duration (5 seconds) for a file to exist.
1048− /// </summary>
1049− /// <param name="fileName">The name of the file to wait for until it is created.</param>
1050− public static void WaitTillExists(string fileName)
1051− {
1052− WaitTillExists(fileName, 5);
1053− }
1054−
1055− /// <summary>
1056− /// Waits for a file to exist for the specified number of seconds.
1057− /// </summary>
1058− /// <param name="fileName">The name of the file to wait for until it is created.</param>
1059− /// <param name="secondsToWait">The time to wait for in seconds for the file to be created. Set to zero to wait infinitely.</param>
1060− public static void WaitTillExists(string fileName, double secondsToWait)
1061− {
1062− // Keeps waiting for a file to be created.
1063− double startTime = Common.SystemTimer;
1064−
1065− while (!File.Exists(fileName))
1066− {
1067− if (secondsToWait > 0)
1068− {
1069− if (Common.SystemTimer > startTime + secondsToWait)
1070− throw new IOException("Waited for \"" + fileName + "\" to exist for " + secondsToWait + " seconds, but it was never created");
1071− }
1072−
1073− // Yields to all other system threads.
1074− Thread.Sleep(250);
1075− }
338+ return Path.Combine(directory, $"{originalFileRoot} ({k}){fileExtension}");
1076339 }
1077340
1078341 [DllImport("mpr.dll", EntryPoint = "WNetAddConnection2W", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
Source/Libraries/GSF.Core/IO/IsamDataFileBase.cs+3−3
@@ -404,7 +404,7 @@ namespace GSF.IO · 403 unmodified lines
404404 set
405405 {
406406 if (string.IsNullOrEmpty(value))
407− throw new ArgumentNullException("value");
407+ throw new ArgumentNullException(nameof(value));
408408
409409 m_fileName = value;
410410 ReOpen();
@@ -536,7 +536,7 @@ namespace GSF.IO · 125 unmodified lines
536536 set
537537 {
538538 if (string.IsNullOrEmpty(value))
539− throw new ArgumentNullException("value");
539+ throw new ArgumentNullException(nameof(value));
540540
541541 m_settingsCategory = value;
542542 }
@@ -1123,7 +1123,7 @@ namespace GSF.IO · 580 unmodified lines
11231123 }
11241124 else
11251125 {
1126− throw new ArgumentNullException("record");
1126+ throw new ArgumentNullException(nameof(record));
11271127 }
11281128 }
11291129 else
Source/Libraries/GSF.Core/IO/LogFile.cs+3−3
@@ -254,7 +254,7 @@ namespace GSF.IO · 253 unmodified lines
254254 set
255255 {
256256 if (string.IsNullOrEmpty(value))
257− throw new ArgumentNullException("value");
257+ throw new ArgumentNullException(nameof(value));
258258
259259 m_fileName = value;
260260 ReOpen();
@@ -277,7 +277,7 @@ namespace GSF.IO · 16 unmodified lines
277277 set
278278 {
279279 if (value < MinFileSize || value > MaxFileSize)
280− throw new ArgumentOutOfRangeException("value", string.Format("Value must be between {0} and {1}", MinFileSize, MaxFileSize));
280+ throw new ArgumentOutOfRangeException(nameof(value), string.Format("Value must be between {0} and {1}", MinFileSize, MaxFileSize));
281281
282282 m_fileSize = value;
283283 }
@@ -376,7 +376,7 @@ namespace GSF.IO · 92 unmodified lines
376376 set
377377 {
378378 if (string.IsNullOrEmpty(value))
379− throw new ArgumentNullException("value");
379+ throw new ArgumentNullException(nameof(value));
380380
381381 m_settingsCategory = value;
382382 }
Source/Libraries/GSF.Core/IO/MultipleDestinationExporter.cs+1−1
@@ -452,7 +452,7 @@ namespace GSF.IO · 451 unmodified lines
452452 set
453453 {
454454 if (string.IsNullOrEmpty(value))
455− throw new ArgumentNullException("value");
455+ throw new ArgumentNullException(nameof(value));
456456
457457 m_settingsCategory = value;
458458 }
Source/Libraries/GSF.Core/IO/OutageLog.cs+1−1
@@ -128,7 +128,7 @@ namespace GSF.IO · 127 unmodified lines
128128 set
129129 {
130130 if (string.IsNullOrWhiteSpace(value))
131− throw new ArgumentNullException("value");
131+ throw new ArgumentNullException(nameof(value));
132132
133133 m_fileName = FilePath.GetAbsolutePath(FilePath.GetValidFilePath(value));
134134 }
Source/Libraries/GSF.Core/IO/RunTimeLog.cs+1−1
@@ -128,7 +128,7 @@ namespace GSF.IO · 127 unmodified lines
128128 set
129129 {
130130 if (string.IsNullOrWhiteSpace(value))
131− throw new ArgumentNullException("value");
131+ throw new ArgumentNullException(nameof(value));
132132
133133 m_fileName = FilePath.GetAbsolutePath(FilePath.GetValidFilePath(value));
134134 }
Source/Libraries/GSF.Core/Identity/UnixUserInfo.cs+3−3
@@ -1629,7 +1629,7 @@ namespace GSF.Identity · 1628 unmodified lines
16291629 uint userID;
16301630
16311631 if ((object)userName == null)
1632− throw new ArgumentNullException("userName");
1632+ throw new ArgumentNullException(nameof(userName));
16331633
16341634 if (GetLocalUserID(ValidateAccountName(userName), out userID) == 0)
16351635 return "user:" + userID;
@@ -1643,7 +1643,7 @@ namespace GSF.Identity · 7 unmodified lines
16431643 uint groupID;
16441644
16451645 if ((object)groupName == null)
1646− throw new ArgumentNullException("groupName");
1646+ throw new ArgumentNullException(nameof(groupName));
16471647
16481648 if (GetLocalGroupID(ValidateAccountName(groupName), out groupID) == 0)
16491649 return "group:" + groupID;
@@ -1925,7 +1925,7 @@ namespace GSF.Identity · 275 unmodified lines
19251925 private static string[] PtrToStringArray(int count, IntPtr stringArray)
19261926 {
19271927 if (count < 0)
1928− throw new ArgumentOutOfRangeException("count", "< 0");
1928+ throw new ArgumentOutOfRangeException(nameof(count), "< 0");
19291929
19301930 if (stringArray == IntPtr.Zero)
19311931 return new string[count];
Source/Libraries/GSF.Core/Identity/UserInfo.cs+35−35
@@ -243,7 +243,7 @@ namespace GSF.Identity · 242 unmodified lines
243243 public UserInfo(string loginID, string ldapPath)
244244 {
245245 if (string.IsNullOrEmpty(loginID))
246− throw new ArgumentNullException("loginID");
246+ throw new ArgumentNullException(nameof(loginID));
247247
248248 string[] accountParts = loginID.Split('\\');
249249
@@ -348,7 +348,7 @@ namespace GSF.Identity · 98 unmodified lines
348348 set
349349 {
350350 if (string.IsNullOrEmpty(value))
351− throw new ArgumentNullException("value");
351+ throw new ArgumentNullException(nameof(value));
352352
353353 m_settingsCategory = value;
354354 }
@@ -992,13 +992,13 @@ namespace GSF.Identity · 637 unmodified lines
992992 {
993993 // Check input parameters.
994994 if (string.IsNullOrEmpty(domain))
995− throw new ArgumentNullException("domain");
995+ throw new ArgumentNullException(nameof(domain));
996996
997997 if (string.IsNullOrEmpty(username))
998− throw new ArgumentNullException("username");
998+ throw new ArgumentNullException(nameof(username));
999999
10001000 if (string.IsNullOrEmpty(password))
1001− throw new ArgumentNullException("password");
1001+ throw new ArgumentNullException(nameof(password));
10021002
10031003 // Set the credentials for privileged domain user account.
10041004 m_privilegedDomain = domain;
@@ -1394,13 +1394,13 @@ namespace GSF.Identity · 389 unmodified lines
13941394 public static bool LocalUserExists(string userName)
13951395 {
13961396 if ((object)userName == null)
1397− throw new ArgumentNullException("userName");
1397+ throw new ArgumentNullException(nameof(userName));
13981398
13991399 // Remove any irrelevant white space
14001400 userName = userName.Trim();
14011401
14021402 if (userName.Length == 0)
1403− throw new ArgumentException("No user name was specified.", "userName");
1403+ throw new ArgumentException("No user name was specified.", nameof(userName));
14041404
14051405 if (Common.IsPosixEnvironment)
14061406 return UnixUserInfo.LocalUserExists(userName);
@@ -1421,16 +1421,16 @@ namespace GSF.Identity · 14 unmodified lines
14211421 public static bool CreateLocalUser(string userName, string password, string userDescription = null)
14221422 {
14231423 if ((object)userName == null)
1424− throw new ArgumentNullException("userName");
1424+ throw new ArgumentNullException(nameof(userName));
14251425
14261426 if ((object)password == null)
1427− throw new ArgumentNullException("password");
1427+ throw new ArgumentNullException(nameof(password));
14281428
14291429 // Remove any irrelevant white space
14301430 userName = userName.Trim();
14311431
14321432 if (userName.Length == 0)
1433− throw new ArgumentException("Cannot create local user: no user name was specified.", "userName");
1433+ throw new ArgumentException("Cannot create local user: no user name was specified.", nameof(userName));
14341434
14351435 if (Common.IsPosixEnvironment)
14361436 return UnixUserInfo.CreateLocalUser(userName, password, userDescription);
@@ -1449,16 +1449,16 @@ namespace GSF.Identity · 12 unmodified lines
14491449 public static void SetLocalUserPassword(string userName, string password)
14501450 {
14511451 if ((object)userName == null)
1452− throw new ArgumentNullException("userName");
1452+ throw new ArgumentNullException(nameof(userName));
14531453
14541454 if ((object)password == null)
1455− throw new ArgumentNullException("password");
1455+ throw new ArgumentNullException(nameof(password));
14561456
14571457 // Remove any irrelevant white space
14581458 userName = userName.Trim();
14591459
14601460 if (userName.Length == 0)
1461− throw new ArgumentException("Cannot set password for local user: no user name was specified.", "userName");
1461+ throw new ArgumentException("Cannot set password for local user: no user name was specified.", nameof(userName));
14621462
14631463 if (Common.IsPosixEnvironment)
14641464 UnixUserInfo.SetLocalUserPassword(userName, password);
@@ -1477,13 +1477,13 @@ namespace GSF.Identity · 12 unmodified lines
14771477 public static bool RemoveLocalUser(string userName)
14781478 {
14791479 if ((object)userName == null)
1480− throw new ArgumentNullException("userName");
1480+ throw new ArgumentNullException(nameof(userName));
14811481
14821482 // Remove any irrelevant white space
14831483 userName = userName.Trim();
14841484
14851485 if (userName.Length == 0)
1486− throw new ArgumentException("Cannot remove local user: no user name was specified.", "userName");
1486+ throw new ArgumentException("Cannot remove local user: no user name was specified.", nameof(userName));
14871487
14881488 if (Common.IsPosixEnvironment)
14891489 return UnixUserInfo.RemoveLocalUser(userName);
@@ -1501,13 +1501,13 @@ namespace GSF.Identity · 11 unmodified lines
15011501 public static bool LocalGroupExists(string groupName)
15021502 {
15031503 if ((object)groupName == null)
1504− throw new ArgumentNullException("groupName");
1504+ throw new ArgumentNullException(nameof(groupName));
15051505
15061506 // Remove any irrelevant white space
15071507 groupName = groupName.Trim();
15081508
15091509 if (groupName.Length == 0)
1510− throw new ArgumentException("No group name was specified.", "groupName");
1510+ throw new ArgumentException("No group name was specified.", nameof(groupName));
15111511
15121512 groupName = ValidateGroupName(groupName);
15131513
@@ -1529,13 +1529,13 @@ namespace GSF.Identity · 15 unmodified lines
15291529 public static bool CreateLocalGroup(string groupName, string groupDescription = null)
15301530 {
15311531 if ((object)groupName == null)
1532− throw new ArgumentNullException("groupName");
1532+ throw new ArgumentNullException(nameof(groupName));
15331533
15341534 // Remove any irrelevant white space
15351535 groupName = groupName.Trim();
15361536
15371537 if (groupName.Length == 0)
1538− throw new ArgumentException("Cannot create local group: no group name was specified.", "groupName");
1538+ throw new ArgumentException("Cannot create local group: no group name was specified.", nameof(groupName));
15391539
15401540 groupName = ValidateGroupName(groupName);
15411541
@@ -1556,13 +1556,13 @@ namespace GSF.Identity · 14 unmodified lines
15561556 public static bool RemoveLocalGroup(string groupName)
15571557 {
15581558 if ((object)groupName == null)
1559− throw new ArgumentNullException("groupName");
1559+ throw new ArgumentNullException(nameof(groupName));
15601560
15611561 // Remove any irrelevant white space
15621562 groupName = groupName.Trim();
15631563
15641564 if (groupName.Length == 0)
1565− throw new ArgumentException("Cannot remove local group: no group name was specified.", "groupName");
1565+ throw new ArgumentException("Cannot remove local group: no group name was specified.", nameof(groupName));
15661566
15671567 groupName = ValidateGroupName(groupName);
15681568
@@ -1590,20 +1590,20 @@ namespace GSF.Identity · 21 unmodified lines
15901590 public static bool UserIsInLocalGroup(string groupName, string userName)
15911591 {
15921592 if ((object)groupName == null)
1593− throw new ArgumentNullException("groupName");
1593+ throw new ArgumentNullException(nameof(groupName));
15941594
15951595 if ((object)userName == null)
1596− throw new ArgumentNullException("userName");
1596+ throw new ArgumentNullException(nameof(userName));
15971597
15981598 // Remove any irrelevant white space
15991599 groupName = groupName.Trim();
16001600 userName = userName.Trim();
16011601
16021602 if (groupName.Length == 0)
1603− throw new ArgumentException("Cannot determine if user is in local group: no group name was specified.", "groupName");
1603+ throw new ArgumentException("Cannot determine if user is in local group: no group name was specified.", nameof(groupName));
16041604
16051605 if (userName.Length == 0)
1606− throw new ArgumentException("Cannot determine if user is in local group: no user name was specified.", "userName");
1606+ throw new ArgumentException("Cannot determine if user is in local group: no user name was specified.", nameof(userName));
16071607
16081608 groupName = ValidateGroupName(groupName);
16091609
@@ -1631,20 +1631,20 @@ namespace GSF.Identity · 21 unmodified lines
16311631 public static bool AddUserToLocalGroup(string groupName, string userName)
16321632 {
16331633 if ((object)groupName == null)
1634− throw new ArgumentNullException("groupName");
1634+ throw new ArgumentNullException(nameof(groupName));
16351635
16361636 if ((object)userName == null)
1637− throw new ArgumentNullException("userName");
1637+ throw new ArgumentNullException(nameof(userName));
16381638
16391639 // Remove any irrelevant white space
16401640 groupName = groupName.Trim();
16411641 userName = userName.Trim();
16421642
16431643 if (groupName.Length == 0)
1644− throw new ArgumentException("Cannot add user to local group: no group name was specified.", "groupName");
1644+ throw new ArgumentException("Cannot add user to local group: no group name was specified.", nameof(groupName));
16451645
16461646 if (userName.Length == 0)
1647− throw new ArgumentException("Cannot add user to local group: no user name was specified.", "userName");
1647+ throw new ArgumentException("Cannot add user to local group: no user name was specified.", nameof(userName));
16481648
16491649 groupName = ValidateGroupName(groupName);
16501650
@@ -1672,20 +1672,20 @@ namespace GSF.Identity · 21 unmodified lines
16721672 public static bool RemoveUserFromLocalGroup(string groupName, string userName)
16731673 {
16741674 if ((object)groupName == null)
1675− throw new ArgumentNullException("groupName");
1675+ throw new ArgumentNullException(nameof(groupName));
16761676
16771677 if ((object)userName == null)
1678− throw new ArgumentNullException("userName");
1678+ throw new ArgumentNullException(nameof(userName));
16791679
16801680 // Remove any irrelevant white space
16811681 groupName = groupName.Trim();
16821682 userName = userName.Trim();
16831683
16841684 if (groupName.Length == 0)
1685− throw new ArgumentException("Cannot remove user from local group: no group name was specified.", "groupName");
1685+ throw new ArgumentException("Cannot remove user from local group: no group name was specified.", nameof(groupName));
16861686
16871687 if (userName.Length == 0)
1688− throw new ArgumentException("Cannot remove user from local group: no user name was specified.", "userName");
1688+ throw new ArgumentException("Cannot remove user from local group: no user name was specified.", nameof(userName));
16891689
16901690 groupName = ValidateGroupName(groupName);
16911691
@@ -1706,13 +1706,13 @@ namespace GSF.Identity · 14 unmodified lines
17061706 public static string[] GetLocalGroupUserList(string groupName)
17071707 {
17081708 if ((object)groupName == null)
1709− throw new ArgumentNullException("groupName");
1709+ throw new ArgumentNullException(nameof(groupName));
17101710
17111711 // Remove any irrelevant white space
17121712 groupName = groupName.Trim();
17131713
17141714 if (groupName.Length == 0)
1715− throw new ArgumentException("Cannot get members for local group: no group name was specified.", "groupName");
1715+ throw new ArgumentException("Cannot get members for local group: no group name was specified.", nameof(groupName));
17161716
17171717 groupName = ValidateGroupName(groupName);
17181718
Source/Libraries/GSF.Core/Identity/WindowsUserInfo.cs+3−3
@@ -1390,7 +1390,7 @@ namespace GSF.Identity · 1389 unmodified lines
13901390 string accountAliasSID;
13911391
13921392 if ((object)accountName == null)
1393− throw new ArgumentNullException("accountName");
1393+ throw new ArgumentNullException(nameof(accountName));
13941394
13951395 try
13961396 {
@@ -1444,7 +1444,7 @@ namespace GSF.Identity · 47 unmodified lines
14441444 NTAccount account;
14451445
14461446 if ((object)sid == null)
1447− throw new ArgumentNullException("sid");
1447+ throw new ArgumentNullException(nameof(sid));
14481448
14491449 securityIdentifier = new SecurityIdentifier(CleanSid(sid));
14501450 account = (NTAccount)securityIdentifier.Translate(typeof(NTAccount));
@@ -1478,7 +1478,7 @@ namespace GSF.Identity · 27 unmodified lines
14781478 string accountName;
14791479
14801480 if ((object)sid == null)
1481− throw new ArgumentNullException("sid");
1481+ throw new ArgumentNullException(nameof(sid));
14821482
14831483 sid = CleanSid(sid);
14841484
Source/Libraries/GSF.Core/Net/Smtp/Mail.cs+2−2
@@ -167,7 +167,7 @@ namespace GSF.Net.Smtp · 166 unmodified lines
167167 {
168168 // This is a required field.
169169 if (string.IsNullOrEmpty(value))
170− throw new ArgumentNullException("value");
170+ throw new ArgumentNullException(nameof(value));
171171
172172 m_from = value;
173173 }
@@ -266,7 +266,7 @@ namespace GSF.Net.Smtp · 92 unmodified lines
266266
267267 // This is a required field.
268268 if (string.IsNullOrEmpty(value))
269− throw new ArgumentNullException("value");
269+ throw new ArgumentNullException(nameof(value));
270270
271271 #if !MONO
272272 // Dispose existing client.
Source/Libraries/GSF.Core/NumericalAnalysis/CurveFit.cs+3−3
@@ -64,10 +64,10 @@ namespace GSF.NumericalAnalysis · 63 unmodified lines
6464 public static double[] Compute(int polynomialOrder, IList<double> xValues, IList<double> yValues)
6565 {
6666 if ((object)xValues == null)
67− throw new ArgumentNullException("xValues");
67+ throw new ArgumentNullException(nameof(xValues));
6868
6969 if ((object)yValues == null)
70− throw new ArgumentNullException("yValues");
70+ throw new ArgumentNullException(nameof(yValues));
7171
7272 if (xValues.Count != yValues.Count)
7373 throw new ArgumentException("Point count for x-values and y-values must be equal");
@@ -76,7 +76,7 @@ namespace GSF.NumericalAnalysis · 2 unmodified lines
7676 throw new ArgumentException("Point count must be greater than requested polynomial order");
7777
7878 if (!(polynomialOrder >= 1) && (polynomialOrder <= 7))
79− throw new ArgumentOutOfRangeException("polynomialOrder", "Polynomial order must be between 1 and 7");
79+ throw new ArgumentOutOfRangeException(nameof(polynomialOrder), "Polynomial order must be between 1 and 7");
8080
8181 // Curve fit function (courtesy of Brian Fox from DatAWare client code)
8282 double[] coeffs = new double[8];
Source/Libraries/GSF.Core/ObjectState.cs+1−1
@@ -100,7 +100,7 @@ namespace GSF · 99 unmodified lines
100100 set
101101 {
102102 if (string.IsNullOrEmpty(value))
103− throw new ArgumentNullException("value");
103+ throw new ArgumentNullException(nameof(value));
104104
105105 m_objectName = value;
106106 }
Source/Libraries/GSF.Core/Parsing/ISupportBinaryImage.cs+3−3
@@ -89,7 +89,7 @@ namespace GSF.Parsing · 88 unmodified lines
8989 public static byte[] BinaryImage(this ISupportBinaryImage imageSource)
9090 {
9191 if ((object)imageSource == null)
92− throw new ArgumentNullException("imageSource");
92+ throw new ArgumentNullException(nameof(imageSource));
9393
9494 byte[] buffer = new byte[imageSource.BinaryLength];
9595
@@ -107,7 +107,7 @@ namespace GSF.Parsing · 11 unmodified lines
107107 public static void CopyBinaryImageToStream(this ISupportBinaryImage imageSource, Stream stream)
108108 {
109109 if ((object)imageSource == null)
110− throw new ArgumentNullException("imageSource");
110+ throw new ArgumentNullException(nameof(imageSource));
111111
112112 int length = imageSource.BinaryLength;
113113 byte[] buffer = new byte[length];
@@ -130,7 +130,7 @@ namespace GSF.Parsing · 16 unmodified lines
130130 public static int ParseBinaryImageFromStream(this ISupportBinaryImage imageSource, Stream stream)
131131 {
132132 if ((object)imageSource == null)
133− throw new ArgumentNullException("imageSource");
133+ throw new ArgumentNullException(nameof(imageSource));
134134
135135 int length = imageSource.BinaryLength;
136136 byte[] buffer = new byte[length];
Source/Libraries/GSF.Core/Parsing/MultiSourceFrameImageParserBase.cs+1−1
@@ -226,7 +226,7 @@ namespace GSF.Parsing · 225 unmodified lines
226226 public virtual void Parse(TSourceIdentifier source, byte[] buffer)
227227 {
228228 if ((object)buffer == null)
229− throw new ArgumentNullException("buffer");
229+ throw new ArgumentNullException(nameof(buffer));
230230
231231 Parse(source, buffer, 0, buffer.Length);
232232 }
Source/Libraries/GSF.Core/PrecisionTimer.cs+2−2
@@ -252,7 +252,7 @@ namespace GSF · 251 unmodified lines
252252 throw new ObjectDisposedException("PrecisionTimer");
253253
254254 if (value < Capabilities.PeriodMinimum || value > Capabilities.PeriodMaximum)
255− throw new ArgumentOutOfRangeException("value", value, "Multimedia Timer period out of range");
255+ throw new ArgumentOutOfRangeException(nameof(value), value, "Multimedia Timer period out of range");
256256
257257 m_period = value;
258258
@@ -296,7 +296,7 @@ namespace GSF · 37 unmodified lines
296296 throw new ObjectDisposedException("PrecisionTimer");
297297
298298 if (value < 0)
299− throw new ArgumentOutOfRangeException("value", value, "Multimedia timer resolution out of range");
299+ throw new ArgumentOutOfRangeException(nameof(value), value, "Multimedia timer resolution out of range");
300300
301301 m_resolution = value;
302302
Source/Libraries/GSF.Core/ReusableObjectPool.cs+2−2
@@ -280,7 +280,7 @@ namespace GSF · 279 unmodified lines
280280 public void SetPoolSize(int size)
281281 {
282282 if (size < 1)
283− throw new ArgumentOutOfRangeException("size", "pool size must at least be one");
283+ throw new ArgumentOutOfRangeException(nameof(size), "pool size must at least be one");
284284
285285 for (int i = 0; i < size - m_objectPool.Count; i++)
286286 {
@@ -458,7 +458,7 @@ namespace GSF · 171 unmodified lines
458458 public static void SetPoolSize(Type type, int size)
459459 {
460460 if (size < 1)
461− throw new ArgumentOutOfRangeException("size", "pool size must at least be one");
461+ throw new ArgumentOutOfRangeException(nameof(size), "pool size must at least be one");
462462
463463 // Get or create object pool associated with specified type
464464 ConcurrentQueue<object> objectPool = s_objectPools.GetOrAdd(type, (objType) => new ConcurrentQueue<object>());
Source/Libraries/GSF.Core/Scheduling/Schedule.cs+2−2
@@ -185,7 +185,7 @@ namespace GSF.Scheduling · 184 unmodified lines
185185 set
186186 {
187187 if (string.IsNullOrEmpty(value))
188− throw new ArgumentNullException("value");
188+ throw new ArgumentNullException(nameof(value));
189189
190190 m_name = value;
191191 }
@@ -205,7 +205,7 @@ namespace GSF.Scheduling · 13 unmodified lines
205205 set
206206 {
207207 if (string.IsNullOrEmpty(value))
208− throw new ArgumentNullException("value");
208+ throw new ArgumentNullException(nameof(value));
209209
210210 string[] scheduleParts = value.RemoveDuplicateWhiteSpace().Split(' ');
211211
Source/Libraries/GSF.Core/Scheduling/ScheduleManager.cs+1−1
@@ -246,7 +246,7 @@ namespace GSF.Scheduling · 245 unmodified lines
246246 set
247247 {
248248 if (string.IsNullOrEmpty(value))
249− throw new ArgumentNullException("value");
249+ throw new ArgumentNullException(nameof(value));
250250
251251 m_settingsCategory = value;
252252 }
Source/Libraries/GSF.Core/Security/Cryptography/Cipher.cs+4−4
@@ -737,7 +737,7 @@ namespace GSF.Security.Cryptography · 736 unmodified lines
737737 return source;
738738
739739 if (string.IsNullOrEmpty(password))
740− throw new ArgumentNullException("password");
740+ throw new ArgumentNullException(nameof(password));
741741
742742 byte[][] keyIV = s_keyIVCache.GetCryptoKeyIV(password, (int)strength);
743743
@@ -883,7 +883,7 @@ namespace GSF.Security.Cryptography · 139 unmodified lines
883883 using (FileStream sourceFileStream = File.Open(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read), destFileStream = File.Create(destinationFileName))
884884 {
885885 if (string.IsNullOrEmpty(password))
886− throw new ArgumentNullException("password");
886+ throw new ArgumentNullException(nameof(password));
887887
888888 byte[][] keyIV = s_keyIVCache.GetCryptoKeyIV(password, (int)strength);
889889
@@ -940,7 +940,7 @@ namespace GSF.Security.Cryptography · 50 unmodified lines
940940 return source;
941941
942942 if (string.IsNullOrEmpty(password))
943− throw new ArgumentNullException("password");
943+ throw new ArgumentNullException(nameof(password));
944944
945945 byte[][] keyIV = s_keyIVCache.GetCryptoKeyIV(password, (int)strength);
946946
@@ -1098,7 +1098,7 @@ namespace GSF.Security.Cryptography · 151 unmodified lines
10981098 using (FileStream sourceFileStream = File.Open(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read), destFileStream = File.Create(destinationFileName))
10991099 {
11001100 if (string.IsNullOrEmpty(password))
1101− throw new ArgumentNullException("password");
1101+ throw new ArgumentNullException(nameof(password));
11021102
11031103 byte[][] keyIV = s_keyIVCache.GetCryptoKeyIV(password, (int)strength);
11041104
Source/Libraries/GSF.Core/Serialization.cs+4−4
@@ -386,10 +386,10 @@ namespace GSF · 385 unmodified lines
386386 public static void Serialize<T>(T serializableObject, SerializationFormat serializationFormat, Stream serializedOutput)
387387 {
388388 if ((object)serializedOutput == null)
389− throw new ArgumentNullException("serializedOutput");
389+ throw new ArgumentNullException(nameof(serializedOutput));
390390
391391 if ((object)serializableObject == null)
392− throw new ArgumentNullException("serializableObject");
392+ throw new ArgumentNullException(nameof(serializableObject));
393393
394394 // Serialize object to the provided stream.
395395 if (serializationFormat == SerializationFormat.Xml)
@@ -441,7 +441,7 @@ namespace GSF · 45 unmodified lines
441441 public static T Deserialize<T>(byte[] serializedObject, SerializationFormat serializationFormat)
442442 {
443443 if ((object)serializedObject == null)
444− throw new ArgumentNullException("serializedObject");
444+ throw new ArgumentNullException(nameof(serializedObject));
445445
446446 using (MemoryStream stream = new MemoryStream(serializedObject))
447447 {
@@ -461,7 +461,7 @@ namespace GSF · 13 unmodified lines
461461 public static T Deserialize<T>(Stream serializedObject, SerializationFormat serializationFormat)
462462 {
463463 if ((object)serializedObject == null)
464− throw new ArgumentNullException("serializedObject");
464+ throw new ArgumentNullException(nameof(serializedObject));
465465
466466 // Deserialize the serialized object.
467467 T deserializedObject;
Source/Libraries/GSF.Core/Threading/ManagedThreadPool.cs+3−3
@@ -56,7 +56,7 @@ namespace GSF.Threading · 55 unmodified lines
5656 public static ManagedThread QueueUserWorkItem(ThreadStart callback)
5757 {
5858 if ((object)callback == null)
59− throw (new ArgumentNullException("callback"));
59+ throw (new ArgumentNullException(nameof(callback)));
6060
6161 ManagedThread item = new ManagedThread(ThreadType.QueuedThread, callback, null, null);
6262
@@ -96,7 +96,7 @@ namespace GSF.Threading · 33 unmodified lines
9696 public static ManagedThread QueueUserWorkItem(ParameterizedThreadStart callback, object state)
9797 {
9898 if ((object)callback == null)
99− throw (new ArgumentNullException("callback"));
99+ throw (new ArgumentNullException(nameof(callback)));
100100
101101 ManagedThread item = new ManagedThread(ThreadType.QueuedThread, callback, state, null);
102102
@@ -138,7 +138,7 @@ namespace GSF.Threading · 35 unmodified lines
138138 public static ManagedThread QueueUserWorkItem(ContextCallback callback, object state, ExecutionContext ctx)
139139 {
140140 if ((object)callback == null)
141− throw (new ArgumentNullException("callback"));
141+ throw (new ArgumentNullException(nameof(callback)));
142142
143143 ManagedThread item = new ManagedThread(ThreadType.QueuedThread, callback, state, ctx);
144144
Source/Libraries/GSF.Core/Threading/ManagedThreads.cs+1−1
@@ -201,7 +201,7 @@ namespace GSF.Threading · 200 unmodified lines
201201 public static void Cancel(ManagedThread item, bool allowAbort, object stateInfo)
202202 {
203203 if ((object)item == null)
204− throw new ArgumentNullException("item");
204+ throw new ArgumentNullException(nameof(item));
205205
206206 LinkedListNode<ManagedThread> node;
207207
Source/Libraries/GSF.Core/Threading/SynchronizedOperationBase.cs+1−1
@@ -70,7 +70,7 @@ namespace GSF.Threading · 69 unmodified lines
7070 protected SynchronizedOperationBase(Action action, Action<Exception> exceptionAction)
7171 {
7272 if ((object)action == null)
73− throw new ArgumentNullException("action");
73+ throw new ArgumentNullException(nameof(action));
7474
7575 m_action = action;
7676 m_exceptionAction = exceptionAction;
Source/Libraries/GSF.Core/TransformEqualityComparer.cs+1−1
@@ -48,7 +48,7 @@ namespace GSF · 47 unmodified lines
4848 public TransformEqualityComparer(Func<T, object> transformFunction)
4949 {
5050 if ((object)transformFunction == null)
51− throw new ArgumentNullException("transformFunction");
51+ throw new ArgumentNullException(nameof(transformFunction));
5252
5353 m_transformFunction = transformFunction;
5454 }
Source/Libraries/GSF.Core/Validation/ValidationService.cs+2−2
@@ -115,10 +115,10 @@ namespace GSF.Validation · 114 unmodified lines
115115 public void AddValidation(string source, IValidator validator)
116116 {
117117 if (string.IsNullOrEmpty(source))
118− throw new ArgumentNullException("source");
118+ throw new ArgumentNullException(nameof(source));
119119
120120 if ((object)validator == null)
121− throw new ArgumentNullException("validator");
121+ throw new ArgumentNullException(nameof(validator));
122122
123123 m_validations.Add(string.Format("{0}+{1}", source, validator.GetType().Name), validator);
124124 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t