| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.solr.internal.csv; |
| |
| /** |
| * A simple StringBuffer replacement that aims to |
| * reduce copying as much as possible. The buffer |
| * grows as necessary. |
| * This class is not thread safe. |
| */ |
| public class CharBuffer { |
| |
| private char[] c; |
| |
| /** |
| * Actually used number of characters in the array. |
| * It is also the index at which |
| * a new character will be inserted into <code>c</code>. |
| */ |
| private int length; |
| |
| /** |
| * Creates a new CharBuffer with an initial capacity of 32 characters. |
| */ |
| public CharBuffer() { |
| this(32); |
| } |
| |
| /** |
| * Creates a new CharBuffer with an initial capacity |
| * of <code>length</code> characters. |
| */ |
| public CharBuffer(final int length) { |
| if (length == 0) { |
| throw new IllegalArgumentException("Can't create an empty CharBuffer"); |
| } |
| this.c = new char[length]; |
| } |
| |
| /** |
| * Empties the buffer. The capacity still remains the same, so no memory is freed. |
| */ |
| public void clear() { |
| length = 0; |
| } |
| |
| /** |
| * Returns the number of characters in the buffer. |
| * @return the number of characters |
| */ |
| public int length() { |
| return length; |
| } |
| |
| /** |
| * Returns the current capacity of the buffer. |
| * @return the maximum number of characters that can be stored in this buffer without |
| * resizing it. |
| */ |
| public int capacity() { |
| return c.length; |
| } |
| |
| |
| /** |
| * Appends the contents of <code>cb</code> to the end of this CharBuffer. |
| * @param cb the CharBuffer to append or null |
| */ |
| public void append(final CharBuffer cb) { |
| if (cb == null) { |
| return; |
| } |
| provideCapacity(length + cb.length); |
| System.arraycopy(cb.c, 0, c, length, cb.length); |
| length += cb.length; |
| } |
| |
| /** |
| * Appends <code>s</code> to the end of this CharBuffer. |
| * This method involves copying the new data once! |
| * @param s the String to append or null |
| */ |
| public void append(final String s) { |
| if (s == null) { |
| return; |
| } |
| append(s.toCharArray()); |
| } |
| |
| /** |
| * Appends <code>sb</code> to the end of this CharBuffer. |
| * This method involves copying the new data once! |
| * @param sb the StringBuffer to append or null |
| */ |
| public void append(final StringBuffer sb) { |
| if (sb == null) { |
| return; |
| } |
| provideCapacity(length + sb.length()); |
| sb.getChars(0, sb.length(), c, length); |
| length += sb.length(); |
| } |
| |
| /** |
| * Appends <code>data</code> to the end of this CharBuffer. |
| * This method involves copying the new data once! |
| * @param data the char[] to append or null |
| */ |
| public void append(final char[] data) { |
| if (data == null) { |
| return; |
| } |
| provideCapacity(length + data.length); |
| System.arraycopy(data, 0, c, length, data.length); |
| length += data.length; |
| } |
| |
| /** |
| * Appends a single character to the end of this CharBuffer. |
| * This method involves copying the new data once! |
| * @param data the char to append |
| */ |
| public void append(final char data) { |
| provideCapacity(length + 1); |
| c[length] = data; |
| length++; |
| } |
| |
| /** |
| * Shrinks the capacity of the buffer to the current length if necessary. |
| * This method involves copying the data once! |
| */ |
| public void shrink() { |
| if (c.length == length) { |
| return; |
| } |
| char[] newc = new char[length]; |
| System.arraycopy(c, 0, newc, 0, length); |
| c = newc; |
| } |
| |
| /** |
| * Removes trailing whitespace. |
| */ |
| public void trimTrailingWhitespace() { |
| while (length>0 && Character.isWhitespace(c[length-1])) { |
| length--; |
| } |
| } |
| |
| /** |
| * Returns the contents of the buffer as a char[]. The returned array may |
| * be the internal array of the buffer, so the caller must take care when |
| * modifying it. |
| * This method allows to avoid copying if the caller knows the exact capacity |
| * before. |
| */ |
| public char[] getCharacters() { |
| if (c.length == length) { |
| return c; |
| } |
| char[] chars = new char[length]; |
| System.arraycopy(c, 0, chars, 0, length); |
| return chars; |
| } |
| |
| /** |
| * Returns the character at the specified position. |
| */ |
| public char charAt(int pos) { |
| return c[pos]; |
| } |
| |
| /** |
| * Converts the contents of the buffer into a StringBuffer. |
| * This method involves copying the new data once! |
| */ |
| @Override |
| public String toString() { |
| return new String(c, 0, length); |
| } |
| |
| /** |
| * Copies the data into a new array of at least <code>capacity</code> size. |
| */ |
| public void provideCapacity(final int capacity) { |
| if (c.length >= capacity) { |
| return; |
| } |
| int newcapacity = ((capacity*3)>>1) + 1; |
| char[] newc = new char[newcapacity]; |
| System.arraycopy(c, 0, newc, 0, length); |
| c = newc; |
| } |
| } |