/* * 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. */ #ifndef JSON_OBJECT_H_ #define JSON_OBJECT_H_ #include <media/stagefright/foundation/ABase.h> #include <media/stagefright/foundation/AString.h> #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/RefBase.h> #include <utils/Vector.h> namespace android { struct JSONArray; struct JSONCompound; struct JSONObject; struct JSONValue { enum FieldType { TYPE_STRING, TYPE_INT32, TYPE_FLOAT, TYPE_BOOLEAN, TYPE_NULL, TYPE_OBJECT, TYPE_ARRAY, }; // Returns the number of bytes consumed or an error. static ssize_t Parse(const char *data, size_t size, JSONValue *out); JSONValue(); JSONValue(const JSONValue &); JSONValue &operator=(const JSONValue &); ~JSONValue(); FieldType type() const; bool getInt32(int32_t *value) const; bool getFloat(float *value) const; bool getString(AString *value) const; bool getBoolean(bool *value) const; bool getObject(sp<JSONObject> *value) const; bool getArray(sp<JSONArray> *value) const; void setInt32(int32_t value); void setFloat(float value); void setString(const AString &value); void setBoolean(bool value); void setObject(const sp<JSONObject> &obj); void setArray(const sp<JSONArray> &array); void unset(); // i.e. setNull() AString toString(size_t depth = 0, bool indentFirstLine = true) const; private: FieldType mType; union { int32_t mInt32; float mFloat; AString *mString; bool mBoolean; JSONCompound *mObjectOrArray; } mValue; }; struct JSONCompound : public RefBase { static sp<JSONCompound> Parse(const char *data, size_t size); AString toString(size_t depth = 0, bool indentFirstLine = true) const; virtual bool isObject() const = 0; protected: virtual ~JSONCompound() {} virtual AString internalToString(size_t depth) const = 0; JSONCompound() {} private: friend struct JSONValue; DISALLOW_EVIL_CONSTRUCTORS(JSONCompound); }; template<class KEY> struct JSONBase : public JSONCompound { JSONBase() {} #define PREAMBLE() \ JSONValue value; \ if (!getValue(key, &value)) { \ return false; \ } bool getFieldType(KEY key, JSONValue::FieldType *type) const { PREAMBLE() *type = value.type(); return true; } bool getInt32(KEY key, int32_t *out) const { PREAMBLE() return value.getInt32(out); } bool getFloat(KEY key, float *out) const { PREAMBLE() return value.getFloat(out); } bool getString(KEY key, AString *out) const { PREAMBLE() return value.getString(out); } bool getBoolean(KEY key, bool *out) const { PREAMBLE() return value.getBoolean(out); } bool getObject(KEY key, sp<JSONObject> *obj) const { PREAMBLE() return value.getObject(obj); } bool getArray(KEY key, sp<JSONArray> *obj) const { PREAMBLE() return value.getArray(obj); } #undef PREAMBLE protected: virtual ~JSONBase() {} virtual bool getValue(KEY key, JSONValue *value) const = 0; private: DISALLOW_EVIL_CONSTRUCTORS(JSONBase); }; struct JSONObject : public JSONBase<const char *> { JSONObject(); virtual bool isObject() const; void setValue(const char *key, const JSONValue &value); void setInt32(const char *key, int32_t in) { JSONValue val; val.setInt32(in); setValue(key, val); } void setFloat(const char *key, float in) { JSONValue val; val.setFloat(in); setValue(key, val); } void setString(const char *key, AString in) { JSONValue val; val.setString(in); setValue(key, val); } void setBoolean(const char *key, bool in) { JSONValue val; val.setBoolean(in); setValue(key, val); } void setObject(const char *key, const sp<JSONObject> &obj) { JSONValue val; val.setObject(obj); setValue(key, val); } void setArray(const char *key, const sp<JSONArray> &obj) { JSONValue val; val.setArray(obj); setValue(key, val); } protected: virtual ~JSONObject(); virtual bool getValue(const char *key, JSONValue *value) const; virtual AString internalToString(size_t depth) const; private: KeyedVector<AString, JSONValue> mValues; DISALLOW_EVIL_CONSTRUCTORS(JSONObject); }; struct JSONArray : public JSONBase<size_t> { JSONArray(); virtual bool isObject() const; size_t size() const; void addValue(const JSONValue &value); void addInt32(int32_t in) { JSONValue val; val.setInt32(in); addValue(val); } void addFloat(float in) { JSONValue val; val.setFloat(in); addValue(val); } void addString(AString in) { JSONValue val; val.setString(in); addValue(val); } void addBoolean(bool in) { JSONValue val; val.setBoolean(in); addValue(val); } void addObject(const sp<JSONObject> &obj) { JSONValue val; val.setObject(obj); addValue(val); } void addArray(const sp<JSONArray> &obj) { JSONValue val; val.setArray(obj); addValue(val); } protected: virtual ~JSONArray(); virtual bool getValue(size_t key, JSONValue *value) const; virtual AString internalToString(size_t depth) const; private: Vector<JSONValue> mValues; DISALLOW_EVIL_CONSTRUCTORS(JSONArray); }; } // namespace android #endif // JSON_OBJECT_H_