Пример #1
1
 public static int GetLevel(string Source, string Destination)
 {
     Differ DiffMaker = new Differ();
     SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker);
     SideBySideDiffModel SideBySideDiffResult = SideBySideDiffer.BuildDiffModel(Source, Destination);
     return GetLevel(SideBySideDiffResult, Source, Destination);
 }
Пример #2
0
		public static void Diff(this string expected, string actual, string message = null)
		{
			var d = new Differ();
			var inlineBuilder = new InlineDiffBuilder(d);
			var result = inlineBuilder.BuildDiffModel(expected, actual);
			var hasChanges = result.Lines.Any(l => l.Type != ChangeType.Unchanged);
			if (!hasChanges) return;

			var diff = result.Lines.Aggregate(new StringBuilder().AppendLine(message), (sb, line) =>
			{
				if (line.Type == ChangeType.Inserted)
					sb.Append("+ ");
				else if (line.Type == ChangeType.Deleted)
					sb.Append("- ");
				else
					sb.Append("  ");
				sb.AppendLine(line.Text);
				return sb;
			}, sb => sb.ToString());

			diff += "\r\n C# approximation of actual: \r\n new ";
			var approx = Regex.Replace(actual, @"^(?=.*:.*)[^:]+:", (s) => s
				.Value.Replace("\"", "")
				.Replace(":", " =")
			, RegexOptions.Multiline)
				.Replace(" = {", " = new {")
				.Replace(" = [", " = new [] {")
				;
			approx = Regex.Replace(approx, @"^\s*\],?.*$", s => s.Value.Replace("]", "}"), RegexOptions.Multiline);
			diff += approx + ";";

			throw new Exception(diff);
		}
Пример #3
0
        /// <summary>
        /// measure differential between two files
        /// </summary>
        public static DiffCounter Count(
            string originalFile, string modifiedFile)
        {
            var original = File.ReadAllText(@originalFile);
            var modified = File.ReadAllText(@modifiedFile);

            var d = new Differ();
            var counter = new DiffCounter();
            var side = new SideBySideDiffBuilder(d);
            var result = side.BuildDiffModel(original, modified);

            // added, modified, and unmodified at modified file
            foreach (var line in result.NewText.Lines) {
                if (line.Type == ChangeType.Inserted) {
                    counter.AddedCount++;
                }
                if (line.Type == ChangeType.Modified) {
                    counter.ModifiedCount++;
                }
                if (line.Type == ChangeType.Unchanged) {
                    counter.EqualCount++;
                }
            }

            // deleted from original file
            foreach (var line in result.OldText.Lines) {
                if (line.Type == ChangeType.Deleted) {
                    counter.DeletedCount++;
                }
            }

            return counter;
        }
Пример #4
0
        public void DisplayDiff(string filename, string fullpath, string author, string old, string updated)
        {
            grid.RowDefinitions.Clear();
              var rd = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) };
              grid.RowDefinitions.Add(rd);

              // Remove the line number blocks and such. actionsThem is the last item in the XAML
              int x = grid.Children.IndexOf(message);
              grid.Children.RemoveRange(x + 1, grid.Children.Count - x);

              message.Visibility = Visibility.Collapsed;
              if (filename.EndsWith(".docx") || filename.EndsWith(".doc")) {
            // Word document. So let the user open the doc in Word
            message.Visibility = Visibility.Visible;
            message.Text = "This is a Word document. Please save it to view its contents.";
            message.Inlines.Add(" You can also ");
            var fakeUri = new Uri("http://asdf.com");
            var link = new Hyperlink(new Run("view the changes")) { NavigateUri = fakeUri };
            link.RequestNavigate += (s, e) => CompareInWord(old, updated, filename, Path.GetDirectoryName(fullpath), author);
            message.Inlines.Add(link);
            message.Inlines.Add(" in Word.");
              } else if (SentenceFilter.IsBinary(old) || SentenceFilter.IsBinary(updated)) {
            message.Visibility = Visibility.Visible;
            message.Text = "This file is in binary. Please save it to view its contents.";
              } else {
            // Compute the diff, break it into blocks
            if (old == null) old = "";
            if (updated == null) updated = "";
            var d = new Differ();
            var dr = d.CreateLineDiffs(old, updated, false);
            int curBlock = 0, numBlocks = dr.DiffBlocks.Count;

            List<LineBlock> lineBlocks = new List<LineBlock>();
            for (int i = 0; i <= dr.PiecesOld.Length; i++) {
              while (curBlock < numBlocks && dr.DiffBlocks[curBlock].DeleteStartA < i) {
            curBlock++;
              }

              if (curBlock < numBlocks && dr.DiffBlocks[curBlock].DeleteStartA == i) {
            var db = dr.DiffBlocks[curBlock];
            if (db.DeleteCountA > 0) {
              lineBlocks.Add(new LineBlock(Util.ArraySlice(dr.PiecesOld, db.DeleteStartA, db.DeleteCountA), BlockType.ChangeDelete));
            }
            if (db.InsertCountB > 0) {
              lineBlocks.Add(new LineBlock(Util.ArraySlice(dr.PiecesNew, db.InsertStartB, db.InsertCountB), BlockType.ChangeAdd));
            }
            i += db.DeleteCountA;
            curBlock++;
              }

              if (i < dr.PiecesOld.Length) {
            lineBlocks.Add(new LineBlock(Util.ArraySlice(dr.PiecesOld, i, 1)));
              }
            }

            // Draw the actual blocks.
            DrawLineBlocks(lineBlocks);
              }
        }
