diff options
Diffstat (limited to 'src/com/android/camera/BufferedInputStream.java')
-rw-r--r-- | src/com/android/camera/BufferedInputStream.java | 231 |
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); + } +} |