|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package com.github.javaparser; |
|
|
|
import com.github.javaparser.utils.LineSeparator; |
|
|
|
import java.io.IOException; |
|
import java.util.HashMap; |
|
import java.util.Map; |
|
import java.util.Optional; |
|
|
|
|
|
|
|
*/ |
|
public class LineEndingProcessingProvider implements Provider { |
|
|
|
private static final int EOF = -1; |
|
|
|
private static final int DEFAULT_BUFFER_SIZE = 2048; |
|
|
|
|
|
|
|
*/ |
|
private final Provider _input; |
|
|
|
|
|
|
|
*/ |
|
private final char[] _data; |
|
|
|
|
|
|
|
*/ |
|
private int _len = 0; |
|
|
|
|
|
|
|
*/ |
|
private int _pos = 0; |
|
|
|
private final Map<LineSeparator, Integer> eolCounts = new HashMap<>(); |
|
|
|
public LineEndingProcessingProvider(Provider input) { |
|
this(DEFAULT_BUFFER_SIZE, input); |
|
} |
|
|
|
public LineEndingProcessingProvider(int bufferSize, Provider input) { |
|
_input = input; |
|
_data = new char[bufferSize]; |
|
} |
|
|
|
@Override |
|
public void close() throws IOException { |
|
_input.close(); |
|
} |
|
|
|
private int fillBuffer() throws IOException { |
|
_pos = 0; |
|
int direct = _input.read(_data, 0, _data.length); |
|
if (direct != 0) { |
|
_len = direct; |
|
} |
|
return direct; |
|
} |
|
|
|
public LineSeparator getDetectedLineEnding() { |
|
return LineSeparator.getLineEnding( |
|
eolCounts.getOrDefault(LineSeparator.CR, 0), |
|
eolCounts.getOrDefault(LineSeparator.LF, 0), |
|
eolCounts.getOrDefault(LineSeparator.CRLF, 0) |
|
); |
|
} |
|
|
|
private boolean isBufferEmpty() { |
|
return _pos >= _len; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private int nextBufferedChar() throws IOException { |
|
while (isBufferEmpty()) { |
|
int direct = fillBuffer(); |
|
if (direct < 0) { |
|
return EOF; |
|
} |
|
} |
|
return _data[_pos++]; |
|
} |
|
|
|
@Override |
|
public int read(char[] buffer, final int offset, int len) throws IOException { |
|
int pos = offset; |
|
int stop = offset + len; |
|
LineSeparator previousLineSeparator = null; |
|
while (pos < stop) { |
|
int ch = nextBufferedChar(); |
|
if (ch < 0) { |
|
if (pos == offset) { |
|
|
|
return EOF; |
|
} else { |
|
break; |
|
} |
|
} else { |
|
String str = String.valueOf((char) ch); |
|
Optional<LineSeparator> lookup = LineSeparator.lookup(str); |
|
|
|
if (lookup.isPresent()) { |
|
LineSeparator lineSeparator = lookup.get(); |
|
|
|
|
|
eolCounts.putIfAbsent(lineSeparator, 0); |
|
eolCounts.put(lineSeparator, eolCounts.get(lineSeparator) + 1); |
|
|
|
// Handle line separators of length two (specifically CRLF) |
|
|
|
if (lineSeparator == LineSeparator.LF) { |
|
if (previousLineSeparator == LineSeparator.CR) { |
|
eolCounts.putIfAbsent(LineSeparator.CRLF, 0); |
|
eolCounts.put(LineSeparator.CRLF, eolCounts.get(LineSeparator.CRLF) + 1); |
|
} |
|
} |
|
|
|
|
|
previousLineSeparator = lineSeparator; |
|
} else { |
|
|
|
previousLineSeparator = null; |
|
} |
|
|
|
|
|
buffer[pos++] = (char) ch; |
|
} |
|
} |
|
return pos - offset; |
|
} |
|
|
|
} |