commit c87f5c92adea22967dbd6e1d5f6973f329ee0e95
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Apr 25 12:08:59 2012 +0200
Parse annotations preceding the actual descriptors.
---
src/org/torproject/descriptor/Descriptor.java | 3 +
.../torproject/descriptor/impl/DescriptorImpl.java | 64 ++++++++++++++++----
2 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/src/org/torproject/descriptor/Descriptor.java b/src/org/torproject/descriptor/Descriptor.java
index 6e02966..a341ef7 100644
--- a/src/org/torproject/descriptor/Descriptor.java
+++ b/src/org/torproject/descriptor/Descriptor.java
@@ -11,6 +11,9 @@ public interface Descriptor {
/* Return the raw descriptor bytes. */
public byte[] getRawDescriptorBytes();
+ /* Return the (possibly empty) list of annotations. */
+ public List<String> getAnnotations();
+
/* Return any unrecognized lines when parsing this descriptor, or an
* empty list if there were no unrecognized lines. */
public List<String> getUnrecognizedLines();
diff --git a/src/org/torproject/descriptor/impl/DescriptorImpl.java b/src/org/torproject/descriptor/impl/DescriptorImpl.java
index 8ddd7c8..33b94e9 100644
--- a/src/org/torproject/descriptor/impl/DescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/DescriptorImpl.java
@@ -76,19 +76,37 @@ public abstract class DescriptorImpl implements Descriptor {
List<byte[]> rawDescriptors = new ArrayList<byte[]>();
String splitToken = "\n" + startToken;
String ascii = new String(rawDescriptorBytes);
- int length = rawDescriptorBytes.length,
- start = ascii.indexOf(startToken);
- while (start < length) {
- int end = ascii.indexOf(splitToken, start);
- if (end < 0) {
- end = length;
+ int endAllDescriptors = rawDescriptorBytes.length,
+ startAnnotations = 0;
+ boolean containsAnnotations = ascii.startsWith("@") ||
+ ascii.contains("\n@");
+ while (startAnnotations < endAllDescriptors) {
+ int startDescriptor;
+ if (ascii.indexOf(startToken, startAnnotations) == 0) {
+ startDescriptor = startAnnotations;
} else {
- end += 1;
+ startDescriptor = ascii.indexOf(splitToken, startAnnotations - 1);
+ if (startDescriptor < 0) {
+ break;
+ } else {
+ startDescriptor += 1;
+ }
}
- byte[] rawDescriptor = new byte[end - start];
- System.arraycopy(rawDescriptorBytes, start, rawDescriptor, 0,
- end - start);
- start = end;
+ int endDescriptor = -1;
+ if (containsAnnotations) {
+ endDescriptor = ascii.indexOf("\n@", startDescriptor);
+ }
+ if (endDescriptor < 0) {
+ endDescriptor = ascii.indexOf(splitToken, startDescriptor);
+ }
+ if (endDescriptor < 0) {
+ endDescriptor = endAllDescriptors - 1;
+ }
+ endDescriptor += 1;
+ byte[] rawDescriptor = new byte[endDescriptor - startAnnotations];
+ System.arraycopy(rawDescriptorBytes, startAnnotations,
+ rawDescriptor, 0, endDescriptor - startAnnotations);
+ startAnnotations = endDescriptor;
rawDescriptors.add(rawDescriptor);
}
return rawDescriptors;
@@ -113,9 +131,33 @@ public abstract class DescriptorImpl implements Descriptor {
this.rawDescriptorBytes = rawDescriptorBytes;
this.failUnrecognizedDescriptorLines =
failUnrecognizedDescriptorLines;
+ this.cutOffAnnotations(rawDescriptorBytes);
this.countKeywords(rawDescriptorBytes);
}
+ /* Parse annotation lines from the descriptor bytes. */
+ private List<String> annotations = new ArrayList<String>();
+ private void cutOffAnnotations(byte[] rawDescriptorBytes) {
+ String ascii = new String(rawDescriptorBytes);
+ int start = 0;
+ while ((start == 0 && ascii.startsWith("@")) ||
+ (start > 0 && ascii.indexOf("\n@", start - 1) >= 0)) {
+ int end = ascii.indexOf("\n", start);
+ this.annotations.add(ascii.substring(start, end));
+ start = end + 1;
+ }
+ if (start > 0) {
+ int length = rawDescriptorBytes.length;
+ byte[] rawDescriptor = new byte[length - start];
+ System.arraycopy(rawDescriptorBytes, start, rawDescriptor, 0,
+ length - start);
+ this.rawDescriptorBytes = rawDescriptor;
+ }
+ }
+ public List<String> getAnnotations() {
+ return new ArrayList<String>(this.annotations);
+ }
+
/* Count parsed keywords for consistency checks by subclasses. */
private String firstKeyword, lastKeyword;
private Map<String, Integer> parsedKeywords =