summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/BufferedInputStream.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/BufferedInputStream.java')
-rw-r--r--src/com/android/camera/BufferedInputStream.java231
1 files changed, 231 insertions, 0 deletions
diff --git a/src/com/android/camera/BufferedInputStream.java b/src/com/android/camera/BufferedInputStream.java
new file mode 100644
index 0000000..1505e87
--- /dev/null
+++ b/src/com/android/camera/BufferedInputStream.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.camera;
+/*
+* This file derives from the Apache version of the BufferedInputStream.
+* Mods to support passing in the buffer rather than creating one directly.
+*/
+import java.io.InputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+
+public class BufferedInputStream extends FilterInputStream {
+ protected byte[] buf;
+ protected int count;
+ protected int marklimit;
+ protected int markpos = -1;
+ protected int pos;
+
+ private boolean closed = false;
+
+ public BufferedInputStream(InputStream in, byte [] buffer) {
+ super(in);
+ buf = buffer;
+ if (buf == null) {
+ throw new java.security.InvalidParameterException();
+ }
+ }
+
+ @Override
+ public synchronized int available() throws IOException {
+ return count - pos + in.available();
+ }
+
+ @Override
+ public synchronized void close() throws IOException {
+ if (null != in) {
+ super.close();
+ in = null;
+ }
+ buf = null;
+ closed = true;
+ }
+
+ private int fillbuf() throws IOException {
+ if (markpos == -1 || (pos - markpos >= marklimit)) {
+ /* Mark position not set or exceeded readlimit */
+ int result = in.read(buf);
+ if (result > 0) {
+ markpos = -1;
+ pos = 0;
+ count = result == -1 ? 0 : result;
+ }
+ return result;
+ }
+ if (markpos == 0 && marklimit > buf.length) {
+ /* Increase buffer size to accomodate the readlimit */
+ int newLength = buf.length * 2;
+ if (newLength > marklimit) {
+ newLength = marklimit;
+ }
+ byte[] newbuf = new byte[newLength];
+ System.arraycopy(buf, 0, newbuf, 0, buf.length);
+ buf = newbuf;
+ } else if (markpos > 0) {
+ System.arraycopy(buf, markpos, buf, 0, buf.length - markpos);
+ }
+ /* Set the new position and mark position */
+ pos -= markpos;
+ count = markpos = 0;
+ int bytesread = in.read(buf, pos, buf.length - pos);
+ count = bytesread <= 0 ? pos : pos + bytesread;
+ return bytesread;
+ }
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ marklimit = readlimit;
+ markpos = pos;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+ @Override
+ public synchronized int read() throws IOException {
+ if (in == null) {
+ // K0059=Stream is closed
+ throw new IOException(); //$NON-NLS-1$
+ }
+
+ /* Are there buffered bytes available? */
+ if (pos >= count && fillbuf() == -1) {
+ return -1; /* no, fill buffer */
+ }
+
+ /* Did filling the buffer fail with -1 (EOF)? */
+ if (count - pos > 0) {
+ return buf[pos++] & 0xFF;
+ }
+ return -1;
+ }
+
+ @Override
+ public synchronized int read(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (closed) {
+ // K0059=Stream is closed
+ throw new IOException(); //$NON-NLS-1$
+ }
+ // avoid int overflow
+ if (offset > buffer.length - length || offset < 0 || length < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ if (length == 0) {
+ return 0;
+ }
+ if (null == buf) {
+ throw new IOException(); //$NON-NLS-1$
+ }
+
+ int required;
+ if (pos < count) {
+ /* There are bytes available in the buffer. */
+ int copylength = count - pos >= length ? length : count - pos;
+ System.arraycopy(buf, pos, buffer, offset, copylength);
+ pos += copylength;
+ if (copylength == length || in.available() == 0) {
+ return copylength;
+ }
+ offset += copylength;
+ required = length - copylength;
+ } else {
+ required = length;
+ }
+
+ while (true) {
+ int read;
+ /*
+ * If we're not marked and the required size is greater than the
+ * buffer, simply read the bytes directly bypassing the buffer.
+ */
+ if (markpos == -1 && required >= buf.length) {
+ read = in.read(buffer, offset, required);
+ if (read == -1) {
+ return required == length ? -1 : length - required;
+ }
+ } else {
+ if (fillbuf() == -1) {
+ return required == length ? -1 : length - required;
+ }
+ read = count - pos >= required ? required : count - pos;
+ System.arraycopy(buf, pos, buffer, offset, read);
+ pos += read;
+ }
+ required -= read;
+ if (required == 0) {
+ return length;
+ }
+ if (in.available() == 0) {
+ return length - required;
+ }
+ offset += read;
+ }
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ if (closed) {
+ // K0059=Stream is closed
+ throw new IOException(); //$NON-NLS-1$
+ }
+ if (-1 == markpos) {
+ // K005a=Mark has been invalidated.
+ throw new IOException(); //$NON-NLS-1$
+ }
+ pos = markpos;
+ }
+
+ @Override
+ public synchronized long skip(long amount) throws IOException {
+ if (null == in) {
+ // K0059=Stream is closed
+ throw new IOException(); //$NON-NLS-1$
+ }
+ if (amount < 1) {
+ return 0;
+ }
+
+ if (count - pos >= amount) {
+ pos += amount;
+ return amount;
+ }
+ long read = count - pos;
+ pos = count;
+
+ if (markpos != -1) {
+ if (amount <= marklimit) {
+ if (fillbuf() == -1) {
+ return read;
+ }
+ if (count - pos >= amount - read) {
+ pos += amount - read;
+ return amount;
+ }
+ // Couldn't get all the bytes, skip what we read
+ read += (count - pos);
+ pos = count;
+ return read;
+ }
+ markpos = -1;
+ }
+ return read + in.skip(amount - read);
+ }
+}