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  */
16 
17 #ifndef JSON_OBJECT_H_
18 
19 #define JSON_OBJECT_H_
20 
21 #include <media/stagefright/foundation/ABase.h>
22 #include <media/stagefright/foundation/AString.h>
23 #include <utils/Errors.h>
24 #include <utils/KeyedVector.h>
25 #include <utils/RefBase.h>
26 #include <utils/Vector.h>
27 
28 namespace android {
29 
30 struct JSONArray;
31 struct JSONCompound;
32 struct JSONObject;
33 
34 struct JSONValue {
35     enum FieldType {
36         TYPE_STRING,
37         TYPE_INT32,
38         TYPE_FLOAT,
39         TYPE_BOOLEAN,
40         TYPE_NULL,
41         TYPE_OBJECT,
42         TYPE_ARRAY,
43     };
44 
45     // Returns the number of bytes consumed or an error.
46     static ssize_t Parse(const char *data, size_t size, JSONValue *out);
47 
48     JSONValue();
49     JSONValue(const JSONValue &);
50     JSONValue &operator=(const JSONValue &);
51     ~JSONValue();
52 
53     FieldType type() const;
54     bool getInt32(int32_t *value) const;
55     bool getFloat(float *value) const;
56     bool getString(AString *value) const;
57     bool getBoolean(bool *value) const;
58     bool getObject(sp<JSONObject> *value) const;
59     bool getArray(sp<JSONArray> *value) const;
60 
61     void setInt32(int32_t value);
62     void setFloat(float value);
63     void setString(const AString &value);
64     void setBoolean(bool value);
65     void setObject(const sp<JSONObject> &obj);
66     void setArray(const sp<JSONArray> &array);
67     void unset();  // i.e. setNull()
68 
69     AString toString(size_t depth = 0, bool indentFirstLine = true) const;
70 
71 private:
72     FieldType mType;
73 
74     union {
75         int32_t mInt32;
76         float mFloat;
77         AString *mString;
78         bool mBoolean;
79         JSONCompound *mObjectOrArray;
80     } mValue;
81 };
82 
83 struct JSONCompound : public RefBase {
84     static sp<JSONCompound> Parse(const char *data, size_t size);
85 
86     AString toString(size_t depth = 0, bool indentFirstLine = true) const;
87 
88     virtual bool isObject() const = 0;
89 
90 protected:
~JSONCompoundJSONCompound91     virtual ~JSONCompound() {}
92 
93     virtual AString internalToString(size_t depth) const = 0;
94 
JSONCompoundJSONCompound95     JSONCompound() {}
96 
97 private:
98     friend struct JSONValue;
99 
100     DISALLOW_EVIL_CONSTRUCTORS(JSONCompound);
101 };
102 
103 template<class KEY>
104 struct JSONBase : public JSONCompound {
JSONBaseJSONBase105     JSONBase() {}
106 
107 #define PREAMBLE()                              \
108     JSONValue value;                            \
109     if (!getValue(key, &value)) {               \
110         return false;                           \
111     }
112 
getFieldTypeJSONBase113     bool getFieldType(KEY key, JSONValue::FieldType *type) const {
114         PREAMBLE()
115         *type = value.type();
116         return true;
117     }
118 
getInt32JSONBase119     bool getInt32(KEY key, int32_t *out) const {
120         PREAMBLE()
121         return value.getInt32(out);
122     }
123 
getFloatJSONBase124     bool getFloat(KEY key, float *out) const {
125         PREAMBLE()
126         return value.getFloat(out);
127     }
128 
getStringJSONBase129     bool getString(KEY key, AString *out) const {
130         PREAMBLE()
131         return value.getString(out);
132     }
133 
getBooleanJSONBase134     bool getBoolean(KEY key, bool *out) const {
135         PREAMBLE()
136         return value.getBoolean(out);
137     }
138 
getObjectJSONBase139     bool getObject(KEY key, sp<JSONObject> *obj) const {
140         PREAMBLE()
141         return value.getObject(obj);
142     }
143 
getArrayJSONBase144     bool getArray(KEY key, sp<JSONArray> *obj) const {
145         PREAMBLE()
146         return value.getArray(obj);
147     }
148 
149 #undef PREAMBLE
150 
151 protected:
~JSONBaseJSONBase152     virtual ~JSONBase() {}
153 
154     virtual bool getValue(KEY key, JSONValue *value) const = 0;
155 
156 private:
157     DISALLOW_EVIL_CONSTRUCTORS(JSONBase);
158 };
159 
160 struct JSONObject : public JSONBase<const char *> {
161     JSONObject();
162 
163     virtual bool isObject() const;
164     void setValue(const char *key, const JSONValue &value);
165 
setInt32JSONObject166     void setInt32(const char *key, int32_t in) {
167         JSONValue val;
168         val.setInt32(in);
169         setValue(key, val);
170     }
171 
setFloatJSONObject172     void setFloat(const char *key, float in) {
173         JSONValue val;
174         val.setFloat(in);
175         setValue(key, val);
176     }
177 
setStringJSONObject178     void setString(const char *key, AString in) {
179         JSONValue val;
180         val.setString(in);
181         setValue(key, val);
182     }
183 
setBooleanJSONObject184     void setBoolean(const char *key, bool in) {
185         JSONValue val;
186         val.setBoolean(in);
187         setValue(key, val);
188     }
189 
setObjectJSONObject190     void setObject(const char *key, const sp<JSONObject> &obj) {
191         JSONValue val;
192         val.setObject(obj);
193         setValue(key, val);
194     }
195 
setArrayJSONObject196     void setArray(const char *key, const sp<JSONArray> &obj) {
197         JSONValue val;
198         val.setArray(obj);
199         setValue(key, val);
200     }
201 
202 protected:
203     virtual ~JSONObject();
204 
205     virtual bool getValue(const char *key, JSONValue *value) const;
206     virtual AString internalToString(size_t depth) const;
207 
208 private:
209     KeyedVector<AString, JSONValue> mValues;
210 
211     DISALLOW_EVIL_CONSTRUCTORS(JSONObject);
212 };
213 
214 struct JSONArray : public JSONBase<size_t> {
215     JSONArray();
216 
217     virtual bool isObject() const;
218     size_t size() const;
219     void addValue(const JSONValue &value);
220 
addInt32JSONArray221     void addInt32(int32_t in) {
222         JSONValue val;
223         val.setInt32(in);
224         addValue(val);
225     }
226 
addFloatJSONArray227     void addFloat(float in) {
228         JSONValue val;
229         val.setFloat(in);
230         addValue(val);
231     }
232 
addStringJSONArray233     void addString(AString in) {
234         JSONValue val;
235         val.setString(in);
236         addValue(val);
237     }
238 
addBooleanJSONArray239     void addBoolean(bool in) {
240         JSONValue val;
241         val.setBoolean(in);
242         addValue(val);
243     }
244 
addObjectJSONArray245     void addObject(const sp<JSONObject> &obj) {
246         JSONValue val;
247         val.setObject(obj);
248         addValue(val);
249     }
250 
addArrayJSONArray251     void addArray(const sp<JSONArray> &obj) {
252         JSONValue val;
253         val.setArray(obj);
254         addValue(val);
255     }
256 
257 protected:
258     virtual ~JSONArray();
259 
260     virtual bool getValue(size_t key, JSONValue *value) const;
261     virtual AString internalToString(size_t depth) const;
262 
263 
264 private:
265     Vector<JSONValue> mValues;
266 
267     DISALLOW_EVIL_CONSTRUCTORS(JSONArray);
268 };
269 
270 }  // namespace android
271 
272 #endif  // JSON_OBJECT_H_
273