blob: 7eef63efd14dc169181295927442a5729f5ee9d9 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.util;
import android.text.TextUtils;
import java.time.Duration;
import java.time.format.DateTimeParseException;
/**
* Parses a list of key=value pairs, separated by some delimiter, and puts the results in
* an internal Map. Values can be then queried by key, or if not found, a default value
* can be used.
* @hide
*/
public class KeyValueListParser {
private final ArrayMap<String, String> mValues = new ArrayMap<>();
private final TextUtils.StringSplitter mSplitter;
/**
* Constructs a new KeyValueListParser. This can be reused for different strings
* by calling {@link #setString(String)}.
* @param delim The delimiter that separates key=value pairs.
*/
public KeyValueListParser(char delim) {
mSplitter = new TextUtils.SimpleStringSplitter(delim);
}
/**
* Resets the parser with a new string to parse. The string is expected to be in the following
* format:
* <pre>key1=value,key2=value,key3=value</pre>
*
* where the delimiter is a comma.
*
* @param str the string to parse.
* @throws IllegalArgumentException if the string is malformed.
*/
public void setString(String str) throws IllegalArgumentException {
mValues.clear();
if (str != null) {
mSplitter.setString(str);
for (String pair : mSplitter) {
int sep = pair.indexOf('=');
if (sep < 0) {
mValues.clear();
throw new IllegalArgumentException(
"'" + pair + "' in '" + str + "' is not a valid key-value pair");
}
mValues.put(pair.substring(0, sep).trim(), pair.substring(sep + 1).trim());
}
}
}
/**
* Get the value for key as an int.
* @param key The key to lookup.
* @param def The value to return if the key was not found, or the value was not a long.
* @return the int value associated with the key.
*/
public int getInt(String key, int def) {
String value = mValues.get(key);
if (value != null) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
// fallthrough
}
}
return def;
}
/**
* Get the value for key as a long.
* @param key The key to lookup.
* @param def The value to return if the key was not found, or the value was not a long.
* @return the long value associated with the key.
*/
public long getLong(String key, long def) {
String value = mValues.get(key);
if (value != null) {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
// fallthrough
}
}
return def;
}
/**
* Get the value for key as a float.
* @param key The key to lookup.
* @param def The value to return if the key was not found, or the value was not a float.
* @return the float value associated with the key.
*/
public float getFloat(String key, float def) {
String value = mValues.get(key);
if (value != null) {
try {
return Float.parseFloat(value);
} catch (NumberFormatException e) {
// fallthrough
}
}
return def;
}
/**
* Get the value for key as a string.
* @param key The key to lookup.
* @param def The value to return if the key was not found.
* @return the string value associated with the key.
*/
public String getString(String key, String def) {
String value = mValues.get(key);
if (value != null) {
return value;
}
return def;
}
/**
* Get the value for key as a boolean.
* @param key The key to lookup.
* @param def The value to return if the key was not found.
* @return the string value associated with the key.
*/
public boolean getBoolean(String key, boolean def) {
String value = mValues.get(key);
if (value != null) {
try {
return Boolean.parseBoolean(value);
} catch (NumberFormatException e) {
// fallthrough
}
}
return def;
}
/**
* Get the value for key as an integer array.
*
* The value should be encoded as "0:1:2:3:4"
*
* @param key The key to lookup.
* @param def The value to return if the key was not found.
* @return the int[] value associated with the key.
*/
public int[] getIntArray(String key, int[] def) {
String value = mValues.get(key);
if (value != null) {
try {
String[] parts = value.split(":");
if (parts.length > 0) {
int[] ret = new int[parts.length];
for (int i = 0; i < parts.length; i++) {
ret[i] = Integer.parseInt(parts[i]);
}
return ret;
}
} catch (NumberFormatException e) {
// fallthrough
}
}
return def;
}
/**
* @return the number of keys.
*/
public int size() {
return mValues.size();
}
/**
* @return the key at {@code index}. Use with {@link #size()} to enumerate all key-value pairs.
*/
public String keyAt(int index) {
return mValues.keyAt(index);
}
/**
* {@hide}
* Parse a duration in millis based on java.time.Duration or just a number (millis)
*/
public long getDurationMillis(String key, long def) {
String value = mValues.get(key);
if (value != null) {
try {
if (value.startsWith("P") || value.startsWith("p")) {
return Duration.parse(value).toMillis();
} else {
return Long.parseLong(value);
}
} catch (NumberFormatException | DateTimeParseException e) {
// fallthrough
}
}
return def;
}
}