mobile/android/thirdparty/ch/boye/httpclientandroidlib/util/CharArrayBuffer.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 import ch.boye.httpclientandroidlib.protocol.HTTP;
michael@0 33
michael@0 34 /**
michael@0 35 * A resizable char array.
michael@0 36 *
michael@0 37 * @since 4.0
michael@0 38 */
michael@0 39 public final class CharArrayBuffer implements Serializable {
michael@0 40
michael@0 41 private static final long serialVersionUID = -6208952725094867135L;
michael@0 42
michael@0 43 private char[] buffer;
michael@0 44 private int len;
michael@0 45
michael@0 46 /**
michael@0 47 * Creates an instance of {@link CharArrayBuffer} with the given initial
michael@0 48 * capacity.
michael@0 49 *
michael@0 50 * @param capacity the capacity
michael@0 51 */
michael@0 52 public CharArrayBuffer(int capacity) {
michael@0 53 super();
michael@0 54 if (capacity < 0) {
michael@0 55 throw new IllegalArgumentException("Buffer capacity may not be negative");
michael@0 56 }
michael@0 57 this.buffer = new char[capacity];
michael@0 58 }
michael@0 59
michael@0 60 private void expand(int newlen) {
michael@0 61 char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)];
michael@0 62 System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
michael@0 63 this.buffer = newbuffer;
michael@0 64 }
michael@0 65
michael@0 66 /**
michael@0 67 * Appends <code>len</code> chars to this buffer from the given source
michael@0 68 * array starting at index <code>off</code>. The capacity of the buffer
michael@0 69 * is increased, if necessary, to accommodate all <code>len</code> chars.
michael@0 70 *
michael@0 71 * @param b the chars to be appended.
michael@0 72 * @param off the index of the first char to append.
michael@0 73 * @param len the number of chars to append.
michael@0 74 * @throws IndexOutOfBoundsException if <code>off</code> is out of
michael@0 75 * range, <code>len</code> is negative, or
michael@0 76 * <code>off</code> + <code>len</code> is out of range.
michael@0 77 */
michael@0 78 public void append(final char[] b, int off, int len) {
michael@0 79 if (b == null) {
michael@0 80 return;
michael@0 81 }
michael@0 82 if ((off < 0) || (off > b.length) || (len < 0) ||
michael@0 83 ((off + len) < 0) || ((off + len) > b.length)) {
michael@0 84 throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
michael@0 85 }
michael@0 86 if (len == 0) {
michael@0 87 return;
michael@0 88 }
michael@0 89 int newlen = this.len + len;
michael@0 90 if (newlen > this.buffer.length) {
michael@0 91 expand(newlen);
michael@0 92 }
michael@0 93 System.arraycopy(b, off, this.buffer, this.len, len);
michael@0 94 this.len = newlen;
michael@0 95 }
michael@0 96
michael@0 97 /**
michael@0 98 * Appends chars of the given string to this buffer. The capacity of the
michael@0 99 * buffer is increased, if necessary, to accommodate all chars.
michael@0 100 *
michael@0 101 * @param str the string.
michael@0 102 */
michael@0 103 public void append(String str) {
michael@0 104 if (str == null) {
michael@0 105 str = "null";
michael@0 106 }
michael@0 107 int strlen = str.length();
michael@0 108 int newlen = this.len + strlen;
michael@0 109 if (newlen > this.buffer.length) {
michael@0 110 expand(newlen);
michael@0 111 }
michael@0 112 str.getChars(0, strlen, this.buffer, this.len);
michael@0 113 this.len = newlen;
michael@0 114 }
michael@0 115
michael@0 116 /**
michael@0 117 * Appends <code>len</code> chars to this buffer from the given source
michael@0 118 * buffer starting at index <code>off</code>. The capacity of the
michael@0 119 * destination buffer is increased, if necessary, to accommodate all
michael@0 120 * <code>len</code> chars.
michael@0 121 *
michael@0 122 * @param b the source buffer to be appended.
michael@0 123 * @param off the index of the first char to append.
michael@0 124 * @param len the number of chars to append.
michael@0 125 * @throws IndexOutOfBoundsException if <code>off</code> is out of
michael@0 126 * range, <code>len</code> is negative, or
michael@0 127 * <code>off</code> + <code>len</code> is out of range.
michael@0 128 */
michael@0 129 public void append(final CharArrayBuffer b, int off, int len) {
michael@0 130 if (b == null) {
michael@0 131 return;
michael@0 132 }
michael@0 133 append(b.buffer, off, len);
michael@0 134 }
michael@0 135
michael@0 136 /**
michael@0 137 * Appends all chars to this buffer from the given source buffer starting
michael@0 138 * at index <code>0</code>. The capacity of the destination buffer is
michael@0 139 * increased, if necessary, to accommodate all {@link #length()} chars.
michael@0 140 *
michael@0 141 * @param b the source buffer to be appended.
michael@0 142 */
michael@0 143 public void append(final CharArrayBuffer b) {
michael@0 144 if (b == null) {
michael@0 145 return;
michael@0 146 }
michael@0 147 append(b.buffer,0, b.len);
michael@0 148 }
michael@0 149
michael@0 150 /**
michael@0 151 * Appends <code>ch</code> char to this buffer. The capacity of the buffer
michael@0 152 * is increased, if necessary, to accommodate the additional char.
michael@0 153 *
michael@0 154 * @param ch the char to be appended.
michael@0 155 */
michael@0 156 public void append(char ch) {
michael@0 157 int newlen = this.len + 1;
michael@0 158 if (newlen > this.buffer.length) {
michael@0 159 expand(newlen);
michael@0 160 }
michael@0 161 this.buffer[this.len] = ch;
michael@0 162 this.len = newlen;
michael@0 163 }
michael@0 164
michael@0 165 /**
michael@0 166 * Appends <code>len</code> bytes to this buffer from the given source
michael@0 167 * array starting at index <code>off</code>. The capacity of the buffer
michael@0 168 * is increased, if necessary, to accommodate all <code>len</code> bytes.
michael@0 169 * <p>
michael@0 170 * The bytes are converted to chars using simple cast.
michael@0 171 *
michael@0 172 * @param b the bytes to be appended.
michael@0 173 * @param off the index of the first byte to append.
michael@0 174 * @param len the number of bytes to append.
michael@0 175 * @throws IndexOutOfBoundsException if <code>off</code> is out of
michael@0 176 * range, <code>len</code> is negative, or
michael@0 177 * <code>off</code> + <code>len</code> is out of range.
michael@0 178 */
michael@0 179 public void append(final byte[] b, int off, int len) {
michael@0 180 if (b == null) {
michael@0 181 return;
michael@0 182 }
michael@0 183 if ((off < 0) || (off > b.length) || (len < 0) ||
michael@0 184 ((off + len) < 0) || ((off + len) > b.length)) {
michael@0 185 throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length);
michael@0 186 }
michael@0 187 if (len == 0) {
michael@0 188 return;
michael@0 189 }
michael@0 190 int oldlen = this.len;
michael@0 191 int newlen = oldlen + len;
michael@0 192 if (newlen > this.buffer.length) {
michael@0 193 expand(newlen);
michael@0 194 }
michael@0 195 for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) {
michael@0 196 this.buffer[i2] = (char) (b[i1] & 0xff);
michael@0 197 }
michael@0 198 this.len = newlen;
michael@0 199 }
michael@0 200
michael@0 201 /**
michael@0 202 * Appends <code>len</code> bytes to this buffer from the given source
michael@0 203 * array starting at index <code>off</code>. The capacity of the buffer
michael@0 204 * is increased, if necessary, to accommodate all <code>len</code> bytes.
michael@0 205 * <p>
michael@0 206 * The bytes are converted to chars using simple cast.
michael@0 207 *
michael@0 208 * @param b the bytes to be appended.
michael@0 209 * @param off the index of the first byte to append.
michael@0 210 * @param len the number of bytes to append.
michael@0 211 * @throws IndexOutOfBoundsException if <code>off</code> is out of
michael@0 212 * range, <code>len</code> is negative, or
michael@0 213 * <code>off</code> + <code>len</code> is out of range.
michael@0 214 */
michael@0 215 public void append(final ByteArrayBuffer b, int off, int len) {
michael@0 216 if (b == null) {
michael@0 217 return;
michael@0 218 }
michael@0 219 append(b.buffer(), off, len);
michael@0 220 }
michael@0 221
michael@0 222 /**
michael@0 223 * Appends chars of the textual representation of the given object to this
michael@0 224 * buffer. The capacity of the buffer is increased, if necessary, to
michael@0 225 * accommodate all chars.
michael@0 226 *
michael@0 227 * @param obj the object.
michael@0 228 */
michael@0 229 public void append(final Object obj) {
michael@0 230 append(String.valueOf(obj));
michael@0 231 }
michael@0 232
michael@0 233 /**
michael@0 234 * Clears content of the buffer. The underlying char array is not resized.
michael@0 235 */
michael@0 236 public void clear() {
michael@0 237 this.len = 0;
michael@0 238 }
michael@0 239
michael@0 240 /**
michael@0 241 * Converts the content of this buffer to an array of chars.
michael@0 242 *
michael@0 243 * @return char array
michael@0 244 */
michael@0 245 public char[] toCharArray() {
michael@0 246 char[] b = new char[this.len];
michael@0 247 if (this.len > 0) {
michael@0 248 System.arraycopy(this.buffer, 0, b, 0, this.len);
michael@0 249 }
michael@0 250 return b;
michael@0 251 }
michael@0 252
michael@0 253 /**
michael@0 254 * Returns the <code>char</code> value in this buffer at the specified
michael@0 255 * index. The index argument must be greater than or equal to
michael@0 256 * <code>0</code>, and less than the length of this buffer.
michael@0 257 *
michael@0 258 * @param i the index of the desired char value.
michael@0 259 * @return the char value at the specified index.
michael@0 260 * @throws IndexOutOfBoundsException if <code>index</code> is
michael@0 261 * negative or greater than or equal to {@link #length()}.
michael@0 262 */
michael@0 263 public char charAt(int i) {
michael@0 264 return this.buffer[i];
michael@0 265 }
michael@0 266
michael@0 267 /**
michael@0 268 * Returns reference to the underlying char array.
michael@0 269 *
michael@0 270 * @return the char array.
michael@0 271 */
michael@0 272 public char[] buffer() {
michael@0 273 return this.buffer;
michael@0 274 }
michael@0 275
michael@0 276 /**
michael@0 277 * Returns the current capacity. The capacity is the amount of storage
michael@0 278 * available for newly appended chars, beyond which an allocation will
michael@0 279 * occur.
michael@0 280 *
michael@0 281 * @return the current capacity
michael@0 282 */
michael@0 283 public int capacity() {
michael@0 284 return this.buffer.length;
michael@0 285 }
michael@0 286
michael@0 287 /**
michael@0 288 * Returns the length of the buffer (char count).
michael@0 289 *
michael@0 290 * @return the length of the buffer
michael@0 291 */
michael@0 292 public int length() {
michael@0 293 return this.len;
michael@0 294 }
michael@0 295
michael@0 296 /**
michael@0 297 * Ensures that the capacity is at least equal to the specified minimum.
michael@0 298 * If the current capacity is less than the argument, then a new internal
michael@0 299 * array is allocated with greater capacity. If the <code>required</code>
michael@0 300 * argument is non-positive, this method takes no action.
michael@0 301 *
michael@0 302 * @param required the minimum required capacity.
michael@0 303 */
michael@0 304 public void ensureCapacity(int required) {
michael@0 305 if (required <= 0) {
michael@0 306 return;
michael@0 307 }
michael@0 308 int available = this.buffer.length - this.len;
michael@0 309 if (required > available) {
michael@0 310 expand(this.len + required);
michael@0 311 }
michael@0 312 }
michael@0 313
michael@0 314 /**
michael@0 315 * Sets the length of the buffer. The new length value is expected to be
michael@0 316 * less than the current capacity and greater than or equal to
michael@0 317 * <code>0</code>.
michael@0 318 *
michael@0 319 * @param len the new length
michael@0 320 * @throws IndexOutOfBoundsException if the
michael@0 321 * <code>len</code> argument is greater than the current
michael@0 322 * capacity of the buffer or less than <code>0</code>.
michael@0 323 */
michael@0 324 public void setLength(int len) {
michael@0 325 if (len < 0 || len > this.buffer.length) {
michael@0 326 throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length);
michael@0 327 }
michael@0 328 this.len = len;
michael@0 329 }
michael@0 330
michael@0 331 /**
michael@0 332 * Returns <code>true</code> if this buffer is empty, that is, its
michael@0 333 * {@link #length()} is equal to <code>0</code>.
michael@0 334 * @return <code>true</code> if this buffer is empty, <code>false</code>
michael@0 335 * otherwise.
michael@0 336 */
michael@0 337 public boolean isEmpty() {
michael@0 338 return this.len == 0;
michael@0 339 }
michael@0 340
michael@0 341 /**
michael@0 342 * Returns <code>true</code> if this buffer is full, that is, its
michael@0 343 * {@link #length()} is equal to its {@link #capacity()}.
michael@0 344 * @return <code>true</code> if this buffer is full, <code>false</code>
michael@0 345 * otherwise.
michael@0 346 */
michael@0 347 public boolean isFull() {
michael@0 348 return this.len == this.buffer.length;
michael@0 349 }
michael@0 350
michael@0 351 /**
michael@0 352 * Returns the index within this buffer of the first occurrence of the
michael@0 353 * specified character, starting the search at the specified
michael@0 354 * <code>beginIndex</code> and finishing at <code>endIndex</code>.
michael@0 355 * If no such character occurs in this buffer within the specified bounds,
michael@0 356 * <code>-1</code> is returned.
michael@0 357 * <p>
michael@0 358 * There is no restriction on the value of <code>beginIndex</code> and
michael@0 359 * <code>endIndex</code>. If <code>beginIndex</code> is negative,
michael@0 360 * it has the same effect as if it were zero. If <code>endIndex</code> is
michael@0 361 * greater than {@link #length()}, it has the same effect as if it were
michael@0 362 * {@link #length()}. If the <code>beginIndex</code> is greater than
michael@0 363 * the <code>endIndex</code>, <code>-1</code> is returned.
michael@0 364 *
michael@0 365 * @param ch the char to search for.
michael@0 366 * @param beginIndex the index to start the search from.
michael@0 367 * @param endIndex the index to finish the search at.
michael@0 368 * @return the index of the first occurrence of the character in the buffer
michael@0 369 * within the given bounds, or <code>-1</code> if the character does
michael@0 370 * not occur.
michael@0 371 */
michael@0 372 public int indexOf(int ch, int beginIndex, int endIndex) {
michael@0 373 if (beginIndex < 0) {
michael@0 374 beginIndex = 0;
michael@0 375 }
michael@0 376 if (endIndex > this.len) {
michael@0 377 endIndex = this.len;
michael@0 378 }
michael@0 379 if (beginIndex > endIndex) {
michael@0 380 return -1;
michael@0 381 }
michael@0 382 for (int i = beginIndex; i < endIndex; i++) {
michael@0 383 if (this.buffer[i] == ch) {
michael@0 384 return i;
michael@0 385 }
michael@0 386 }
michael@0 387 return -1;
michael@0 388 }
michael@0 389
michael@0 390 /**
michael@0 391 * Returns the index within this buffer of the first occurrence of the
michael@0 392 * specified character, starting the search at <code>0</code> and finishing
michael@0 393 * at {@link #length()}. If no such character occurs in this buffer within
michael@0 394 * those bounds, <code>-1</code> is returned.
michael@0 395 *
michael@0 396 * @param ch the char to search for.
michael@0 397 * @return the index of the first occurrence of the character in the
michael@0 398 * buffer, or <code>-1</code> if the character does not occur.
michael@0 399 */
michael@0 400 public int indexOf(int ch) {
michael@0 401 return indexOf(ch, 0, this.len);
michael@0 402 }
michael@0 403
michael@0 404 /**
michael@0 405 * Returns a substring of this buffer. The substring begins at the specified
michael@0 406 * <code>beginIndex</code> and extends to the character at index
michael@0 407 * <code>endIndex - 1</code>.
michael@0 408 *
michael@0 409 * @param beginIndex the beginning index, inclusive.
michael@0 410 * @param endIndex the ending index, exclusive.
michael@0 411 * @return the specified substring.
michael@0 412 * @exception StringIndexOutOfBoundsException if the
michael@0 413 * <code>beginIndex</code> is negative, or
michael@0 414 * <code>endIndex</code> is larger than the length of this
michael@0 415 * buffer, or <code>beginIndex</code> is larger than
michael@0 416 * <code>endIndex</code>.
michael@0 417 */
michael@0 418 public String substring(int beginIndex, int endIndex) {
michael@0 419 return new String(this.buffer, beginIndex, endIndex - beginIndex);
michael@0 420 }
michael@0 421
michael@0 422 /**
michael@0 423 * Returns a substring of this buffer with leading and trailing whitespace
michael@0 424 * omitted. The substring begins with the first non-whitespace character
michael@0 425 * from <code>beginIndex</code> and extends to the last
michael@0 426 * non-whitespace character with the index lesser than
michael@0 427 * <code>endIndex</code>.
michael@0 428 *
michael@0 429 * @param beginIndex the beginning index, inclusive.
michael@0 430 * @param endIndex the ending index, exclusive.
michael@0 431 * @return the specified substring.
michael@0 432 * @exception IndexOutOfBoundsException if the
michael@0 433 * <code>beginIndex</code> is negative, or
michael@0 434 * <code>endIndex</code> is larger than the length of this
michael@0 435 * buffer, or <code>beginIndex</code> is larger than
michael@0 436 * <code>endIndex</code>.
michael@0 437 */
michael@0 438 public String substringTrimmed(int beginIndex, int endIndex) {
michael@0 439 if (beginIndex < 0) {
michael@0 440 throw new IndexOutOfBoundsException("Negative beginIndex: "+beginIndex);
michael@0 441 }
michael@0 442 if (endIndex > this.len) {
michael@0 443 throw new IndexOutOfBoundsException("endIndex: "+endIndex+" > length: "+this.len);
michael@0 444 }
michael@0 445 if (beginIndex > endIndex) {
michael@0 446 throw new IndexOutOfBoundsException("beginIndex: "+beginIndex+" > endIndex: "+endIndex);
michael@0 447 }
michael@0 448 while (beginIndex < endIndex && HTTP.isWhitespace(this.buffer[beginIndex])) {
michael@0 449 beginIndex++;
michael@0 450 }
michael@0 451 while (endIndex > beginIndex && HTTP.isWhitespace(this.buffer[endIndex - 1])) {
michael@0 452 endIndex--;
michael@0 453 }
michael@0 454 return new String(this.buffer, beginIndex, endIndex - beginIndex);
michael@0 455 }
michael@0 456
michael@0 457 public String toString() {
michael@0 458 return new String(this.buffer, 0, this.len);
michael@0 459 }
michael@0 460
michael@0 461 }

mercurial