Search

2025-01-15

line skip 추가
핵심은 기존 interface의 canParse 부분을 재활용하기 위하여 검증로직을 추가함. skip 할 수 있는 라인을 검증하는 부분을 추가
package parserTest; public class CSVConfig { private final char[] lineDelimiter; private final char[] fieldSeparator; private final char quote; private final char comment; private int skipLine = 0; public CSVConfig(String lineDelimiter, String fieldSeparator, char quote, char comment, int skipLine) { this.lineDelimiter = lineDelimiter.toCharArray(); this.fieldSeparator = fieldSeparator.toCharArray(); this.quote = quote; this.comment = comment; if (skipLine < 0){ throw new IllegalArgumentException(String.format("skipLine cannot be negative. Provided: %d", skipLine)); } this.skipLine = skipLine; } public boolean shouldSkipLine(int lineIndex){ return skipLine == 0 || lineIndex >= skipLine; } public int getLineDelimiterLength(){ return lineDelimiter.length; } public int getFieldSeparatorLength(){ return fieldSeparator.length; } public char[] getLineDelimiter() { return lineDelimiter; } public char[] getFieldSeparator() { return fieldSeparator; } public char getQuote() { return quote; } public char getComment() { return comment; } }
Java
복사
package parserTest; import org.apache.bcel.generic.IF_ACMPEQ; import java.io.Reader; import java.util.ArrayList; import java.util.List; public class RecordParser implements CSVParser<List<Record>> { private final InternalBuffer buffer; private final CSVConfig csvConfig; private final CSVParser<List<String>> fieldParser; private int order = 0; public RecordParser(Reader reader, int bufferCapacity ,CSVConfig csvConfig) { if (bufferCapacity <= 0) throw new IllegalArgumentException("Buffer capacity cannot be less than 1."); this.buffer = new InternalBuffer(reader, bufferCapacity); this.csvConfig = csvConfig; this.fieldParser = new FieldParser(buffer, new CommentParser(buffer, csvConfig),csvConfig); } @Override public List<Record> parse() { final List<Record> records = new ArrayList<>(); int matchIndex = 0; boolean inQuote = false; while (buffer.fill()) { int limit = buffer.getLimit(); for (int cursor = 0; cursor < limit; cursor++) { char c = buffer.charAt(cursor); if (c == csvConfig.getQuote()) { inQuote = !inQuote; continue; } if (!inQuote && (matchIndex = incrementIfMatch(csvConfig.getLineDelimiter(), c, matchIndex)) == csvConfig.getLineDelimiterLength()) { // buffer 의 길이를 넘어서 matchIndex를 발견할 경우 자르는 위치가 애매해짐 그렇기에 제외해서 넘길 수 없음 // 예를 들면 버퍼의 크기가 1024일때 마지막 (\r)문자열 중 일부만 끝날 경우 뒤의 1024 버퍼에서 matchIndex 만큼 빼버리면 음수가 나옴 if (canParse()){ int length = (matchIndex == 1 ? cursor + matchIndex : cursor + matchIndex - 1) - buffer.getPos(); buffer.mergeOrAppendChars(length); records.add(new Record(order, false, fieldParser.parse())); } buffer.setNewPosition(cursor + 1); matchIndex = 0; buffer.setRowLimit(0); } } if (buffer.notPosAtLimit()) { buffer.mergeOrAppendChars(buffer.getLimit() - buffer.getPos()); } } if (buffer.getRowLimit() != 0){ records.add(new Record(order, false, fieldParser.parse())); buffer.setRowLimit(0); } return records; } @Override public boolean canParse() { return csvConfig.shouldSkipLine(order++); // throw new UnsupportedOperationException("this method is Unsupported method"); } }
Java
복사