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: }