Mercurial > hg4j
annotate src/org/tmatesoft/hg/internal/InflaterDataAccess.java @ 507:a6435c1a42d0
Test for HgChangesetTreeHandler - make sure nothing is broken prior to adding --follow support
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 12 Dec 2012 14:17:12 +0100 |
parents | 2a08466838d3 |
children | 8bf184c9d733 |
rev | line source |
---|---|
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
1 /* |
420
6c22bdc0bdfd
Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
399
diff
changeset
|
2 * Copyright (c) 2011-2012 TMate Software Ltd |
157
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
3 * |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
4 * This program is free software; you can redistribute it and/or modify |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
6 * the Free Software Foundation; version 2 of the License. |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
7 * |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
8 * This program is distributed in the hope that it will be useful, |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
11 * GNU General Public License for more details. |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
12 * |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
13 * For information on how to redistribute this software under |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
14 * the terms of a license other than GNU General Public License |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
15 * contact TMate Software at support@hg4j.com |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
16 */ |
157
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
17 package org.tmatesoft.hg.internal; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
18 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
19 import java.io.EOFException; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
20 import java.io.IOException; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
21 import java.util.zip.DataFormatException; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
22 import java.util.zip.Inflater; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
23 import java.util.zip.ZipException; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
24 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
25 /** |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
26 * DataAccess counterpart for InflaterInputStream. |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
27 * XXX is it really needed to be subclass of FilterDataAccess? |
157
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
28 * |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
29 * @author Artem Tikhomirov |
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
30 * @author TMate Software Ltd. |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
31 */ |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
32 public class InflaterDataAccess extends FilterDataAccess { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
33 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
34 private final Inflater inflater; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
35 private final byte[] buffer; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
36 private final byte[] singleByte = new byte[1]; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
37 private int decompressedPos = 0; |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
38 private int decompressedLength; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
39 |
420
6c22bdc0bdfd
Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
399
diff
changeset
|
40 public InflaterDataAccess(DataAccess dataAccess, long offset, int compressedLength) { |
263
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
41 this(dataAccess, offset, compressedLength, -1, new Inflater(), new byte[512]); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
42 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
43 |
420
6c22bdc0bdfd
Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
399
diff
changeset
|
44 public InflaterDataAccess(DataAccess dataAccess, long offset, int compressedLength, int actualLength) { |
263
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
45 this(dataAccess, offset, compressedLength, actualLength, new Inflater(), new byte[512]); |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
46 } |
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
47 |
420
6c22bdc0bdfd
Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
399
diff
changeset
|
48 public InflaterDataAccess(DataAccess dataAccess, long offset, int compressedLength, int actualLength, Inflater inflater, byte[] buf) { |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
49 super(dataAccess, offset, compressedLength); |
263
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
50 if (inflater == null || buf == null) { |
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
51 throw new IllegalArgumentException(); |
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
52 } |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
53 this.inflater = inflater; |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
54 this.decompressedLength = actualLength; |
263
31f67be94e71
RevlogStream - reduce number of object instances, reuse when possible
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
158
diff
changeset
|
55 buffer = buf; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
56 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
57 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
58 @Override |
157
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
59 public InflaterDataAccess reset() throws IOException { |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
60 super.reset(); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
61 inflater.reset(); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
62 decompressedPos = 0; |
157
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
63 return this; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
64 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
65 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
66 @Override |
421
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
67 protected int available() throws IOException { |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
68 return length() - decompressedPos; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
69 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
70 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
71 @Override |
421
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
72 public boolean isEmpty() throws IOException { |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
73 // can't use super.available() <= 0 because even when 0 < super.count < 6(?) |
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
74 // decompressedPos might be already == length() |
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
75 return available() <= 0; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
76 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
77 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
78 @Override |
421
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
79 public int length() throws IOException { |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
80 if (decompressedLength != -1) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
81 return decompressedLength; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
82 } |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
83 decompressedLength = 0; // guard to avoid endless loop in case length() would get invoked from below. |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
84 int c = 0; |
421
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
85 int oldPos = decompressedPos; |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
86 byte[] dummy = new byte[buffer.length]; |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
87 int toRead; |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
88 while ((toRead = super.available()) > 0) { |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
89 if (toRead > buffer.length) { |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
90 toRead = buffer.length; |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
91 } |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
92 super.readBytes(buffer, 0, toRead); |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
93 inflater.setInput(buffer, 0, toRead); |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
94 try { |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
95 while (!inflater.needsInput()) { |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
96 c += inflater.inflate(dummy, 0, dummy.length); |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
97 } |
421
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
98 } catch (DataFormatException ex) { |
441
2a08466838d3
Don't use methods not available in Java 5
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
423
diff
changeset
|
99 throw new IOException(ex.toString()); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
100 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
101 } |
421
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
102 decompressedLength = c + oldPos; |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
103 reset(); |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
104 seek(oldPos); |
fdd7d756dea0
Allow IOException from DataAccess methods for subclasses with non-trivial implementations, to avoid exception dumps when inapropriate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
420
diff
changeset
|
105 return decompressedLength; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
106 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
107 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
108 @Override |
158
b413b16d10a5
Integer offsets and file length explictly, rather than casts throughout code. Inflater may benefit from total length hint, but shall calculate it by its own if needed
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
157
diff
changeset
|
109 public void seek(int localOffset) throws IOException { |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
110 if (localOffset < 0 /* || localOffset >= length() */) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
111 throw new IllegalArgumentException(); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
112 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
113 if (localOffset >= decompressedPos) { |
420
6c22bdc0bdfd
Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
399
diff
changeset
|
114 skip(localOffset - decompressedPos); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
115 } else { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
116 reset(); |
420
6c22bdc0bdfd
Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
399
diff
changeset
|
117 skip(localOffset); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
118 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
119 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
120 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
121 @Override |
391
856517285256
Provide more details about exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
263
diff
changeset
|
122 public void skip(final int bytesToSkip) throws IOException { |
856517285256
Provide more details about exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
263
diff
changeset
|
123 int bytes = bytesToSkip; |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
124 if (bytes < 0) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
125 bytes += decompressedPos; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
126 if (bytes < 0) { |
391
856517285256
Provide more details about exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
263
diff
changeset
|
127 throw new IOException(String.format("Underflow. Rewind past start of the slice. To skip:%d, decPos:%d, decLen:%d. Left:%d", bytesToSkip, decompressedPos, decompressedLength, bytes)); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
128 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
129 reset(); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
130 // fall-through |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
131 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
132 while (!isEmpty() && bytes > 0) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
133 readByte(); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
134 bytes--; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
135 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
136 if (bytes != 0) { |
391
856517285256
Provide more details about exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
263
diff
changeset
|
137 throw new IOException(String.format("Underflow. Rewind past end of the slice. To skip:%d, decPos:%d, decLen:%d. Left:%d", bytesToSkip, decompressedPos, decompressedLength, bytes)); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
138 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
139 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
140 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
141 @Override |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
142 public byte readByte() throws IOException { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
143 readBytes(singleByte, 0, 1); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
144 return singleByte[0]; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
145 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
146 |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
147 @Override |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
148 public void readBytes(byte[] b, int off, int len) throws IOException { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
149 try { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
150 int n; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
151 while (len > 0) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
152 while ((n = inflater.inflate(b, off, len)) == 0) { |
399
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
153 // XXX few last bytes (checksum?) may be ignored by inflater, thus inflate may return 0 in |
157
d5268ca7715b
Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
51
diff
changeset
|
154 // perfectly legal conditions (when all data already expanded, but there are still some bytes |
399
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
155 // in the input stream) |
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
156 int toRead = -1; |
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
157 if (inflater.needsInput() && (toRead = super.available()) > 0) { |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
158 // fill: |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
159 if (toRead > buffer.length) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
160 toRead = buffer.length; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
161 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
162 super.readBytes(buffer, 0, toRead); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
163 inflater.setInput(buffer, 0, toRead); |
399
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
164 } else { |
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
165 // prevent hang up in this cycle if no more data is available, see Issue 25 |
fdc1db8f7f61
Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
391
diff
changeset
|
166 throw new EOFException(String.format("No more compressed data is available to satisfy request for %d bytes. [finished:%b, needDict:%b, needInp:%b, available:%d", len, inflater.finished(), inflater.needsDictionary(), inflater.needsInput(), toRead)); |
51
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
167 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
168 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
169 off += n; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
170 len -= n; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
171 decompressedPos += n; |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
172 if (len == 0) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
173 return; // filled |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
174 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
175 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
176 } catch (DataFormatException e) { |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
177 String s = e.getMessage(); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
178 throw new ZipException(s != null ? s : "Invalid ZLIB data format"); |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
179 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
180 } |
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff
changeset
|
181 } |