Пример #5
0
        public static string GetFormattedDiff(string oldText, string newText)
        {
            var differ = new Differ();
              var diff = GetDiff(differ, oldText, newText);

              return diff.Lines.Any(x => x.Type != ChangeType.Unchanged)
              ? FormatDiff(diff)
              : string.Empty;
        }
Пример #6
0
        /// <summary>
        /// Make a diff between two strings
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static DiffResult Diff(string a, string b)
        {
            var differ = new Differ();
            //var result = differ.CreateCharacterDiffs(a, b, false, true);

            var result = differ.CreateWordDiffs(a, b, true, true, new char[]{',',' ','\''});

            return result;
        }
Пример #7
0
 internal static string[] DoSideBySideDiff(string SourceText, string DestinationText)
 {
     string[] Result = new string[3];
     Differ DiffMaker = new Differ();
     SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker);
     SideBySideDiffModel SideBySideDiffResult = SideBySideDiffer.BuildDiffModel(SourceText, DestinationText);
     int DiffLevel = IronDiffer.GetLevel(SideBySideDiffResult, SourceText, DestinationText);
     Result[0] = FullDiff(SideBySideDiffResult.OldText.Lines);
     Result[1] = FullDiff(SideBySideDiffResult.NewText.Lines);
     Result[2] = DiffLevel.ToString();
     return Result;
 }
Пример #8
0
        public static void Do(string upc1, string upc2)
        {
            Product product1 = DataAccess.GetProduct("794552240051");
            Product product2 = DataAccess.GetProduct("794552240358");

            Differ differ = new Differ();

            ISideBySideDiffBuilder diffBuilder = new SideBySideDiffBuilder2(differ);

            PrintToConsole(product1, diffBuilder, product2);

            //PrintToHtml(product1, diffBuilder, product2);
        }
Пример #9
0
        private void DetectChunkChanges(byte[] previousChunkData, byte[] chunkData, string name, string label, string display)
        {
            bool debugChunkFiles = true;
            DiffType InvestigatePluginPresetFileFormatDiffType = DiffType.Binary;

            // do a binary comparison between what changed before and after this method was called

            // if the chunk is not empty, try to detect what has changed
            if (chunkData != null && chunkData.Length > 0) {
                int chunkLength = chunkData.Length;

                // binary comparison to find out where the chunk has changed
                if (previousChunkData != null && previousChunkData.Length > 0) {

                    if (debugChunkFiles) {
                        BinaryFile.ByteArrayToFile("Preset Chunk Data - previousChunkData.dat", previousChunkData);
                        BinaryFile.ByteArrayToFile("Preset Chunk Data - chunkData.dat", chunkData);
                    }

                    if (InvestigatePluginPresetFileFormatDiffType == DiffType.Binary) {
                        SimpleBinaryDiff.Diff diff = SimpleBinaryDiff.GetDiff(previousChunkData, chunkData);
                        if (diff != null) {
                            System.Diagnostics.Debug.WriteLine("BinDiff: {0}", diff);

                            // store each of the chunk differences in a list
                            foreach (SimpleBinaryDiff.DiffPoint point in diff.Points) {
                                this.InvestigatedPluginPresetFileFormatList.Add(
                                    new InvestigatedPluginPresetFileFormat(point.Index, point.NewValue, name, label, display));
                            }
                        }
                    } else if (InvestigatePluginPresetFileFormatDiffType == DiffType.Text) {
                        // assume we are dealing with text and not binary data
                        var d = new Differ();
                        string OldText = BinaryFile.ByteArrayToString(previousChunkData);
                        string NewText = BinaryFile.ByteArrayToString(chunkData);

                        DiffResult res = d.CreateWordDiffs(OldText, NewText, true, true, new[] {' ', '\r', '\n'});
                        //DiffResult res = d.CreateCharacterDiffs(OldText, NewText, true, true);

                        List<UnidiffEntry> diffList = UnidiffSeqFormater.GenerateWithLineNumbers(res);
                        var queryTextDiffs = from dl in diffList
                            where dl.Type == UnidiffType.Insert
                            select dl;

                        foreach (var e in queryTextDiffs) {
                            string text = e.Text;
                            text = text.Replace("\n", "");
                            if (text != "") {
                                System.Diagnostics.Debug.WriteLine(String.Format("TextDiff: {0} {1}", e.Index, text));

                                this.InvestigatedPluginPresetFileFormatList.Add(
                                    new InvestigatedPluginPresetFileFormat(e.Index, 0, name, label, display, text));
                            }
                        }
                    }
                }
            }
        }
