TabooLib/src/main/src/me/skymc/taboolib/csvutils/CsvReader.java

1111 lines
47 KiB
Java

package me.skymc.taboolib.csvutils;
import java.nio.charset.*;
import java.text.*;
import java.io.*;
import java.util.*;
public class CsvReader
{
private Reader inputStream;
private String fileName;
private UserSettings userSettings;
private Charset charset;
private boolean useCustomRecordDelimiter;
private DataBuffer dataBuffer;
private ColumnBuffer columnBuffer;
private RawRecordBuffer rawBuffer;
private boolean[] isQualified;
private String rawRecord;
private HeadersHolder headersHolder;
private boolean startedColumn;
private boolean startedWithQualifier;
private boolean hasMoreData;
private char lastLetter;
private boolean hasReadNextLine;
private int columnsCount;
private long currentRecord;
private String[] values;
private boolean initialized;
private boolean closed;
public static final int ESCAPE_MODE_DOUBLED = 1;
public static final int ESCAPE_MODE_BACKSLASH = 2;
public CsvReader(final String fileName, final char delimiter, final Charset charset) throws FileNotFoundException {
this.inputStream = null;
this.fileName = null;
this.userSettings = new UserSettings();
this.charset = null;
this.useCustomRecordDelimiter = false;
this.dataBuffer = new DataBuffer();
this.columnBuffer = new ColumnBuffer();
this.rawBuffer = new RawRecordBuffer();
this.isQualified = null;
this.rawRecord = "";
this.headersHolder = new HeadersHolder();
this.startedColumn = false;
this.startedWithQualifier = false;
this.hasMoreData = true;
this.lastLetter = '\0';
this.hasReadNextLine = false;
this.columnsCount = 0;
this.currentRecord = 0L;
this.values = new String[10];
this.initialized = false;
this.closed = false;
if (fileName == null) {
throw new IllegalArgumentException("Parameter fileName can not be null.");
}
if (charset == null) {
throw new IllegalArgumentException("Parameter charset can not be null.");
}
if (!new File(fileName).exists()) {
throw new FileNotFoundException("File " + fileName + " does not exist.");
}
this.fileName = fileName;
this.userSettings.Delimiter = delimiter;
this.charset = charset;
this.isQualified = new boolean[this.values.length];
}
public CsvReader(final String s, final char c) throws FileNotFoundException {
this(s, c, Charset.forName("ISO-8859-1"));
}
public CsvReader(final String s) throws FileNotFoundException {
this(s, ',');
}
public CsvReader(final Reader inputStream, final char delimiter) {
this.inputStream = null;
this.fileName = null;
this.userSettings = new UserSettings();
this.charset = null;
this.useCustomRecordDelimiter = false;
this.dataBuffer = new DataBuffer();
this.columnBuffer = new ColumnBuffer();
this.rawBuffer = new RawRecordBuffer();
this.isQualified = null;
this.rawRecord = "";
this.headersHolder = new HeadersHolder();
this.startedColumn = false;
this.startedWithQualifier = false;
this.hasMoreData = true;
this.lastLetter = '\0';
this.hasReadNextLine = false;
this.columnsCount = 0;
this.currentRecord = 0L;
this.values = new String[10];
this.initialized = false;
this.closed = false;
if (inputStream == null) {
throw new IllegalArgumentException("Parameter inputStream can not be null.");
}
this.inputStream = inputStream;
this.userSettings.Delimiter = delimiter;
this.initialized = true;
this.isQualified = new boolean[this.values.length];
}
public CsvReader(final Reader reader) {
this(reader, ',');
}
public CsvReader(final InputStream inputStream, final char c, final Charset charset) {
this(new InputStreamReader(inputStream, charset), c);
}
public CsvReader(final InputStream inputStream, final Charset charset) {
this(new InputStreamReader(inputStream, charset));
}
public boolean getCaptureRawRecord() {
return this.userSettings.CaptureRawRecord;
}
public void setCaptureRawRecord(final boolean captureRawRecord) {
this.userSettings.CaptureRawRecord = captureRawRecord;
}
public String getRawRecord() {
return this.rawRecord;
}
public boolean getTrimWhitespace() {
return this.userSettings.TrimWhitespace;
}
public void setTrimWhitespace(final boolean trimWhitespace) {
this.userSettings.TrimWhitespace = trimWhitespace;
}
public char getDelimiter() {
return this.userSettings.Delimiter;
}
public void setDelimiter(final char delimiter) {
this.userSettings.Delimiter = delimiter;
}
public char getRecordDelimiter() {
return this.userSettings.RecordDelimiter;
}
public void setRecordDelimiter(final char recordDelimiter) {
this.useCustomRecordDelimiter = true;
this.userSettings.RecordDelimiter = recordDelimiter;
}
public char getTextQualifier() {
return this.userSettings.TextQualifier;
}
public void setTextQualifier(final char textQualifier) {
this.userSettings.TextQualifier = textQualifier;
}
public boolean getUseTextQualifier() {
return this.userSettings.UseTextQualifier;
}
public void setUseTextQualifier(final boolean useTextQualifier) {
this.userSettings.UseTextQualifier = useTextQualifier;
}
public char getComment() {
return this.userSettings.Comment;
}
public void setComment(final char comment) {
this.userSettings.Comment = comment;
}
public boolean getUseComments() {
return this.userSettings.UseComments;
}
public void setUseComments(final boolean useComments) {
this.userSettings.UseComments = useComments;
}
public int getEscapeMode() {
return this.userSettings.EscapeMode;
}
public void setEscapeMode(final int escapeMode) throws IllegalArgumentException {
if (escapeMode != 1 && escapeMode != 2) {
throw new IllegalArgumentException("Parameter escapeMode must be a valid value.");
}
this.userSettings.EscapeMode = escapeMode;
}
public boolean getSkipEmptyRecords() {
return this.userSettings.SkipEmptyRecords;
}
public void setSkipEmptyRecords(final boolean skipEmptyRecords) {
this.userSettings.SkipEmptyRecords = skipEmptyRecords;
}
public boolean getSafetySwitch() {
return this.userSettings.SafetySwitch;
}
public void setSafetySwitch(final boolean safetySwitch) {
this.userSettings.SafetySwitch = safetySwitch;
}
public int getColumnCount() {
return this.columnsCount;
}
public long getCurrentRecord() {
return this.currentRecord - 1L;
}
// TODO 2017-11-29 18:38:13 UPDATED
public long setCurrentRecord(long currentRecord) {
return this.currentRecord = currentRecord;
}
public int getHeaderCount() {
return this.headersHolder.Length;
}
public String[] getHeaders() throws IOException {
this.checkClosed();
if (this.headersHolder.Headers == null) {
return null;
}
final String[] array = new String[this.headersHolder.Length];
System.arraycopy(this.headersHolder.Headers, 0, array, 0, this.headersHolder.Length);
return array;
}
public void setHeaders(final String[] headers) {
this.headersHolder.Headers = headers;
this.headersHolder.IndexByName.clear();
if (headers != null) {
this.headersHolder.Length = headers.length;
}
else {
this.headersHolder.Length = 0;
}
for (int i = 0; i < this.headersHolder.Length; ++i) {
this.headersHolder.IndexByName.put(headers[i], i);
}
}
public String[] getValues() throws IOException {
this.checkClosed();
final String[] array = new String[this.columnsCount];
System.arraycopy(this.values, 0, array, 0, this.columnsCount);
return array;
}
public String get(final int n) throws IOException {
this.checkClosed();
if (n > -1 && n < this.columnsCount) {
return this.values[n];
}
return "";
}
public String get(final String s) throws IOException {
this.checkClosed();
return this.get(this.getIndex(s));
}
public static CsvReader parse(final String s) {
if (s == null) {
throw new IllegalArgumentException("Parameter data can not be null.");
}
return new CsvReader(new StringReader(s));
}
public boolean readRecord() throws IOException {
this.checkClosed();
this.columnsCount = 0;
this.rawBuffer.Position = 0;
this.dataBuffer.LineStart = this.dataBuffer.Position;
this.hasReadNextLine = false;
if (this.hasMoreData) {
do {
if (this.dataBuffer.Position == this.dataBuffer.Count) {
this.checkDataLength();
}
else {
this.startedWithQualifier = false;
char c = this.dataBuffer.Buffer[this.dataBuffer.Position];
if (this.userSettings.UseTextQualifier && c == this.userSettings.TextQualifier) {
this.lastLetter = c;
this.startedColumn = true;
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
this.startedWithQualifier = true;
int n = 0;
char textQualifier = this.userSettings.TextQualifier;
if (this.userSettings.EscapeMode == 2) {
textQualifier = '\\';
}
int n2 = 0;
int n3 = 0;
int n4 = 0;
int n5 = 1;
int n6 = 0;
char c2 = '\0';
final DataBuffer dataBuffer = this.dataBuffer;
++dataBuffer.Position;
do {
if (this.dataBuffer.Position == this.dataBuffer.Count) {
this.checkDataLength();
}
else {
final char lastLetter = this.dataBuffer.Buffer[this.dataBuffer.Position];
if (n2 != 0) {
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
if (lastLetter == this.userSettings.Delimiter) {
this.endColumn();
}
else if ((!this.useCustomRecordDelimiter && (lastLetter == '\r' || lastLetter == '\n')) || (this.useCustomRecordDelimiter && lastLetter == this.userSettings.RecordDelimiter)) {
this.endColumn();
this.endRecord();
}
}
else if (n4 != 0) {
++n6;
switch (n5) {
case 1: {
c2 = (char)((char)(c2 * '\u0010') + hexToDec(lastLetter));
if (n6 == 4) {
n4 = 0;
break;
}
break;
}
case 2: {
c2 = (char)((char)(c2 * '\b') + (char)(lastLetter - '0'));
if (n6 == 3) {
n4 = 0;
break;
}
break;
}
case 3: {
c2 = (char)((char)(c2 * '\n') + (char)(lastLetter - '0'));
if (n6 == 3) {
n4 = 0;
break;
}
break;
}
case 4: {
c2 = (char)((char)(c2 * '\u0010') + hexToDec(lastLetter));
if (n6 == 2) {
n4 = 0;
break;
}
break;
}
}
if (n4 == 0) {
this.appendLetter(c2);
}
else {
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
}
}
else if (lastLetter == this.userSettings.TextQualifier) {
if (n3 != 0) {
n3 = 0;
n = 0;
}
else {
this.updateCurrentValue();
if (this.userSettings.EscapeMode == 1) {
n3 = 1;
}
n = 1;
}
}
else if (this.userSettings.EscapeMode == 2 && n3 != 0) {
switch (lastLetter) {
case 'n': {
this.appendLetter('\n');
break;
}
case 'r': {
this.appendLetter('\r');
break;
}
case 't': {
this.appendLetter('\t');
break;
}
case 'b': {
this.appendLetter('\b');
break;
}
case 'f': {
this.appendLetter('\f');
break;
}
case 'e': {
this.appendLetter('\u001b');
break;
}
case 'v': {
this.appendLetter('\u000b');
break;
}
case 'a': {
this.appendLetter('\u0007');
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
n5 = 2;
n4 = 1;
n6 = 1;
c2 = (char)(lastLetter - '0');
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
break;
}
case 'D':
case 'O':
case 'U':
case 'X':
case 'd':
case 'o':
case 'u':
case 'x': {
switch (lastLetter) {
case 'U':
case 'u': {
n5 = 1;
break;
}
case 'X':
case 'x': {
n5 = 4;
break;
}
case 'O':
case 'o': {
n5 = 2;
break;
}
case 'D':
case 'd': {
n5 = 3;
break;
}
}
n4 = 1;
n6 = 0;
c2 = '\0';
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
break;
}
}
n3 = 0;
}
else if (lastLetter == textQualifier) {
this.updateCurrentValue();
n3 = 1;
}
else if (n != 0) {
if (lastLetter == this.userSettings.Delimiter) {
this.endColumn();
}
else if ((!this.useCustomRecordDelimiter && (lastLetter == '\r' || lastLetter == '\n')) || (this.useCustomRecordDelimiter && lastLetter == this.userSettings.RecordDelimiter)) {
this.endColumn();
this.endRecord();
}
else {
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
n2 = 1;
}
n = 0;
}
this.lastLetter = lastLetter;
if (!this.startedColumn) {
continue;
}
final DataBuffer dataBuffer2 = this.dataBuffer;
++dataBuffer2.Position;
if (this.userSettings.SafetySwitch && this.dataBuffer.Position - this.dataBuffer.ColumnStart + this.columnBuffer.Position > 100000) {
this.close();
throw new IOException("Maximum column length of 100,000 exceeded in column " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting column lengths greater than 100,000 characters to" + " avoid this error.");
}
continue;
}
} while (this.hasMoreData && this.startedColumn);
}
else if (c == this.userSettings.Delimiter) {
this.lastLetter = c;
this.endColumn();
}
else if (this.useCustomRecordDelimiter && c == this.userSettings.RecordDelimiter) {
if (this.startedColumn || this.columnsCount > 0 || !this.userSettings.SkipEmptyRecords) {
this.endColumn();
this.endRecord();
}
else {
this.dataBuffer.LineStart = this.dataBuffer.Position + 1;
}
this.lastLetter = c;
}
else if (!this.useCustomRecordDelimiter && (c == '\r' || c == '\n')) {
if (this.startedColumn || this.columnsCount > 0 || (!this.userSettings.SkipEmptyRecords && (c == '\r' || this.lastLetter != '\r'))) {
this.endColumn();
this.endRecord();
}
else {
this.dataBuffer.LineStart = this.dataBuffer.Position + 1;
}
this.lastLetter = c;
}
else if (this.userSettings.UseComments && this.columnsCount == 0 && c == this.userSettings.Comment) {
this.lastLetter = c;
this.skipLine();
}
else if (this.userSettings.TrimWhitespace && (c == ' ' || c == '\t')) {
this.startedColumn = true;
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
}
else {
this.startedColumn = true;
this.dataBuffer.ColumnStart = this.dataBuffer.Position;
int n7 = 0;
int n8 = 0;
int n9 = 1;
int n10 = 0;
char c3 = '\0';
int n11 = 1;
do {
if (n11 == 0 && this.dataBuffer.Position == this.dataBuffer.Count) {
this.checkDataLength();
}
else {
if (n11 == 0) {
c = this.dataBuffer.Buffer[this.dataBuffer.Position];
}
if (!this.userSettings.UseTextQualifier && this.userSettings.EscapeMode == 2 && c == '\\') {
if (n7 != 0) {
n7 = 0;
}
else {
this.updateCurrentValue();
n7 = 1;
}
}
else if (n8 != 0) {
++n10;
switch (n9) {
case 1: {
c3 = (char)((char)(c3 * '\u0010') + hexToDec(c));
if (n10 == 4) {
n8 = 0;
break;
}
break;
}
case 2: {
c3 = (char)((char)(c3 * '\b') + (char)(c - '0'));
if (n10 == 3) {
n8 = 0;
break;
}
break;
}
case 3: {
c3 = (char)((char)(c3 * '\n') + (char)(c - '0'));
if (n10 == 3) {
n8 = 0;
break;
}
break;
}
case 4: {
c3 = (char)((char)(c3 * '\u0010') + hexToDec(c));
if (n10 == 2) {
n8 = 0;
break;
}
break;
}
}
if (n8 == 0) {
this.appendLetter(c3);
}
else {
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
}
}
else if (this.userSettings.EscapeMode == 2 && n7 != 0) {
switch (c) {
case 'n': {
this.appendLetter('\n');
break;
}
case 'r': {
this.appendLetter('\r');
break;
}
case 't': {
this.appendLetter('\t');
break;
}
case 'b': {
this.appendLetter('\b');
break;
}
case 'f': {
this.appendLetter('\f');
break;
}
case 'e': {
this.appendLetter('\u001b');
break;
}
case 'v': {
this.appendLetter('\u000b');
break;
}
case 'a': {
this.appendLetter('\u0007');
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': {
n9 = 2;
n8 = 1;
n10 = 1;
c3 = (char)(c - '0');
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
break;
}
case 'D':
case 'O':
case 'U':
case 'X':
case 'd':
case 'o':
case 'u':
case 'x': {
switch (c) {
case 'U':
case 'u': {
n9 = 1;
break;
}
case 'X':
case 'x': {
n9 = 4;
break;
}
case 'O':
case 'o': {
n9 = 2;
break;
}
case 'D':
case 'd': {
n9 = 3;
break;
}
}
n8 = 1;
n10 = 0;
c3 = '\0';
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
break;
}
}
n7 = 0;
}
else if (c == this.userSettings.Delimiter) {
this.endColumn();
}
else if ((!this.useCustomRecordDelimiter && (c == '\r' || c == '\n')) || (this.useCustomRecordDelimiter && c == this.userSettings.RecordDelimiter)) {
this.endColumn();
this.endRecord();
}
this.lastLetter = c;
n11 = 0;
if (!this.startedColumn) {
continue;
}
final DataBuffer dataBuffer3 = this.dataBuffer;
++dataBuffer3.Position;
if (this.userSettings.SafetySwitch && this.dataBuffer.Position - this.dataBuffer.ColumnStart + this.columnBuffer.Position > 100000) {
this.close();
throw new IOException("Maximum column length of 100,000 exceeded in column " + NumberFormat.getIntegerInstance().format(this.columnsCount) + " in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting column lengths greater than 100,000 characters to" + " avoid this error.");
}
continue;
}
} while (this.hasMoreData && this.startedColumn);
}
if (!this.hasMoreData) {
continue;
}
final DataBuffer dataBuffer4 = this.dataBuffer;
++dataBuffer4.Position;
}
} while (this.hasMoreData && !this.hasReadNextLine);
if (this.startedColumn || this.lastLetter == this.userSettings.Delimiter) {
this.endColumn();
this.endRecord();
}
}
if (this.userSettings.CaptureRawRecord) {
if (this.hasMoreData) {
if (this.rawBuffer.Position == 0) {
this.rawRecord = new String(this.dataBuffer.Buffer, this.dataBuffer.LineStart, this.dataBuffer.Position - this.dataBuffer.LineStart - 1);
}
else {
this.rawRecord = new String(this.rawBuffer.Buffer, 0, this.rawBuffer.Position) + new String(this.dataBuffer.Buffer, this.dataBuffer.LineStart, this.dataBuffer.Position - this.dataBuffer.LineStart - 1);
}
}
else {
this.rawRecord = new String(this.rawBuffer.Buffer, 0, this.rawBuffer.Position);
}
}
else {
this.rawRecord = "";
}
return this.hasReadNextLine;
}
private void checkDataLength() throws IOException {
if (!this.initialized) {
if (this.fileName != null) {
this.inputStream = new BufferedReader(new InputStreamReader(new FileInputStream(this.fileName), this.charset), 4096);
}
this.charset = null;
this.initialized = true;
}
this.updateCurrentValue();
if (this.userSettings.CaptureRawRecord && this.dataBuffer.Count > 0) {
if (this.rawBuffer.Buffer.length - this.rawBuffer.Position < this.dataBuffer.Count - this.dataBuffer.LineStart) {
final char[] buffer = new char[this.rawBuffer.Buffer.length + Math.max(this.dataBuffer.Count - this.dataBuffer.LineStart, this.rawBuffer.Buffer.length)];
System.arraycopy(this.rawBuffer.Buffer, 0, buffer, 0, this.rawBuffer.Position);
this.rawBuffer.Buffer = buffer;
}
System.arraycopy(this.dataBuffer.Buffer, this.dataBuffer.LineStart, this.rawBuffer.Buffer, this.rawBuffer.Position, this.dataBuffer.Count - this.dataBuffer.LineStart);
final RawRecordBuffer rawBuffer = this.rawBuffer;
rawBuffer.Position += this.dataBuffer.Count - this.dataBuffer.LineStart;
}
try {
this.dataBuffer.Count = this.inputStream.read(this.dataBuffer.Buffer, 0, this.dataBuffer.Buffer.length);
}
catch (IOException ex) {
this.close();
throw ex;
}
if (this.dataBuffer.Count == -1) {
this.hasMoreData = false;
}
this.dataBuffer.Position = 0;
this.dataBuffer.LineStart = 0;
this.dataBuffer.ColumnStart = 0;
}
public boolean readHeaders() throws IOException {
final boolean record = this.readRecord();
this.headersHolder.Length = this.columnsCount;
this.headersHolder.Headers = new String[this.columnsCount];
for (int i = 0; i < this.headersHolder.Length; ++i) {
final String value = this.get(i);
this.headersHolder.Headers[i] = value;
this.headersHolder.IndexByName.put(value, i);
}
if (record) {
--this.currentRecord;
}
this.columnsCount = 0;
return record;
}
public String getHeader(final int n) throws IOException {
this.checkClosed();
if (n > -1 && n < this.headersHolder.Length) {
return this.headersHolder.Headers[n];
}
return "";
}
public boolean isQualified(final int n) throws IOException {
this.checkClosed();
return n < this.columnsCount && n > -1 && this.isQualified[n];
}
public void endColumn() throws IOException {
String s = "";
if (this.startedColumn) {
if (this.columnBuffer.Position == 0) {
if (this.dataBuffer.ColumnStart < this.dataBuffer.Position) {
int n = this.dataBuffer.Position - 1;
if (this.userSettings.TrimWhitespace && !this.startedWithQualifier) {
while (n >= this.dataBuffer.ColumnStart && (this.dataBuffer.Buffer[n] == ' ' || this.dataBuffer.Buffer[n] == '\t')) {
--n;
}
}
s = new String(this.dataBuffer.Buffer, this.dataBuffer.ColumnStart, n - this.dataBuffer.ColumnStart + 1);
}
}
else {
this.updateCurrentValue();
int n2 = this.columnBuffer.Position - 1;
if (this.userSettings.TrimWhitespace && !this.startedWithQualifier) {
while (n2 >= 0 && (this.columnBuffer.Buffer[n2] == ' ' || this.columnBuffer.Buffer[n2] == ' ')) {
--n2;
}
}
s = new String(this.columnBuffer.Buffer, 0, n2 + 1);
}
}
this.columnBuffer.Position = 0;
this.startedColumn = false;
if (this.columnsCount >= 100000 && this.userSettings.SafetySwitch) {
this.close();
throw new IOException("Maximum column count of 100,000 exceeded in record " + NumberFormat.getIntegerInstance().format(this.currentRecord) + ". Set the SafetySwitch property to false" + " if you're expecting more than 100,000 columns per record to" + " avoid this error.");
}
if (this.columnsCount == this.values.length) {
final int n3 = this.values.length * 2;
final String[] values = new String[n3];
System.arraycopy(this.values, 0, values, 0, this.values.length);
this.values = values;
final boolean[] isQualified = new boolean[n3];
System.arraycopy(this.isQualified, 0, isQualified, 0, this.isQualified.length);
this.isQualified = isQualified;
}
this.values[this.columnsCount] = s;
this.isQualified[this.columnsCount] = this.startedWithQualifier;
++this.columnsCount;
}
private void appendLetter(final char c) {
if (this.columnBuffer.Position == this.columnBuffer.Buffer.length) {
final char[] buffer = new char[this.columnBuffer.Buffer.length * 2];
System.arraycopy(this.columnBuffer.Buffer, 0, buffer, 0, this.columnBuffer.Position);
this.columnBuffer.Buffer = buffer;
}
this.columnBuffer.Buffer[this.columnBuffer.Position++] = c;
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
}
private void updateCurrentValue() {
if (this.startedColumn && this.dataBuffer.ColumnStart < this.dataBuffer.Position) {
if (this.columnBuffer.Buffer.length - this.columnBuffer.Position < this.dataBuffer.Position - this.dataBuffer.ColumnStart) {
final char[] buffer = new char[this.columnBuffer.Buffer.length + Math.max(this.dataBuffer.Position - this.dataBuffer.ColumnStart, this.columnBuffer.Buffer.length)];
System.arraycopy(this.columnBuffer.Buffer, 0, buffer, 0, this.columnBuffer.Position);
this.columnBuffer.Buffer = buffer;
}
System.arraycopy(this.dataBuffer.Buffer, this.dataBuffer.ColumnStart, this.columnBuffer.Buffer, this.columnBuffer.Position, this.dataBuffer.Position - this.dataBuffer.ColumnStart);
final ColumnBuffer columnBuffer = this.columnBuffer;
columnBuffer.Position += this.dataBuffer.Position - this.dataBuffer.ColumnStart;
}
this.dataBuffer.ColumnStart = this.dataBuffer.Position + 1;
}
public void endRecord() throws IOException {
this.hasReadNextLine = true;
++this.currentRecord;
}
public int getIndex(final String s) throws IOException {
this.checkClosed();
final Integer value = this.headersHolder.IndexByName.get(s);
if (value != null) {
return value;
}
return -1;
}
public boolean skipRecord() throws IOException {
this.checkClosed();
boolean record = false;
if (this.hasMoreData) {
record = this.readRecord();
if (record) {
--this.currentRecord;
}
}
return record;
}
public boolean skipLine() throws IOException {
this.checkClosed();
this.columnsCount = 0;
boolean b = false;
if (this.hasMoreData) {
boolean b2 = false;
do {
if (this.dataBuffer.Position == this.dataBuffer.Count) {
this.checkDataLength();
}
else {
b = true;
final char lastLetter = this.dataBuffer.Buffer[this.dataBuffer.Position];
if (lastLetter == '\r' || lastLetter == '\n') {
b2 = true;
}
this.lastLetter = lastLetter;
if (b2) {
continue;
}
final DataBuffer dataBuffer = this.dataBuffer;
++dataBuffer.Position;
}
} while (this.hasMoreData && !b2);
this.columnBuffer.Position = 0;
this.dataBuffer.LineStart = this.dataBuffer.Position + 1;
}
this.rawBuffer.Position = 0;
this.rawRecord = "";
return b;
}
public void close() {
if (!this.closed) {
this.close(true);
this.closed = true;
}
}
private void close(final boolean b) {
if (!this.closed) {
if (b) {
this.charset = null;
this.headersHolder.Headers = null;
this.headersHolder.IndexByName = null;
this.dataBuffer.Buffer = null;
this.columnBuffer.Buffer = null;
this.rawBuffer.Buffer = null;
}
try {
if (this.initialized) {
this.inputStream.close();
}
}
catch (Exception ex) {}
this.inputStream = null;
this.closed = true;
}
}
private void checkClosed() throws IOException {
if (this.closed) {
throw new IOException("This instance of the CsvReader class has already been closed.");
}
}
protected void finalize() {
this.close(false);
}
private static char hexToDec(final char c) {
char c2;
if (c >= 'a') {
c2 = (char)(c - 'a' + '\n');
}
else if (c >= 'A') {
c2 = (char)(c - 'A' + '\n');
}
else {
c2 = (char)(c - '0');
}
return c2;
}
private class StaticSettings
{
public static final int MAX_BUFFER_SIZE = 1024;
public static final int MAX_FILE_BUFFER_SIZE = 4096;
public static final int INITIAL_COLUMN_COUNT = 10;
public static final int INITIAL_COLUMN_BUFFER_SIZE = 50;
}
private class HeadersHolder
{
public String[] Headers;
public int Length;
public HashMap<String, Integer> IndexByName;
public HeadersHolder() {
this.Headers = null;
this.Length = 0;
this.IndexByName = new HashMap<>();
}
}
private class UserSettings
{
public boolean CaseSensitive;
public char TextQualifier;
public boolean TrimWhitespace;
public boolean UseTextQualifier;
public char Delimiter;
public char RecordDelimiter;
public char Comment;
public boolean UseComments;
public int EscapeMode;
public boolean SafetySwitch;
public boolean SkipEmptyRecords;
public boolean CaptureRawRecord;
public UserSettings() {
this.CaseSensitive = true;
this.TextQualifier = '\"';
this.TrimWhitespace = true;
this.UseTextQualifier = true;
this.Delimiter = ',';
this.RecordDelimiter = '\0';
this.Comment = '#';
this.UseComments = false;
this.EscapeMode = 1;
this.SafetySwitch = true;
this.SkipEmptyRecords = true;
this.CaptureRawRecord = true;
}
}
private class Letters
{
public static final char LF = '\n';
public static final char CR = '\r';
public static final char QUOTE = '\"';
public static final char COMMA = ',';
public static final char SPACE = ' ';
public static final char TAB = '\t';
public static final char POUND = '#';
public static final char BACKSLASH = '\\';
public static final char NULL = '\0';
public static final char BACKSPACE = '\b';
public static final char FORM_FEED = '\f';
public static final char ESCAPE = '\u001b';
public static final char VERTICAL_TAB = '\u000b';
public static final char ALERT = '\u0007';
}
private class RawRecordBuffer
{
public char[] Buffer;
public int Position;
public RawRecordBuffer() {
this.Buffer = new char[500];
this.Position = 0;
}
}
private class ColumnBuffer
{
public char[] Buffer;
public int Position;
public ColumnBuffer() {
this.Buffer = new char[50];
this.Position = 0;
}
}
private class DataBuffer
{
public char[] Buffer;
public int Position;
public int Count;
public int ColumnStart;
public int LineStart;
public DataBuffer() {
this.Buffer = new char[1024];
this.Position = 0;
this.Count = 0;
this.ColumnStart = 0;
this.LineStart = 0;
}
}
private class ComplexEscape
{
private static final int UNICODE = 1;
private static final int OCTAL = 2;
private static final int DECIMAL = 3;
private static final int HEX = 4;
}
}