michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0:
michael@0: package org.mozilla.gecko.background.bagheera;
michael@0:
michael@0: import java.io.ByteArrayInputStream;
michael@0: import java.io.IOException;
michael@0: import java.io.InputStream;
michael@0: import java.io.OutputStream;
michael@0:
michael@0: import ch.boye.httpclientandroidlib.entity.AbstractHttpEntity;
michael@0: import ch.boye.httpclientandroidlib.entity.ByteArrayEntity;
michael@0:
michael@0: /**
michael@0: * An entity that acts like {@link ByteArrayEntity}, but exposes a window onto
michael@0: * the byte array that is a subsection of the array. The purpose of this is to
michael@0: * allow a smaller entity to be created without having to resize the source
michael@0: * array.
michael@0: */
michael@0: public class BoundedByteArrayEntity extends AbstractHttpEntity implements
michael@0: Cloneable {
michael@0: protected final byte[] content;
michael@0: protected final int start;
michael@0: protected final int end;
michael@0: protected final int length;
michael@0:
michael@0: /**
michael@0: * Create a new entity that behaves exactly like a {@link ByteArrayEntity}
michael@0: * created with a copy of b
truncated to (
michael@0: * end - start
) bytes, starting at start
.
michael@0: *
michael@0: * @param b the byte array to use.
michael@0: * @param start the start index.
michael@0: * @param end the end index.
michael@0: */
michael@0: public BoundedByteArrayEntity(final byte[] b, final int start, final int end) {
michael@0: if (b == null) {
michael@0: throw new IllegalArgumentException("Source byte array may not be null.");
michael@0: }
michael@0:
michael@0: if (end < start ||
michael@0: start < 0 ||
michael@0: end < 0 ||
michael@0: start > b.length ||
michael@0: end > b.length) {
michael@0: throw new IllegalArgumentException("Bounds out of range.");
michael@0: }
michael@0: this.content = b;
michael@0: this.start = start;
michael@0: this.end = end;
michael@0: this.length = end - start;
michael@0: }
michael@0:
michael@0: @Override
michael@0: public boolean isRepeatable() {
michael@0: return true;
michael@0: }
michael@0:
michael@0: @Override
michael@0: public long getContentLength() {
michael@0: return this.length;
michael@0: }
michael@0:
michael@0: @Override
michael@0: public InputStream getContent() {
michael@0: return new ByteArrayInputStream(this.content, this.start, this.length);
michael@0: }
michael@0:
michael@0: @Override
michael@0: public void writeTo(final OutputStream outstream) throws IOException {
michael@0: if (outstream == null) {
michael@0: throw new IllegalArgumentException("Output stream may not be null.");
michael@0: }
michael@0: outstream.write(this.content);
michael@0: outstream.flush();
michael@0: }
michael@0:
michael@0: @Override
michael@0: public boolean isStreaming() {
michael@0: return false;
michael@0: }
michael@0:
michael@0: @Override
michael@0: public Object clone() throws CloneNotSupportedException {
michael@0: return super.clone();
michael@0: }
michael@0: }