Skip to content

Commit b0715ab

Browse files
committed
[ a84668e ] before bug fix 6
2 parents 10ebc1e + a84668e commit b0715ab

17 files changed

Lines changed: 910 additions & 499 deletions

checkstyle.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ limitations under the License.
3636
<!-- Checks for Tab characters -->
3737
<!-- See http://checkstyle.sourceforge.net/config_whitespace.html#FileTabCharacter -->
3838
<module name="FileTabCharacter">
39-
<property name="fileExtensions" value="java" />
39+
<property name="fileExtensions" value="java,xml" />
4040
</module>
4141

4242
<!-- Checks for white space at the end of the line -->

pom.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,11 @@ CSV files of various types.
127127
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
128128
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
129129
<commons.encoding>UTF-8</commons.encoding>
130-
<!--
130+
<!--
131131
Use 2.9.1 instead of 2.10; 2.10 seems to scan the 'target' dir
132-
and wants license headers in .properties to be the header for Java files.
132+
and wants license headers in .properties to be the header for Java files.
133133
-->
134-
<checkstyle.version>2.9.1</checkstyle.version>
134+
<checkstyle.version>2.12</checkstyle.version>
135135
<checkstyle.header.file>${basedir}/LICENSE-header.txt</checkstyle.header.file>
136136
</properties>
137137

@@ -194,15 +194,15 @@ CSV files of various types.
194194
<plugin>
195195
<groupId>org.apache.maven.plugins</groupId>
196196
<artifactId>maven-pmd-plugin</artifactId>
197-
<version>3.0.1</version>
197+
<version>3.1</version>
198198
<configuration>
199199
<targetJdk>${maven.compiler.target}</targetJdk>
200200
</configuration>
201201
</plugin>
202202
<plugin>
203203
<groupId>org.codehaus.mojo</groupId>
204204
<artifactId>findbugs-maven-plugin</artifactId>
205-
<version>2.5.2</version>
205+
<version>2.5.3</version>
206206
</plugin>
207207
<plugin>
208208
<groupId>org.codehaus.mojo</groupId>

