Search

2025-01-18

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
복사