Пример #10
0
        public async Task<ActionResult> CompareBlobs(Errorable<BlobID.Partial> epida, Errorable<BlobID.Partial> epidb)
        {
            if (epida.HasErrors || epidb.HasErrors) return Json(new { errors = (epida.Errors + epidb.Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            // Resolve the partial IDs:
            var eids = await cms.blrepo.ResolvePartialIDs(epida.Value, epidb.Value);
            if (eids[0].HasErrors || eids[1].HasErrors) return Json(new { errors = (eids[0].Errors + eids[1].Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            BlobID idA = eids[0].Value;
            BlobID idB = eids[1].Value;

            // Get the Blobs:
            var ebls = await cms.blrepo.GetBlobs(idA, idB);
            if (ebls[0].HasErrors || ebls[1].HasErrors) return Json(new { errors = (ebls[0].Errors + ebls[1].Errors).ToJSON() }, JsonRequestBehavior.AllowGet);

            IStreamedBlob blA = ebls[0].Value, blB = ebls[1].Value;

            // Stream in both blobs' contents to string values:
            var etextA = await blA.ReadStreamAsync<string>(async st => { using (var sr = new StreamReader(st, Encoding.UTF8)) return (Errorable<string>)await sr.ReadToEndAsync(); });
            if (etextA.HasErrors) return ErrorJson(etextA);
            
            var etextB = await blB.ReadStreamAsync<string>(async st => { using (var sr = new StreamReader(st, Encoding.UTF8)) return (Errorable<string>)await sr.ReadToEndAsync(); });
            if (etextB.HasErrors) return ErrorJson(etextB);

            // TODO: update to a better diff engine that supports merging...

            // Create a diff engine:
            IDiffer differ = new Differ();
            ISideBySideDiffBuilder builder = new SideBySideDiffBuilder(differ);

            // Run the diff engine to get the output model:
            // NOTE: I would prefer it to read in via a Stream but perhaps that is not possible given the algorithm implemented.
            var sxs = builder.BuildDiffModel(etextA.Value, etextB.Value);

            // Return the result as JSON:
            return Json(sxs.ToJSON(), JsonRequestBehavior.AllowGet);
        }
Пример #11
0
        private void ProcessBlockDiff(LineBlock oldLineBlock, LineBlock newLineBlock, bool modifyOld = true)
        {
            // Do block-by-block diffs inside LineBlocks.
              var oldBlocks = new List<Block>();
              var newBlocks = new List<Block>();

              foreach (var line in oldLineBlock.lines) {
            oldBlocks.AddRange(line.blocks);
              }

              foreach (var line in newLineBlock.lines) {
            newBlocks.AddRange(line.blocks);
              }

              var d = new Differ();
              DiffResult diff = d.CreateLineDiffs(String.Join("\n", oldBlocks.Select(x => x.ToString()).ToArray()),
            String.Join("\n", newBlocks.Select(x => x.ToString()).ToArray()), false);

              foreach (DiffBlock dblock in diff.DiffBlocks) {
            if (modifyOld) {
              for (int i = 0; i < dblock.DeleteCountA && dblock.DeleteStartA + i < oldBlocks.Count; i++) {
            oldBlocks[i + dblock.DeleteStartA].type = BlockType.ChangeDelete;
              }
            }
            for (int i = 0; i < dblock.InsertCountB && dblock.InsertStartB + i < newBlocks.Count; i++) {
              newBlocks[i + dblock.InsertStartB].type = BlockType.ChangeAdd;
            }
              }
        }
Пример #12
0
 public static SideBySideDiffModel GetDiff(string Source, string Destination)
 {
     Differ DiffMaker = new Differ();
     SideBySideDiffBuilder SideBySideDiffer = new SideBySideDiffBuilder(DiffMaker);
     return SideBySideDiffer.BuildDiffModel(Source, Destination);
 }
Пример #13
0
		/// <inheritdoc />
		public void SetParameterAutomated(int index, float value)
		{
			RaisePluginCalled("SetParameterAutomated(" + index + ", " + value + ")");
			
			// This chunk of code handles investigation of a preset format in order to be able to
			// reverse engineer where the different changes to the parameters are stored within the preset file.
			string name = PluginContext.PluginCommandStub.GetParameterName(index);
			string label = PluginContext.PluginCommandStub.GetParameterLabel(index);
			string display = PluginContext.PluginCommandStub.GetParameterDisplay(index);
			if ("".Equals(display)) display = "" + value;
			Debug.WriteLine(string.Format("SetParameterAutomated. Name: {0}, Label: {1}, Value: {2}", name, label, display));
			
			if (DoInvestigatePluginPresetFileFormat) {
				// read in the preset chunk and
				// do a binary comparison between what changed before and after this method was called
				byte[] chunkData = PluginContext.PluginCommandStub.GetChunk(true);
				
				// if we are tracking a specific number of bytes from the chunk, store those
				if (DoTrackPluginPresetFileFormat) {
					if (TrackPluginPresetFilePosition > -1 && TrackPluginPresetFileNumberOfBytes > 0) {
						var trackedChunkData = new byte[TrackPluginPresetFileNumberOfBytes];
						Array.Copy(chunkData, TrackPluginPresetFilePosition, trackedChunkData, 0, TrackPluginPresetFileNumberOfBytes);
						TrackPluginPresetFileBytes = trackedChunkData;
					}
				}
				
				// if the chunk is not empty, try to detect what has changed
				if (chunkData != null && chunkData.Length > 0) {
					int chunkLength = chunkData.Length;
					
					// TODO: DELETE THIS
					/*
					string wavesPluginName = WavesPreset.GetPluginName(chunkData);
					if (wavesPluginName != null) {
						switch (wavesPluginName) {
							case "SSLChannel":
								WavesSSLChannel sslChannel = new WavesSSLChannel();
								sslChannel.ReadChunkData(chunkData);
								sslChannel.Write("sslchannel-output.txt");
								break;
							case "SSLComp":
								WavesSSLComp sslComp = new WavesSSLComp();
								sslComp.ReadChunkData(chunkData);
								sslComp.Write("sslcomp-output.txt");
								break;
							case "PuigChild":
								break;
						}
					}
					 */
					
					// binary comparison to find out where the chunk has changed
					if (previousChunkData != null && previousChunkData.Length > 0) {
						
						if (debugChunkFiles) {
							BinaryFile.ByteArrayToFile("Preset Chunk Data - previousChunkData.dat", previousChunkData);
							BinaryFile.ByteArrayToFile("Preset Chunk Data - chunkData.dat", chunkData);
						}
						
						if (InvestigatePluginPresetFileFormatDiffType == DiffType.Binary) {
							SimpleBinaryDiff.Diff diff = SimpleBinaryDiff.GetDiff(previousChunkData, chunkData);
							if (diff != null) {
								Debug.WriteLine(string.Format("BinDiff: {0}", diff));
								
								// store each of the chunk differences in a list
								foreach (SimpleBinaryDiff.DiffPoint point in diff.Points) {
									this.InvestigatedPluginPresetFileFormatList.Add(
										new InvestigatedPluginPresetFileFormat(point.Index, point.NewValue, name, label, display));
								}
							}
						} else if (InvestigatePluginPresetFileFormatDiffType == DiffType.Text) {
							// assume we are dealing with text and not binary data
							var d = new Differ();
							string OldText = BinaryFile.ByteArrayToString(previousChunkData);
							string NewText = BinaryFile.ByteArrayToString(chunkData);
							
							DiffResult res = d.CreateWordDiffs(OldText, NewText, true, true, new[] {' ', '\r', '\n'});
							//DiffResult res = d.CreateCharacterDiffs(OldText, NewText, true, true);

							List<UnidiffEntry> diffList = UnidiffSeqFormater.GenerateWithLineNumbers(res);
							var queryTextDiffs = from dl in diffList
								where dl.Type == UnidiffType.Insert
								select dl;
							
							foreach (var e in queryTextDiffs) {
								string text = e.Text;
								text = text.Replace("\n", "");
								if (text != "") {
									System.Diagnostics.Debug.WriteLine(String.Format("TextDiff: {0} {1}", e.Index, text));
									
									this.InvestigatedPluginPresetFileFormatList.Add(
										new InvestigatedPluginPresetFileFormat(e.Index, 0, name, label, display, text));
								}
							}
						}
					}
					previousChunkData = chunkData;
				}
			}
		}
Пример #14
0
        /// <summary>
        /// Lê o csv e retorna uma lista com as rodadas
        /// </summary>
        /// <param name="instanceFile"></param>
        /// <param name="biblioteca"></param>
        /// <param name="dirGa"></param>
        private static List<RodadaMapper> RecuperarRodadasDoGaNoCsv(FileInfo instanceFile, DirectoryInfo biblioteca, DirectoryInfo dirGa)
        {
            if (!File.Exists(biblioteca.GetFiles().First().FullName))
            {
                Console.WriteLine("Deveria existir o arquivo original da biblioteca aqui. | {0}", dirGa.FullName);
                Environment.Exit(-1);
            }

            //Ler as rodadas
            var rodadas = new List<RodadaMapper>();

            using (var csv = new TextFieldParser(instanceFile.FullName))
            {
                csv.ReadLine();
                csv.ReadLine();

                csv.TextFieldType = FieldType.Delimited;
                csv.SetDelimiters(",");
                csv.HasFieldsEnclosedInQuotes = true;

                //Conta das linhas do original
                var totalLinhas = ContarLinhas(biblioteca.GetFiles().First().FullName);
                //Conta Tokens do Original
                var totalchars = GetNumOfCharsInFile(biblioteca.GetFiles().First().FullName);
                //Texto do Original
                var textoOriginal = File.ReadAllText(biblioteca.GetFiles().First().FullName);

                while (!csv.EndOfData)
                {
                    string[] currentRow = csv.ReadFields();
                    string bestFile = Path.GetFileName(currentRow[1]);
                    int totalLinhasBest = 0;
                    int totalcharsBest = 0;
                    string tempoOriginal = "00:00:00,000";
                    string fitOrignal = "00000";
                    string tempoFinalComUnload = "";
                    string fitFinal = "";
                    DiffPaneModel resultadoComparacao = null;

                    //Tempo e fit originais
                    tempoOriginal = RecuperarTempoMedioeFitOriginal(biblioteca, dirGa, currentRow[0], out fitOrignal);

                    var fileList = dirGa.GetFiles(bestFile, SearchOption.AllDirectories);
                    //Se o arquivo melhorado existe, conta as linhas e os caracteres do mesmo

                    if (fileList.Any())
                    {
                        totalLinhasBest = ContarLinhas(fileList.First().FullName);
                        totalcharsBest = GetNumOfCharsInFile(fileList.First().FullName);
                        tempoFinalComUnload = currentRow[4];
                        fitFinal = currentRow[3];

                        var textoMelhor = File.ReadAllText(fileList.First().FullName);

                        var d = new Differ();
                        var builder = new InlineDiffBuilder(d);
                        resultadoComparacao = builder.BuildDiffModel(textoOriginal, textoMelhor);
                    }
                    else
                    {
                        //Não houve melhor
                        totalLinhasBest = totalLinhas;
                        totalcharsBest = totalchars;
                        tempoFinalComUnload = tempoOriginal;
                        fitFinal = fitOrignal;
                    }

                    rodadas.Add(new RodadaMapper()
                        {
                            Algoritmo = dirGa.Name,
                            Biblioteca = biblioteca.Name,
                            Rodada = currentRow[0],
                            Individuo = currentRow[1],
                            Operacao = currentRow[2],
                            Fitness = fitOrignal,
                            FitnessFinal = fitFinal,
                            TempoOriginalComUnload = tempoOriginal,
                            TempoFinalComUnload = tempoFinalComUnload,
                            Testes = currentRow[5],
                            LocOriginal = totalLinhas,
                            LocFinal = totalLinhasBest,
                            CaracteresOriginal = totalchars,
                            CaracteresFinal = totalcharsBest,
                            Diferencas = resultadoComparacao
                        });
                }
            }

            return rodadas;
        }
Пример #15
0
 private void MakeDiffPangoMarkup()
 {
     var d = new Differ ();
     var differ = new SideBySideFullDiffBuilder(d);
     var diffRes = differ.BuildDiffModel(OldValue, NewValue);
     OldPangoText = PangoRender.RenderDiffLines (diffRes.OldText);
     NewPangoText = PangoRender.RenderDiffLines (diffRes.NewText);
     isPangoMade = true;
 }
Пример #16
0
        // 创建展示两个 OPAC 记录差异的 HTML 字符串
        // parameters:
        //      strNewText  如果为 "",表示内容全部被删除,依然会输出对照格式;如果为 null,表示只输出左边的部分
        // return:
        //      -1  出错
        //      0   成功。两边相等
        //      1   两边不相等
        public static int DiffOpacHtml(
            string strOldText,
            string strNewText,
            out string strHtml,
            out string strError)
        {
            strError = "";
            strHtml = "";

            if (string.IsNullOrEmpty(strOldText) == true && string.IsNullOrEmpty(strNewText) == true)
                return 0;

            var marc_differ = new Differ();
            var marc_builder = new SideBySideDiffBuilder(marc_differ);
            var marc_diff_result = marc_builder.BuildDiffModel(strOldText, 
                strNewText == null? "" : strNewText);

            Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, "");

            /*
    public enum ChangeType
    {
        Unchanged,
        Deleted,
        Inserted,
        Imaginary,
        Modified
    }
             * */

            bool bChanged = false;

            StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096);

            for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++)
            {
                var newline = marc_diff_result.NewText.Lines[index];
                var oldline = marc_diff_result.OldText.Lines[index];

                if (string.IsNullOrEmpty(newline.Text) == true
                    && string.IsNullOrEmpty(oldline.Text) == true)
                    continue;

                if (oldline.Type != ChangeType.Unchanged
                    || newline.Type != ChangeType.Unchanged)
                    bChanged = true;

                string strLineClass = "datafield";
                if (strNewText == null)
                {
                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildOpacFieldHtml(ChangeType.Unchanged, oldline.Text));
                    strResult.Append("\r\n</tr>");
                    continue;
                }

                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                // 创建一个字段的 HTML 局部 三个 <td>
                strResult.Append(BuildOpacFieldHtml(oldline.Type, oldline.Text));
                strResult.Append(SEP);
                strResult.Append(BuildOpacFieldHtml(newline.Type, newline.Text));
                strResult.Append("\r\n</tr>");
            }

            strResult.Append("</table>");
            strHtml = strResult.ToString();

            if (bChanged == false)
                return 0;

            return 1;
        }
Пример #17
0
        static string DiffXml(
            int nLevel,
            string strOldFragmentXml,
            XmlNodeType old_nodetype,
            string strNewFragmentXml,
            XmlNodeType new_nodetype)
        {
            if (string.IsNullOrEmpty(strOldFragmentXml) == true && string.IsNullOrEmpty(strNewFragmentXml) == true)
                return "";

            if (old_nodetype != XmlNodeType.Element || new_nodetype != XmlNodeType.Element)
            {
                if (old_nodetype == XmlNodeType.Element)
                    strOldFragmentXml = GetIndentXml(strOldFragmentXml);
                if (new_nodetype == XmlNodeType.Element)
                    strNewFragmentXml = GetIndentXml(strNewFragmentXml);
                return GetPlanTextDiffHtml(
                    nLevel,
                    strOldFragmentXml,
                    strNewFragmentXml);
            }

            string strOldChildren = "";
            string strOldBegin = "";
            string strOldEnd = "";
            List<XmlNode> old_childnodes = null;
            string strOldElementName = "";
            GetComparableXmlString(strOldFragmentXml,
                out strOldChildren,
                out old_childnodes,
                out strOldElementName,
                out strOldBegin,
                out strOldEnd);

            string strNewChildren = "";
            string strNewBegin = "";
            string strNewEnd = "";
            List<XmlNode> new_childnodes = null;
            string strNewElementName = "";
            GetComparableXmlString(strNewFragmentXml,
                out strNewChildren,
                out new_childnodes,
                out strNewElementName,
                out strNewBegin,
                out strNewEnd);

            bool bSpecialCompare = false;   // 是否属于特殊情况: 根元素名不相同,但仍需要比较下级
            if (strOldElementName != strNewElementName
                && nLevel == 0)
                bSpecialCompare = true;

            if (strOldElementName != strNewElementName && bSpecialCompare == false)
            {
                // 元素名不一样了并且不是根级别,就没有必要做细节比较了
                // 意思是说如果是根级别,即便根元素名不一样,也要比较其下级
                if (old_nodetype == XmlNodeType.Element)
                    strOldFragmentXml = GetIndentXml(strOldFragmentXml);
                if (new_nodetype == XmlNodeType.Element)
                    strNewFragmentXml = GetIndentXml(strNewFragmentXml);
                return GetPlanTextDiffHtml(
    nLevel,
    strOldFragmentXml,
    strNewFragmentXml);
            }

            string strLineClass = "datafield";
            StringBuilder strResult = new StringBuilder(4096);

            if (nLevel > 0 || bSpecialCompare == true)
            {
                ChangeType begin_type = ChangeType.Unchanged;
                if (strOldBegin != strNewBegin)
                    begin_type = ChangeType.Modified;

                // Begin
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append(BuildFragmentFieldHtml(nLevel, begin_type, strOldBegin));
                strResult.Append(SEP);
                strResult.Append(BuildFragmentFieldHtml(nLevel, begin_type, strNewBegin));
                strResult.Append("\r\n</tr>");
            }

            // return "\r\n<td class='content' colspan='3'></td>";

            if (string.IsNullOrEmpty(strOldChildren) == false || string.IsNullOrEmpty(strNewChildren) == false)
            {
                var xml_differ = new Differ();
                var xml_builder = new SideBySideDiffBuilder(xml_differ);
                var xml_diff_result = xml_builder.BuildDiffModel(strOldChildren, strNewChildren);

                Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, "");
                int old_index = 0;
                int new_index = 0;
                for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++)
                {
                    var newline = xml_diff_result.NewText.Lines[index];
                    var oldline = xml_diff_result.OldText.Lines[index];

                    XmlNode new_node = null;
                    if (newline.Type != ChangeType.Imaginary)
                        new_node = new_childnodes[new_index++];

                    XmlNode old_node = null;
                    if (oldline.Type != ChangeType.Imaginary)
                        old_node = old_childnodes[old_index++];

                    if (newline.Type == ChangeType.Modified)
                    {
                        strResult.Append(DiffXml(nLevel + 1,
                            oldline.Text,
                            old_node.NodeType,
                            newline.Text,
                            new_node.NodeType));
                        continue;
                    }

                    string strOldText = "";
                    if (old_node != null && old_node.NodeType == XmlNodeType.Element)
                        strOldText = GetIndentXml(oldline.Text);
                    else 
                        strOldText = oldline.Text;

                    string strNewText = "";
                    if (new_node != null && new_node.NodeType == XmlNodeType.Element)
                        strNewText = GetIndentXml(newline.Text);
                    else
                        strNewText = newline.Text;

                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个 XML 字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildFragmentFieldHtml(nLevel + 1, oldline.Type, strOldText));
                    strResult.Append(SEP);
                    strResult.Append(BuildFragmentFieldHtml(nLevel + 1, newline.Type, strNewText));
                    strResult.Append("\r\n</tr>");
                }
            }

            if (nLevel > 0 || bSpecialCompare == true)
            {
                ChangeType end_type = ChangeType.Unchanged;
                if (strOldEnd != strNewEnd)
                    end_type = ChangeType.Modified;

                // End
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append(BuildFragmentFieldHtml(nLevel, end_type, strOldEnd));
                strResult.Append(SEP);
                strResult.Append(BuildFragmentFieldHtml(nLevel, end_type, strNewEnd));
                strResult.Append("\r\n</tr>");
            }

            return strResult.ToString();
        }
