Replaced CharBuffer with StringBuilder (CSV-59)
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1300659 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f8294d2d22
commit
3cb5801a98
|
@ -235,7 +235,7 @@ class CSVLexer {
|
||||||
/** length of the initial token (content-)buffer */
|
/** length of the initial token (content-)buffer */
|
||||||
private static final int INITIAL_TOKEN_LENGTH = 50;
|
private static final int INITIAL_TOKEN_LENGTH = 50;
|
||||||
|
|
||||||
private final CharBuffer wsBuf = new CharBuffer();
|
private final StringBuilder wsBuf = new StringBuilder();
|
||||||
|
|
||||||
private final CSVFormat format;
|
private final CSVFormat format;
|
||||||
|
|
||||||
|
@ -267,13 +267,13 @@ class CSVLexer {
|
||||||
Type type = INVALID;
|
Type type = INVALID;
|
||||||
|
|
||||||
/** The content buffer. */
|
/** The content buffer. */
|
||||||
CharBuffer content = new CharBuffer(INITIAL_TOKEN_LENGTH);
|
StringBuilder content = new StringBuilder(INITIAL_TOKEN_LENGTH);
|
||||||
|
|
||||||
/** Token ready flag: indicates a valid token with content (ready for the parser). */
|
/** Token ready flag: indicates a valid token with content (ready for the parser). */
|
||||||
boolean isReady;
|
boolean isReady;
|
||||||
|
|
||||||
Token reset() {
|
Token reset() {
|
||||||
content.clear();
|
content.setLength(0);
|
||||||
type = INVALID;
|
type = INVALID;
|
||||||
isReady = false;
|
isReady = false;
|
||||||
return this;
|
return this;
|
||||||
|
@ -299,7 +299,7 @@ class CSVLexer {
|
||||||
* @throws IOException on stream access error
|
* @throws IOException on stream access error
|
||||||
*/
|
*/
|
||||||
Token nextToken(Token tkn) throws IOException {
|
Token nextToken(Token tkn) throws IOException {
|
||||||
wsBuf.clear(); // reuse
|
wsBuf.setLength(0); // reuse
|
||||||
|
|
||||||
// get the last read char (required for empty line detection)
|
// get the last read char (required for empty line detection)
|
||||||
int lastChar = in.readAgain();
|
int lastChar = in.readAgain();
|
||||||
|
@ -308,7 +308,6 @@ class CSVLexer {
|
||||||
/* note: unfortunately isEndOfLine may consumes a character silently.
|
/* note: unfortunately isEndOfLine may consumes a character silently.
|
||||||
* this has no effect outside of the method. so a simple workaround
|
* this has no effect outside of the method. so a simple workaround
|
||||||
* is to call 'readAgain' on the stream...
|
* is to call 'readAgain' on the stream...
|
||||||
* uh: might using objects instead of base-types (jdk1.5 autoboxing!)
|
|
||||||
*/
|
*/
|
||||||
int c = in.read();
|
int c = in.read();
|
||||||
boolean eol = isEndOfLine(c);
|
boolean eol = isEndOfLine(c);
|
||||||
|
@ -427,12 +426,17 @@ class CSVLexer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format.isTrailingSpacesIgnored()) {
|
if (format.isTrailingSpacesIgnored()) {
|
||||||
tkn.content.trimTrailingWhitespace();
|
trimTrailingSpaces(tkn.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tkn;
|
return tkn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void trimTrailingSpaces(StringBuilder buffer) {
|
||||||
|
while (buffer.length() > 0 && Character.isWhitespace(buffer.charAt(buffer.length() - 1))) {
|
||||||
|
buffer.setLength(buffer.length() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An encapsulated token lexer
|
* An encapsulated token lexer
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.commons.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.
|
|
||||||
*
|
|
||||||
* @author Ortwin Glück
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
CharBuffer() {
|
|
||||||
this(32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new CharBuffer with an initial capacity
|
|
||||||
* of <code>length</code> characters.
|
|
||||||
*/
|
|
||||||
CharBuffer(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.
|
|
||||||
*/
|
|
||||||
void clear() {
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of characters in the buffer.
|
|
||||||
*
|
|
||||||
* @return the number of characters
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
void append(CharBuffer cb) {
|
|
||||||
if (cb != null) {
|
|
||||||
ensureCapacity(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
|
|
||||||
*/
|
|
||||||
void append(String s) {
|
|
||||||
if (s != null) {
|
|
||||||
append(s.toCharArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
void append(char[] data) {
|
|
||||||
if (data != null) {
|
|
||||||
ensureCapacity(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
|
|
||||||
*/
|
|
||||||
void append(char data) {
|
|
||||||
ensureCapacity(length + 1);
|
|
||||||
c[length] = data;
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes trailing whitespace.
|
|
||||||
*/
|
|
||||||
void trimTrailingWhitespace() {
|
|
||||||
while (length > 0 && Character.isWhitespace(c[length - 1])) {
|
|
||||||
length--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the contents of the buffer into a StringBuffer.
|
|
||||||
* This method involves copying the new data once!
|
|
||||||
*
|
|
||||||
* @return the contents of the character buffer as a String
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new String(c, 0, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies the data into a new array of at least <code>capacity</code> size.
|
|
||||||
*
|
|
||||||
* @param capacity
|
|
||||||
*/
|
|
||||||
void ensureCapacity(int capacity) {
|
|
||||||
if (c.length < capacity) {
|
|
||||||
int newcapacity = ((capacity * 3) >> 1) + 1;
|
|
||||||
char[] newc = new char[newcapacity];
|
|
||||||
System.arraycopy(c, 0, newc, 0, length);
|
|
||||||
c = newc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,179 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.commons.csv;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Ortwin Glück
|
|
||||||
*/
|
|
||||||
public class CharBufferTest extends TestCase {
|
|
||||||
public void testCreate() {
|
|
||||||
CharBuffer cb = new CharBuffer();
|
|
||||||
assertEquals(0, cb.length());
|
|
||||||
try {
|
|
||||||
cb = new CharBuffer(0);
|
|
||||||
fail("Should not be possible");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
cb = new CharBuffer(128);
|
|
||||||
assertEquals(0, cb.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendChar() {
|
|
||||||
CharBuffer cb = new CharBuffer(1);
|
|
||||||
String expected = "";
|
|
||||||
for (char c = 'a'; c < 'z'; c++) {
|
|
||||||
cb.append(c);
|
|
||||||
expected += c;
|
|
||||||
assertEquals(expected, cb.toString());
|
|
||||||
assertEquals(expected.length(), cb.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendCharArray() {
|
|
||||||
CharBuffer cb = new CharBuffer(1);
|
|
||||||
char[] abcd = "abcd".toCharArray();
|
|
||||||
String expected = "";
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
cb.append(abcd);
|
|
||||||
expected += "abcd";
|
|
||||||
assertEquals(expected, cb.toString());
|
|
||||||
assertEquals(4 * (i + 1), cb.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendString() {
|
|
||||||
CharBuffer cb = new CharBuffer(1);
|
|
||||||
String abcd = "abcd";
|
|
||||||
String expected = "";
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
cb.append(abcd);
|
|
||||||
expected += abcd;
|
|
||||||
assertEquals(expected, cb.toString());
|
|
||||||
assertEquals(4 * (i + 1), cb.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendCharBuffer() {
|
|
||||||
CharBuffer cb = new CharBuffer(1);
|
|
||||||
CharBuffer abcd = new CharBuffer(17);
|
|
||||||
abcd.append("abcd");
|
|
||||||
String expected = "";
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
cb.append(abcd);
|
|
||||||
expected += "abcd";
|
|
||||||
assertEquals(expected, cb.toString());
|
|
||||||
assertEquals(4 * (i + 1), cb.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-- the following test cases have been adapted from the HttpComponents project
|
|
||||||
//-- written by Oleg Kalnichevski
|
|
||||||
|
|
||||||
public void testSimpleAppend() throws Exception {
|
|
||||||
CharBuffer buffer = new CharBuffer(16);
|
|
||||||
assertEquals(16, buffer.capacity());
|
|
||||||
assertEquals(0, buffer.length());
|
|
||||||
char[] b1 = buffer.toString().toCharArray();
|
|
||||||
assertNotNull(b1);
|
|
||||||
assertEquals(0, b1.length);
|
|
||||||
assertEquals(0, buffer.length());
|
|
||||||
|
|
||||||
char[] tmp = new char[]{'1', '2', '3', '4'};
|
|
||||||
buffer.append(tmp);
|
|
||||||
assertEquals(16, buffer.capacity());
|
|
||||||
assertEquals(4, buffer.length());
|
|
||||||
|
|
||||||
char[] b2 = buffer.toString().toCharArray();
|
|
||||||
assertNotNull(b2);
|
|
||||||
assertEquals(4, b2.length);
|
|
||||||
for (int i = 0; i < tmp.length; i++) {
|
|
||||||
assertEquals(tmp[i], b2[i]);
|
|
||||||
}
|
|
||||||
assertEquals("1234", buffer.toString());
|
|
||||||
|
|
||||||
buffer.clear();
|
|
||||||
assertEquals(16, buffer.capacity());
|
|
||||||
assertEquals(0, buffer.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendString2() throws Exception {
|
|
||||||
CharBuffer buffer = new CharBuffer(8);
|
|
||||||
buffer.append("stuff");
|
|
||||||
buffer.append(" and more stuff");
|
|
||||||
assertEquals("stuff and more stuff", buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendNull() throws Exception {
|
|
||||||
CharBuffer buffer = new CharBuffer(8);
|
|
||||||
|
|
||||||
buffer.append((String) null);
|
|
||||||
assertEquals("", buffer.toString());
|
|
||||||
|
|
||||||
buffer.append((CharBuffer) null);
|
|
||||||
assertEquals("", buffer.toString());
|
|
||||||
|
|
||||||
buffer.append((char[]) null);
|
|
||||||
assertEquals("", buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendCharArrayBuffer() throws Exception {
|
|
||||||
CharBuffer buffer1 = new CharBuffer(8);
|
|
||||||
buffer1.append(" and more stuff");
|
|
||||||
CharBuffer buffer2 = new CharBuffer(8);
|
|
||||||
buffer2.append("stuff");
|
|
||||||
buffer2.append(buffer1);
|
|
||||||
assertEquals("stuff and more stuff", buffer2.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testAppendSingleChar() throws Exception {
|
|
||||||
CharBuffer buffer = new CharBuffer(4);
|
|
||||||
buffer.append('1');
|
|
||||||
buffer.append('2');
|
|
||||||
buffer.append('3');
|
|
||||||
buffer.append('4');
|
|
||||||
buffer.append('5');
|
|
||||||
buffer.append('6');
|
|
||||||
assertEquals("123456", buffer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testProvideCapacity() throws Exception {
|
|
||||||
CharBuffer buffer = new CharBuffer(4);
|
|
||||||
buffer.ensureCapacity(2);
|
|
||||||
assertEquals(4, buffer.capacity());
|
|
||||||
buffer.ensureCapacity(8);
|
|
||||||
assertTrue(buffer.capacity() >= 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTrim() throws Exception {
|
|
||||||
CharBuffer buffer = new CharBuffer();
|
|
||||||
buffer.append(" ");
|
|
||||||
buffer.trimTrailingWhitespace();
|
|
||||||
assertEquals(0, buffer.length());
|
|
||||||
|
|
||||||
buffer = new CharBuffer();
|
|
||||||
buffer.append("Hello World! ");
|
|
||||||
buffer.trimTrailingWhitespace();
|
|
||||||
assertEquals("Hello World!", buffer.toString());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue