mobile/android/thirdparty/ch/boye/httpclientandroidlib/util/ByteArrayBuffer.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 * ====================================================================
michael@0 3 * Licensed to the Apache Software Foundation (ASF) under one
michael@0 4 * or more contributor license agreements. See the NOTICE file
michael@0 5 * distributed with this work for additional information
michael@0 6 * regarding copyright ownership. The ASF licenses this file
michael@0 7 * to you under the Apache License, Version 2.0 (the
michael@0 8 * "License"); you may not use this file except in compliance
michael@0 9 * with the License. You may obtain a copy of the License at
michael@0 10 *
michael@0 11 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 12 *
michael@0 13 * Unless required by applicable law or agreed to in writing,
michael@0 14 * software distributed under the License is distributed on an
michael@0 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
michael@0 16 * KIND, either express or implied. See the License for the
michael@0 17 * specific language governing permissions and limitations
michael@0 18 * under the License.
michael@0 19 * ====================================================================
michael@0 20 *
michael@0 21 * This software consists of voluntary contributions made by many
michael@0 22 * individuals on behalf of the Apache Software Foundation. For more
michael@0 23 * information on the Apache Software Foundation, please see
michael@0 24 * <http://www.apache.org/>.
michael@0 25 *
michael@0 26 */
michael@0 27
michael@0 28 package ch.boye.httpclientandroidlib.util;
michael@0 29
michael@0 30 import java.io.Serializable;
michael@0 31
michael@0 32 /**
michael@0 33 * A resizable byte array.
michael@0 34 *
michael@0 35 * @since 4.0
michael@0 36 */
michael@0 37 public final class ByteArrayBuffer implements Serializable {
michael@0 38
michael@0 39 private static final long serialVersionUID = 4359112959524048036L;
michael@0 40
michael@0 41 private byte[] buffer;
michael@0 42 private int len;
michael@0 43
michael@0 44 /**
michael@0 45 * Creates an instance of {@link ByteArrayBuffer} with the given initial
michael@0 46 * capacity.
michael@0 47 *
michael@0 48 * @param capacity the capacity
michael@0 49 */
michael@0 50 public ByteArrayBuffer(int capacity) {
michael@0 51 super();
michael@0 52 if (capacity < 0) {
michael@0 53 throw new IllegalArgumentException("Buffer capacity may not be negative");
michael@0 54 }
michael@0 55 this.buffer = new byte[capacity];
michael@0 56 }
michael@0 57
michael@0 58 private void expand(int newlen) {
michael@0 59 byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)];
michael@0 60 System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
michael@0 61 this.buffer = newbuffer;
michael@0 62 }
michael@0 63
michael@0 64 /**
michael@0 65 * Appends <code>len</code> bytes to this buffer from the given source
michael@0 66 * array starting at index <code>off</code>. The capacity of the buffer
michael@0 67 * is increased, if necessary, to accommodate all <code>len</code> bytes.
michael@0 68 *
michael@0 69 * @param b the bytes to be appended.
michael@0 70 * @param off the index of the first byte to append.
michael@0 71 * @param len the number of bytes to append.
michael@0 72 * @throws IndexOutOfBoundsException if <code>off</code> if out of
michael@0 73 * range, <code>len</code> is negative, or
michael@0 74 * <code>off</code> + <code>len</code> is out of range.
michael@0 75 */
michael@0 76 public void append(final byte[] b, int off, int len) {
michael@0 77 if (b == null) {
michael@0 78 return;
michael@0 79 }
michael@0 80 if ((off < 0) || (off > b.length) || (len < 0) ||
michael@0 81 ((off + len) < 0) || ((off + len) > b.length)) {
michael@0 82 throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
michael@0 83 }
michael@0 84 if (len == 0) {
michael@0 85 return;
michael@0 86 }
michael@0 87 int newlen = this.len + len;
michael@0 88 if (newlen > this.buffer.length) {
michael@0 89 expand(newlen);
michael@0 90 }
michael@0 91 System.arraycopy(b, off, this.buffer, this.len, len);
michael@0 92 this.len = newlen;
michael@0 93 }
michael@0 94
michael@0 95 /**
michael@0 96 * Appends <code>b</code> byte to this buffer. The capacity of the buffer
michael@0 97 * is increased, if necessary, to accommodate the additional byte.
michael@0 98 *
michael@0 99 * @param b the byte to be appended.
michael@0 100 */
michael@0 101 public void append(int b) {
michael@0 102 int newlen = this.len + 1;
michael@0 103 if (newlen > this.buffer.length) {
michael@0 104 expand(newlen);
michael@0 105 }
michael@0 106 this.buffer[this.len] = (byte)b;
michael@0 107 this.len = newlen;
michael@0 108 }
michael@0 109
michael@0 110 /**
michael@0 111 * Appends <code>len</code> chars to this buffer from the given source
michael@0 112 * array starting at index <code>off</code>. The capacity of the buffer
michael@0 113 * is increased if necessary to accommodate all <code>len</code> chars.
michael@0 114 * <p>
michael@0 115 * The chars are converted to bytes using simple cast.
michael@0 116 *
michael@0 117 * @param b the chars to be appended.
michael@0 118 * @param off the index of the first char to append.
michael@0 119 * @param len the number of bytes to append.
michael@0 120 * @throws IndexOutOfBoundsException if <code>off</code> if out of
michael@0 121 * range, <code>len</code> is negative, or
michael@0 122 * <code>off</code> + <code>len</code> is out of range.
michael@0 123 */
michael@0 124 public void append(final char[] b, int off, int len) {
michael@0 125 if (b == null) {
michael@0 126 return;
michael@0 127 }
michael@0 128 if ((off < 0) || (off > b.length) || (len < 0) ||
michael@0 129 ((off + len) < 0) || ((off + len) > b.length)) {
michael@0 130 throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
michael@0 131 }
michael@0 132 if (len == 0) {
michael@0 133 return;
michael@0 134 }
michael@0 135 int oldlen = this.len;
michael@0 136 int newlen = oldlen + len;
michael@0 137 if (newlen > this.buffer.length) {
michael@0 138 expand(newlen);
michael@0 139 }
michael@0 140 for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) {
michael@0 141 this.buffer[i2] = (byte) b[i1];
michael@0 142 }
michael@0 143 this.len = newlen;
michael@0 144 }
michael@0 145
michael@0 146 /**
michael@0 147 * Appends <code>len</code> chars to this buffer from the given source
michael@0 148 * char array buffer starting at index <code>off</code>. The capacity
michael@0 149 * of the buffer is increased if necessary to accommodate all
michael@0 150 * <code>len</code> chars.
michael@0 151 * <p>
michael@0 152 * The chars are converted to bytes using simple cast.
michael@0 153 *
michael@0 154 * @param b the chars to be appended.
michael@0 155 * @param off the index of the first char to append.
michael@0 156 * @param len the number of bytes to append.
michael@0 157 * @throws IndexOutOfBoundsException if <code>off</code> if out of
michael@0 158 * range, <code>len</code> is negative, or
michael@0 159 * <code>off</code> + <code>len</code> is out of range.
michael@0 160 */
michael@0 161 public void append(final CharArrayBuffer b, int off, int len) {
michael@0 162 if (b == null) {
michael@0 163 return;
michael@0 164 }
michael@0 165 append(b.buffer(), off, len);
michael@0 166 }
michael@0 167
michael@0 168 /**
michael@0 169 * Clears content of the buffer. The underlying byte array is not resized.
michael@0 170 */
michael@0 171 public void clear() {
michael@0 172 this.len = 0;
michael@0 173 }
michael@0 174
michael@0 175 /**
michael@0 176 * Converts the content of this buffer to an array of bytes.
michael@0 177 *
michael@0 178 * @return byte array
michael@0 179 */
michael@0 180 public byte[] toByteArray() {
michael@0 181 byte[] b = new byte[this.len];
michael@0 182 if (this.len > 0) {
michael@0 183 System.arraycopy(this.buffer, 0, b, 0, this.len);
michael@0 184 }
michael@0 185 return b;
michael@0 186 }
michael@0 187
michael@0 188 /**
michael@0 189 * Returns the <code>byte</code> value in this buffer at the specified
michael@0 190 * index. The index argument must be greater than or equal to
michael@0 191 * <code>0</code>, and less than the length of this buffer.
michael@0 192 *
michael@0 193 * @param i the index of the desired byte value.
michael@0 194 * @return the byte value at the specified index.
michael@0 195 * @throws IndexOutOfBoundsException if <code>index</code> is
michael@0 196 * negative or greater than or equal to {@link #length()}.
michael@0 197 */
michael@0 198 public int byteAt(int i) {
michael@0 199 return this.buffer[i];
michael@0 200 }
michael@0 201
michael@0 202 /**
michael@0 203 * Returns the current capacity. The capacity is the amount of storage
michael@0 204 * available for newly appended bytes, beyond which an allocation
michael@0 205 * will occur.
michael@0 206 *
michael@0 207 * @return the current capacity
michael@0 208 */
michael@0 209 public int capacity() {
michael@0 210 return this.buffer.length;
michael@0 211 }
michael@0 212
michael@0 213 /**
michael@0 214 * Returns the length of the buffer (byte count).
michael@0 215 *
michael@0 216 * @return the length of the buffer
michael@0 217 */
michael@0 218 public int length() {
michael@0 219 return this.len;
michael@0 220 }
michael@0 221
michael@0 222 /**
michael@0 223 * Ensures that the capacity is at least equal to the specified minimum.
michael@0 224 * If the current capacity is less than the argument, then a new internal
michael@0 225 * array is allocated with greater capacity. If the <code>required</code>
michael@0 226 * argument is non-positive, this method takes no action.
michael@0 227 *
michael@0 228 * @param required the minimum required capacity.
michael@0 229 *
michael@0 230 * @since 4.1
michael@0 231 */
michael@0 232 public void ensureCapacity(int required) {
michael@0 233 if (required <= 0) {
michael@0 234 return;
michael@0 235 }
michael@0 236 int available = this.buffer.length - this.len;
michael@0 237 if (required > available) {
michael@0 238 expand(this.len + required);
michael@0 239 }
michael@0 240 }
michael@0 241
michael@0 242 /**
michael@0 243 * Returns reference to the underlying byte array.
michael@0 244 *
michael@0 245 * @return the byte array.
michael@0 246 */
michael@0 247 public byte[] buffer() {
michael@0 248 return this.buffer;
michael@0 249 }
michael@0 250
michael@0 251 /**
michael@0 252 * Sets the length of the buffer. The new length value is expected to be
michael@0 253 * less than the current capacity and greater than or equal to
michael@0 254 * <code>0</code>.
michael@0 255 *
michael@0 256 * @param len the new length
michael@0 257 * @throws IndexOutOfBoundsException if the
michael@0 258 * <code>len</code> argument is greater than the current
michael@0 259 * capacity of the buffer or less than <code>0</code>.
michael@0 260 */
michael@0 261 public void setLength(int len) {
michael@0 262 if (len < 0 || len > this.buffer.length) {
michael@0 263 throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length);
michael@0 264 }
michael@0 265 this.len = len;
michael@0 266 }
michael@0 267
michael@0 268 /**
michael@0 269 * Returns <code>true</code> if this buffer is empty, that is, its
michael@0 270 * {@link #length()} is equal to <code>0</code>.
michael@0 271 * @return <code>true</code> if this buffer is empty, <code>false</code>
michael@0 272 * otherwise.
michael@0 273 */
michael@0 274 public boolean isEmpty() {
michael@0 275 return this.len == 0;
michael@0 276 }
michael@0 277
michael@0 278 /**
michael@0 279 * Returns <code>true</code> if this buffer is full, that is, its
michael@0 280 * {@link #length()} is equal to its {@link #capacity()}.
michael@0 281 * @return <code>true</code> if this buffer is full, <code>false</code>
michael@0 282 * otherwise.
michael@0 283 */
michael@0 284 public boolean isFull() {
michael@0 285 return this.len == this.buffer.length;
michael@0 286 }
michael@0 287
michael@0 288 /**
michael@0 289 * Returns the index within this buffer of the first occurrence of the
michael@0 290 * specified byte, starting the search at the specified
michael@0 291 * <code>beginIndex</code> and finishing at <code>endIndex</code>.
michael@0 292 * If no such byte occurs in this buffer within the specified bounds,
michael@0 293 * <code>-1</code> is returned.
michael@0 294 * <p>
michael@0 295 * There is no restriction on the value of <code>beginIndex</code> and
michael@0 296 * <code>endIndex</code>. If <code>beginIndex</code> is negative,
michael@0 297 * it has the same effect as if it were zero. If <code>endIndex</code> is
michael@0 298 * greater than {@link #length()}, it has the same effect as if it were
michael@0 299 * {@link #length()}. If the <code>beginIndex</code> is greater than
michael@0 300 * the <code>endIndex</code>, <code>-1</code> is returned.
michael@0 301 *
michael@0 302 * @param b the byte to search for.
michael@0 303 * @param beginIndex the index to start the search from.
michael@0 304 * @param endIndex the index to finish the search at.
michael@0 305 * @return the index of the first occurrence of the byte in the buffer
michael@0 306 * within the given bounds, or <code>-1</code> if the byte does
michael@0 307 * not occur.
michael@0 308 *
michael@0 309 * @since 4.1
michael@0 310 */
michael@0 311 public int indexOf(byte b, int beginIndex, int endIndex) {
michael@0 312 if (beginIndex < 0) {
michael@0 313 beginIndex = 0;
michael@0 314 }
michael@0 315 if (endIndex > this.len) {
michael@0 316 endIndex = this.len;
michael@0 317 }
michael@0 318 if (beginIndex > endIndex) {
michael@0 319 return -1;
michael@0 320 }
michael@0 321 for (int i = beginIndex; i < endIndex; i++) {
michael@0 322 if (this.buffer[i] == b) {
michael@0 323 return i;
michael@0 324 }
michael@0 325 }
michael@0 326 return -1;
michael@0 327 }
michael@0 328
michael@0 329 /**
michael@0 330 * Returns the index within this buffer of the first occurrence of the
michael@0 331 * specified byte, starting the search at <code>0</code> and finishing
michael@0 332 * at {@link #length()}. If no such byte occurs in this buffer within
michael@0 333 * those bounds, <code>-1</code> is returned.
michael@0 334 *
michael@0 335 * @param b the byte to search for.
michael@0 336 * @return the index of the first occurrence of the byte in the
michael@0 337 * buffer, or <code>-1</code> if the byte does not occur.
michael@0 338 *
michael@0 339 * @since 4.1
michael@0 340 */
michael@0 341 public int indexOf(byte b) {
michael@0 342 return indexOf(b, 0, this.len);
michael@0 343 }
michael@0 344 }

mercurial