1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.util;
17
18import android.text.TextUtils;
19
20/**
21 * Parses a list of key=value pairs, separated by some delimiter, and puts the results in
22 * an internal Map. Values can be then queried by key, or if not found, a default value
23 * can be used.
24 * @hide
25 */
26public class KeyValueListParser {
27    private final ArrayMap<String, String> mValues = new ArrayMap<>();
28    private final TextUtils.StringSplitter mSplitter;
29
30    /**
31     * Constructs a new KeyValueListParser. This can be reused for different strings
32     * by calling {@link #setString(String)}.
33     * @param delim The delimiter that separates key=value pairs.
34     */
35    public KeyValueListParser(char delim) {
36        mSplitter = new TextUtils.SimpleStringSplitter(delim);
37    }
38
39    /**
40     * Resets the parser with a new string to parse. The string is expected to be in the following
41     * format:
42     * <pre>key1=value,key2=value,key3=value</pre>
43     *
44     * where the delimiter is a comma.
45     *
46     * @param str the string to parse.
47     * @throws IllegalArgumentException if the string is malformed.
48     */
49    public void setString(String str) throws IllegalArgumentException {
50        mValues.clear();
51        if (str != null) {
52            mSplitter.setString(str);
53            for (String pair : mSplitter) {
54                int sep = pair.indexOf('=');
55                if (sep < 0) {
56                    mValues.clear();
57                    throw new IllegalArgumentException(
58                            "'" + pair + "' in '" + str + "' is not a valid key-value pair");
59                }
60                mValues.put(pair.substring(0, sep).trim(), pair.substring(sep + 1).trim());
61            }
62        }
63    }
64
65    /**
66     * Get the value for key as an int.
67     * @param key The key to lookup.
68     * @param def The value to return if the key was not found, or the value was not a long.
69     * @return the int value associated with the key.
70     */
71    public int getInt(String key, int def) {
72        String value = mValues.get(key);
73        if (value != null) {
74            try {
75                return Integer.parseInt(value);
76            } catch (NumberFormatException e) {
77                // fallthrough
78            }
79        }
80        return def;
81    }
82
83    /**
84     * Get the value for key as a long.
85     * @param key The key to lookup.
86     * @param def The value to return if the key was not found, or the value was not a long.
87     * @return the long value associated with the key.
88     */
89    public long getLong(String key, long def) {
90        String value = mValues.get(key);
91        if (value != null) {
92            try {
93                return Long.parseLong(value);
94            } catch (NumberFormatException e) {
95                // fallthrough
96            }
97        }
98        return def;
99    }
100
101    /**
102     * Get the value for key as a float.
103     * @param key The key to lookup.
104     * @param def The value to return if the key was not found, or the value was not a float.
105     * @return the float value associated with the key.
106     */
107    public float getFloat(String key, float def) {
108        String value = mValues.get(key);
109        if (value != null) {
110            try {
111                return Float.parseFloat(value);
112            } catch (NumberFormatException e) {
113                // fallthrough
114            }
115        }
116        return def;
117    }
118
119    /**
120     * Get the value for key as a string.
121     * @param key The key to lookup.
122     * @param def The value to return if the key was not found.
123     * @return the string value associated with the key.
124     */
125    public String getString(String key, String def) {
126        String value = mValues.get(key);
127        if (value != null) {
128            return value;
129        }
130        return def;
131    }
132}
133