comparison src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java @ 219:d63583b47bfa

ArrayIndexOutOfBoundsException when file appended. Erroneous 'areTheSame' when trailing were deleted.
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 17 May 2011 05:43:09 +0200
parents 047b1dec7a04
children 26ad7827a62d
comparison
equal deleted inserted replaced
218:047b1dec7a04 219:d63583b47bfa
287 FileInputStream fis = null; 287 FileInputStream fis = null;
288 try { 288 try {
289 try { 289 try {
290 fis = new FileInputStream(f); 290 fis = new FileInputStream(f);
291 FileChannel fc = fis.getChannel(); 291 FileChannel fc = fis.getChannel();
292 ByteBuffer fb = ByteBuffer.allocate(min(data.length, 8192)); 292 ByteBuffer fb = ByteBuffer.allocate(min(data.length * 2 /*to fit couple of lines appended*/, 8192));
293 final boolean[] checkValue = new boolean[] { true }; 293 class Check implements ByteChannel {
294 ByteChannel check = new ByteChannel() { 294 final boolean debug = false; // XXX may want to add global variable to allow clients to turn
295 boolean sameSoFar = true;
295 int x = 0; 296 int x = 0;
296 final boolean debug = false; // XXX may want to add global variable to allow clients to turn 297
297 public int write(ByteBuffer buffer) { 298 public int write(ByteBuffer buffer) {
298 for (int i = buffer.remaining(); i > 0; i--, x++) { 299 for (int i = buffer.remaining(); i > 0; i--, x++) {
299 if (data[x] != buffer.get()) { 300 if (x >= data.length /*file has been appended*/ || data[x] != buffer.get()) {
300 if (debug) { 301 if (debug) {
301 byte[] xx = new byte[15]; 302 byte[] xx = new byte[15];
302 if (buffer.position() > 5) { 303 if (buffer.position() > 5) {
303 buffer.position(buffer.position() - 5); 304 buffer.position(buffer.position() - 5);
304 } 305 }
305 buffer.get(xx); 306 buffer.get(xx);
306 System.out.print("expected >>" + new String(data, max(0, x - 4), 20) + "<< but got >>"); 307 System.out.print("expected >>" + new String(data, max(0, x - 4), 20) + "<< but got >>");
307 System.out.println(new String(xx) + "<<"); 308 System.out.println(new String(xx) + "<<");
308 } 309 }
309 checkValue[0] = false; 310 sameSoFar = false;
310 break; 311 break;
311 } 312 }
312 } 313 }
313 buffer.position(buffer.limit()); // mark as read 314 buffer.position(buffer.limit()); // mark as read
314 return buffer.limit(); 315 return buffer.limit();
315 } 316 }
317
318 public boolean sameSoFar() {
319 return sameSoFar;
320 }
321 public boolean ultimatelyTheSame() {
322 return sameSoFar && x == data.length;
323 }
316 }; 324 };
325 Check check = new Check();
317 FilterByteChannel filters = new FilterByteChannel(check, repo.getFiltersFromWorkingDirToRepo(p)); 326 FilterByteChannel filters = new FilterByteChannel(check, repo.getFiltersFromWorkingDirToRepo(p));
318 while (fc.read(fb) != -1 && checkValue[0]) { 327 while (fc.read(fb) != -1 && check.sameSoFar()) {
319 fb.flip(); 328 fb.flip();
320 filters.write(fb); 329 filters.write(fb);
321 fb.compact(); 330 fb.compact();
322 } 331 }
323 return checkValue[0]; 332 return check.ultimatelyTheSame();
324 } catch (IOException ex) { 333 } catch (IOException ex) {
325 if (fis != null) { 334 if (fis != null) {
326 fis.close(); 335 fis.close();
327 } 336 }
328 ex.printStackTrace(); // log warn 337 ex.printStackTrace(); // log warn