Пример #18
0
        private void ProcessDiff(string original, string myVersion, string newVersion)
        {
            // Do a line-by-line diff, marking changed line groups.
              // Also, find intersecting diffs and mark them as conflicted changes for resolution.
              var d = new Differ();
              var diffs = new DiffResult[2] {
            d.CreateLineDiffs(original, myVersion ?? "", false),
            d.CreateLineDiffs(original, newVersion ?? "", false)
              };

              string[][] newPieces = new string[2][];
              newPieces[0] = diffs[0].PiecesNew;
              newPieces[1] = diffs[1].PiecesNew;
              if (myVersion == "") newPieces[0] = new string[] { "" };
              if (newVersion == "") newPieces[1] = new string[] { "" };

              var dblocks = new List<Tuple<DiffBlock, int>>();
              for (int side = 0; side < 2; side++) {
            foreach (var block in diffs[side].DiffBlocks) {
              DiffBlock actualBlock = block;
              if (diffs[side].PiecesNew.Length == 0 && block.InsertCountB == 0 && block.InsertStartB == 0) {
            actualBlock = new DiffBlock(block.DeleteStartA, block.DeleteCountA, 0, 1);
              }
              dblocks.Add(new Tuple<DiffBlock, int>(actualBlock, side));
            }
              }
              dblocks.Sort((a, b) => a.Item1.DeleteStartA.CompareTo(b.Item1.DeleteStartA));

              content = new List<LineBlock>[2];
              for (int i = 0; i < 2; i++) {
            content[i] = new List<LineBlock>();
              }
              conflictOrigBlocks = new List<LineBlock>();

              string[] origLines = diffs[0].PiecesOld;
              int nextOriginalLine = 0;
              for (int i = 0; i < dblocks.Count; ) {
            DiffBlock block = dblocks[i].Item1;
            int owner = dblocks[i].Item2;
            // Add unchanged (original) lines.
            if (block.DeleteStartA > nextOriginalLine) {
              foreach (var lineBlocks in content) {
            lineBlocks.Add(new LineBlock(Util.ArraySlice(origLines, nextOriginalLine, block.DeleteStartA - nextOriginalLine)));
              }
              nextOriginalLine = block.DeleteStartA;
            }

            int rangeStart = block.DeleteStartA;
            int rangeEnd = rangeStart + block.DeleteCountA;
            int j = i;
            // If this change intersects any other changes, then merge them together to form a block.
            while (j < dblocks.Count && dblocks[j].Item1.DeleteStartA <= rangeEnd) {
              rangeEnd = Math.Max(rangeEnd, dblocks[j].Item1.DeleteStartA + dblocks[j].Item1.DeleteCountA);
              j++;
            }

            if (j == i + 1) {
              // A regular change.
              var oldBlock = new LineBlock(Util.ArraySlice(diffs[owner].PiecesOld, block.DeleteStartA, block.DeleteCountA), BlockType.ChangeDelete);
              var newBlock = new LineBlock(Util.ArraySlice(newPieces[owner], block.InsertStartB, block.InsertCountB), BlockType.ChangeAdd);
              if (block.DeleteCountA != 0 && block.InsertCountB != 0) {
            oldBlock.type = BlockType.Conflict;
            newBlock.type = BlockType.Conflict;
              } else if (block.DeleteCountA == 0) {
            oldBlock.type = BlockType.Blank;
              } else if (block.InsertCountB == 0) {
            newBlock.type = BlockType.Blank;
              } // can't both be empty!
              ProcessBlockDiff(oldBlock, newBlock);
              content[owner].Add(newBlock);
              content[1 - owner].Add(oldBlock);
              conflictOrigBlocks.Add(owner == 0 ? newBlock : oldBlock);
            } else {
              // Create a change block.
              for (int side = 0; side < 2; side++) {
            int curOriginalLine = rangeStart;
            var conflictBlock = new LineBlock();
            var origBlock = new LineBlock();
            conflictBlock.type = BlockType.Conflict;
            for (int k = i; k < j; k++) {
              DiffBlock subBlock = dblocks[k].Item1;
              if (dblocks[k].Item2 != side) continue;
              if (subBlock.DeleteStartA > curOriginalLine) {
                conflictBlock.AddLines(Util.ArraySlice(origLines, curOriginalLine, subBlock.DeleteStartA - curOriginalLine));
              }
              curOriginalLine = subBlock.DeleteStartA + subBlock.DeleteCountA;
              var oldBlock = new LineBlock(Util.ArraySlice(diffs[side].PiecesOld, subBlock.DeleteStartA, subBlock.DeleteCountA), BlockType.ChangeDelete);
              var newBlock = new LineBlock(Util.ArraySlice(newPieces[side], subBlock.InsertStartB, subBlock.InsertCountB), BlockType.ChangeAdd);
              ProcessBlockDiff(oldBlock, newBlock, false);
              origBlock.Append(oldBlock);
              conflictBlock.Append(newBlock);
            }
            if (rangeEnd > curOriginalLine) {
              conflictBlock.AddLines(Util.ArraySlice(origLines, curOriginalLine, rangeEnd - curOriginalLine));
            }
            if (conflictBlock.lines.Count == 0) {
              conflictBlock.type = BlockType.ChangeDelete;
            }
            content[side].Add(conflictBlock);
            if (side == 0) {
              conflictOrigBlocks.Add(origBlock);
            }
              }

              int last = content[0].Count - 1;
              if (content[0][last].ToString() == content[1][last].ToString()) {
            // Not actually a conflict if they're both the same change.
            if (content[0][last].lines.Count == 0) {
              // If both are deleted, just show nothing.
              content[0].RemoveAt(last);
              content[1].RemoveAt(last);
            } else {
              // Make them normal blocks.
              content[0][last] = new LineBlock(content[0][last].lines.Select(x => x.ToString()).ToArray());
              content[1][last] = new LineBlock(content[1][last].lines.Select(x => x.ToString()).ToArray());
            }
            conflictOrigBlocks.RemoveAt(conflictOrigBlocks.Count - 1);
              }
            }

            nextOriginalLine = rangeEnd;
            i = j;
              }

              // Add any remaining unchanged lines.
              if (origLines.Length > nextOriginalLine) {
            foreach (var lineBlocks in content) {
              lineBlocks.Add(new LineBlock(Util.ArraySlice(origLines, nextOriginalLine, origLines.Length - nextOriginalLine)));
            }
              }

              origBlocks = new LineBlock[2][];
              origBlocks[0] = new LineBlock[content[0].Count];
              origBlocks[1] = new LineBlock[content[1].Count];
              content[0].CopyTo(origBlocks[0]);
              content[1].CopyTo(origBlocks[1]);
        }
