// 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); } } }