FieldParser class에서의 지역변수[limit, pos, matchIndex, inQuote, isQuoteField] 등을 초기화 메서드를 이용하여 초기화.
기존 Field parse시에 field 길이 연산로직을 메서드로 분리
package parserTest;
import java.util.ArrayList;
import java.util.List;
public class FieldParser implements CSVParser<List<String>>{
private final InternalBuffer buffer;
private final CSVConfig csvConfig;
private final CSVParser<List<String>> commentParser;
private final StringBuilder builder = new StringBuilder();
private int limit;
private int pos;
private int matchIndex;
private boolean inQuote;
private boolean isQuoteField;
private List<String> fields;
public FieldParser(InternalBuffer buffer, CSVConfig csvConfig) {
this.buffer = buffer;
this.commentParser = new CommentParser(buffer, csvConfig);
this.csvConfig = csvConfig;
}
@Override
public List<String> parse() {
initialize();
if (commentParser.canParse()) return commentParser.parse();
for (int cursor = 0; cursor < limit; cursor++) {
char c = buffer.getRow()[cursor];
if (c == csvConfig.getQuote()) {
inQuote = !inQuote;
isQuoteField = true;
} else if (!inQuote && (matchIndex = incrementIfMatch(csvConfig.getFieldSeparator(), c, matchIndex)) == csvConfig.getFieldSeparatorLength()) {
if (isQuoteField) {
quoteFieldParse(pos, getFieldLength(cursor));
isQuoteField = false;
} else {
builder.append(buffer.getRow(), pos, getFieldLength(cursor));
}
addField(fields);
builder.setLength(0);
pos = cursor + 1;
matchIndex = 0;
}
}
if (isQuoteField) {
quoteFieldParse(pos, limit);
} else {
// 둘다 처리가 된다. 예를 들어 limit가 5이고 pos가 3일 경우도 처리되고, 둘다 동일한 길이를 가지면 결국 구분자가 마지막에 존재하기 때문에 빈값 추가
builder.append(buffer.getRow(), pos, limit - pos);
}
addField(fields);
return fields;
}
private int getFieldLength(int cursor){
return (matchIndex == 1 ? cursor : cursor - matchIndex + 1) - pos;
}
private void initialize(){
fields = new ArrayList<>();
limit = buffer.getRowLimit() - csvConfig.getFieldSeparatorLength();
pos = 0;
matchIndex = 0;
inQuote = false;
isQuoteField = false;
builder.setLength(0);
}
private void quoteFieldParse(int pos, int length) {
int doubleQuote = 0; // 1 이 되면 삭제
pos = pos + 1; // 시작점 찾아야함 근데 TODO 인용부호임을 보장함
int limit = length - 1; // 마지막이 인용부호 인지 확인 -1 TODO 인용부호임을 보장함
for (int cursor = pos; cursor < limit; cursor++) {
char c = buffer.getRow()[cursor];
if (c == csvConfig.getQuote()) {
doubleQuote++;
}
if (doubleQuote == 2) {
builder.append(buffer.getRow(), pos, cursor - pos);
doubleQuote = 0;
pos = cursor + 1;
}
}
if (pos < limit) {
builder.append(buffer.getRow(), pos, limit - pos);
}
}
private void addField(List<String> fields){
fields.add(builder.toString());
}
@Override
public boolean canParse() {
throw new UnsupportedOperationException("this method is Unsupported method");
}
}
Java
복사