1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/mobile/android/thirdparty/ch/boye/httpclientandroidlib/util/CharArrayBuffer.java Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,461 @@ 1.4 +/* 1.5 + * ==================================================================== 1.6 + * Licensed to the Apache Software Foundation (ASF) under one 1.7 + * or more contributor license agreements. See the NOTICE file 1.8 + * distributed with this work for additional information 1.9 + * regarding copyright ownership. The ASF licenses this file 1.10 + * to you under the Apache License, Version 2.0 (the 1.11 + * "License"); you may not use this file except in compliance 1.12 + * with the License. You may obtain a copy of the License at 1.13 + * 1.14 + * http://www.apache.org/licenses/LICENSE-2.0 1.15 + * 1.16 + * Unless required by applicable law or agreed to in writing, 1.17 + * software distributed under the License is distributed on an 1.18 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1.19 + * KIND, either express or implied. See the License for the 1.20 + * specific language governing permissions and limitations 1.21 + * under the License. 1.22 + * ==================================================================== 1.23 + * 1.24 + * This software consists of voluntary contributions made by many 1.25 + * individuals on behalf of the Apache Software Foundation. For more 1.26 + * information on the Apache Software Foundation, please see 1.27 + * <http://www.apache.org/>. 1.28 + * 1.29 + */ 1.30 + 1.31 +package ch.boye.httpclientandroidlib.util; 1.32 + 1.33 +import java.io.Serializable; 1.34 + 1.35 +import ch.boye.httpclientandroidlib.protocol.HTTP; 1.36 + 1.37 +/** 1.38 + * A resizable char array. 1.39 + * 1.40 + * @since 4.0 1.41 + */ 1.42 +public final class CharArrayBuffer implements Serializable { 1.43 + 1.44 + private static final long serialVersionUID = -6208952725094867135L; 1.45 + 1.46 + private char[] buffer; 1.47 + private int len; 1.48 + 1.49 + /** 1.50 + * Creates an instance of {@link CharArrayBuffer} with the given initial 1.51 + * capacity. 1.52 + * 1.53 + * @param capacity the capacity 1.54 + */ 1.55 + public CharArrayBuffer(int capacity) { 1.56 + super(); 1.57 + if (capacity < 0) { 1.58 + throw new IllegalArgumentException("Buffer capacity may not be negative"); 1.59 + } 1.60 + this.buffer = new char[capacity]; 1.61 + } 1.62 + 1.63 + private void expand(int newlen) { 1.64 + char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)]; 1.65 + System.arraycopy(this.buffer, 0, newbuffer, 0, this.len); 1.66 + this.buffer = newbuffer; 1.67 + } 1.68 + 1.69 + /** 1.70 + * Appends <code>len</code> chars to this buffer from the given source 1.71 + * array starting at index <code>off</code>. The capacity of the buffer 1.72 + * is increased, if necessary, to accommodate all <code>len</code> chars. 1.73 + * 1.74 + * @param b the chars to be appended. 1.75 + * @param off the index of the first char to append. 1.76 + * @param len the number of chars to append. 1.77 + * @throws IndexOutOfBoundsException if <code>off</code> is out of 1.78 + * range, <code>len</code> is negative, or 1.79 + * <code>off</code> + <code>len</code> is out of range. 1.80 + */ 1.81 + public void append(final char[] b, int off, int len) { 1.82 + if (b == null) { 1.83 + return; 1.84 + } 1.85 + if ((off < 0) || (off > b.length) || (len < 0) || 1.86 + ((off + len) < 0) || ((off + len) > b.length)) { 1.87 + throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length); 1.88 + } 1.89 + if (len == 0) { 1.90 + return; 1.91 + } 1.92 + int newlen = this.len + len; 1.93 + if (newlen > this.buffer.length) { 1.94 + expand(newlen); 1.95 + } 1.96 + System.arraycopy(b, off, this.buffer, this.len, len); 1.97 + this.len = newlen; 1.98 + } 1.99 + 1.100 + /** 1.101 + * Appends chars of the given string to this buffer. The capacity of the 1.102 + * buffer is increased, if necessary, to accommodate all chars. 1.103 + * 1.104 + * @param str the string. 1.105 + */ 1.106 + public void append(String str) { 1.107 + if (str == null) { 1.108 + str = "null"; 1.109 + } 1.110 + int strlen = str.length(); 1.111 + int newlen = this.len + strlen; 1.112 + if (newlen > this.buffer.length) { 1.113 + expand(newlen); 1.114 + } 1.115 + str.getChars(0, strlen, this.buffer, this.len); 1.116 + this.len = newlen; 1.117 + } 1.118 + 1.119 + /** 1.120 + * Appends <code>len</code> chars to this buffer from the given source 1.121 + * buffer starting at index <code>off</code>. The capacity of the 1.122 + * destination buffer is increased, if necessary, to accommodate all 1.123 + * <code>len</code> chars. 1.124 + * 1.125 + * @param b the source buffer to be appended. 1.126 + * @param off the index of the first char to append. 1.127 + * @param len the number of chars to append. 1.128 + * @throws IndexOutOfBoundsException if <code>off</code> is out of 1.129 + * range, <code>len</code> is negative, or 1.130 + * <code>off</code> + <code>len</code> is out of range. 1.131 + */ 1.132 + public void append(final CharArrayBuffer b, int off, int len) { 1.133 + if (b == null) { 1.134 + return; 1.135 + } 1.136 + append(b.buffer, off, len); 1.137 + } 1.138 + 1.139 + /** 1.140 + * Appends all chars to this buffer from the given source buffer starting 1.141 + * at index <code>0</code>. The capacity of the destination buffer is 1.142 + * increased, if necessary, to accommodate all {@link #length()} chars. 1.143 + * 1.144 + * @param b the source buffer to be appended. 1.145 + */ 1.146 + public void append(final CharArrayBuffer b) { 1.147 + if (b == null) { 1.148 + return; 1.149 + } 1.150 + append(b.buffer,0, b.len); 1.151 + } 1.152 + 1.153 + /** 1.154 + * Appends <code>ch</code> char to this buffer. The capacity of the buffer 1.155 + * is increased, if necessary, to accommodate the additional char. 1.156 + * 1.157 + * @param ch the char to be appended. 1.158 + */ 1.159 + public void append(char ch) { 1.160 + int newlen = this.len + 1; 1.161 + if (newlen > this.buffer.length) { 1.162 + expand(newlen); 1.163 + } 1.164 + this.buffer[this.len] = ch; 1.165 + this.len = newlen; 1.166 + } 1.167 + 1.168 + /** 1.169 + * Appends <code>len</code> bytes to this buffer from the given source 1.170 + * array starting at index <code>off</code>. The capacity of the buffer 1.171 + * is increased, if necessary, to accommodate all <code>len</code> bytes. 1.172 + * <p> 1.173 + * The bytes are converted to chars using simple cast. 1.174 + * 1.175 + * @param b the bytes to be appended. 1.176 + * @param off the index of the first byte to append. 1.177 + * @param len the number of bytes to append. 1.178 + * @throws IndexOutOfBoundsException if <code>off</code> is out of 1.179 + * range, <code>len</code> is negative, or 1.180 + * <code>off</code> + <code>len</code> is out of range. 1.181 + */ 1.182 + public void append(final byte[] b, int off, int len) { 1.183 + if (b == null) { 1.184 + return; 1.185 + } 1.186 + if ((off < 0) || (off > b.length) || (len < 0) || 1.187 + ((off + len) < 0) || ((off + len) > b.length)) { 1.188 + throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length); 1.189 + } 1.190 + if (len == 0) { 1.191 + return; 1.192 + } 1.193 + int oldlen = this.len; 1.194 + int newlen = oldlen + len; 1.195 + if (newlen > this.buffer.length) { 1.196 + expand(newlen); 1.197 + } 1.198 + for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) { 1.199 + this.buffer[i2] = (char) (b[i1] & 0xff); 1.200 + } 1.201 + this.len = newlen; 1.202 + } 1.203 + 1.204 + /** 1.205 + * Appends <code>len</code> bytes to this buffer from the given source 1.206 + * array starting at index <code>off</code>. The capacity of the buffer 1.207 + * is increased, if necessary, to accommodate all <code>len</code> bytes. 1.208 + * <p> 1.209 + * The bytes are converted to chars using simple cast. 1.210 + * 1.211 + * @param b the bytes to be appended. 1.212 + * @param off the index of the first byte to append. 1.213 + * @param len the number of bytes to append. 1.214 + * @throws IndexOutOfBoundsException if <code>off</code> is out of 1.215 + * range, <code>len</code> is negative, or 1.216 + * <code>off</code> + <code>len</code> is out of range. 1.217 + */ 1.218 + public void append(final ByteArrayBuffer b, int off, int len) { 1.219 + if (b == null) { 1.220 + return; 1.221 + } 1.222 + append(b.buffer(), off, len); 1.223 + } 1.224 + 1.225 + /** 1.226 + * Appends chars of the textual representation of the given object to this 1.227 + * buffer. The capacity of the buffer is increased, if necessary, to 1.228 + * accommodate all chars. 1.229 + * 1.230 + * @param obj the object. 1.231 + */ 1.232 + public void append(final Object obj) { 1.233 + append(String.valueOf(obj)); 1.234 + } 1.235 + 1.236 + /** 1.237 + * Clears content of the buffer. The underlying char array is not resized. 1.238 + */ 1.239 + public void clear() { 1.240 + this.len = 0; 1.241 + } 1.242 + 1.243 + /** 1.244 + * Converts the content of this buffer to an array of chars. 1.245 + * 1.246 + * @return char array 1.247 + */ 1.248 + public char[] toCharArray() { 1.249 + char[] b = new char[this.len]; 1.250 + if (this.len > 0) { 1.251 + System.arraycopy(this.buffer, 0, b, 0, this.len); 1.252 + } 1.253 + return b; 1.254 + } 1.255 + 1.256 + /** 1.257 + * Returns the <code>char</code> value in this buffer at the specified 1.258 + * index. The index argument must be greater than or equal to 1.259 + * <code>0</code>, and less than the length of this buffer. 1.260 + * 1.261 + * @param i the index of the desired char value. 1.262 + * @return the char value at the specified index. 1.263 + * @throws IndexOutOfBoundsException if <code>index</code> is 1.264 + * negative or greater than or equal to {@link #length()}. 1.265 + */ 1.266 + public char charAt(int i) { 1.267 + return this.buffer[i]; 1.268 + } 1.269 + 1.270 + /** 1.271 + * Returns reference to the underlying char array. 1.272 + * 1.273 + * @return the char array. 1.274 + */ 1.275 + public char[] buffer() { 1.276 + return this.buffer; 1.277 + } 1.278 + 1.279 + /** 1.280 + * Returns the current capacity. The capacity is the amount of storage 1.281 + * available for newly appended chars, beyond which an allocation will 1.282 + * occur. 1.283 + * 1.284 + * @return the current capacity 1.285 + */ 1.286 + public int capacity() { 1.287 + return this.buffer.length; 1.288 + } 1.289 + 1.290 + /** 1.291 + * Returns the length of the buffer (char count). 1.292 + * 1.293 + * @return the length of the buffer 1.294 + */ 1.295 + public int length() { 1.296 + return this.len; 1.297 + } 1.298 + 1.299 + /** 1.300 + * Ensures that the capacity is at least equal to the specified minimum. 1.301 + * If the current capacity is less than the argument, then a new internal 1.302 + * array is allocated with greater capacity. If the <code>required</code> 1.303 + * argument is non-positive, this method takes no action. 1.304 + * 1.305 + * @param required the minimum required capacity. 1.306 + */ 1.307 + public void ensureCapacity(int required) { 1.308 + if (required <= 0) { 1.309 + return; 1.310 + } 1.311 + int available = this.buffer.length - this.len; 1.312 + if (required > available) { 1.313 + expand(this.len + required); 1.314 + } 1.315 + } 1.316 + 1.317 + /** 1.318 + * Sets the length of the buffer. The new length value is expected to be 1.319 + * less than the current capacity and greater than or equal to 1.320 + * <code>0</code>. 1.321 + * 1.322 + * @param len the new length 1.323 + * @throws IndexOutOfBoundsException if the 1.324 + * <code>len</code> argument is greater than the current 1.325 + * capacity of the buffer or less than <code>0</code>. 1.326 + */ 1.327 + public void setLength(int len) { 1.328 + if (len < 0 || len > this.buffer.length) { 1.329 + throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length); 1.330 + } 1.331 + this.len = len; 1.332 + } 1.333 + 1.334 + /** 1.335 + * Returns <code>true</code> if this buffer is empty, that is, its 1.336 + * {@link #length()} is equal to <code>0</code>. 1.337 + * @return <code>true</code> if this buffer is empty, <code>false</code> 1.338 + * otherwise. 1.339 + */ 1.340 + public boolean isEmpty() { 1.341 + return this.len == 0; 1.342 + } 1.343 + 1.344 + /** 1.345 + * Returns <code>true</code> if this buffer is full, that is, its 1.346 + * {@link #length()} is equal to its {@link #capacity()}. 1.347 + * @return <code>true</code> if this buffer is full, <code>false</code> 1.348 + * otherwise. 1.349 + */ 1.350 + public boolean isFull() { 1.351 + return this.len == this.buffer.length; 1.352 + } 1.353 + 1.354 + /** 1.355 + * Returns the index within this buffer of the first occurrence of the 1.356 + * specified character, starting the search at the specified 1.357 + * <code>beginIndex</code> and finishing at <code>endIndex</code>. 1.358 + * If no such character occurs in this buffer within the specified bounds, 1.359 + * <code>-1</code> is returned. 1.360 + * <p> 1.361 + * There is no restriction on the value of <code>beginIndex</code> and 1.362 + * <code>endIndex</code>. If <code>beginIndex</code> is negative, 1.363 + * it has the same effect as if it were zero. If <code>endIndex</code> is 1.364 + * greater than {@link #length()}, it has the same effect as if it were 1.365 + * {@link #length()}. If the <code>beginIndex</code> is greater than 1.366 + * the <code>endIndex</code>, <code>-1</code> is returned. 1.367 + * 1.368 + * @param ch the char to search for. 1.369 + * @param beginIndex the index to start the search from. 1.370 + * @param endIndex the index to finish the search at. 1.371 + * @return the index of the first occurrence of the character in the buffer 1.372 + * within the given bounds, or <code>-1</code> if the character does 1.373 + * not occur. 1.374 + */ 1.375 + public int indexOf(int ch, int beginIndex, int endIndex) { 1.376 + if (beginIndex < 0) { 1.377 + beginIndex = 0; 1.378 + } 1.379 + if (endIndex > this.len) { 1.380 + endIndex = this.len; 1.381 + } 1.382 + if (beginIndex > endIndex) { 1.383 + return -1; 1.384 + } 1.385 + for (int i = beginIndex; i < endIndex; i++) { 1.386 + if (this.buffer[i] == ch) { 1.387 + return i; 1.388 + } 1.389 + } 1.390 + return -1; 1.391 + } 1.392 + 1.393 + /** 1.394 + * Returns the index within this buffer of the first occurrence of the 1.395 + * specified character, starting the search at <code>0</code> and finishing 1.396 + * at {@link #length()}. If no such character occurs in this buffer within 1.397 + * those bounds, <code>-1</code> is returned. 1.398 + * 1.399 + * @param ch the char to search for. 1.400 + * @return the index of the first occurrence of the character in the 1.401 + * buffer, or <code>-1</code> if the character does not occur. 1.402 + */ 1.403 + public int indexOf(int ch) { 1.404 + return indexOf(ch, 0, this.len); 1.405 + } 1.406 + 1.407 + /** 1.408 + * Returns a substring of this buffer. The substring begins at the specified 1.409 + * <code>beginIndex</code> and extends to the character at index 1.410 + * <code>endIndex - 1</code>. 1.411 + * 1.412 + * @param beginIndex the beginning index, inclusive. 1.413 + * @param endIndex the ending index, exclusive. 1.414 + * @return the specified substring. 1.415 + * @exception StringIndexOutOfBoundsException if the 1.416 + * <code>beginIndex</code> is negative, or 1.417 + * <code>endIndex</code> is larger than the length of this 1.418 + * buffer, or <code>beginIndex</code> is larger than 1.419 + * <code>endIndex</code>. 1.420 + */ 1.421 + public String substring(int beginIndex, int endIndex) { 1.422 + return new String(this.buffer, beginIndex, endIndex - beginIndex); 1.423 + } 1.424 + 1.425 + /** 1.426 + * Returns a substring of this buffer with leading and trailing whitespace 1.427 + * omitted. The substring begins with the first non-whitespace character 1.428 + * from <code>beginIndex</code> and extends to the last 1.429 + * non-whitespace character with the index lesser than 1.430 + * <code>endIndex</code>. 1.431 + * 1.432 + * @param beginIndex the beginning index, inclusive. 1.433 + * @param endIndex the ending index, exclusive. 1.434 + * @return the specified substring. 1.435 + * @exception IndexOutOfBoundsException if the 1.436 + * <code>beginIndex</code> is negative, or 1.437 + * <code>endIndex</code> is larger than the length of this 1.438 + * buffer, or <code>beginIndex</code> is larger than 1.439 + * <code>endIndex</code>. 1.440 + */ 1.441 + public String substringTrimmed(int beginIndex, int endIndex) { 1.442 + if (beginIndex < 0) { 1.443 + throw new IndexOutOfBoundsException("Negative beginIndex: "+beginIndex); 1.444 + } 1.445 + if (endIndex > this.len) { 1.446 + throw new IndexOutOfBoundsException("endIndex: "+endIndex+" > length: "+this.len); 1.447 + } 1.448 + if (beginIndex > endIndex) { 1.449 + throw new IndexOutOfBoundsException("beginIndex: "+beginIndex+" > endIndex: "+endIndex); 1.450 + } 1.451 + while (beginIndex < endIndex && HTTP.isWhitespace(this.buffer[beginIndex])) { 1.452 + beginIndex++; 1.453 + } 1.454 + while (endIndex > beginIndex && HTTP.isWhitespace(this.buffer[endIndex - 1])) { 1.455 + endIndex--; 1.456 + } 1.457 + return new String(this.buffer, beginIndex, endIndex - beginIndex); 1.458 + } 1.459 + 1.460 + public String toString() { 1.461 + return new String(this.buffer, 0, this.len); 1.462 + } 1.463 + 1.464 +}