コード例 #1
0
        public static Diff Compare(string fileOnePath, string fileOneContent, string fileTwoPath, string fileTwoContent, CompareOptions options)
        {
            if (fileOneContent == null && fileTwoContent == null)
            {
                throw new InvalidOperationException("Both files were null");
            }

            if (options.BomMode == BomMode.Ignore)
            {
                if (fileOneContent != null)
                {
                    fileOneContent = RemoveBom(fileOneContent);
                }
                if (fileTwoContent != null)
                {
                    fileTwoContent = RemoveBom(fileTwoContent);
                }
            }

            if (fileTwoContent == null)
            {
                return(DeletedFileDiff(fileOneContent, fileOnePath));
            }
            if (fileOneContent == null)
            {
                return(NewFileDiff(fileTwoContent, fileTwoPath));
            }
            if (IsBinary(fileOneContent))
            {
                throw new BinaryFileException(fileOnePath);
            }
            if (IsBinary(fileTwoContent))
            {
                throw new BinaryFileException(fileTwoPath);
            }

            var patchMaker = new PatchMaker();
            var patches    = patchMaker.MakePatch(fileOneContent, fileTwoContent, options);
            var chunks     = new List <Chunk>();

            foreach (var patch in patches)
            {
                var originalRange = new ChangeRange(patch.start1 + 1, patch.length1);
                var newRange      = new ChangeRange(patch.start2 + 1, patch.length2);
                var range         = new ChunkRange(originalRange, newRange);
                var snippets      = new List <ISnippet>();

                var       lines             = new List <DiffMatchPatch.Diff>();
                Operation?previousOperation = null;
                var       isModification    = false;

                foreach (var diff in patch.diffs)
                {
                    if (previousOperation == null)
                    {
                        previousOperation = diff.operation;
                    }
                    if (previousOperation == Operation.DELETE && diff.operation == Operation.INSERT)
                    {
                        isModification = true;
                    }
                    else if (previousOperation != diff.operation)
                    {
                        // different operation
                        if (previousOperation == Operation.EQUAL)
                        {
                            snippets.Add(new ContextSnippet(lines.Select(x => new ContextLine(x.text)).Cast <ILine>()));
                        }
                        else if (isModification)
                        {
                            snippets.Add(new ModificationSnippet(
                                             lines
                                             .Where(x => x.operation == Operation.DELETE)
                                             .Select(x => new SubtractionLine(x.text))
                                             .Cast <ILine>(),
                                             lines
                                             .Where(x => x.operation == Operation.INSERT)
                                             .Select(x => new AdditionLine(x.text))
                                             .Cast <ILine>()
                                             ));
                        }
                        else if (previousOperation == Operation.INSERT)
                        {
                            snippets.Add(new AdditionSnippet(lines.Select(x => new AdditionLine(x.text)).Cast <ILine>()));
                        }
                        else if (previousOperation == Operation.DELETE)
                        {
                            snippets.Add(new SubtractionSnippet(lines.Select(x => new SubtractionLine(x.text)).Cast <ILine>()));
                        }

                        lines.Clear();
                        isModification = false;
                    }

                    lines.Add(diff);
                    previousOperation = diff.operation;
                }

                if (lines.Count > 0)
                {
                    if (previousOperation == Operation.INSERT)
                    {
                        snippets.Add(new AdditionSnippet(lines.Select(x => new AdditionLine(x.text)).Cast <ILine>()));
                    }
                    else if (previousOperation == Operation.DELETE)
                    {
                        snippets.Add(new SubtractionSnippet(lines.Select(x => new SubtractionLine(x.text)).Cast <ILine>()));
                    }
                    else
                    {
                        snippets.Add(new ContextSnippet(lines.Select(x => new ContextLine(x.text)).Cast <ILine>()));
                    }
                }

                chunks.Add(new Chunk(range, snippets));
            }

            var header = new Header(new FormatType("generated"), new[]
            {
                new File('a', fileOnePath),
                new File('b', fileTwoPath)
            });

            return(new Diff(header, chunks));
        }
