30 std::vector<wxString> lines;
32 auto appendLine = [&lines]( std::string aLine )
34 if( !aLine.empty() && aLine.back() ==
'\r' )
37 wxString
text = wxString::FromUTF8( aLine.c_str(), aLine.size() );
39 if(
text.IsEmpty() && !aLine.empty() )
40 text = wxString::From8BitData( aLine.c_str(), aLine.size() );
42 lines.push_back(
text );
47 while( start <= aContent.size() )
49 size_t end = aContent.find(
'\n', start );
51 if(
end == std::string::npos )
54 if( start < aContent.size() )
55 appendLine( aContent.substr( start ) );
60 appendLine( aContent.substr( start,
end - start ) );
77std::vector<TEXT_DIFF_LINE>
BuildTextDiff(
const std::vector<wxString>& aOld,
const std::vector<wxString>& aNew )
79 std::vector<TEXT_DIFF_LINE>
result;
83 while( prefix < aOld.size() && prefix < aNew.size() && aOld[prefix] == aNew[prefix] )
88 while( suffix < aOld.size() - prefix && suffix < aNew.size() - prefix
89 && aOld[aOld.size() - 1 - suffix] == aNew[aNew.size() - 1 - suffix] )
94 for(
size_t i = 0; i < prefix; i++ )
95 result.push_back( { TEXT_DIFF_KIND::CONTEXT, aOld[i] } );
97 size_t n = aOld.size() - prefix - suffix;
98 size_t m = aNew.size() - prefix - suffix;
102 const size_t maxCells = 4000000;
103 const size_t rows = n + 1;
104 const size_t stride = m + 1;
106 if( n > 0 && m > 0 && rows <= maxCells / stride )
108 std::vector<unsigned> lcs( rows * stride, 0 );
110 auto cell = [&lcs, stride](
size_t aRow,
size_t aCol ) ->
unsigned&
112 return lcs[aRow * stride + aCol];
115 for(
size_t i = n; i-- > 0; )
117 for(
size_t j = m; j-- > 0; )
119 if( aOld[prefix + i] == aNew[prefix + j] )
120 cell( i, j ) = cell( i + 1, j + 1 ) + 1;
122 cell( i, j ) = std::max( cell( i + 1, j ), cell( i, j + 1 ) );
128 while( i < n && j < m )
130 if( aOld[prefix + i] == aNew[prefix + j] )
136 else if( cell( i + 1, j ) >= cell( i, j + 1 ) )
149 result.push_back( { TEXT_DIFF_KIND::REMOVED, aOld[prefix + i] } );
152 result.push_back( { TEXT_DIFF_KIND::ADDED, aNew[prefix + j] } );
156 for(
size_t i = 0; i < n; i++ )
157 result.push_back( { TEXT_DIFF_KIND::REMOVED, aOld[prefix + i] } );
159 for(
size_t j = 0; j < m; j++ )
160 result.push_back( { TEXT_DIFF_KIND::ADDED, aNew[prefix + j] } );
163 for(
size_t i = aOld.size() - suffix; i < aOld.size(); i++ )
std::vector< TEXT_DIFF_LINE > BuildTextDiff(const std::vector< wxString > &aOld, const std::vector< wxString > &aNew)
Every line of both sides appears once. There are no hunks and nothing is elided.
wxString result
Test unit parsing edge cases and error handling.