Commit 1062da63 authored by Karsten Loesing's avatar Karsten Loesing
Browse files

Make DescriptorFile obsolete.

This change simplifies the DescriptorReader interface and allows for
shorter and more concise application code.  The result is that
DescriptorReader returns Descriptor instances rather than
DescriptorFile instances containing Descriptors and accepts a maximum
queue size in Descriptors, DescriptorFile is deprecated, and
Descriptor contains a File reference to the descriptor file.
Implements #22141.

Related to this change, this commit introduces a new
UnparseableDescriptor to be returned by DescriptorParser and
DescriptorReader if a descriptor cannot be parsed, as opposed to
throwing a DescriptorParseException or skipping the entire descriptor
file (fixes #22139), respectively.

Also related to this change, DescriptorParser now returns an Iterable
instead of a List, which prepares parsing large descriptor files
descriptor by descriptor (will be tackled in #20395).
parent 0236dc77
# Changes in version 1.9.0 - 2017-06-??
* Major changes
- Simplify DescriptorReader by returning Descriptor instances
rather than DescriptorFile instances containing Descriptors,
deprecate DescriptorFile, and add a File reference to Descriptor.
- Introduce a new UnparseableDescriptor to be returned by
DescriptorParser and DescriptorReader if a descriptor cannot be
parsed, as opposed to throwing a DescriptorParseException or
skipping the entire descriptor file, respectively.
* Medium changes
- Let DescriptorParser return an Iterable instead of a List, which
prepares parsing large descriptor files descriptor by descriptor.
* Minor changes
- Fix a bug where NetworkStatusEntry's getMicrodescriptorDigests()
and getMicrodescriptorDigestsSha256Base64() return hex strings
......
......@@ -3,6 +3,7 @@
package org.torproject.descriptor;
import java.io.File;
import java.util.List;
/**
......@@ -24,6 +25,10 @@ public interface Descriptor {
* Return the (possibly empty) list of annotations in the format
* {@code "@key( value)*"}.
*
* <p>Some implementations might not support this operation and will throw an
* {@code UnsupportedOperationException}, e.g.,
* {@link UnparseableDescriptor}.</p>
*
* @since 1.0.0
*/
public List<String> getAnnotations();
......@@ -32,8 +37,22 @@ public interface Descriptor {
* Return any unrecognized lines when parsing this descriptor, or an
* empty list if there were no unrecognized lines.
*
* <p>Some implementations might not support this operation and will throw an
* {@code UnsupportedOperationException}, * e.g.,
* {@link UnparseableDescriptor}.</p>
*
* @since 1.0.0
*/
public List<String> getUnrecognizedLines();
/**
* Return the file, tarball or plain file, that contained this descriptor, or
* {@code null} if this descriptor was not read from a file.
*
* @return Descriptor file that contained this descriptor.
*
* @since 1.9.0
*/
public File getDescriptorFile();
}
......@@ -15,6 +15,13 @@ import java.util.List;
* This container also stores potentially useful meta-data about the
* descriptor file.</p>
*
* @deprecated Irrelevant after introducing
* {@link DescriptorReader#readDescriptors(File...)}, which returns
* {@link Descriptor}s rather than {@link DescriptorFile}s, and including
* the descriptor file reference in {@link Descriptor#getDescriptorFile()}
* and the first thrown {@link DescriptorParseException} in
* {@link UnparseableDescriptor#getDescriptorParseException()}.
*
* @since 1.0.0
*/
public interface DescriptorFile {
......
......@@ -3,6 +3,7 @@
package org.torproject.descriptor;
import java.io.File;
import java.util.List;
/**
......@@ -48,4 +49,22 @@ public interface DescriptorParser {
*/
public List<Descriptor> parseDescriptors(byte[] rawDescriptorBytes,
String fileName) throws DescriptorParseException;
/**
* Parse descriptors in the given byte array and return the parsed/unparseable
* descriptors.
*
* @param rawDescriptorBytes Raw descriptor bytes containing one or more
* descriptors
* @param descriptorFile Optional descriptor file reference included in
* parsed/unparseable descriptors
* @param fileName Descriptor file name used for parsing the descriptor
* publication time of some descriptor types
*
* @return Parsed/unparseable descriptors
*
* @since 1.9.0
*/
public Iterable<Descriptor> parseDescriptors(byte[] rawDescriptorBytes,
File descriptorFile, String fileName);
}
......@@ -23,18 +23,13 @@ import java.util.SortedMap;
* DescriptorReader descriptorReader =
* DescriptorSourceFactory.createDescriptorReader();
* // Read descriptors from local directory called in/.
* descriptorReader.addDirectory(new File("in"));
* Iterator<DescriptorFile> descriptorFiles =
* descriptorReader.readDescriptors();
* while (descriptorFiles.hasNext()) {
* DescriptorFile descriptorFile = descriptorFiles.next();
* for (Descriptor descriptor : descriptorFile.getDescriptors()) {
* if ((descriptor instanceof RelayNetworkStatusConsensus)) {
* // Only process network status consensuses, ignore the rest.
* RelayNetworkStatusConsensus consensus =
* (RelayNetworkStatusConsensus) descriptor;
* processConsensus(consensus);
* }
* for (Descriptor descriptor :
* descriptorReader.readDescriptors(new File("in")) {
* // Only process network status consensuses, ignore the rest.
* if ((descriptor instanceof RelayNetworkStatusConsensus)) {
* RelayNetworkStatusConsensus consensus =
* (RelayNetworkStatusConsensus) descriptor;
* processConsensus(consensus);
* }
* }}</pre>
*
......@@ -46,6 +41,9 @@ public interface DescriptorReader {
* Add a local directory to read descriptors from, which may contain
* descriptor files or tarballs containing descriptor files.
*
* @deprecated Replaced with a parameter in {@link #readDescriptors(File...)},
* which ignores any directories added via this deprecated method.
*
* @since 1.0.0
*/
public void addDirectory(File directory);
......@@ -54,6 +52,9 @@ public interface DescriptorReader {
* Add a tarball to read descriptors from, which may be uncompressed,
* bz2-compressed, or xz-compressed.
*
* @deprecated Replaced with a parameter in {@link #readDescriptors(File...)},
* which ignores any tarballs added via this deprecated method.
*
* @since 1.0.0
*/
public void addTarball(File tarball);
......@@ -157,10 +158,22 @@ public interface DescriptorReader {
* <p>The default is 100, but if descriptor files contain hundreds or
* even thousands of descriptors, that default may be too high.</p>
*
* @deprecated Replaced with {@link #setMaxDescriptorsInQueue(int)}.
*
* @since 1.0.0
*/
public void setMaxDescriptorFilesInQueue(int max);
/**
* Don't keep more than this number of descriptors in the queue (default:
* 100).
*
* @param maxDescriptorsInQueue Maximum number of descriptors in the queue.
*
* @since 1.9.0
*/
public void setMaxDescriptorsInQueue(int maxDescriptorsInQueue);
/**
* Read the previously configured descriptors and make them available
* via the returned blocking iterator.
......@@ -169,8 +182,27 @@ public interface DescriptorReader {
* more shortly after, it blocks the caller. This method can only be
* run once.</p>
*
* @deprecated Replaced with {@link #readDescriptors(File...)}.
*
* @since 1.0.0
*/
public Iterator<DescriptorFile> readDescriptors();
/**
* Read descriptors from the given descriptor file(s) and return the parsed
* descriptors.
*
* <p>Whenever the reader runs out of descriptors and expects to provide
* more shortly after, it blocks the caller. This method can only be
* run once.</p>
*
* @param descriptorFiles One or more directories, tarballs, or files
* containing descriptors.
*
* @return Parsed descriptors.
*
* @since 1.9.0
*/
public Iterable<Descriptor> readDescriptors(File... descriptorFiles);
}
/* Copyright 2017 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
import java.util.List;
/**
* Contains a descriptor that could not be parsed.
* Only {@link UnparseableDescriptor#getRawDescriptorBytes} and
* {@link UnparseableDescriptor#getDescriptorFile} are supported.
*
* @since 1.9.0
*/
public interface UnparseableDescriptor extends Descriptor {
/**
* Return the first exception thrown while attempting to parse this
* descriptor.
*
* @return First exception thrown.
*
* @since 1.9.0
*/
public DescriptorParseException getDescriptorParseException();
/**
* Will always throw an {@code UnsupportedOperationException}.
*
* @since 1.9.0
*/
@Override
public List<String> getAnnotations();
/**
* Will always throw an {@code UnsupportedOperationException}.
*
* @since 1.9.0
*/
@Override
public List<String> getUnrecognizedLines();
}
......@@ -11,7 +11,7 @@ import java.util.Queue;
/* Provide an iterator for a queue of objects and block when there are
* currently no objects in the queue. Allow the producer to signal that
* there won't be further objects and unblock any waiting consumers. */
public class BlockingIteratorImpl<T> implements Iterator<T> {
public class BlockingIteratorImpl<T> implements Iterator<T>, Iterable<T> {
/* Queue containing produced elemnts waiting for consumers. */
private Queue<T> queue = new LinkedList<>();
......@@ -24,8 +24,10 @@ public class BlockingIteratorImpl<T> implements Iterator<T> {
}
/* Create instance with maximum queue size. */
protected BlockingIteratorImpl(int maxQueueSize) {
this.maxQueueSize = maxQueueSize;
protected BlockingIteratorImpl(Integer maxQueueSize) {
if (null != maxQueueSize) {
this.maxQueueSize = maxQueueSize;
}
}
/* Add an object to the queue if there's still room. */
......@@ -99,5 +101,10 @@ public class BlockingIteratorImpl<T> implements Iterator<T> {
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public Iterator<T> iterator() {
return this;
}
}
......@@ -6,13 +6,16 @@ package org.torproject.descriptor.impl;
import org.torproject.descriptor.BridgeExtraInfoDescriptor;
import org.torproject.descriptor.DescriptorParseException;
import java.io.File;
public class BridgeExtraInfoDescriptorImpl
extends ExtraInfoDescriptorImpl implements BridgeExtraInfoDescriptor {
protected BridgeExtraInfoDescriptorImpl(byte[] descriptorBytes,
int[] offsetAndLimit, boolean failUnrecognizedDescriptorLines)
throws DescriptorParseException {
super(descriptorBytes, offsetAndLimit, failUnrecognizedDescriptorLines);
int[] offsetAndLimit, File descriptorFile,
boolean failUnrecognizedDescriptorLines) throws DescriptorParseException {
super(descriptorBytes, offsetAndLimit, descriptorFile,
failUnrecognizedDescriptorLines);
}
}
......@@ -6,6 +6,7 @@ package org.torproject.descriptor.impl;
import org.torproject.descriptor.BridgeNetworkStatus;
import org.torproject.descriptor.DescriptorParseException;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
......@@ -19,10 +20,10 @@ public class BridgeNetworkStatusImpl extends NetworkStatusImpl
implements BridgeNetworkStatus {
protected BridgeNetworkStatusImpl(byte[] rawDescriptorBytes,
int[] offsetAndLength, String fileName,
int[] offsetAndLength, File descriptorFile, String fileName,
boolean failUnrecognizedDescriptorLines) throws DescriptorParseException {
super(rawDescriptorBytes, offsetAndLength, failUnrecognizedDescriptorLines,
false, false);
super(rawDescriptorBytes, offsetAndLength, descriptorFile,
failUnrecognizedDescriptorLines, false, false);
this.setPublishedMillisFromFileName(fileName);
}
......
......@@ -6,6 +6,7 @@ package org.torproject.descriptor.impl;
import org.torproject.descriptor.BridgePoolAssignment;
import org.torproject.descriptor.DescriptorParseException;
import java.io.File;
import java.util.EnumSet;
import java.util.Scanner;
import java.util.SortedMap;
......@@ -15,10 +16,10 @@ public class BridgePoolAssignmentImpl extends DescriptorImpl
implements BridgePoolAssignment {
protected BridgePoolAssignmentImpl(byte[] rawDescriptorBytes,
int[] offsetAndlength, boolean failUnrecognizedDescriptorLines)
throws DescriptorParseException {
super(rawDescriptorBytes, offsetAndlength, failUnrecognizedDescriptorLines,
false);
int[] offsetAndlength, File descriptorFile,
boolean failUnrecognizedDescriptorLines) throws DescriptorParseException {
super(rawDescriptorBytes, offsetAndlength, descriptorFile,
failUnrecognizedDescriptorLines, false);
this.parseDescriptorBytes();
this.checkExactlyOnceKeys(EnumSet.of(Key.BRIDGE_POOL_ASSIGNMENT));
this.checkFirstKey(Key.BRIDGE_POOL_ASSIGNMENT);
......
......@@ -6,13 +6,16 @@ package org.torproject.descriptor.impl;
import org.torproject.descriptor.BridgeServerDescriptor;
import org.torproject.descriptor.DescriptorParseException;
import java.io.File;
public class BridgeServerDescriptorImpl extends ServerDescriptorImpl
implements BridgeServerDescriptor {
protected BridgeServerDescriptorImpl(byte[] rawDescriptorBytes,
int[] offsetAndLength, boolean failUnrecognizedDescriptorLines)
throws DescriptorParseException {
super(rawDescriptorBytes, offsetAndLength, failUnrecognizedDescriptorLines);
int[] offsetAndLength, File descriptorFile,
boolean failUnrecognizedDescriptorLines) throws DescriptorParseException {
super(rawDescriptorBytes, offsetAndLength, descriptorFile,
failUnrecognizedDescriptorLines);
}
}
......@@ -7,6 +7,7 @@ import org.torproject.descriptor.Descriptor;
import org.torproject.descriptor.DescriptorParseException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
......@@ -40,6 +41,17 @@ public abstract class DescriptorImpl implements Descriptor {
*/
protected int length;
/**
* Optional reference to the descriptor file, if this descriptor was read from
* a descriptor file.
*/
private File descriptorFile;
@Override
public File getDescriptorFile() {
return this.descriptorFile;
}
/**
* Returns a <emph>copy</emph> of the full raw descriptor bytes.
*
......@@ -178,8 +190,7 @@ public abstract class DescriptorImpl implements Descriptor {
}
protected DescriptorImpl(byte[] rawDescriptorBytes, int[] offsetAndLength,
boolean failUnrecognizedDescriptorLines, boolean blankLinesAllowed)
throws DescriptorParseException {
File descriptorFile, boolean failUnrecognizedDescriptorLines) {
int offset = offsetAndLength[0];
int length = offsetAndLength[1];
if (offset < 0 || offset + length > rawDescriptorBytes.length
......@@ -191,8 +202,16 @@ public abstract class DescriptorImpl implements Descriptor {
this.rawDescriptorBytes = rawDescriptorBytes;
this.offset = offset;
this.length = length;
this.descriptorFile = descriptorFile;
this.failUnrecognizedDescriptorLines =
failUnrecognizedDescriptorLines;
}
protected DescriptorImpl(byte[] rawDescriptorBytes, int[] offsetAndLength,
File descriptorFile, boolean failUnrecognizedDescriptorLines,
boolean blankLinesAllowed) throws DescriptorParseException {
this(rawDescriptorBytes, offsetAndLength, descriptorFile,
failUnrecognizedDescriptorLines);
this.cutOffAnnotations();
this.countKeys(rawDescriptorBytes, blankLinesAllowed);
}
......
......@@ -10,6 +10,7 @@ import org.torproject.descriptor.Descriptor;
import org.torproject.descriptor.DescriptorParseException;
import org.torproject.descriptor.DescriptorParser;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
......@@ -31,6 +32,29 @@ public class DescriptorParserImpl implements DescriptorParser {
public List<Descriptor> parseDescriptors(
byte[] rawDescriptorBytes, String fileName)
throws DescriptorParseException {
return this.parseDescriptors(rawDescriptorBytes, null, fileName, false);
}
@Override
public Iterable<Descriptor> parseDescriptors(byte[] rawDescriptorBytes,
File descriptorFile, String fileName) {
try {
return this.parseDescriptors(rawDescriptorBytes, descriptorFile, fileName,
true);
} catch (DescriptorParseException e) {
/* Looks like we attempted to parse the whole raw descriptor bytes at once
* below and ran into a parse issue. */
List<Descriptor> parsedDescriptors = new ArrayList<>();
parsedDescriptors.add(new UnparseableDescriptorImpl(rawDescriptorBytes,
new int[] { 0, rawDescriptorBytes.length }, descriptorFile,
failUnrecognizedDescriptorLines, e));
return parsedDescriptors;
}
}
private List<Descriptor> parseDescriptors(
byte[] rawDescriptorBytes, File descriptorFile, String fileName,
boolean includeUnparseableDescriptors) throws DescriptorParseException {
byte[] first100Chars = new byte[Math.min(100,
rawDescriptorBytes.length)];
System.arraycopy(rawDescriptorBytes, 0, first100Chars, 0,
......@@ -45,9 +69,9 @@ public class DescriptorParserImpl implements DescriptorParser {
NL + Key.NETWORK_STATUS_VERSION.keyword + SP + "3"))
&& firstLines.contains(
NL + Key.VOTE_STATUS.keyword + SP + "consensus" + NL))) {
return parseDescriptors(rawDescriptorBytes, Key.NETWORK_STATUS_VERSION,
RelayNetworkStatusConsensusImpl.class,
this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.NETWORK_STATUS_VERSION, RelayNetworkStatusConsensusImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type network-status-vote-3 1.")
|| ((firstLines.startsWith(
Key.NETWORK_STATUS_VERSION.keyword + SP + "3" + NL)
......@@ -55,89 +79,95 @@ public class DescriptorParserImpl implements DescriptorParser {
NL + Key.NETWORK_STATUS_VERSION.keyword + SP + "3" + NL))
&& firstLines.contains(
NL + Key.VOTE_STATUS.keyword + SP + "vote" + NL))) {
return parseDescriptors(rawDescriptorBytes, Key.NETWORK_STATUS_VERSION,
RelayNetworkStatusVoteImpl.class,
this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.NETWORK_STATUS_VERSION, RelayNetworkStatusVoteImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type bridge-network-status 1.")
|| firstLines.startsWith(Key.R.keyword + SP)) {
List<Descriptor> parsedDescriptors = new ArrayList<>();
parsedDescriptors.add(new BridgeNetworkStatusImpl(
rawDescriptorBytes, new int[] { 0, rawDescriptorBytes.length },
fileName, this.failUnrecognizedDescriptorLines));
descriptorFile, fileName, this.failUnrecognizedDescriptorLines));
return parsedDescriptors;
} else if (firstLines.startsWith("@type bridge-server-descriptor 1.")) {
return parseDescriptors(rawDescriptorBytes, Key.ROUTER,
BridgeServerDescriptorImpl.class,
this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.ROUTER, BridgeServerDescriptorImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type server-descriptor 1.")
|| firstLines.startsWith(Key.ROUTER.keyword + SP)
|| firstLines.contains(NL + Key.ROUTER.keyword + SP)) {
return parseDescriptors(rawDescriptorBytes, Key.ROUTER,
RelayServerDescriptorImpl.class,
this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.ROUTER, RelayServerDescriptorImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type bridge-extra-info 1.")) {
return parseDescriptors(rawDescriptorBytes, Key.EXTRA_INFO,
BridgeExtraInfoDescriptorImpl.class,
this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.EXTRA_INFO, BridgeExtraInfoDescriptorImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type extra-info 1.")
|| firstLines.startsWith(Key.EXTRA_INFO.keyword + SP)
|| firstLines.contains(NL + Key.EXTRA_INFO.keyword + SP)) {
return parseDescriptors(rawDescriptorBytes, Key.EXTRA_INFO,
RelayExtraInfoDescriptorImpl.class,
this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.EXTRA_INFO, RelayExtraInfoDescriptorImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type microdescriptor 1.")
|| firstLines.startsWith(Key.ONION_KEY.keyword + NL)
|| firstLines.contains(NL + Key.ONION_KEY.keyword + NL)) {
return parseDescriptors(rawDescriptorBytes, Key.ONION_KEY,
MicrodescriptorImpl.class, this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.ONION_KEY, MicrodescriptorImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type bridge-pool-assignment 1.")
|| firstLines.startsWith(Key.BRIDGE_POOL_ASSIGNMENT.keyword + SP)
|| firstLines.contains(NL + Key.BRIDGE_POOL_ASSIGNMENT.keyword + SP)) {
return parseDescriptors(rawDescriptorBytes, Key.BRIDGE_POOL_ASSIGNMENT,
BridgePoolAssignmentImpl.class, this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.BRIDGE_POOL_ASSIGNMENT, BridgePoolAssignmentImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type dir-key-certificate-3 1.")
|| firstLines.startsWith(Key.DIR_KEY_CERTIFICATE_VERSION.keyword + SP)
|| firstLines.contains(
NL + Key.DIR_KEY_CERTIFICATE_VERSION.keyword + SP)) {
return parseDescriptors(rawDescriptorBytes,
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.DIR_KEY_CERTIFICATE_VERSION, DirectoryKeyCertificateImpl.class,
this.failUnrecognizedDescriptorLines);
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type tordnsel 1.")
|| firstLines.startsWith("ExitNode" + SP)
|| firstLines.contains(NL + "ExitNode" + SP)) {
List<Descriptor> parsedDescriptors = new ArrayList<>();
parsedDescriptors.add(new ExitListImpl(rawDescriptorBytes, fileName,
this.failUnrecognizedDescriptorLines));
parsedDescriptors.add(new ExitListImpl(rawDescriptorBytes, descriptorFile,
fileName, this.failUnrecognizedDescriptorLines));
return parsedDescriptors;
} else if (firstLines.startsWith("@type network-status-2 1.")
|| firstLines.startsWith(
Key.NETWORK_STATUS_VERSION.keyword + SP + "2" + NL)
|| firstLines.contains(
NL + Key.NETWORK_STATUS_VERSION.keyword + SP + "2" + NL)) {
return parseDescriptors(rawDescriptorBytes, Key.NETWORK_STATUS_VERSION,
RelayNetworkStatusImpl.class, this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.NETWORK_STATUS_VERSION, RelayNetworkStatusImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type directory 1.")
|| firstLines.startsWith(Key.SIGNED_DIRECTORY.keyword + NL)
|| firstLines.contains(NL + Key.SIGNED_DIRECTORY.keyword + NL)) {
return parseDescriptors(rawDescriptorBytes, Key.SIGNED_DIRECTORY,
RelayDirectoryImpl.class, this.failUnrecognizedDescriptorLines);
return this.parseDescriptors(rawDescriptorBytes, descriptorFile,
Key.SIGNED_DIRECTORY, RelayDirectoryImpl.class,
this.failUnrecognizedDescriptorLines, includeUnparseableDescriptors);
} else if (firstLines.startsWith("@type torperf 1.")) {
return TorperfResultImpl.parseTorperfResults(
rawDescriptorBytes, this.failUnrecognizedDescriptorLines);
return TorperfResultImpl.parseTorperfResults(rawDescriptorBytes,
descriptorFile, this.failUnrecognizedDescriptorLines);
} else {
throw new DescriptorParseException("Could not detect descriptor "
+ "type in descriptor starting with '" + firstLines + "'.");
}
}