コード例 #2
0
ファイル: Differ.cs プロジェクト: jagregory/sharpdiff
        public static Diff Compare(string fileOnePath, string fileOneContent, string fileTwoPath, string fileTwoContent, CompareOptions options)
        {
            if (fileOneContent == null && fileTwoContent == null)
                throw new InvalidOperationException("Both files were null");

            if (options.BomMode == BomMode.Ignore)
            {
                if (fileOneContent != null)
                    fileOneContent = RemoveBom(fileOneContent);
                if (fileTwoContent != null)
                    fileTwoContent = RemoveBom(fileTwoContent);
            }

            if (fileTwoContent == null)
                return DeletedFileDiff(fileOneContent, fileOnePath);
            if (fileOneContent == null)
                return NewFileDiff(fileTwoContent, fileTwoPath);
            if (IsBinary(fileOneContent))
                throw new BinaryFileException(fileOnePath);
            if (IsBinary(fileTwoContent))
                throw new BinaryFileException(fileTwoPath);

            var patchMaker = new PatchMaker();
            var patches = patchMaker.MakePatch(fileOneContent, fileTwoContent, options);
            var chunks = new List<Chunk>();

            foreach (var patch in patches)
            {
                var originalRange = new ChangeRange(patch.start1 + 1, patch.length1);
                var newRange = new ChangeRange(patch.start2 + 1, patch.length2);
                var range = new ChunkRange(originalRange, newRange);
                var snippets = new List<ISnippet>();

                var lines = new List<DiffMatchPatch.Diff>();
                Operation? previousOperation = null;
                var isModification = false;

                foreach (var diff in patch.diffs)
                {
                    if (previousOperation == null)
                        previousOperation = diff.operation;
                    if (previousOperation == Operation.DELETE && diff.operation == Operation.INSERT)
                        isModification = true;
                    else if (previousOperation != diff.operation)
                    {
                        // different operation
                        if (previousOperation == Operation.EQUAL)
                            snippets.Add(new ContextSnippet(lines.Select(x => new ContextLine(x.text)).Cast<ILine>()));
                        else if (isModification)
                            snippets.Add(new ModificationSnippet(
                                lines
                                    .Where(x => x.operation == Operation.DELETE)
                                    .Select(x => new SubtractionLine(x.text))
                                    .Cast<ILine>(),
                                lines
                                    .Where(x => x.operation == Operation.INSERT)
                                    .Select(x => new AdditionLine(x.text))
                                    .Cast<ILine>()
                            ));
                        else if (previousOperation == Operation.INSERT)
                            snippets.Add(new AdditionSnippet(lines.Select(x => new AdditionLine(x.text)).Cast<ILine>()));
                        else if (previousOperation == Operation.DELETE)
                            snippets.Add(new SubtractionSnippet(lines.Select(x => new SubtractionLine(x.text)).Cast<ILine>()));

                        lines.Clear();
                        isModification = false;
                    }

                    lines.Add(diff);
                    previousOperation = diff.operation;
                }

                if (lines.Count > 0)
                {
                    if (previousOperation == Operation.INSERT)
                        snippets.Add(new AdditionSnippet(lines.Select(x => new AdditionLine(x.text)).Cast<ILine>()));
                    else if (previousOperation == Operation.DELETE)
                        snippets.Add(new SubtractionSnippet(lines.Select(x => new SubtractionLine(x.text)).Cast<ILine>()));
                    else
                        snippets.Add(new ContextSnippet(lines.Select(x => new ContextLine(x.text)).Cast<ILine>()));
                }

                chunks.Add(new Chunk(range, snippets));
            }

            var header = new Header(new FormatType("generated"), new[]
            {
                new File('a', fileOnePath),
                new File('b', fileTwoPath)
            });

            return new Diff(header, chunks);
        }