1 11 package org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer; 12 13 import org.eclipse.jface.text.*; 14 15 23 public final class DocLineComparator implements IRangeComparator { 24 25 28 public static class DocumentCharSequence implements CharSequence { 29 30 31 private IDocument fDocument; 32 33 34 private int fOffset; 35 36 37 private int fLength; 38 39 43 public DocumentCharSequence() { 44 } 46 47 55 public DocumentCharSequence(IDocument document, int offset, int length) { 56 fDocument= document; 57 fOffset= offset; 58 fLength= length; 59 } 60 61 64 public int length() { 65 return fLength; 66 } 67 68 71 public char charAt(int index) { 72 try { 73 return fDocument.getChar(fOffset + index); 74 } catch (BadLocationException e) { 75 throw new IndexOutOfBoundsException (); 76 } 77 } 78 79 82 public CharSequence subSequence(int start, int end) { 83 return new DocumentCharSequence(fDocument, start, end - start); 84 } 85 86 87 90 public int hashCode() { 91 int hash= 0; 92 for (int i= 0, n= fLength; i < n; i++) 93 hash= 29*hash + charAt(i); 94 return hash; 95 } 96 97 98 101 public boolean equals(Object obj) { 102 if (obj == this) 103 return true; 104 if (!(obj instanceof DocumentCharSequence)) 105 return false; 106 DocumentCharSequence buffer= (DocumentCharSequence) obj; 107 int length= buffer.length(); 108 if (length != fLength) 109 return false; 110 for (int i= 0; i < length; i++) 111 if (buffer.charAt(i) != charAt(i)) 112 return false; 113 return true; 114 } 115 116 121 public void setDocument(IDocument document) { 122 fDocument= document; 123 } 124 125 130 public void setOffset(int offset) { 131 fOffset= offset; 132 } 133 134 139 public void setLength(int length) { 140 fLength= length; 141 } 142 } 143 144 private final IDocument fDocument; 145 private final int fLineOffset; 146 private final int fLineCount; 147 private final int fLength; 148 private final boolean fIgnoreWhiteSpace; 149 private final int fMaxOffset; 150 151 152 private boolean fSkip= false; 153 private int fLastOffset; 154 private int fLastLength; 155 156 157 private DocumentCharSequence fThisBuffer= new DocumentCharSequence(); 158 159 private DocumentCharSequence fOtherBuffer= new DocumentCharSequence(); 160 161 170 public DocLineComparator(IDocument document, IRegion region, boolean ignoreWhiteSpace) { 171 172 fDocument= document; 173 fIgnoreWhiteSpace= ignoreWhiteSpace; 174 175 if (region != null) { 176 fLength= region.getLength(); 177 int start= region.getOffset(); 178 int lineOffset= 0; 179 try { 180 lineOffset= fDocument.getLineOfOffset(start); 181 } catch (BadLocationException ex) { 182 } 183 fLineOffset= lineOffset; 184 185 fMaxOffset= start + fLength; 186 187 if (fLength == 0) 188 fLineCount= 0; 189 else { 190 int endLine= fDocument.getNumberOfLines(); 191 try { 192 endLine= fDocument.getLineOfOffset(start + fLength); 193 } catch (BadLocationException ex) { 194 } 195 fLineCount= endLine - fLineOffset + 1; 196 } 197 198 } else { 199 fLineOffset= 0; 200 fLength= document.getLength(); 201 fLineCount= fDocument.getNumberOfLines(); 202 fMaxOffset= fDocument.getLength(); 203 } 204 } 205 206 211 public int getRangeCount() { 212 return fLineCount; 213 } 214 215 221 private int getLineLength(int line) { 222 if (line >= fLineCount) 223 return 0; 224 try { 225 int docLine= fLineOffset + line; 226 String delim= fDocument.getLineDelimiter(docLine); 227 int length= fDocument.getLineLength(docLine) - (delim == null ? 0 : delim.length()); 228 if (line == fLineCount - 1) { 229 fLastOffset= fDocument.getLineOffset(docLine); 230 fLastLength= Math.min(length, fMaxOffset - fLastOffset); 231 } else { 232 fLastOffset= -1; 233 fLastLength= length; 234 } 235 return fLastLength; 236 } catch (BadLocationException e) { 237 fLastOffset= 0; 238 fLastLength= 0; 239 fSkip= true; 240 return 0; 241 } 242 } 243 244 253 public boolean rangesEqual(int thisIndex, IRangeComparator other, int otherIndex) { 254 255 if (other != null && other.getClass() == getClass()) { 256 DocLineComparator dlc= (DocLineComparator) other; 257 258 if (fIgnoreWhiteSpace) { 259 extract(thisIndex, fThisBuffer); 260 dlc.extract(otherIndex, fOtherBuffer); 261 return compare(fThisBuffer, fOtherBuffer); 262 } 263 264 int tlen= getLineLength(thisIndex); 265 int olen= dlc.getLineLength(otherIndex); 266 if (tlen == olen) { 267 extract(thisIndex, fThisBuffer); 268 dlc.extract(otherIndex, fOtherBuffer); 269 return fThisBuffer.equals(fOtherBuffer); 270 } 271 272 } 273 return false; 274 } 275 276 284 public boolean skipRangeComparison(int length, int max, IRangeComparator other) { 285 return fSkip; 286 } 287 288 290 297 private void extract(int line, DocumentCharSequence buffer) { 298 if (line < fLineCount) { 299 try { 300 int docLine= fLineOffset + line; 301 if (fLastOffset == -1) 302 fLastOffset= fDocument.getLineOffset(docLine); 303 304 buffer.setDocument(fDocument); 305 buffer.setOffset(fLastOffset); 306 buffer.setLength(fLastLength); 307 return; 308 } catch(BadLocationException e) { 309 fSkip= true; 310 } 311 } 312 buffer.setDocument(fDocument); 313 buffer.setOffset(0); 314 buffer.setLength(0); 315 } 316 317 private boolean compare(CharSequence s1, CharSequence s2) { 318 int l1= s1.length(); 319 int l2= s2.length(); 320 int c1= 0, c2= 0; 321 int i1= 0, i2= 0; 322 323 while (c1 != -1) { 324 325 c1= -1; 326 while (i1 < l1) { 327 char c= s1.charAt(i1++); 328 if (! Character.isWhitespace(c)) { 329 c1= c; 330 break; 331 } 332 } 333 334 c2= -1; 335 while (i2 < l2) { 336 char c= s2.charAt(i2++); 337 if (! Character.isWhitespace(c)) { 338 c2= c; 339 break; 340 } 341 } 342 343 if (c1 != c2) 344 return false; 345 } 346 return true; 347 } 348 349 } 350 351 | Popular Tags |