Пример #19
-2
        // 创建展示两个 MARC 记录差异的 HTML 字符串
        // return:
        //      -1  出错
        //      0   成功
        public static int DiffHtml(
            string strOldTitle,
            string strOldMarc,
            string strOldFragmentXml,
            string strOldImageFragment,
            string strNewTitle,
            string strNewMarc,
            string strNewFragmentXml,
            string strNewImageFragment,
            out string strHtml,
            out string strError)
        {
            strError = "";
            strHtml = "";
            // int nRet = 0;

            if (string.IsNullOrEmpty(strOldMarc) == true && string.IsNullOrEmpty(strNewMarc) == true)
                return 0;

            string strOldHeader = "";
            string strNewHeader = "";
            string strOldBody = "";
            string strNewBody = "";

            SplitMarc(strOldMarc,
                out strOldHeader,
                out strOldBody);
            SplitMarc(strNewMarc,
                out strNewHeader,
                out strNewBody);

            if (strOldHeader.Length < 24)
                strOldHeader = strOldHeader.PadRight(24, '?');
            if (strNewHeader.Length < 24)
                strNewHeader = strNewHeader.PadRight(24, '?');

            var marc_differ = new MarcDiffer();
            var marc_builder = new MarcDiffBuilder(marc_differ);
            var marc_diff_result = marc_builder.BuildDiffModel(strOldBody, strNewBody);

            Debug.Assert(marc_diff_result.OldText.Lines.Count == marc_diff_result.NewText.Lines.Count, "");

            /*
    public enum ChangeType
    {
        Unchanged,
        Deleted,
        Inserted,
        Imaginary,
        Modified
    }
             * */

            StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096);

            if (string.IsNullOrEmpty(strOldTitle) == false
                || string.IsNullOrEmpty(strNewTitle) == false)
            {
                string strLineClass = "header";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(BuildHeaderHtml(false, strOldTitle));
                strResult.Append(SEP);
                strResult.Append(BuildHeaderHtml(false, strNewTitle));
                strResult.Append("\r\n</tr>");
            }


            {
                string strLineClass = "header";
                bool bModified = strOldHeader != strNewHeader;
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(BuildHeaderHtml(bModified, strOldHeader));
                strResult.Append(SEP);
                strResult.Append(BuildHeaderHtml(bModified, strNewHeader));
                strResult.Append("\r\n</tr>");
            }

            if (string.IsNullOrEmpty(strOldImageFragment) == false
|| string.IsNullOrEmpty(strNewImageFragment) == false)
            {
                string strLineClass = "header";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");

                strResult.Append(GetImageHtml(strOldImageFragment));
                strResult.Append(SEP);
                strResult.Append(GetImageHtml(strNewImageFragment));
                strResult.Append("\r\n</tr>");
            }


            for (int index = 0; index < marc_diff_result.NewText.Lines.Count; index++)
            {
                var newline = marc_diff_result.NewText.Lines[index];
                var oldline = marc_diff_result.OldText.Lines[index];

                if (string.IsNullOrEmpty(newline.Text) == true
                    && string.IsNullOrEmpty(oldline.Text) == true)
                    continue;

                string strLineClass = "datafield";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                // 创建一个字段的 HTML 局部 三个 <td>
                strResult.Append(BuildFieldHtml( oldline.Type, oldline.Text));
                strResult.Append(SEP);
                strResult.Append(BuildFieldHtml(newline.Type, newline.Text));
                strResult.Append("\r\n</tr>");

#if NO
                if (newline.Type == ChangeType.Unchanged)
                {

                }
                else if (newline.Type == ChangeType.Inserted)
                {

                }
                else if (newline.Type == ChangeType.Modified)
                {

                }
                else if (oldline.Type == ChangeType.Deleted)
                {

                }
#endif
            }

