summaryrefslogtreecommitdiffstats
path: root/luni/src/main/java/javax/crypto/CipherInputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/main/java/javax/crypto/CipherInputStream.java')
-rw-r--r--luni/src/main/java/javax/crypto/CipherInputStream.java73
1 files changed, 44 insertions, 29 deletions
diff --git a/luni/src/main/java/javax/crypto/CipherInputStream.java b/luni/src/main/java/javax/crypto/CipherInputStream.java
index f2f59c1..3061655 100644
--- a/luni/src/main/java/javax/crypto/CipherInputStream.java
+++ b/luni/src/main/java/javax/crypto/CipherInputStream.java
@@ -17,6 +17,7 @@
package javax.crypto;
+import java.io.BufferedInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -34,11 +35,8 @@ import libcore.io.Streams;
* CipherInputStream} tries to read the data an decrypt them before returning.
*/
public class CipherInputStream extends FilterInputStream {
-
- private static final int I_BUFFER_SIZE = 20;
-
private final Cipher cipher;
- private final byte[] inputBuffer = new byte[I_BUFFER_SIZE];
+ private final byte[] inputBuffer;
private byte[] outputBuffer;
private int outputIndex; // index of the first byte to return from outputBuffer
private int outputLength; // count of the bytes to return from outputBuffer
@@ -60,6 +58,11 @@ public class CipherInputStream extends FilterInputStream {
public CipherInputStream(InputStream is, Cipher c) {
super(is);
this.cipher = c;
+ int blockSize = Math.max(c.getBlockSize(), 1);
+ int bufferSize = Math.max(blockSize,
+ BufferedInputStream.DEFAULT_BUFFER_SIZE / blockSize * blockSize);
+ inputBuffer = new byte[bufferSize];
+ outputBuffer = new byte[bufferSize + ((blockSize > 1) ? 2 * blockSize : 0)];
}
/**
@@ -76,19 +79,13 @@ public class CipherInputStream extends FilterInputStream {
}
/**
- * Reads the next byte from this cipher input stream.
- *
- * @return the next byte, or {@code -1} if the end of the stream is reached.
- * @throws IOException
- * if an error occurs.
+ * Attempts to fill the input buffer and process some data through the
+ * cipher. Returns {@code true} if output from the cipher is available to
+ * use.
*/
- @Override
- public int read() throws IOException {
+ private boolean fillBuffer() throws IOException {
if (finished) {
- return (outputIndex == outputLength) ? -1 : outputBuffer[outputIndex++] & 0xFF;
- }
- if (outputIndex < outputLength) {
- return outputBuffer[outputIndex++] & 0xFF;
+ return false;
}
outputIndex = 0;
outputLength = 0;
@@ -107,7 +104,7 @@ public class CipherInputStream extends FilterInputStream {
throw new IOException("Error while finalizing cipher", e);
}
finished = true;
- break;
+ return outputLength != 0;
}
try {
outputLength = cipher.update(inputBuffer, 0, byteCount, outputBuffer, 0);
@@ -115,7 +112,25 @@ public class CipherInputStream extends FilterInputStream {
throw new AssertionError(e); // should not happen since we sized with getOutputSize
}
}
- return read();
+ return true;
+ }
+
+ /**
+ * Reads the next byte from this cipher input stream.
+ *
+ * @return the next byte, or {@code -1} if the end of the stream is reached.
+ * @throws IOException
+ * if an error occurs.
+ */
+ @Override
+ public int read() throws IOException {
+ if (in == null) {
+ throw new NullPointerException("in == null");
+ }
+ if (outputIndex == outputLength && !fillBuffer()) {
+ return -1;
+ }
+ return outputBuffer[outputIndex++] & 0xFF;
}
/**
@@ -137,18 +152,18 @@ public class CipherInputStream extends FilterInputStream {
if (in == null) {
throw new NullPointerException("in == null");
}
-
- int i;
- for (i = 0; i < len; ++i) {
- int b = read();
- if (b == -1) {
- return (i == 0) ? -1 : i;
- }
- if (buf != null) {
- buf[off+i] = (byte) b;
- }
+ if (outputIndex == outputLength && !fillBuffer()) {
+ return -1;
+ }
+ int available = outputLength - outputIndex;
+ if (available < len) {
+ len = available;
+ }
+ if (buf != null) {
+ System.arraycopy(outputBuffer, outputIndex, buf, off, len);
}
- return i;
+ outputIndex += len;
+ return len;
}
@Override
@@ -158,7 +173,7 @@ public class CipherInputStream extends FilterInputStream {
@Override
public int available() throws IOException {
- return 0;
+ return outputLength - outputIndex;
}
/**