src/main/java/org/apache/commons/csv/CSVParser.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.net.URL;
3030
import java.nio.charset.Charset;
3131
import java.util.ArrayList;
32+
import java.util.Collection;
3233
import java.util.Iterator;
3334
import java.util.LinkedHashMap;
3435
import java.util.List;
@@ -54,7 +55,7 @@
5455
* </p>
5556
* <p>
5657
* Alternatively parsers can also be created by passing a {@link Reader} directly to the sole constructor.
57-
*
58+
*
5859
* For those who like fluent APIs, parsers can be created using {@link CSVFormat#parse(java.io.Reader)} as a shortcut:
5960
* </p>
6061
* <pre>
@@ -197,8 +198,7 @@ public static CSVParser parse(final URL url, final Charset charset, final CSVFor
197198
Assertions.notNull(charset, "charset");
198199
Assertions.notNull(format, "format");
199200

200-
return new CSVParser(new InputStreamReader(url.openStream(),
201-
charset == null ? Charset.forName("UTF-8") : charset), format);
201+
return new CSVParser(new InputStreamReader(url.openStream(), charset), format);
202202
}
203203

204204
// the following objects are shared to reduce garbage
@@ -310,7 +310,22 @@ public long getRecordNumber() {
310310
* on parse error or input read-failure
311311
*/
312312
public List<CSVRecord> getRecords() throws IOException {
313-
final List<CSVRecord> records = new ArrayList<CSVRecord>();
313+
return getRecords(new ArrayList<CSVRecord>());
314+
}
315+
316+
/**
317+
* Parses the CSV input according to the given format and adds the content to the collection of {@link CSVRecord
318+
* CSVRecords}.
319+
* <p/>
320+
* The returned content starts at the current parse-position in the stream.
321+
*
322+
* @param records
323+
* The collection to add to.
324+
* @return a collection of {@link CSVRecord CSVRecords}, may be empty
325+
* @throws IOException
326+
* on parse error or input read-failure
327+
*/
328+
public <T extends Collection<CSVRecord>> T getRecords(T records) throws IOException {
314329
CSVRecord rec;
315330
while ((rec = this.nextRecord()) != null) {
316331
records.add(rec);
@@ -320,7 +335,7 @@ public List<CSVRecord> getRecords() throws IOException {
320335

321336
/**
322337
* Initializes the name to index mapping if the format defines a header.
323-
*
338+
*
324339
* @return null if the format has no header.
325340
*/
326341
private Map<String, Integer> initializeHeader() throws IOException {
@@ -450,6 +465,8 @@ CSVRecord nextRecord() throws IOException {
450465
sb.append(this.reusableToken.content);
451466
this.reusableToken.type = TOKEN; // Read another token
452467
break;
468+
default:
469+
throw new IllegalStateException("Unexpected Token type: " + this.reusableToken.type);
453470
}
454471
} while (this.reusableToken.type == TOKEN);
455472

src/main/java/org/apache/commons/csv/CSVPrinter.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@ private void printAndQuote(final Object object, final CharSequence value,
240240
return;
241241
}
242242
break;
243+
default:
244+
throw new IllegalStateException("Unexpected Quote value: " + quotePolicy);
243245
}
244246

245247
if (!quote) {
@@ -420,9 +422,9 @@ public void printRecords(final ResultSet resultSet) throws SQLException, IOExcep
420422
}
421423

422424
/**
423-
* Gets the target Appendable.
424-
*
425-
* @return the target Appendable.
425+
* Gets the target Appendable.
426+
*
427+
* @return the target Appendable.
426428
*/
427429
public Appendable getOut() {
428430
return this.out;

src/main/java/org/apache/commons/csv/CSVRecord.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ public Iterator<String> iterator() {
172172

173173
/**
174174
* Puts all values of this record into the given Map.
175-
*
175+
*
176176
* @param map The Map to populate.
177177
* @return the given map.
178178
*/
@@ -194,7 +194,7 @@ public int size() {
194194

195195
/**
196196
* Converts the values to a List.
197-
*
197+
*
198198
* TODO: Maybe make this public?
199199
* @return a new List
200200
*/
@@ -204,7 +204,7 @@ private List<String> toList() {
204204

205205
/**
206206
* Copies this record into a new Map. The new map is not connect
207-
*
207+
*
208208
* @return A new Map. The map is empty if the record has no headers.
209209
*/
210210
public Map<String, String> toMap() {

src/main/java/org/apache/commons/csv/Constants.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ final class Constants {
3939
static final char LF = '\n';
4040
static final char SP = ' ';
4141
static final char TAB = '\t';
42+
43+
/** ASCII record separator */
44+
static final char RS = 30;
45+
46+
/** ASCII unit separator */
47+
static final char US = 31;
48+
4249
static final String EMPTY = "";
4350

4451
/** The end of stream symbol */

src/main/java/org/apache/commons/csv/Lexer.java

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ final class Lexer {
5555
private final boolean ignoreEmptyLines;
5656

5757
/** The input stream */
58-
private final ExtendedBufferedReader in;
58+
private final ExtendedBufferedReader reader;
5959

6060
/** INTERNAL API. but ctor needs to be called dynamically by PerformanceTest class */
61-
Lexer(final CSVFormat format, final ExtendedBufferedReader in) {
62-
this.in = in;
61+
Lexer(final CSVFormat format, final ExtendedBufferedReader reader) {
62+
this.reader = reader;
6363
this.delimiter = format.getDelimiter();
6464
this.escape = mapNullToDisabled(format.getEscape());
6565
this.quoteChar = mapNullToDisabled(format.getQuoteChar());
@@ -82,10 +82,10 @@ final class Lexer {
8282
Token nextToken(final Token token) throws IOException {
8383

8484
// get the last read char (required for empty line detection)
85-
int lastChar = in.getLastChar();
85+
int lastChar = reader.getLastChar();
8686

8787
// read the next char and set eol
88-
int c = in.read();
88+
int c = reader.read();
8989
/*
9090
* Note: The following call will swallow LF if c == CR. But we don't need to know if the last char was CR or LF
9191
* - they are equivalent here.
@@ -97,7 +97,7 @@ Token nextToken(final Token token) throws IOException {
9797
while (eol && isStartOfLine(lastChar)) {
9898
// go on char ahead ...
9999
lastChar = c;
100-
c = in.read();
100+
c = reader.read();
101101
eol = readEndOfLine(c);
102102
// reached end of file without any content (empty line at the end)
103103
if (isEndOfFile(c)) {
@@ -116,7 +116,7 @@ Token nextToken(final Token token) throws IOException {
116116
}
117117

118118
if (isStartOfLine(lastChar) && isCommentStart(c)) {
119-
final String line = in.readLine();
119+
final String line = reader.readLine();
120120
if (line == null) {
121121
token.type = EOF;
122122
// don't set token.isReady here because no content
@@ -133,7 +133,7 @@ Token nextToken(final Token token) throws IOException {
133133
// ignore whitespaces at beginning of a token
134134
if (ignoreSurroundingSpaces) {
135135
while (isWhitespace(c) && !eol) {
136-
c = in.read();
136+
c = reader.read();
137137
eol = readEndOfLine(c);
138138
}
139139
}
@@ -198,14 +198,14 @@ private Token parseSimpleToken(final Token token, int ch) throws IOException {
198198
} else if (isEscape(ch)) {
199199
final int unescaped = readEscape();
200200
if (unescaped == Constants.END_OF_STREAM) { // unexpected char after escape
201-
token.content.append((char) ch).append((char) in.getLastChar());
201+
token.content.append((char) ch).append((char) reader.getLastChar());
202202
} else {
203203
token.content.append((char) unescaped);
204204
}
205-
ch = in.read(); // continue
205+
ch = reader.read(); // continue
206206
} else {
207207
token.content.append((char) ch);
208-
ch = in.read(); // continue
208+
ch = reader.read(); // continue
209209
}
210210
}
211211

@@ -241,24 +241,24 @@ private Token parseEncapsulatedToken(final Token token) throws IOException {
241241
final long startLineNumber = getCurrentLineNumber();
242242
int c;
243243
while (true) {
244-
c = in.read();
244+
c = reader.read();
245245

246246
if (isEscape(c)) {
247247
final int unescaped = readEscape();
248248
if (unescaped == Constants.END_OF_STREAM) { // unexpected char after escape
249-
token.content.append((char) c).append((char) in.getLastChar());
249+
token.content.append((char) c).append((char) reader.getLastChar());
250250
} else {
251251
token.content.append((char) unescaped);
252252
}
253253
} else if (isQuoteChar(c)) {
254-
if (isQuoteChar(in.lookAhead())) {
254+
if (isQuoteChar(reader.lookAhead())) {
255255
// double or escaped encapsulator -> add single encapsulator to token
256-
c = in.read();
256+
c = reader.read();
257257
token.content.append((char) c);
258258
} else {
259259
// token finish mark (encapsulator) reached: ignore whitespace till delimiter
260260
while (true) {
261-
c = in.read();
261+
c = reader.read();
262262
if (isDelimiter(c)) {
263263
token.type = TOKEN;
264264
return token;
@@ -297,7 +297,7 @@ private char mapNullToDisabled(final Character c) {
297297
* @return the current line number
298298
*/
299299
long getCurrentLineNumber() {
300-
return in.getCurrentLineNumber();
300+
return reader.getCurrentLineNumber();
301301
}
302302

303303
// TODO escape handling needs more work
@@ -314,7 +314,7 @@ long getCurrentLineNumber() {
314314
*/
315315
int readEscape() throws IOException {
316316
// the escape char has just been read (normally a backslash)
317-
final int ch = in.read();
317+
final int ch = reader.read();
318318
switch (ch) {
319319
case 'r':
320320
return CR;
@@ -361,15 +361,15 @@ void trimTrailingSpaces(final StringBuilder buffer) {
361361
*/
362362
boolean readEndOfLine(int ch) throws IOException {
363363
// check if we have \r\n...
364-
if (ch == CR && in.lookAhead() == LF) {
364+
if (ch == CR && reader.lookAhead() == LF) {
365365
// note: does not change ch outside of this method!
366-
ch = in.read();
366+
ch = reader.read();
367367
}
368368
return ch == LF || ch == CR;
369369
}
370370

371371
boolean isClosed() {
372-
return in.isClosed();
372+
return reader.isClosed();
373373
}
374374

375375
/**
@@ -426,6 +426,6 @@ private boolean isMetaChar(final int ch) {
426426
* If an I/O error occurs
427427
*/
428428
void close() throws IOException {
429-
in.close();
429+
reader.close();
430430
}
431431
}

src/test/java/org/apache/commons/csv/CSVFileParserTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public void testCSVFile() throws Exception {
124124
final int count = record.size();
125125
assertEquals(testName, readTestData(), count+":"+parsed);
126126
}
127+
parser.close();
127128
}
128129

129130
@Test
@@ -167,5 +168,6 @@ public void testCSVUrl() throws Exception {
167168
final int count = record.size();
168169
assertEquals(testName, readTestData(), count + ":" + parsed);
169170
}
171+
parser.close();
170172
}
171173
}

src/test/java/org/apache/commons/csv/CSVFormatTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static CSVFormat copy(final CSVFormat format) {
5555
public void testDelimiterSameAsCommentStartThrowsException() {
5656
CSVFormat.DEFAULT.withDelimiter('!').withCommentStart('!').validate();
5757
}
58-
58+
5959
@Test(expected = IllegalStateException.class)
6060
public void testDelimiterSameAsEscapeThrowsException() {
6161
CSVFormat.DEFAULT.withDelimiter('!').withEscape('!').validate();

0 commit comments

Comments
 (0)