Commit 3b4409ae by Oliver Woodman

Allow relaxation of TTML validity requirement when parsing subtitles.

parent d4e82463
......@@ -26,8 +26,12 @@ public class ParserException extends IOException {
super(message);
}
public ParserException(Exception cause) {
public ParserException(Throwable cause) {
super(cause);
}
public ParserException(String message, Throwable cause) {
super(message, cause);
}
}
......@@ -73,8 +73,23 @@ public class TtmlParser implements SubtitleParser {
private static final int DEFAULT_TICKRATE = 1;
private final XmlPullParserFactory xmlParserFactory;
private final boolean strictParsing;
/**
* Equivalent to {@code TtmlParser(true)}.
*/
public TtmlParser() {
this(true);
}
/**
* @param strictParsing If true, {@link #parse(InputStream, String, long)} will throw a
* {@link ParserException} if the stream contains invalid ttml. If false, the parser will
* make a best effort to ignore minor errors in the stream. Note however that a
* {@link ParserException} will still be thrown when this is not possible.
*/
public TtmlParser(boolean strictParsing) {
this.strictParsing = strictParsing;
try {
xmlParserFactory = XmlPullParserFactory.newInstance();
} catch (XmlPullParserException e) {
......@@ -90,21 +105,31 @@ public class TtmlParser implements SubtitleParser {
xmlParser.setInput(inputStream, inputEncoding);
TtmlSubtitle ttmlSubtitle = null;
LinkedList<TtmlNode> nodeStack = new LinkedList<TtmlNode>();
int unsupportedTagDepth = 0;
int unsupportedNodeDepth = 0;
int eventType = xmlParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
TtmlNode parent = nodeStack.peekLast();
if (unsupportedTagDepth == 0) {
if (unsupportedNodeDepth == 0) {
String name = xmlParser.getName();
if (eventType == XmlPullParser.START_TAG) {
if (!isSupportedTag(name)) {
Log.w(TAG, "Ignoring unsupported tag: " + xmlParser.getName());
unsupportedTagDepth++;
Log.i(TAG, "Ignoring unsupported tag: " + xmlParser.getName());
unsupportedNodeDepth++;
} else {
TtmlNode node = parseNode(xmlParser, parent);
nodeStack.addLast(node);
if (parent != null) {
parent.addChild(node);
try {
TtmlNode node = parseNode(xmlParser, parent);
nodeStack.addLast(node);
if (parent != null) {
parent.addChild(node);
}
} catch (ParserException e) {
if (strictParsing) {
throw e;
} else {
Log.e(TAG, "Suppressing parser error", e);
// Treat the node (and by extension, all of its children) as unsupported.
unsupportedNodeDepth++;
}
}
}
} else if (eventType == XmlPullParser.TEXT) {
......@@ -117,9 +142,9 @@ public class TtmlParser implements SubtitleParser {
}
} else {
if (eventType == XmlPullParser.START_TAG) {
unsupportedTagDepth++;
unsupportedNodeDepth++;
} else if (eventType == XmlPullParser.END_TAG) {
unsupportedTagDepth--;
unsupportedNodeDepth--;
}
}
xmlParser.next();
......@@ -127,7 +152,7 @@ public class TtmlParser implements SubtitleParser {
}
return ttmlSubtitle;
} catch (XmlPullParserException xppe) {
throw new IOException("Unable to parse source", xppe);
throw new ParserException("Unable to parse source", xppe);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment