static SnakeWithCharResults ConvertToLines( CompareCharsData data, bool deleted, IList<Snake> chars, Snake lineSnake ) { //Debug.WriteLine( "\nConvertToLines " + ( deleted ? "DELETED" : "INSERTED" ) ); //Debug.WriteLine( data.ToString() ); var list = new List<CharSnake>(); foreach ( var s in chars ) { //Debug.WriteLine( "Char " + s ); int lStart, cStart, lMid, cMid, lEnd, cEnd; data.LineFromChar( deleted ? s.XStart : s.YStart, out lStart, out cStart ); data.LineFromChar( deleted ? s.XMid : s.YMid, out lMid, out cMid ); data.LineFromChar( deleted ? s.XEnd : s.YEnd, out lEnd, out cEnd ); //Debug.WriteLine( "LINE:CHAR Start: " + lStart + ":" + cStart + " Mid: " + lMid + ":" + cMid + " End:" + lEnd + ":" + cEnd ); if ( deleted ? s.ADeleted > 0 : s.BInserted > 0 ) { for ( int l = lStart ; l <= lMid ; l++ ) { var cs = new CharSnake(); cs.Line = l; cs.IsDeleted = deleted; cs.CharStart = ( l == lStart ? cStart : 0 ); var end = ( l == lMid ? cMid : data.LineLength( l ) ); cs.Diff = end - cs.CharStart; cs.IsEOL = data.IsEOL( l, end ); //Debug.WriteLine( "Diff " + cs + " = '" + data.Substring( cs.CharStart, cs.Diff ) + "'" ); if ( cs.Diff > 0 || data.LineLength( l ) == 0 ) list.Add( cs ); } } if ( s.DiagonalLength > 0 ) { for ( int l = lMid ; l <= lEnd ; l++ ) { var cs = new CharSnake(); cs.Line = l; cs.IsDeleted = deleted; cs.CharStart = ( l == lMid ? cMid : 0 ); var end = ( l == lEnd ? cEnd : data.LineLength( l ) ); cs.Same = end - cs.CharStart; cs.IsEOL = data.IsEOL( l, end ); //Debug.WriteLine( "Same " + cs + " = '" + data.Substring( cs.CharStart, cs.Same ) + "'" ); if ( cs.Same > 0 || data.LineLength( l ) == 0 ) list.Add( cs ); } } } return new SnakeWithCharResults( lineSnake, list ); }
//----------------------------------------------------------------------------------------- // CompareChars static IList<SnakeWithCharResults> CompareChars( string[] aa, string[] ab, IList<Snake> lines, bool diffChars, ref V VForward, ref V VReverse ) { var list = new List<SnakeWithCharResults>(); foreach ( var line in lines ) { if ( !diffChars || line.ADeleted == 0 || line.BInserted == 0 ) list.Add( new SnakeWithCharResults( line, null ) ); else { var ca = new CompareCharsData( aa, line.XStart, line.ADeleted ); var cb = new CompareCharsData( ab, line.YStart, line.BInserted ); var charSnakes = new List<Snake>(); EnsureArraySize( ca.Chars.Length, cb.Chars.Length, ref VForward, ref VReverse ); Compare( charSnakes, ca.Chars, ca.Chars.Length, cb.Chars, cb.Chars.Length, VForward, VReverse ); var tmp = MergeSnakes( charSnakes, 0, ca.Chars.Length, 0, cb.Chars.Length ); foreach ( var s in tmp ) for ( int matchLength = 1 ; matchLength <= 3 ; matchLength++ ) if ( s.DiagonalLength == matchLength && s.XStart > 0 && s.XEnd < ca.Chars.Length && s.YEnd < cb.Chars.Length ) { s.ADeleted += matchLength; s.BInserted += matchLength; s.DiagonalLength = 0; } var chars = MergeSnakes( tmp, 0, ca.Chars.Length, 0, cb.Chars.Length ); list.Add( ConvertToLines( ca, true, chars, null ) ); list.Add( ConvertToLines( cb, false, chars, line ) ); } } return list; }