blob: 720dde0b123ee081a13dff8edf1175513ceaa492 [file] [log] [blame]
package aQute.bnd.properties;
import static aQute.bnd.properties.LineType.*;
public class PropertiesLineReader {
private final IDocument document;
private final int lineCount;
private int lineNum = 0;
private IRegion lastRegion = null;
private String lastKey = null;
private String lastValue = null;
public PropertiesLineReader(IDocument document) {
this.document = document;
this.lineCount = document.getNumberOfLines();
}
public PropertiesLineReader(String data) {
this(new Document(data));
}
public LineType next() throws Exception {
int index = 0;
char[] chars = null;
StringBuilder keyData = new StringBuilder();
StringBuilder valueData = new StringBuilder();
StringBuilder currentBuffer = keyData;
boolean started = false;
mainLoop: while (true) {
if (chars == null)
chars = grabLine(false);
if (chars == null)
return eof;
if (index >= chars.length)
break;
char c = chars[index];
if (c == '\\') {
index++;
if (index == chars.length) {
chars = grabLine(true);
index = 0;
if (chars == null || chars.length == 0)
break; // The last line ended with a backslash
}
currentBuffer.append(chars[index]);
index++;
continue mainLoop;
}
if (c == '=' || c == ':')
currentBuffer = valueData;
if (!started && (c == '#' || c == '!'))
return comment;
if (Character.isWhitespace(c)) {
if (started) {
// whitespace ends the key
currentBuffer = valueData;
}
} else {
started = true;
currentBuffer.append(c);
}
index++;
}
if (!started)
return blank;
lastKey = keyData.toString();
return entry;
}
private char[] grabLine(boolean continued) throws BadLocationException {
if (lineNum >= lineCount) {
lastRegion = null;
return null;
}
IRegion lineInfo = document.getLineInformation(lineNum);
char[] chars = document.get(lineInfo.getOffset(), lineInfo.getLength()).toCharArray();
if (continued) {
int length = lastRegion.getLength();
length += document.getLineDelimiter(lineNum - 1).length();
length += lineInfo.getLength();
lastRegion = new Region(lastRegion.getOffset(), length);
} else {
lastRegion = lineInfo;
}
lineNum++;
return chars;
}
public IRegion region() {
if (lastRegion == null)
throw new IllegalStateException("Last region not available: either before start or after end of document.");
return lastRegion;
}
public String key() {
if (lastKey == null)
throw new IllegalStateException(
"Last key not available: either before state or after end of document, or last line type was not 'entry'.");
return lastKey;
}
public String value() {
if (lastValue == null)
throw new IllegalStateException(
"Last value not available: either before state or after end of document, or last line type was not 'entry'.");
return lastValue;
}
}