internal D.DifferenceNode _CompareObject(object left, object right) { Func <bool, D.DifferenceNode> state = (b) => { return(b ? null : new D.DifferenceNode(null, left, right)); }; if (left == null || right == null) { return(state(left == right)); } if (!left.GetType().Equals(right.GetType())) { return(state(false)); } if (left is byte) { return(state(((int)(byte)left - (int)(byte)right) == 0)); } if (left is int) { return(state(((int)left - (int)right) == 0)); } if (left is long) { return(state(((long)left - (long)right) == 0)); } if (left is float) { return(state(((float)left - (float)right).IsNearZero(1e-5f))); } //if (left is double) // return state(((double)left - (double)right).IsNearZero(1e-5)); if (left is string) { return(state(((string)left).CompareTo((string)right) == 0)); } if (left is F.str) { string left_str = (left as F.str).ToString(); string right_str = (right as F.str).ToString(); return(state(left_str.CompareTo(right_str) == 0)); } if (left is P.Properties) { D.DifferenceNode node = new D.DifferenceNode(null, left, right); D.DifferenceNode sub; Func <P.Properties, P.Properties> clone = (src) => { P.Properties dst = new P.Properties(); foreach (P.Property prop in src) { dst.Add(prop); } return(dst); }; P.Properties left_coll = clone(left as P.Properties); P.Properties right_coll = clone(right as P.Properties); for (int index = 0; index < left_coll.Count; ++index) { P.Property left_sub = left_coll[index]; P.Property right_sub = _FindMatch(left_sub, right_coll); if (right_sub != null) { right_coll.Remove(right_sub); } sub = _Compare(left_sub, right_sub); if (sub != null) { string title = left_sub.PrettyName(); if (string.IsNullOrEmpty(title)) { title = index.ToString(); } sub.Title = title; node.Add(sub); } } for (int index = 0; index < right_coll.Count; ++index) { P.Property right_sub = right_coll[index]; if (right_sub != null) { string name = right_sub.GetName(); if (_blacklisted.Contains(name)) { continue; } string title = right_sub.PrettyName(); if (string.IsNullOrEmpty(title)) { title = index.ToString(); } node.Add(title, null, right_sub); } } return(node.ChildCount > 0 ? node : null); } if (left is IDictionary) { D.DifferenceNode node = new D.DifferenceNode(null, left, right); D.DifferenceNode sub; Func <IDictionary, IDictionary> clone = (src) => { Dictionary <object, object> dst = new Dictionary <object, object>(); foreach (object key in src.Keys) { dst.Add(key, src[key]); } return(dst); }; IDictionary left_coll = clone(left as IDictionary); IDictionary right_coll = clone(right as IDictionary); foreach (object key in left_coll.Keys) { object left_sub = left_coll[key]; object right_sub = null; if (right_coll.Contains(key)) { right_sub = right_coll[key]; right_coll.Remove(key); } if (right_sub == null && left_sub != null) { sub = new D.DifferenceNode(null, left_sub, null); } else if (left_sub is P.Property) { sub = _Compare(left_sub as P.Property, right_sub as P.Property); } else { sub = _CompareObject(left_sub, right_sub); } if (sub != null) { sub.Title = key.ToString(); node.Add(sub); } } foreach (object key in right_coll) { node.Add(key.ToString(), null, right_coll[key]); } return(node.ChildCount > 0 ? node : null); } if (left is ICollection) { D.DifferenceNode node = new D.DifferenceNode(null, left, right); D.DifferenceNode sub; Func <ICollection, List <object> > clone = (src) => { List <object> dst = new List <object>(); foreach (object val in src) { dst.Add(val); } return(dst); }; List <object> left_coll = clone(left as ICollection); List <object> right_coll = clone(right as ICollection); for (int index = 0; index < left_coll.Count; ++index) { object left_sub = left_coll[index]; object right_sub = null; if (index < right_coll.Count) { right_sub = right_coll[index]; right_coll[index] = null; } if (right_sub == null && left_sub != null) { sub = new D.DifferenceNode(null, left_sub, null); } else if (left_sub is P.Property) { sub = _Compare(left_sub as P.Property, right_sub as P.Property); } else { sub = _CompareObject(left_sub, right_sub); } if (sub != null) { string title = left_sub.PrettyName(); if (string.IsNullOrEmpty(title)) { title = index.ToString(); } sub.Title = title; node.Add(sub); } } for (int index = 0; index < right_coll.Count; ++index) { object right_sub = right_coll[index]; if (right_sub != null) { string title = right_sub.PrettyName(); if (string.IsNullOrEmpty(title)) { title = index.ToString(); } node.Add(title, null, right_sub); } } return(node.ChildCount > 0 ? node : null); } return(null); }
internal D.DifferenceNode _Compare(P.Property left, P.Property right) { D.DifferenceNode node = new D.DifferenceNode(left.ToString(), left, right); D.DifferenceNode sub; if ((left == null || right == null) && (left != right)) { return(node); } // Do some by-name blacklisting to skips things like delta timestamps if (left is P.ValueProperty) { P.ValueProperty val_prop = left as P.ValueProperty; if (val_prop.Name != null) { string name = val_prop.Name.ToString(); if (_blacklisted.Contains(name)) { return(null); } } } Dictionary <string, object> left_childs = new Dictionary <string, object>(left.GetChilds()); Dictionary <string, object> right_childs = new Dictionary <string, object>(right.GetChilds()); while (left_childs.Count > 0) { var pair = left_childs.First(); object left_sub = pair.Value; left_childs.Remove(pair.Key); object right_sub = null; if (right_childs.ContainsKey(pair.Key)) { right_sub = right_childs[pair.Key]; right_childs.Remove(pair.Key); } if (_blacklisted.Contains(pair.Key)) { continue; } if (right_sub == null && left_sub != null) { sub = new D.DifferenceNode(null, left_sub, null); } else if (left_sub is P.Property) { sub = _Compare(left_sub as P.Property, right_sub as P.Property); } else { sub = _CompareObject(left_sub, right_sub); } if (sub != null) { sub.Title = pair.Key; node.Add(sub); } } foreach (var pair in right_childs) { if (!_blacklisted.Contains(pair.Key)) { node.Add(pair.Key, null, pair.Value); } } return((node.ChildCount > 0) ? node : null); }