#if NO
            if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false)
            {
                var xml_differ = new Differ();
                var xml_builder = new SideBySideDiffBuilder(xml_differ);
                var xml_diff_result = xml_builder.BuildDiffModel(GetComparableXmlString(strOldFragmentXml), GetComparableXmlString(strNewFragmentXml));

                Debug.Assert(xml_diff_result.OldText.Lines.Count == xml_diff_result.NewText.Lines.Count, "");

                for (int index = 0; index < xml_diff_result.NewText.Lines.Count; index++)
                {
                    var newline = xml_diff_result.NewText.Lines[index];
                    var oldline = xml_diff_result.OldText.Lines[index];

                    string strLineClass = "datafield";

                    if (newline.Type == ChangeType.Modified)
                    {

                    }

                    strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                    // 创建一个 XML 字段的 HTML 局部 三个 <td>
                    strResult.Append(BuildFragmentFieldHtml(oldline.Type, oldline.Text));
                strResult.Append(SEP);
                    strResult.Append(BuildFragmentFieldHtml(newline.Type, newline.Text));
                    strResult.Append("\r\n</tr>");
                }

            }
#endif

            if (string.IsNullOrEmpty(strOldFragmentXml) == false || string.IsNullOrEmpty(strNewFragmentXml) == false)
            {
                string strLineClass = "sepline";
                strResult.Append("\r\n<tr class='" + strLineClass + "'>");
                strResult.Append("<td class='sepline' colspan='3'>&nbsp;</td>");
                strResult.Append("<td class='cross'>&nbsp;</td>");
                strResult.Append("<td class='sepline' colspan='3'>&nbsp;</td>");
                strResult.Append("\r\n</tr>");
            }

            strResult.Append(DiffXml(
                0,
                strOldFragmentXml,
                XmlNodeType.Element,
                strNewFragmentXml,
                XmlNodeType.Element));

            strResult.Append("</table>");
            strHtml = strResult.ToString();

            return 0;
        }