// Mono.Util.CorCompare.CompletionInfo
//
// Author(s):
// Piers Haken (piersh@friskit.com)
//
// (C) 2001-2002 Piers Haken
using System;
using System.Reflection;
using System.Xml;
using System.Collections;
namespace Mono.Util.CorCompare
{
#region
public struct CompletionType
{
private enum CompletionTypes
{
Present,
Missing,
Extra
}
private const int MASK_TYPE = 0x0f;
private const int MASK_TODO = 0x10;
//private const int MASK_ERROR = 0x20;
private int m_type;
private CompletionType (CompletionTypes type, bool fTodo)
{
m_type = (int) type;
if (fTodo)
m_type |= MASK_TODO;
}
public bool IsPresent
{
get { return Type == CompletionTypes.Present; }
}
public bool IsMissing
{
get { return Type == CompletionTypes.Missing; }
}
public bool IsExtra
{
get { return Type == CompletionTypes.Extra; }
}
public bool IsTodo
{
get { return (m_type & MASK_TODO) != 0; }
}
private CompletionTypes Type
{
get { return (CompletionTypes) (m_type & MASK_TYPE); }
}
public override string ToString ()
{
switch (Type)
{
case CompletionTypes.Missing:
return "missing";
case CompletionTypes.Extra:
return "extra";
case CompletionTypes.Present:
return "present";
default:
throw new Exception ("Invalid CompletionType: "+Type);
}
}
public static CompletionType Present
{
get { return new CompletionType (CompletionTypes.Present, false); }
}
public static CompletionType Missing
{
get { return new CompletionType (CompletionTypes.Missing, false); }
}
public static CompletionType Extra
{
get { return new CompletionType (CompletionTypes.Extra, false); }
}
public static CompletionType Compare (Object oMono, Object oMS)
{
if (oMono == null)
return Missing;
else if (oMS == null)
return Extra;
else
return Present;
}
}
///
/// Represents the amount of work done on a node
///
///
/// created by - Piersh
/// created on - 3/2/2002 1:12:00 AM
///
public struct CompletionInfo
{
public int cPresent;
public int cExtra;
public int cMissing;
public int cTodo;
///
/// converts a CompletionTypes into a CompletionInfo
/// sets the corresponding field to '1'
///
/// the CompletionTypes to convert
public CompletionInfo (CompletionType ct)
{
cPresent = cTodo = cMissing = cExtra = 0;
if (ct.IsPresent)
cPresent = 1;
else if (ct.IsMissing)
cMissing = 1;
else if (ct.IsExtra)
cExtra = 1;
if (ct.IsTodo)
cTodo = 1;
}
///
/// counts the total number of elements represented by this info
///
public int cTotal
{
get
{
return cPresent + cTodo + cMissing;
}
}
///
/// adds two CompletionInfos together
///
///
public void Add (CompletionInfo m_nodeStatus)
{
cPresent += m_nodeStatus.cPresent;
cTodo += m_nodeStatus.cTodo;
cMissing += m_nodeStatus.cMissing;
cExtra += m_nodeStatus.cExtra;
}
///
/// subtracts two CompletionInfos
///
///
public void Sub (CompletionInfo m_nodeStatus)
{
cPresent -= m_nodeStatus.cPresent;
cTodo -= m_nodeStatus.cTodo;
cMissing -= m_nodeStatus.cMissing;
cExtra -= m_nodeStatus.cExtra;
if (cPresent < 0 || cTodo < 0 || cMissing < 0 || cExtra < 0)
throw new Exception ("Completion underflow on subtract");
}
///
/// increments the corresponding field
///
///
public void Add (CompletionType ct)
{
Add (new CompletionInfo (ct));
}
///
/// decrements the corresponding field
///
///
public void Sub (CompletionType ct)
{
Sub (new CompletionInfo (ct));
}
///
/// adds appropriate 'missing', 'todo' & 'complete' attributes to an XmlElement
///
///
public void SetAttributes (XmlElement elt)
{
elt.SetAttribute ("present", cPresent.ToString ());
elt.SetAttribute ("missing", cMissing.ToString ());
elt.SetAttribute ("extra", cExtra.ToString ());
elt.SetAttribute ("todo", cTodo.ToString ());
//int percentComplete = (cTotal == 0) ? 100 : (100 - 100 * (cMissing + cExtra) / cTotal);
//elt.SetAttribute ("complete", percentComplete.ToString ());
}
}
#endregion
public enum PresenceTypes
{
// UNINITIALIZED = 0,
Missing = 0,
Present,
Extra
}
public enum ErrorTypes
{
// TODO: order is important here... (see Status.SetError ())
// UNINITIALIZED = 0,
OK = 0,
Todo,
Warning,
Error
}
public struct PresenceCounts
{
public int cMissing;
public int cPresent;
public int cExtra;
public PresenceCounts (PresenceTypes type)
{
cMissing = cPresent = cExtra = 0;
if (type == PresenceTypes.Missing)
cMissing = 1;
else if (type == PresenceTypes.Present)
cPresent = 1;
else if (type == PresenceTypes.Extra)
cExtra = 1;
else throw new Exception ("Invalid PresenceType");
}
public int Total
{
get { return cMissing + cPresent + cExtra; }
}
public void Add (PresenceCounts counts)
{
cMissing += counts.cMissing;
cPresent += counts.cPresent;
cExtra += counts.cExtra;
}
public void Sub (PresenceCounts counts)
{
cMissing -= counts.cMissing;
cPresent -= counts.cPresent;
cExtra -= counts.cExtra;
if (cMissing < 0 || cPresent < 0 || cExtra < 0)
throw new Exception ("Underflow");
}
public void Add (PresenceTypes type)
{
Add (new PresenceCounts (type));
}
public void Sub (PresenceTypes type)
{
Sub (new PresenceCounts (type));
}
public void SetAttributes (XmlElement elt, string strSuffix)
{
if (cMissing != 0)
elt.SetAttribute ("missing"+strSuffix, cMissing.ToString ());
if (cPresent != 0)
elt.SetAttribute ("present"+strSuffix, cPresent.ToString ());
if (cExtra != 0)
elt.SetAttribute ("extra"+strSuffix, cExtra.ToString ());
}
}
public struct ErrorCounts
{
public int cOK;
public int cTodo;
public int cWarning;
public int cError;
public ErrorCounts (ErrorTypes type)
{
cOK = cTodo = cWarning = cError = 0;
if (type == ErrorTypes.OK)
cOK = 1;
else if (type == ErrorTypes.Todo)
cTodo = 1;
else if (type == ErrorTypes.Warning)
cWarning = 1;
else if (type == ErrorTypes.Error)
cError = 1;
else throw new Exception ("Invalid ErrorType");
}
public int Total
{
get { return cOK + cTodo + cWarning + cError; }
}
public void Add (ErrorCounts counts)
{
cOK += counts.cOK;
cTodo += counts.cTodo;
cWarning += counts.cWarning;
cError += counts.cError;
}
public void Sub (ErrorCounts counts)
{
cOK -= counts.cOK;
cTodo -= counts.cTodo;
cWarning -= counts.cWarning;
cError -= counts.cError;
if (cOK < 0 || cTodo < 0 || cWarning < 0 || cError < 0)
throw new Exception ("Underflow");
}
public void Add (ErrorTypes type)
{
Add (new ErrorCounts (type));
}
public void Sub (ErrorTypes type)
{
Sub (new ErrorCounts (type));
}
public void SetAttributes (XmlElement elt, string strSuffix)
{
if (cOK != 0)
elt.SetAttribute ("ok"+strSuffix, cOK.ToString ());
if (cTodo != 0)
elt.SetAttribute ("todo"+strSuffix, cTodo.ToString ());
if (cWarning != 0)
elt.SetAttribute ("warning"+strSuffix, cWarning.ToString ());
if (cError != 0)
elt.SetAttribute ("error"+strSuffix, cError.ToString ());
}
}
public struct Status
{
public PresenceTypes presence;
public ErrorTypes error;
public string PresenceName
{
get
{
if (presence == PresenceTypes.Missing)
return "missing";
else if (presence == PresenceTypes.Present)
return "present";
else if (presence == PresenceTypes.Extra)
return "extra";
else throw new Exception ("Invalid PresenceType");
}
}
public string ErrorName
{
get
{
if (error == ErrorTypes.OK)
return "OK";
else if (error == ErrorTypes.Todo)
return "todo";
else if (error == ErrorTypes.Warning)
return "warning";
else if (error == ErrorTypes.Error)
return "error";
else throw new Exception ("Invalid ErrorType");
}
}
public void SetAttributes (XmlElement elt)
{
if (presence != PresenceTypes.Present)
elt.SetAttribute ("presence", PresenceName);
if (error != ErrorTypes.OK)
elt.SetAttribute ("error", ErrorName);
}
}
public struct StatusCounts
{
public PresenceCounts presenceCounts;
public ErrorCounts errorCounts;
public void Add (StatusCounts statusCounts)
{
presenceCounts.Add (statusCounts.presenceCounts);
errorCounts.Add (statusCounts.errorCounts);
if (presenceCounts.Total != errorCounts.Total)
throw new Exception ("invalid status counts");
}
public void Sub (StatusCounts statusCounts)
{
presenceCounts.Sub (statusCounts.presenceCounts);
errorCounts.Sub (statusCounts.errorCounts);
if (presenceCounts.Total != errorCounts.Total)
throw new Exception ("invalid status counts");
}
public void Add (Status status)
{
presenceCounts.Add (status.presence);
errorCounts.Add (status.error);
if (presenceCounts.Total != errorCounts.Total)
throw new Exception ("invalid status counts");
}
public void Sub (Status status)
{
presenceCounts.Sub (status.presence);
errorCounts.Sub (status.error);
if (presenceCounts.Total != errorCounts.Total)
throw new Exception ("invalid status counts");
}
public void SetAttributes (XmlElement elt, string strSuffix)
{
presenceCounts.SetAttributes (elt, strSuffix);
errorCounts.SetAttributes (elt, strSuffix);
int cTotal = presenceCounts.cMissing + presenceCounts.cPresent;
int cIncomplete =
presenceCounts.cMissing +
errorCounts.cTodo +
errorCounts.cWarning +
errorCounts.cError;
if (presenceCounts.Total != errorCounts.Total)
throw new Exception ("invalid status counts");
if (cTotal != 0)
{
int percentComplete = 100 * (cTotal - cIncomplete) / cTotal;
elt.SetAttribute ("complete" + strSuffix, percentComplete.ToString ());
}
}
}
public class NodeMessage
{
protected string msg;
public NodeMessage (string _msg)
{
msg = _msg;
}
public string Message
{
get { return msg; }
}
}
public class NodeStatus
{
public Status status;
protected StatusCounts statusCountsChildren;
protected StatusCounts statusCountsTotal;
protected IList lstWarnings;
public NodeStatus ()
{
status.error = ErrorTypes.OK;
}
///
/// Constructs a NodeStatus by comparing the presence of two objects
/// it only sets the status.presence field
///
///
///
public NodeStatus (Object objMono, Object objMS)
{
status.error = ErrorTypes.OK;
statusCountsChildren = statusCountsTotal = new StatusCounts ();
if (objMono == null)
status.presence = PresenceTypes.Missing;
else if (objMS == null)
status.presence = PresenceTypes.Extra;
else
status.presence = PresenceTypes.Present;
}
public void Add (NodeStatus statusChild)
{
if ((int) statusChild.status.error > (int) status.error)
status.error = statusChild.status.error;
statusCountsTotal.Add (statusChild.statusCountsTotal);
statusCountsChildren.Add (statusChild.statusCountsChildren);
}
public void AddChildren (NodeStatus statusChild)
{
statusCountsTotal.Add (statusChild.statusCountsTotal);
statusCountsTotal.Add (statusChild.status);
statusCountsChildren.Add (statusChild.status);
}
public void SubChildren (NodeStatus statusChild)
{
statusCountsTotal.Sub (statusChild.statusCountsTotal);
statusCountsTotal.Sub (statusChild.status);
statusCountsChildren.Sub (statusChild.status);
}
public void Add (StatusCounts statusCounts)
{
statusCountsChildren.Add (statusCounts);
statusCountsTotal.Add (statusCounts);
}
public void Sub (StatusCounts statusCounts)
{
statusCountsChildren.Sub (statusCounts);
statusCountsTotal.Sub (statusCounts);
}
public void Add (Status status)
{
statusCountsChildren.Add (status);
statusCountsTotal.Add (status);
}
public void Sub (Status status)
{
statusCountsChildren.Sub (status);
statusCountsTotal.Sub (status);
}
public bool IsMissing
{
get { return status.presence == PresenceTypes.Missing; }
}
public bool IsPresent
{
get { return status.presence == PresenceTypes.Present; }
}
public bool IsExtra
{
get { return status.presence == PresenceTypes.Extra; }
}
public void SetAttributes (XmlElement elt)
{
status.SetAttributes (elt);
statusCountsChildren.SetAttributes (elt, "");
statusCountsTotal.SetAttributes (elt, "_total");
// add any warning messages
if (lstWarnings != null)
{
XmlElement eltWarnings = elt.OwnerDocument.CreateElement ("warnings");
elt.AppendChild (eltWarnings);
foreach (NodeMessage msg in lstWarnings)
{
XmlElement eltWarning = elt.OwnerDocument.CreateElement ("warning");
eltWarnings.AppendChild (eltWarning);
eltWarning.SetAttribute ("text", msg.Message);
}
}
//int percentComplete = (cTotal == 0) ? 100 : (100 - 100 * (cMissing + cExtra) / cTotal);
//elt.SetAttribute ("complete", percentComplete.ToString ());
}
public void SetError (ErrorTypes errorNew)
{
// TODO: assumes order of error values
if ((int) errorNew > (int) status.error)
status.error = errorNew;
}
public void AddWarning (string strWarning)
{
if (lstWarnings == null)
lstWarnings = new ArrayList ();
lstWarnings.Add (new NodeMessage (strWarning));
SetError (ErrorTypes.Warning);
}
}
}