Author: bodewig
Date: Tue Jan 7 17:31:27 2014
New Revision: 1556286
URL: http://svn.apache.org/r1556286
Log:
implement input, this compiles but I'm not sure it works - tests are up next
Added:
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveInput.java
- copied, changed from r1556168,
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/IOUtils.java
- copied, changed from r1556168,
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/IOUtils.java
Modified:
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/archivers/ArchiveInput.java
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveOutput.java
Modified:
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/archivers/ArchiveInput.java
URL:
http://svn.apache.org/viewvc/commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/archivers/ArchiveInput.java?rev=1556286&r1=1556285&r2=1556286&view=diff
==============================================================================
---
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/archivers/ArchiveInput.java
(original)
+++
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/archivers/ArchiveInput.java
Tue Jan 7 17:31:27 2014
@@ -18,13 +18,20 @@
*/
package org.apache.commons.compress2.archivers;
+import java.io.IOException;
import java.nio.channels.ReadableByteChannel;
/**
* A channel that reads {@link ArchiveEntry}s.
* @NotThreadSafe
*/
-public interface ArchiveInput<A extends ArchiveEntry> extends
ReadableByteChannel, Iterable<A> {
+public interface ArchiveInput<A extends ArchiveEntry> extends
ReadableByteChannel {
+
+ /**
+ * Obtains the next entry.
+ * @return the next entry or null if the end of the channel has been
reached.
+ */
+ A next() throws IOException;
/**
* Whether this channel is able to read the contents of the given entry.
Copied:
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveInput.java
(from r1556168,
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java)
URL:
http://svn.apache.org/viewvc/commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveInput.java?p2=commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveInput.java&p1=commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java&r1=1556168&r2=1556286&rev=1556286&view=diff
==============================================================================
---
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveInputStream.java
(original)
+++
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveInput.java
Tue Jan 7 17:31:27 2014
@@ -16,31 +16,36 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.commons.compress.archivers.ar;
+package org.apache.commons.compress2.formats.ar;
import java.io.EOFException;
+import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
-
-import org.apache.commons.compress.archivers.ArchiveEntry;
-import org.apache.commons.compress.archivers.ArchiveInputStream;
-import org.apache.commons.compress.utils.ArchiveUtils;
-import org.apache.commons.compress.utils.IOUtils;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+import org.apache.commons.compress2.archivers.ArchiveEntryParameters;
+import org.apache.commons.compress2.archivers.OwnerInformation;
+import org.apache.commons.compress2.archivers.spi.AbstractArchiveInput;
/**
- * Implements the "ar" archive format as an input stream.
+ * Implements the "ar" archive format.
*
* @NotThreadSafe
*
*/
-public class ArArchiveInputStream extends ArchiveInputStream {
+public class ArArchiveInput extends AbstractArchiveInput<ArArchiveEntry> {
- private final InputStream input;
+ private final WrappedStream wrappedStream;
private long offset = 0;
private boolean closed;
/*
- * If getNextEnxtry has been called, the entry metadata is stored in
+ * If next has been called, the entry metadata is stored in
* currentEntry.
*/
private ArArchiveEntry currentEntry = null;
@@ -62,13 +67,13 @@ public class ArArchiveInputStream extend
private final byte[] LENGTH_BUF = new byte[10];
/**
- * Constructs an Ar input stream with the referenced stream
+ * Constructs an Ar input with the referenced channel
*
* @param pInput
- * the ar input stream
+ * the ar input
*/
- public ArArchiveInputStream(final InputStream pInput) {
- input = pInput;
+ public ArArchiveInput(final ReadableByteChannel pInput) {
+ wrappedStream = new WrappedStream(Channels.newInputStream(pInput));
closed = false;
}
@@ -79,48 +84,49 @@ public class ArArchiveInputStream extend
* @throws IOException
* if the entry could not be read
*/
- public ArArchiveEntry getNextArEntry() throws IOException {
+ @Override
+ public ArArchiveEntry next() throws IOException {
if (currentEntry != null) {
- final long entryEnd = entryOffset + currentEntry.getLength();
- IOUtils.skip(this, entryEnd - offset);
+ final long entryEnd = entryOffset + currentEntry.getSize();
+ IOUtils.skip(wrappedStream, entryEnd - offset);
currentEntry = null;
}
if (offset == 0) {
- final byte[] expected =
ArchiveUtils.toAsciiBytes(ArArchiveEntry.HEADER);
+ final byte[] expected =
StandardCharsets.US_ASCII.encode(ArArchiveEntry.HEADER).array();
final byte[] realized = new byte[expected.length];
- final int read = IOUtils.readFully(this, realized);
+ final int read = IOUtils.readFully(wrappedStream, realized);
if (read != expected.length) {
throw new IOException("failed to read header. Occured at byte:
" + getBytesRead());
}
for (int i = 0; i < expected.length; i++) {
if (expected[i] != realized[i]) {
- throw new IOException("invalid header " +
ArchiveUtils.toAsciiString(realized));
+ throw new IOException("invalid header " +
toAsciiString(realized));
}
}
}
- if (offset % 2 != 0 && read() < 0) {
+ if (offset % 2 != 0 && wrappedStream.read() < 0) {
// hit eof
return null;
}
- if (input.available() == 0) {
+ if (wrappedStream.available() == 0) {
return null;
}
- IOUtils.readFully(this, NAME_BUF);
- IOUtils.readFully(this, LAST_MODIFIED_BUF);
- IOUtils.readFully(this, ID_BUF);
+ IOUtils.readFully(wrappedStream, NAME_BUF);
+ IOUtils.readFully(wrappedStream, LAST_MODIFIED_BUF);
+ IOUtils.readFully(wrappedStream, ID_BUF);
int userId = asInt(ID_BUF, true);
- IOUtils.readFully(this, ID_BUF);
- IOUtils.readFully(this, FILE_MODE_BUF);
- IOUtils.readFully(this, LENGTH_BUF);
+ IOUtils.readFully(wrappedStream, ID_BUF);
+ IOUtils.readFully(wrappedStream, FILE_MODE_BUF);
+ IOUtils.readFully(wrappedStream, LENGTH_BUF);
{
- final byte[] expected =
ArchiveUtils.toAsciiBytes(ArArchiveEntry.TRAILER);
+ final byte[] expected =
StandardCharsets.US_ASCII.encode(ArArchiveEntry.TRAILER).array();
final byte[] realized = new byte[expected.length];
- final int read = IOUtils.readFully(this, realized);
+ final int read = IOUtils.readFully(wrappedStream, realized);
if (read != expected.length) {
throw new IOException("failed to read entry trailer. Occured
at byte: " + getBytesRead());
}
@@ -136,10 +142,10 @@ public class ArArchiveInputStream extend
// GNU ar uses a '/' to mark the end of the filename; this allows for
the use of spaces without the use of an extended filename.
// entry name is stored as ASCII string
- String temp = ArchiveUtils.toAsciiString(NAME_BUF).trim();
+ String temp = toAsciiString(NAME_BUF).trim();
if (isGNUStringTable(temp)) { // GNU extended filenames entry
currentEntry = readGNUStringTable(LENGTH_BUF);
- return getNextArEntry();
+ return next();
}
long len = asLong(LENGTH_BUF);
@@ -158,10 +164,10 @@ public class ArArchiveInputStream extend
entryOffset += nameLen;
}
- currentEntry = new ArArchiveEntry(temp, len, userId,
- asInt(ID_BUF, true),
- asInt(FILE_MODE_BUF, 8),
- asLong(LAST_MODIFIED_BUF));
+ currentEntry = new ArArchiveEntry(new
ArchiveEntryParameters().withName(temp).withSize(len)
+ .withOwnerInformation(new
OwnerInformation(userId, asInt(ID_BUF, true)))
+ .withLastModifiedDate(new
Date(asLong(LAST_MODIFIED_BUF))),
+ asInt(FILE_MODE_BUF, 8));
return currentEntry;
}
@@ -181,13 +187,13 @@ public class ArArchiveInputStream extend
if (namebuffer[i-1]=='/') {
i--; // drop trailing /
}
- return ArchiveUtils.toAsciiString(namebuffer, offset,
i-offset);
+ return toAsciiString(namebuffer, offset, i-offset);
}
}
throw new IOException("Failed to read entry: "+offset);
}
private long asLong(byte[] input) {
- return Long.parseLong(ArchiveUtils.toAsciiString(input).trim());
+ return Long.parseLong(toAsciiString(input).trim());
}
private int asInt(byte[] input) {
@@ -203,38 +209,46 @@ public class ArArchiveInputStream extend
}
private int asInt(byte[] input, int base, boolean treatBlankAsZero) {
- String string = ArchiveUtils.toAsciiString(input).trim();
+ String string = toAsciiString(input).trim();
if (string.length() == 0 && treatBlankAsZero) {
return 0;
}
return Integer.parseInt(string, base);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.apache.commons.compress.archivers.ArchiveInputStream#getNextEntry()
- */
- @Override
- public ArchiveEntry getNextEntry() throws IOException {
- return getNextArEntry();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.io.InputStream#close()
- */
@Override
public void close() throws IOException {
if (!closed) {
closed = true;
- input.close();
+ wrappedStream.close();
}
currentEntry = null;
}
+ @Override
+ public boolean isOpen() {
+ return !closed;
+ }
+
+ @Override
+ public int read(ByteBuffer b) throws IOException {
+ byte[] tmp = new byte[b.remaining()];
+ int read = wrappedStream.read(tmp);
+ if (read > 0) {
+ b.put(tmp, 0, read);
+ }
+ return read;
+ }
+
+ private class WrappedStream extends FilterInputStream {
+ private WrappedStream(InputStream i) {
+ super(i);
+ }
+
+ private InputStream getIn() {
+ return in;
+ }
+
/*
* (non-Javadoc)
*
@@ -244,19 +258,29 @@ public class ArArchiveInputStream extend
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();
+ final long entryEnd = entryOffset + currentEntry.getSize();
if (len > 0 && entryEnd > offset) {
toRead = (int) Math.min(len, entryEnd - offset);
} else {
return -1;
}
}
- final int ret = this.input.read(b, off, toRead);
+ final int ret = in.read(b, off, toRead);
count(ret);
offset += ret > 0 ? ret : 0;
return ret;
}
+ private final byte[] SINGLE = new byte[1];
+ private static final int BYTE_MASK = 0xFF;
+
+ @Override
+ public int read() throws IOException {
+ int num = read(SINGLE, 0, 1);
+ return num == -1 ? -1 : SINGLE[0] & BYTE_MASK;
+ }
+ }
+
/**
* Checks if the signature matches ASCII "!<arch>" followed by a
single LF
* control character
@@ -326,8 +350,6 @@ public class ArArchiveInputStream extend
* sum of the size of the file name and the size of
* the member.
* </pre>
- *
- * @since 1.3
*/
private static boolean isBSDLongName(String name) {
return name != null && name.matches(BSD_LONGNAME_PATTERN);
@@ -338,19 +360,17 @@ public class ArArchiveInputStream extend
* first bytes to be read are the real file name.
*
* @see #isBSDLongName
- *
- * @since 1.3
*/
private String getBSDLongName(String bsdLongName) throws IOException {
int nameLen =
Integer.parseInt(bsdLongName.substring(BSD_LONGNAME_PREFIX_LEN));
byte[] name = new byte[nameLen];
- int read = IOUtils.readFully(input, name);
+ int read = IOUtils.readFully(wrappedStream.getIn(), name);
count(read);
if (read != nameLen) {
throw new EOFException();
}
- return ArchiveUtils.toAsciiString(name);
+ return toAsciiString(name);
}
private static final String GNU_STRING_TABLE_NAME = "//";
@@ -384,12 +404,12 @@ public class ArArchiveInputStream extend
private ArArchiveEntry readGNUStringTable(byte[] length) throws
IOException {
int bufflen = asInt(length); // Assume length will fit in an int
namebuffer = new byte[bufflen];
- int read = read(namebuffer, 0, bufflen);
+ int read = wrappedStream.read(namebuffer, 0, bufflen);
if (read != bufflen){
throw new IOException("Failed to read complete // record:
expected="
+ bufflen + " read=" + read);
}
- return new ArArchiveEntry(GNU_STRING_TABLE_NAME, bufflen);
+ return new ArArchiveEntry(new
ArchiveEntryParameters().withName(GNU_STRING_TABLE_NAME).withSize(bufflen));
}
private static final String GNU_LONGNAME_PATTERN = "^/\\d+";
@@ -403,4 +423,12 @@ public class ArArchiveInputStream extend
private boolean isGNULongName(String name) {
return name != null && name.matches(GNU_LONGNAME_PATTERN);
}
+
+ private static String toAsciiString(byte[] b) {
+ return toAsciiString(b, 0, b.length);
+ }
+
+ private static String toAsciiString(byte[] b, int offset, int length) {
+ return StandardCharsets.US_ASCII.decode(ByteBuffer.wrap(b, offset,
length)).toString();
+ }
}
Modified:
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveOutput.java
URL:
http://svn.apache.org/viewvc/commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveOutput.java?rev=1556286&r1=1556285&r2=1556286&view=diff
==============================================================================
---
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveOutput.java
(original)
+++
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/ArArchiveOutput.java
Tue Jan 7 17:31:27 2014
@@ -27,7 +27,7 @@ import org.apache.commons.compress2.arch
import org.apache.commons.compress2.archivers.spi.AbstractArchiveOutput;
/**
- * Implements the "ar" archive format as an output stream.
+ * Implements the "ar" archive format.
*
* @NotThreadSafe
*/
Copied:
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/IOUtils.java
(from r1556168,
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/IOUtils.java)
URL:
http://svn.apache.org/viewvc/commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/IOUtils.java?p2=commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/IOUtils.java&p1=commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/IOUtils.java&r1=1556168&r2=1556286&rev=1556286&view=diff
==============================================================================
---
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/utils/IOUtils.java
(original)
+++
commons/proper/compress/branches/compress-2.0/src/main/java/org/apache/commons/compress2/formats/ar/IOUtils.java
Tue Jan 7 17:31:27 2014
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.commons.compress.utils;
+package org.apache.commons.compress2.formats.ar;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -25,10 +25,10 @@ import java.io.InputStream;
import java.io.OutputStream;
/**
- * Utility functions
+ * THIS CLASS WILL CERTAINLY NOT STAY HERE.
* @Immutable
*/
-public final class IOUtils {
+final class IOUtils {
/** Private constructor to prevent instantiation of this utility class. */
private IOUtils(){