Dash UrlTemplate parses template using ArrayLists

This commit is contained in:
Hugo Houillon 2023-09-28 19:24:20 +02:00 committed by microkatz
parent 022444e751
commit 81e2472034

View file

@ -16,9 +16,8 @@
package androidx.media3.exoplayer.dash.manifest; package androidx.media3.exoplayer.dash.manifest;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* A template from which URLs can be built. * A template from which URLs can be built.
@ -41,7 +40,7 @@ public final class UrlTemplate {
private static final int TIME_ID = 4; private static final int TIME_ID = 4;
private final String[] urlPieces; private final String[] urlPieces;
private final int[] identifiers; private final Integer[] identifiers;
private final String[] identifierFormatTags; private final String[] identifierFormatTags;
private final int identifierCount; private final int identifierCount;
@ -53,29 +52,20 @@ public final class UrlTemplate {
* @throws IllegalArgumentException If the template string is malformed. * @throws IllegalArgumentException If the template string is malformed.
*/ */
public static UrlTemplate compile(String template) { public static UrlTemplate compile(String template) {
// We can have more than once each identifier in the template so we need ArrayList<String> urlPieces = new ArrayList<>();
// to count the total number of identifiers present in the template ArrayList<Integer> identifiers = new ArrayList<>();
int identifiersCount = 0; ArrayList<String> identifierFormatTags = new ArrayList<>();
String[] identifiersNames = { REPRESENTATION, NUMBER, BANDWIDTH, TIME };
for(String identifierName : identifiersNames){
Pattern pattern = Pattern.compile("(\\$" + identifierName + "\\$|" + ESCAPED_DOLLAR + "\\$" + identifierName + "\\$" + ESCAPED_DOLLAR +")");
Matcher matcher = pattern.matcher(template);
while(matcher.find())
identifiersCount++;
}
String[] urlPieces = new String[identifiersCount+1];
int[] identifiers = new int[identifiersCount];
String[] identifierFormatTags = new String[identifiersCount];
int identifierCount = parseTemplate(template, urlPieces, identifiers, identifierFormatTags); int identifierCount = parseTemplate(template, urlPieces, identifiers, identifierFormatTags);
return new UrlTemplate(urlPieces, identifiers, identifierFormatTags, identifierCount); return new UrlTemplate(urlPieces, identifiers, identifierFormatTags, identifierCount);
} }
/** Internal constructor. Use {@link #compile(String)} to build instances of this class. */ /** Internal constructor. Use {@link #compile(String)} to build instances of this class. */
private UrlTemplate( private UrlTemplate(
String[] urlPieces, int[] identifiers, String[] identifierFormatTags, int identifierCount) { ArrayList<String> urlPieces, ArrayList<Integer> identifiers, ArrayList<String> identifierFormatTags, int identifierCount) {
this.urlPieces = urlPieces; this.urlPieces = urlPieces.toArray(new String[0]);
this.identifiers = identifiers; this.identifiers = identifiers.toArray(new Integer[0]);
this.identifierFormatTags = identifierFormatTags; this.identifierFormatTags = identifierFormatTags.toArray(new String[0]);
this.identifierCount = identifierCount; this.identifierCount = identifierCount;
} }
@ -124,26 +114,27 @@ public final class UrlTemplate {
* @throws IllegalArgumentException If the template string is malformed. * @throws IllegalArgumentException If the template string is malformed.
*/ */
private static int parseTemplate( private static int parseTemplate(
String template, String[] urlPieces, int[] identifiers, String[] identifierFormatTags) { String template, ArrayList<String> urlPieces, ArrayList<Integer> identifiers, ArrayList<String> identifierFormatTags) {
urlPieces[0] = ""; urlPieces.add("");
int templateIndex = 0; int templateIndex = 0;
int identifierCount = 0; int identifierCount = 0;
while (templateIndex < template.length()) { while (templateIndex < template.length()) {
int dollarIndex = template.indexOf("$", templateIndex); int dollarIndex = template.indexOf("$", templateIndex);
if (dollarIndex == -1) { if (dollarIndex == -1) {
urlPieces[identifierCount] += template.substring(templateIndex); urlPieces.set(identifierCount, urlPieces.get(identifierCount) + template.substring(templateIndex));
templateIndex = template.length(); templateIndex = template.length();
} else if (dollarIndex != templateIndex) { } else if (dollarIndex != templateIndex) {
urlPieces[identifierCount] += template.substring(templateIndex, dollarIndex); urlPieces.set(identifierCount, urlPieces.get(identifierCount) + template.substring(templateIndex, dollarIndex));
templateIndex = dollarIndex; templateIndex = dollarIndex;
} else if (template.startsWith(ESCAPED_DOLLAR, templateIndex)) { } else if (template.startsWith(ESCAPED_DOLLAR, templateIndex)) {
urlPieces[identifierCount] += "$"; urlPieces.set(identifierCount, urlPieces.get(identifierCount) + "$");
templateIndex += 2; templateIndex += 2;
} else { } else {
identifierFormatTags.add(null);
int secondIndex = template.indexOf("$", templateIndex + 1); int secondIndex = template.indexOf("$", templateIndex + 1);
String identifier = template.substring(templateIndex + 1, secondIndex); String identifier = template.substring(templateIndex + 1, secondIndex);
if (identifier.equals(REPRESENTATION)) { if (identifier.equals(REPRESENTATION)) {
identifiers[identifierCount] = REPRESENTATION_ID; identifiers.add(REPRESENTATION_ID);
} else { } else {
int formatTagIndex = identifier.indexOf("%0"); int formatTagIndex = identifier.indexOf("%0");
String formatTag = DEFAULT_FORMAT_TAG; String formatTag = DEFAULT_FORMAT_TAG;
@ -159,21 +150,21 @@ public final class UrlTemplate {
} }
switch (identifier) { switch (identifier) {
case NUMBER: case NUMBER:
identifiers[identifierCount] = NUMBER_ID; identifiers.add(NUMBER_ID);
break; break;
case BANDWIDTH: case BANDWIDTH:
identifiers[identifierCount] = BANDWIDTH_ID; identifiers.add(BANDWIDTH_ID);
break; break;
case TIME: case TIME:
identifiers[identifierCount] = TIME_ID; identifiers.add(TIME_ID);
break; break;
default: default:
throw new IllegalArgumentException("Invalid template: " + template); throw new IllegalArgumentException("Invalid template: " + template);
} }
identifierFormatTags[identifierCount] = formatTag; identifierFormatTags.set(identifierCount, formatTag);
} }
identifierCount++; identifierCount++;
urlPieces[identifierCount] = ""; urlPieces.add("");
templateIndex = secondIndex + 1; templateIndex = secondIndex + 1;
} }
} }