You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2009/03/30 18:31:16 UTC
svn commit: r760032 -
/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
Author: bodewig
Date: Mon Mar 30 16:31:15 2009
New Revision: 760032
URL: http://svn.apache.org/viewvc?rev=760032&view=rev
Log:
chunking of input by entries in AR-Input, COMPRESS-11
Modified:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java?rev=760032&r1=760031&r2=760032&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java Mon Mar 30 16:31:15 2009
@@ -35,13 +35,42 @@
private final InputStream input;
private long offset = 0;
private boolean closed;
+ /*
+ * If getNextEnxtry has been called, the entry metadata is stored in
+ * currentEntry.
+ */
+ private ArArchiveEntry currentEntry = null;
+ /*
+ * The offset where the current entry started. -1 if no entry has been
+ * called
+ */
+ private long entryOffset = -1;
public ArArchiveInputStream( final InputStream pInput ) {
input = pInput;
closed = false;
}
+ /**
+ * Returns the next AR entry in this stream.
+ *
+ * @return the next AR entry.
+ * @throws IOException
+ * if the entry could not be read
+ */
public ArArchiveEntry getNextArEntry() throws IOException {
+ if (currentEntry != null) {
+ final long entryEnd = entryOffset + currentEntry.getLength();
+ while (offset < entryEnd) {
+ int x = read();
+ if (x == -1) {
+ // hit EOF before previous entry was complete
+ // TODO: throw an exception instead?
+ return null;
+ }
+ }
+ currentEntry = null;
+ }
if (offset == 0) {
final byte[] expected = ArArchiveEntry.HEADER.getBytes();
@@ -57,12 +86,15 @@
}
}
- if (input.available() == 0) {
- return null;
+ if (offset % 2 != 0) {
+ if (read() < 0) {
+ // hit eof
+ return null;
+ }
}
- if (offset % 2 != 0) {
- read();
+ if (input.available() == 0) {
+ return null;
}
final byte[] name = new byte[16];
@@ -93,8 +125,11 @@
}
}
- return new ArArchiveEntry(new String(name).trim(), Long.parseLong(new String(length).trim()));
-
+ entryOffset = offset;
+ currentEntry = new ArArchiveEntry(new String(name).trim(),
+ Long.parseLong(new String(length)
+ .trim()));
+ return currentEntry;
}
@@ -107,20 +142,30 @@
closed = true;
input.close();
}
+ currentEntry = null;
}
public int read() throws IOException {
- final int ret = input.read();
- offset += (ret > 0 ? 1 : 0);
- return ret;
+ byte[] single = new byte[1];
+ int num = read(single, 0, 1);
+ return num == -1 ? -1 : single[0] & 0xff;
}
- public int read(byte b[]) throws IOException {
+ public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
- public int read(byte[] b, int off, int len) throws IOException {
- final int ret = this.input.read(b, off, len);
+ public int read(byte[] b, final int off, final int len) throws IOException {
+ int toRead = len;
+ if (currentEntry != null) {
+ final long entryEnd = entryOffset + currentEntry.getLength();
+ if (len > 0 && entryEnd > offset) {
+ toRead = (int) Math.min(len, entryEnd - offset);
+ } else {
+ return -1;
+ }
+ }
+ final int ret = this.input.read(b, off, toRead);
offset += (ret > 0 ? ret : 0);
return ret;
}