431 lines
13 KiB
Java
431 lines
13 KiB
Java
/*
|
|
* 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 android.util.proto.ProtoOutputStream;
|
|
|
|
import java.io.PrintWriter;
|
|
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
|
|
*/
|
|
@android.ravenwood.annotation.RavenwoodKeepWholeClass
|
|
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;
|
|
}
|
|
|
|
/** Represents an integer config value. */
|
|
public static class IntValue {
|
|
private final String mKey;
|
|
private final int mDefaultValue;
|
|
private int mValue;
|
|
|
|
/** Constructor, initialize with a config key and a default value. */
|
|
public IntValue(String key, int defaultValue) {
|
|
mKey = key;
|
|
mDefaultValue = defaultValue;
|
|
mValue = mDefaultValue;
|
|
}
|
|
|
|
/** Read a value from {@link KeyValueListParser} */
|
|
public void parse(KeyValueListParser parser) {
|
|
mValue = parser.getInt(mKey, mDefaultValue);
|
|
}
|
|
|
|
/** Return the config key. */
|
|
public String getKey() {
|
|
return mKey;
|
|
}
|
|
|
|
/** Return the default value. */
|
|
public int getDefaultValue() {
|
|
return mDefaultValue;
|
|
}
|
|
|
|
/** Return the actual config value. */
|
|
public int getValue() {
|
|
return mValue;
|
|
}
|
|
|
|
/** Overwrites with a value. */
|
|
public void setValue(int value) {
|
|
mValue = value;
|
|
}
|
|
|
|
/** Used for dumpsys */
|
|
public void dump(PrintWriter pw, String prefix) {
|
|
pw.print(prefix);
|
|
pw.print(mKey);
|
|
pw.print("=");
|
|
pw.print(mValue);
|
|
pw.println();
|
|
}
|
|
|
|
/** Used for proto dumpsys */
|
|
public void dumpProto(ProtoOutputStream proto, long tag) {
|
|
proto.write(tag, mValue);
|
|
}
|
|
}
|
|
|
|
/** Represents an long config value. */
|
|
public static class LongValue {
|
|
private final String mKey;
|
|
private final long mDefaultValue;
|
|
private long mValue;
|
|
|
|
/** Constructor, initialize with a config key and a default value. */
|
|
public LongValue(String key, long defaultValue) {
|
|
mKey = key;
|
|
mDefaultValue = defaultValue;
|
|
mValue = mDefaultValue;
|
|
}
|
|
|
|
/** Read a value from {@link KeyValueListParser} */
|
|
public void parse(KeyValueListParser parser) {
|
|
mValue = parser.getLong(mKey, mDefaultValue);
|
|
}
|
|
|
|
/** Return the config key. */
|
|
public String getKey() {
|
|
return mKey;
|
|
}
|
|
|
|
/** Return the default value. */
|
|
public long getDefaultValue() {
|
|
return mDefaultValue;
|
|
}
|
|
|
|
/** Return the actual config value. */
|
|
public long getValue() {
|
|
return mValue;
|
|
}
|
|
|
|
/** Overwrites with a value. */
|
|
public void setValue(long value) {
|
|
mValue = value;
|
|
}
|
|
|
|
/** Used for dumpsys */
|
|
public void dump(PrintWriter pw, String prefix) {
|
|
pw.print(prefix);
|
|
pw.print(mKey);
|
|
pw.print("=");
|
|
pw.print(mValue);
|
|
pw.println();
|
|
}
|
|
|
|
/** Used for proto dumpsys */
|
|
public void dumpProto(ProtoOutputStream proto, long tag) {
|
|
proto.write(tag, mValue);
|
|
}
|
|
}
|
|
|
|
/** Represents an string config value. */
|
|
public static class StringValue {
|
|
private final String mKey;
|
|
private final String mDefaultValue;
|
|
private String mValue;
|
|
|
|
/** Constructor, initialize with a config key and a default value. */
|
|
public StringValue(String key, String defaultValue) {
|
|
mKey = key;
|
|
mDefaultValue = defaultValue;
|
|
mValue = mDefaultValue;
|
|
}
|
|
|
|
/** Read a value from {@link KeyValueListParser} */
|
|
public void parse(KeyValueListParser parser) {
|
|
mValue = parser.getString(mKey, mDefaultValue);
|
|
}
|
|
|
|
/** Return the config key. */
|
|
public String getKey() {
|
|
return mKey;
|
|
}
|
|
|
|
/** Return the default value. */
|
|
public String getDefaultValue() {
|
|
return mDefaultValue;
|
|
}
|
|
|
|
/** Return the actual config value. */
|
|
public String getValue() {
|
|
return mValue;
|
|
}
|
|
|
|
/** Overwrites with a value. */
|
|
public void setValue(String value) {
|
|
mValue = value;
|
|
}
|
|
|
|
/** Used for dumpsys */
|
|
public void dump(PrintWriter pw, String prefix) {
|
|
pw.print(prefix);
|
|
pw.print(mKey);
|
|
pw.print("=");
|
|
pw.print(mValue);
|
|
pw.println();
|
|
}
|
|
|
|
/** Used for proto dumpsys */
|
|
public void dumpProto(ProtoOutputStream proto, long tag) {
|
|
proto.write(tag, mValue);
|
|
}
|
|
}
|
|
|
|
/** Represents an float config value. */
|
|
public static class FloatValue {
|
|
private final String mKey;
|
|
private final float mDefaultValue;
|
|
private float mValue;
|
|
|
|
/** Constructor, initialize with a config key and a default value. */
|
|
public FloatValue(String key, float defaultValue) {
|
|
mKey = key;
|
|
mDefaultValue = defaultValue;
|
|
mValue = mDefaultValue;
|
|
}
|
|
|
|
/** Read a value from {@link KeyValueListParser} */
|
|
public void parse(KeyValueListParser parser) {
|
|
mValue = parser.getFloat(mKey, mDefaultValue);
|
|
}
|
|
|
|
/** Return the config key. */
|
|
public String getKey() {
|
|
return mKey;
|
|
}
|
|
|
|
/** Return the default value. */
|
|
public float getDefaultValue() {
|
|
return mDefaultValue;
|
|
}
|
|
|
|
/** Return the actual config value. */
|
|
public float getValue() {
|
|
return mValue;
|
|
}
|
|
|
|
/** Overwrites with a value. */
|
|
public void setValue(float value) {
|
|
mValue = value;
|
|
}
|
|
|
|
/** Used for dumpsys */
|
|
public void dump(PrintWriter pw, String prefix) {
|
|
pw.print(prefix);
|
|
pw.print(mKey);
|
|
pw.print("=");
|
|
pw.print(mValue);
|
|
pw.println();
|
|
}
|
|
|
|
/** Used for proto dumpsys */
|
|
public void dumpProto(ProtoOutputStream proto, long tag) {
|
|
proto.write(tag, mValue);
|
|
}
|
|
}
|
|
}
|