File indexing completed on 2025-03-09 05:11:45

0001 /*
0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com>
0003 
0004 SPDX-License-Identifier: GPL-3.0-or-later
0005 */
0006 
0007 #include "solution.h"
0008 
0009 namespace Diff
0010 {
0011 
0012 SolutionIterator::Result::Result()
0013     : oldStart(0)
0014     , oldSize(0)
0015     , newStart(0)
0016     , newSize(0)
0017     , success(false)
0018     , type(SegmentType::DifferentOnBoth)
0019 {
0020 }
0021 
0022 SolutionIterator::Result::Result(int oldStart, int oldSize, int newStart, int newSize, bool success, SegmentType type)
0023     : oldStart(oldStart)
0024     , oldSize(oldSize)
0025     , newStart(newStart)
0026     , newSize(newSize)
0027     , success(success)
0028     , type(type)
0029 {
0030 }
0031 
0032 SolutionIterator::SolutionIterator(const Solution &solution, int firstSize, int secondSize)
0033     : _solution(solution)
0034     , i(_solution.begin())
0035     , _firstSize{firstSize}
0036     , _secondSize{secondSize}
0037 {
0038 }
0039 
0040 void SolutionIterator::begin()
0041 {
0042     _firstIndex = _secondIndex = 0;
0043     i = _solution.begin();
0044     _ended = false;
0045 }
0046 
0047 SolutionIterator::Result SolutionIterator::pick()
0048 {
0049     if (i == _solution.end()) {
0050         if (_ended)
0051             return {};
0052         else {
0053             Result r{_firstIndex, _firstSize - _firstIndex, _firstIndex, _secondSize - _secondIndex, true, SegmentType::SameOnBoth};
0054             if (r.newSize && r.oldSize)
0055                 r.type = SegmentType::DifferentOnBoth;
0056             else if (r.newSize)
0057                 r.type = SegmentType::OnlyOnRight;
0058             else
0059                 r.type = SegmentType::OnlyOnLeft;
0060             r.success = true;
0061             _ended = true;
0062             return r;
0063         }
0064     }
0065 
0066     if ((i->first == _firstIndex && i->second == _secondIndex)) {
0067         auto fi = _firstIndex;
0068         auto si = _secondIndex;
0069         do {
0070             _firstIndex++;
0071             _secondIndex++;
0072             ++i;
0073         } while (i != _solution.end() && i->first == _firstIndex && i->second == _secondIndex);
0074 
0075         return {fi, _firstIndex - fi, si, _secondIndex - si, true, SegmentType::SameOnBoth};
0076 
0077     } else {
0078         Result r{_firstIndex, i->first - _firstIndex, _secondIndex, i->second - _secondIndex, true, SegmentType::DifferentOnBoth};
0079         _firstIndex = i->first;
0080         _secondIndex = i->second;
0081 
0082         if (r.newSize && r.oldSize)
0083             r.type = SegmentType::DifferentOnBoth;
0084         else if (r.newSize)
0085             r.type = SegmentType::OnlyOnRight;
0086         else
0087             r.type = SegmentType::OnlyOnLeft;
0088         r.success = true;
0089         return r;
0090     }
0091 
0092     return {};
0093 }
0094 QDebug &operator<<(QDebug &stream, const Diff::Solution &sln)
0095 {
0096     for (auto i = sln.begin(); i != sln.end(); ++i)
0097         stream << "(" << i->first << ", " << i->second << ")";
0098     return stream;
0099 }
0100 
0101 QDebug operator<<(QDebug d, const SolutionIterator::Result &r)
0102 {
0103     d.noquote() << "(Old: " << r.oldStart << " size=" << r.oldSize << ", New: " << r.newStart << " size=" << r.newSize << ")";
0104     return d;
0105 }
0106 
0107 SolutionIterator3::SolutionIterator3(const Solution3 &solution)
0108     : _solution(solution)
0109     , i(_solution.begin())
0110 {
0111 }
0112 
0113 void SolutionIterator3::begin()
0114 {
0115     _firstIndex = _secondIndex = _thirdIndex = -1;
0116     i = _solution.begin();
0117 }
0118 
0119 Diff::SolutionIterator3::Result Diff::SolutionIterator3::pick()
0120 {
0121     if (i == _solution.end())
0122         return {};
0123 
0124     if ((i->first == _firstIndex && i->second == _secondIndex && i->third == _thirdIndex)) {
0125         auto fi = _firstIndex;
0126         auto si = _secondIndex;
0127         auto ti = _thirdIndex;
0128         do {
0129             _firstIndex++;
0130             _secondIndex++;
0131             _thirdIndex++;
0132             ++i;
0133         } while (i != _solution.end() && i->first == _firstIndex && i->second == _secondIndex);
0134 
0135         return {{fi, _firstIndex - fi}, {si, _secondIndex - si}, {ti, _thirdIndex - ti}, SegmentType::SameOnBoth};
0136 
0137     } else {
0138         Result r{{_firstIndex, i->first - _firstIndex},
0139                  {_secondIndex, i->second - _secondIndex},
0140                  {_thirdIndex, i->third - _thirdIndex},
0141                  SegmentType::DifferentOnBoth};
0142         _firstIndex = i->first;
0143         _secondIndex = i->second;
0144         _thirdIndex = i->third;
0145 
0146         if (r.local.size && r.remote.size)
0147             r.type = SegmentType::DifferentOnBoth;
0148         else if (r.remote.size)
0149             r.type = SegmentType::OnlyOnRight;
0150         else
0151             r.type = SegmentType::OnlyOnLeft;
0152         r.success = true;
0153         return r;
0154     }
0155 
0156     return {};
0157 }
0158 
0159 SolutionIterator3::Result::Result()
0160     : base{}
0161     , local{}
0162     , remote{}
0163     , success{false}
0164     , type{}
0165 {
0166 }
0167 
0168 Diff::SolutionIterator3::Result::Result(Range base, Range local, Range remote, SegmentType type)
0169     : base{base}
0170     , local{local}
0171     , remote{remote}
0172     , success{true}
0173     , type{type}
0174 {
0175 }
0176 
0177 Range::Range()
0178     : begin{-1}
0179     , size{-1}
0180 {
0181 }
0182 
0183 Range::Range(int begin, int size)
0184     : begin{begin}
0185     , size{size}
0186 {
0187 }
0188 }