Sync with latest bnd code for testing purposes
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1354104 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/lib/properties/PropertiesLineReader.java b/bundleplugin/src/main/java/aQute/lib/properties/PropertiesLineReader.java
new file mode 100644
index 0000000..c3ea14b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/properties/PropertiesLineReader.java
@@ -0,0 +1,125 @@
+package aQute.lib.properties;
+
+import static aQute.lib.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;
+ }
+}