/// <summary> /// Compare to packages by parts like streams /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <param name="compareToFirstDifference"></param> /// <param name="excludeMethod"></param> /// <param name="message"></param> /// <returns></returns> public static bool Compare(Package left, Package right, bool compareToFirstDifference, Func <Uri, bool> excludeMethod, out string message) { #region Check if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } #endregion Check excludeMethod = excludeMethod ?? (uri => false); PackagePartCollection leftParts = left.GetParts(); PackagePartCollection rightParts = right.GetParts(); var pairs = new Dictionary <Uri, PartPair>(); foreach (PackagePart part in leftParts) { if (excludeMethod(part.Uri)) { continue; } pairs.Add(part.Uri, new PartPair(part.Uri, CompareStatus.OnlyOnLeft)); } foreach (PackagePart part in rightParts) { if (excludeMethod(part.Uri)) { continue; } PartPair pair; if (pairs.TryGetValue(part.Uri, out pair)) { pair.Status = CompareStatus.Equal; } else { pairs.Add(part.Uri, new PartPair(part.Uri, CompareStatus.OnlyOnRight)); } } if (compareToFirstDifference && pairs.Any(pair => pair.Value.Status != CompareStatus.Equal)) { goto EXIT; } foreach (PartPair pair in pairs.Values) { if (pair.Status != CompareStatus.Equal) { continue; } var leftPart = left.GetPart(pair.Uri); var rightPart = right.GetPart(pair.Uri); using (Stream leftPackagePartStream = leftPart.GetStream(FileMode.Open, FileAccess.Read)) using (Stream rightPackagePartStream = rightPart.GetStream(FileMode.Open, FileAccess.Read)) using (var leftMemoryStream = new MemoryStream()) using (var rightMemoryStream = new MemoryStream()) { leftPackagePartStream.CopyTo(leftMemoryStream); rightPackagePartStream.CopyTo(rightMemoryStream); leftMemoryStream.Seek(0, SeekOrigin.Begin); rightMemoryStream.Seek(0, SeekOrigin.Begin); bool stripColumnWidthsFromSheet = TestHelper.StripColumnWidths && leftPart.ContentType == @"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" && rightPart.ContentType == @"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"; var tuple1 = new Tuple <Uri, Stream>(pair.Uri, leftMemoryStream); var tuple2 = new Tuple <Uri, Stream>(pair.Uri, rightMemoryStream); if (!StreamHelper.Compare(tuple1, tuple2, stripColumnWidthsFromSheet)) { pair.Status = CompareStatus.NonEqual; if (compareToFirstDifference) { goto EXIT; } } } } EXIT: List <PartPair> sortedPairs = pairs.Values.ToList(); sortedPairs.Sort((one, other) => one.Uri.OriginalString.CompareTo(other.Uri.OriginalString)); var sbuilder = new StringBuilder(); foreach (PartPair pair in sortedPairs) { if (pair.Status == CompareStatus.Equal) { continue; } sbuilder.AppendFormat("{0} :{1}", pair.Uri, pair.Status); sbuilder.AppendLine(); } message = sbuilder.ToString(); return(message.Length == 0); }
/// <summary> /// Compare to packages by parts like streams /// </summary> /// <param name="left"></param> /// <param name="right"></param> /// <param name="compareToFirstDifference"></param> /// <param name="excludeMethod"></param> /// <param name="message"></param> /// <returns></returns> public static bool Compare(Package left, Package right, bool compareToFirstDifference, Func <Uri, bool> excludeMethod, out string message) { #region Check if (left == null) { throw new ArgumentNullException("left"); } if (right == null) { throw new ArgumentNullException("right"); } #endregion excludeMethod = excludeMethod ?? (uri => false); PackagePartCollection leftParts = left.GetParts(); PackagePartCollection rightParts = right.GetParts(); var pairs = new Dictionary <Uri, PartPair>(); foreach (PackagePart part in leftParts) { if (excludeMethod(part.Uri)) { continue; } pairs.Add(part.Uri, new PartPair(part.Uri, CompareStatus.OnlyOnLeft)); } foreach (PackagePart part in rightParts) { if (excludeMethod(part.Uri)) { continue; } PartPair pair; if (pairs.TryGetValue(part.Uri, out pair)) { pair.Status = CompareStatus.Equal; } else { pairs.Add(part.Uri, new PartPair(part.Uri, CompareStatus.OnlyOnRight)); } } if (compareToFirstDifference && pairs.Any(pair => pair.Value.Status != CompareStatus.Equal)) { goto EXIT; } foreach (PartPair pair in pairs.Values) { if (pair.Status != CompareStatus.Equal) { continue; } using (Stream oneStream = left.GetPart(pair.Uri).GetStream(FileMode.Open, FileAccess.Read)) using (Stream otherStream = right.GetPart(pair.Uri).GetStream(FileMode.Open, FileAccess.Read)) { if (!StreamHelper.Compare(oneStream, otherStream)) { pair.Status = CompareStatus.NonEqual; if (compareToFirstDifference) { goto EXIT; } } } } EXIT: List <PartPair> sortedPairs = pairs.Values.ToList(); sortedPairs.Sort((one, other) => one.Uri.OriginalString.CompareTo(other.Uri.OriginalString)); var sbuilder = new StringBuilder(); foreach (PartPair pair in sortedPairs) { if (pair.Status == CompareStatus.Equal) { continue; } sbuilder.AppendFormat("{0} :{1}", pair.Uri, pair.Status); sbuilder.AppendLine(); } message = sbuilder.ToString(); return(message.Length == 0); }