104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown/*
204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * Copyright (C) 2010 The Android Open Source Project
304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * you may not use this file except in compliance with the License.
604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * You may obtain a copy of the License at
704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
1004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * Unless required by applicable law or agreed to in writing, software
1104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
1204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * See the License for the specific language governing permissions and
1404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * limitations under the License.
1504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown */
1604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
1704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#ifndef _UTILS_PROPERTY_MAP_H
1804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#define _UTILS_PROPERTY_MAP_H
1904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
2004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#include <utils/KeyedVector.h>
2104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#include <utils/String8.h>
2204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#include <utils/Errors.h>
2304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#include <utils/Tokenizer.h>
2404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
2504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brownnamespace android {
2604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
2704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown/*
2804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * Provides a mechanism for passing around string-based property key / value pairs
2904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * and loading them from property files.
3004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
3104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * The property files have the following simple structure:
3204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
3304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * # Comment
3404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * key = value
3504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
3604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * Keys and values are any sequence of printable ASCII characters.
3704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * The '=' separates the key from the value.
3804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * The key and value may not contain whitespace.
3904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
4004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * The '\' character is reserved for escape sequences and is not currently supported.
4104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * The '"" character is reserved for quoting and is not currently supported.
4204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * Files that contain the '\' or '"' character will fail to parse.
4304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
4404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * The file must not contain duplicate keys.
4504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown *
4604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown * TODO Support escape sequences and quoted values when needed.
4704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown */
4804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brownclass PropertyMap {
4904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brownpublic:
5004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    /* Creates an empty property map. */
5104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    PropertyMap();
5204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    ~PropertyMap();
5304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
5404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    /* Clears the property map. */
5504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    void clear();
5604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
5704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    /* Adds a property.
5804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown     * Replaces the property with the same key if it is already present.
5904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown     */
6004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    void addProperty(const String8& key, const String8& value);
6104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
6204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    /* Returns true if the property map contains the specified key. */
6304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    bool hasProperty(const String8& key) const;
6404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
6504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    /* Gets the value of a property and parses it.
6604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown     * Returns true and sets outValue if the key was found and its value was parsed successfully.
6704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown     * Otherwise returns false and does not modify outValue.  (Also logs a warning.)
6804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown     */
6904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    bool tryGetProperty(const String8& key, String8& outValue) const;
7004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    bool tryGetProperty(const String8& key, bool& outValue) const;
7104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    bool tryGetProperty(const String8& key, int32_t& outValue) const;
7204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    bool tryGetProperty(const String8& key, float& outValue) const;
7304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
748659f0be9a7cac99d55f58601d68c0c6da55af7bJeff Brown    /* Adds all values from the specified property map. */
758659f0be9a7cac99d55f58601d68c0c6da55af7bJeff Brown    void addAll(const PropertyMap* map);
768659f0be9a7cac99d55f58601d68c0c6da55af7bJeff Brown
778659f0be9a7cac99d55f58601d68c0c6da55af7bJeff Brown    /* Gets the underlying property map. */
788659f0be9a7cac99d55f58601d68c0c6da55af7bJeff Brown    inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }
798659f0be9a7cac99d55f58601d68c0c6da55af7bJeff Brown
8004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    /* Loads a property map from a file. */
8104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    static status_t load(const String8& filename, PropertyMap** outMap);
8204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
8304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brownprivate:
8404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    class Parser {
8504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        PropertyMap* mMap;
8604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        Tokenizer* mTokenizer;
8704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
8804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    public:
8904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        Parser(PropertyMap* map, Tokenizer* tokenizer);
9004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        ~Parser();
9104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        status_t parse();
9204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
9304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    private:
9404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        status_t parseType();
9504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        status_t parseKey();
9604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        status_t parseKeyProperty();
9704cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        status_t parseModifier(const String8& token, int32_t* outMetaState);
9804cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown        status_t parseCharacterLiteral(char16_t* outCharacter);
9904cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    };
10004cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
10104cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown    KeyedVector<String8, String8> mProperties;
10204cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown};
10304cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
10404cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown} // namespace android
10504cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown
10604cbbc1c47c68e805d2674d9fc702fc44385805fJeff Brown#endif // _UTILS_PROPERTY_MAP_H
107