v1.2
This commit is contained in:
245
RoboSharp/Results/RoboCopyResultsStatus.cs
Normal file
245
RoboSharp/Results/RoboCopyResultsStatus.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using RoboSharp.Interfaces;
|
||||
|
||||
namespace RoboSharp.Results
|
||||
{
|
||||
/// <summary>
|
||||
/// Object that evaluates the ExitCode reported after RoboCopy finishes executing.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see href="https://github.com/tjscience/RoboSharp/wiki/RoboCopyExitStatus"/>
|
||||
/// </remarks>
|
||||
public class RoboCopyExitStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
|
||||
/// </summary>
|
||||
public RoboCopyExitStatus(int exitCodeValue)
|
||||
{
|
||||
ExitCodeValue = exitCodeValue;
|
||||
}
|
||||
|
||||
/// <summary>ExitCode as reported by RoboCopy</summary>
|
||||
public int ExitCodeValue { get; protected set; }
|
||||
|
||||
/// <summary>ExitCode reported by RoboCopy converted into the Enum</summary>
|
||||
public RoboCopyExitCodes ExitCode => (RoboCopyExitCodes)ExitCodeValue;
|
||||
|
||||
/// <inheritdoc cref="RoboCopyExitCodes.FilesCopiedSuccessful"/>
|
||||
public bool Successful => !WasCancelled && ExitCodeValue < 0x10;
|
||||
|
||||
/// <inheritdoc cref="RoboCopyExitCodes.MismatchedDirectoriesDetected"/>
|
||||
public bool HasWarnings => ExitCodeValue >= 0x4;
|
||||
|
||||
/// <inheritdoc cref="RoboCopyExitCodes.SeriousErrorOccurred"/>
|
||||
public bool HasErrors => ExitCodeValue >= 0x10;
|
||||
|
||||
/// <inheritdoc cref="RoboCopyExitCodes.Cancelled"/>
|
||||
public virtual bool WasCancelled => ExitCodeValue < 0x0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the current object.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"ExitCode: {ExitCodeValue} ({ExitCode})";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the combination of multiple Exit Statuses
|
||||
/// </summary>
|
||||
public sealed class RoboCopyCombinedExitStatus : RoboCopyExitStatus, IRoboCopyCombinedExitStatus
|
||||
{
|
||||
#region < Constructor >
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoboCopyCombinedExitStatus"/> class.
|
||||
/// </summary>
|
||||
public RoboCopyCombinedExitStatus() : base(0) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RoboCopyCombinedExitStatus"/> class.
|
||||
/// </summary>
|
||||
public RoboCopyCombinedExitStatus(int exitCodeValue) : base(exitCodeValue) { }
|
||||
|
||||
/// <summary>
|
||||
/// Clone this into a new instance
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
public RoboCopyCombinedExitStatus(RoboCopyCombinedExitStatus obj) :base((int)obj.ExitCode)
|
||||
{
|
||||
wascancelled = obj.wascancelled;
|
||||
noCopyNoError = obj.noCopyNoError;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region < Fields and Event >
|
||||
|
||||
//Private bools for the Combine methods
|
||||
private bool wascancelled;
|
||||
private bool noCopyNoError;
|
||||
private bool EnablePropertyChangeEvent = true;
|
||||
|
||||
/// <summary>This event when the ExitStatus summary has changed </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region < Public Properties >
|
||||
|
||||
/// <summary>Overides <see cref="RoboCopyExitStatus.WasCancelled"/></summary>
|
||||
/// <returns> <see cref="AnyWasCancelled"/></returns>
|
||||
public override bool WasCancelled => AnyWasCancelled;
|
||||
|
||||
/// <summary>
|
||||
/// Atleast one <see cref="RoboCopyExitStatus"/> objects combined into this result resulted in no errors and no files/directories copied.
|
||||
/// </summary>
|
||||
public bool AnyNoCopyNoError => noCopyNoError || ExitCodeValue == 0x0;
|
||||
|
||||
/// <summary>
|
||||
/// Atleast one <see cref="RoboCopyExitStatus"/> object combined into this result had been cancelled / exited prior to completion.
|
||||
/// </summary>
|
||||
public bool AnyWasCancelled => wascancelled || ExitCodeValue < 0x0;
|
||||
|
||||
/// <summary>
|
||||
/// All jobs completed without errors or warnings.
|
||||
/// </summary>
|
||||
public bool AllSuccessful => !WasCancelled && (ExitCodeValue == 0x0 || ExitCodeValue == 0x1);
|
||||
|
||||
/// <summary>
|
||||
/// All jobs completed without errors or warnings, but Extra Files/Folders were detected.
|
||||
/// </summary>
|
||||
public bool AllSuccessful_WithWarnings => !WasCancelled && Successful && ExitCodeValue > 0x1;
|
||||
|
||||
#endregion
|
||||
|
||||
#region < RaiseEvent Methods >
|
||||
|
||||
#if !NET40
|
||||
[MethodImpl(methodImplOptions: MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
private object[] StoreCurrentValues()
|
||||
{
|
||||
return new object[10]
|
||||
{
|
||||
WasCancelled, AnyNoCopyNoError, AnyWasCancelled, AllSuccessful, AllSuccessful_WithWarnings, HasErrors, HasWarnings, Successful, ExitCode, ExitCodeValue
|
||||
};
|
||||
}
|
||||
|
||||
#if !NET40
|
||||
[MethodImpl(methodImplOptions: MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
private void CompareAndRaiseEvents(object[] OriginalValues)
|
||||
{
|
||||
object[] CurrentValues = StoreCurrentValues();
|
||||
if (CurrentValues[0] != OriginalValues[0]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("WasCancelled"));
|
||||
if (CurrentValues[1] != OriginalValues[1]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AnyNoCopyNoError"));
|
||||
if (CurrentValues[2] != OriginalValues[2]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AnyWasCancelled"));
|
||||
if (CurrentValues[3] != OriginalValues[3]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AllSuccessful"));
|
||||
if (CurrentValues[4] != OriginalValues[4]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AllSuccessful_WithWarnings"));
|
||||
if (CurrentValues[5] != OriginalValues[5]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("HasErrors"));
|
||||
if (CurrentValues[6] != OriginalValues[6]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("HasWarnings"));
|
||||
if (CurrentValues[7] != OriginalValues[7]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Successful"));
|
||||
if (CurrentValues[8] != OriginalValues[8]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ExitCode"));
|
||||
if (CurrentValues[9] != OriginalValues[9]) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ExitCodeValue"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Combine the RoboCopyExitCodes of the supplied ExitStatus with this ExitStatus.
|
||||
/// </summary>
|
||||
/// <remarks>If any were Cancelled, set the WasCancelled property to TRUE. Otherwise combine the exit codes.</remarks>
|
||||
/// <param name="status">ExitStatus to combine with</param>
|
||||
#if !NET40
|
||||
[MethodImpl(methodImplOptions: MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public void CombineStatus(RoboCopyExitStatus status)
|
||||
{
|
||||
if (status == null) return;
|
||||
object[] OriginalValues = EnablePropertyChangeEvent ? StoreCurrentValues() : null;
|
||||
//Combine the status
|
||||
if (status.WasCancelled)
|
||||
{
|
||||
wascancelled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (status.ExitCode == 0x0) this.noCopyNoError = true; //0x0 is lost if any other values have been added, so this logs the state
|
||||
RoboCopyExitCodes code = this.ExitCode | status.ExitCode;
|
||||
this.ExitCodeValue = (int)code;
|
||||
}
|
||||
//Raise Property Change Events
|
||||
if (EnablePropertyChangeEvent) CompareAndRaiseEvents(OriginalValues);
|
||||
}
|
||||
|
||||
internal void CombineStatus(RoboCopyExitStatus status, bool enablePropertyChangeEvent)
|
||||
{
|
||||
EnablePropertyChangeEvent = enablePropertyChangeEvent;
|
||||
CombineStatus(status);
|
||||
EnablePropertyChangeEvent = enablePropertyChangeEvent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine all the RoboCopyExitStatuses together.
|
||||
/// </summary>
|
||||
/// <param name="status">Array or List of ExitStatuses to combine.</param>
|
||||
public void CombineStatus(IEnumerable<RoboCopyExitStatus> status)
|
||||
{
|
||||
foreach (RoboCopyExitStatus s in status)
|
||||
{
|
||||
EnablePropertyChangeEvent = s == status.Last();
|
||||
CombineStatus(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine all the RoboCopyExitStatuses together.
|
||||
/// </summary>
|
||||
/// <param name="statuses">Array or List of ExitStatuses to combine.</param>
|
||||
/// <returns> new RoboCopyExitStatus object </returns>
|
||||
public static RoboCopyCombinedExitStatus CombineStatuses(IEnumerable<RoboCopyExitStatus> statuses)
|
||||
{
|
||||
RoboCopyCombinedExitStatus ret = new RoboCopyCombinedExitStatus(0);
|
||||
ret.CombineStatus(statuses);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the value of the object
|
||||
/// </summary>
|
||||
#if !NET40
|
||||
[MethodImpl(methodImplOptions: MethodImplOptions.AggressiveInlining)]
|
||||
#endif
|
||||
public void Reset()
|
||||
{
|
||||
object[] OriginalValues = EnablePropertyChangeEvent ? StoreCurrentValues() : null;
|
||||
this.wascancelled = false;
|
||||
this.noCopyNoError = false;
|
||||
this.ExitCodeValue = 0;
|
||||
if (EnablePropertyChangeEvent) CompareAndRaiseEvents(OriginalValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the value of the object
|
||||
/// </summary>
|
||||
internal void Reset(bool enablePropertyChangeEvent)
|
||||
{
|
||||
EnablePropertyChangeEvent = enablePropertyChangeEvent;
|
||||
Reset();
|
||||
EnablePropertyChangeEvent = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICloneable.Clone"/>
|
||||
public RoboCopyCombinedExitStatus Clone() => new RoboCopyCombinedExitStatus(this);
|
||||
|
||||
object ICloneable.Clone() => Clone();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user