1 | /*
|
---|
2 | Copyright (c) 2001, Interactive Matter, Marcus Nowotny
|
---|
3 |
|
---|
4 | Based on the cJSON Library, Copyright (C) 2009 Dave Gamble
|
---|
5 |
|
---|
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
7 | of this software and associated documentation files (the "Software"), to deal
|
---|
8 | in the Software without restriction, including without limitation the rights
|
---|
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
10 | copies of the Software, and to permit persons to whom the Software is
|
---|
11 | furnished to do so, subject to the following conditions:
|
---|
12 |
|
---|
13 | The above copyright notice and this permission notice shall be included in
|
---|
14 | all copies or substantial portions of the Software.
|
---|
15 |
|
---|
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
---|
22 | THE SOFTWARE.
|
---|
23 | */
|
---|
24 |
|
---|
25 | #ifndef aJson__h
|
---|
26 | #define aJson__h
|
---|
27 |
|
---|
28 | #include <Print.h>
|
---|
29 | #include <Stream.h>
|
---|
30 | #include <Client.h>
|
---|
31 | #include <Arduino.h> // To get access to the Arduino millis() function
|
---|
32 |
|
---|
33 | /******************************************************************************
|
---|
34 | * Definitions
|
---|
35 | ******************************************************************************/
|
---|
36 | // aJson Types:
|
---|
37 | #define aJson_NULL 0
|
---|
38 | #define aJson_Boolean 1
|
---|
39 | #define aJson_Int 2
|
---|
40 | #define aJson_Float 3
|
---|
41 | #define aJson_String 4
|
---|
42 | #define aJson_Array 5
|
---|
43 | #define aJson_Object 6
|
---|
44 |
|
---|
45 | #define aJson_IsReference 128
|
---|
46 |
|
---|
47 | #ifndef EOF
|
---|
48 | #define EOF -1
|
---|
49 | #endif
|
---|
50 |
|
---|
51 | #define PRINT_BUFFER_LEN 256
|
---|
52 |
|
---|
53 | // The aJson structure:
|
---|
54 | typedef struct aJsonObject {
|
---|
55 | char *name; // The item's name string, if this item is the child of, or is in the list of subitems of an object.
|
---|
56 | struct aJsonObject *next, *prev; // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem
|
---|
57 | struct aJsonObject *child; // An array or object item will have a child pointer pointing to a chain of the items in the array/object.
|
---|
58 |
|
---|
59 | char type; // The type of the item, as above.
|
---|
60 |
|
---|
61 | union {
|
---|
62 | char *valuestring; // The item's string, if type==aJson_String
|
---|
63 | char valuebool; //the items value for true & false
|
---|
64 | int valueint; // The item's value, if type==aJson_Int
|
---|
65 | double valuefloat; // The item's value, if type==aJson_Float
|
---|
66 | };
|
---|
67 | } aJsonObject;
|
---|
68 |
|
---|
69 | /* aJsonStream is stream representation of aJson for its internal use;
|
---|
70 | * it is meant to abstract out differences between Stream (e.g. serial
|
---|
71 | * stream) and Client (which may or may not be connected) or provide even
|
---|
72 | * stream-ish interface to string buffers. */
|
---|
73 | class aJsonStream : public Print {
|
---|
74 | public:
|
---|
75 | aJsonStream(Stream *stream_)
|
---|
76 | : stream_obj(stream_), bucket(EOF)
|
---|
77 | {}
|
---|
78 | /* Use this to check if more data is available, as aJsonStream
|
---|
79 | * can read some more data than really consumed and automatically
|
---|
80 | * skips separating whitespace if you use this method. */
|
---|
81 | virtual bool available();
|
---|
82 |
|
---|
83 | int parseNumber(aJsonObject *item);
|
---|
84 | int printInt(aJsonObject *item);
|
---|
85 | int printFloat(aJsonObject *item);
|
---|
86 |
|
---|
87 | int parseString(aJsonObject *item);
|
---|
88 | int printStringPtr(const char *str);
|
---|
89 | int printString(aJsonObject *item);
|
---|
90 |
|
---|
91 | int skip();
|
---|
92 | int flush();
|
---|
93 |
|
---|
94 | int parseValue(aJsonObject *item, char** filter);
|
---|
95 | int printValue(aJsonObject *item);
|
---|
96 |
|
---|
97 | int parseArray(aJsonObject *item, char** filter);
|
---|
98 | int printArray(aJsonObject *item);
|
---|
99 |
|
---|
100 | int parseObject(aJsonObject *item, char** filter);
|
---|
101 | int printObject(aJsonObject *item);
|
---|
102 |
|
---|
103 | protected:
|
---|
104 | /* Blocking load of character, returning EOF if the stream
|
---|
105 | * is exhausted. */
|
---|
106 | /* Base implementation just looks at bucket, returns EOF
|
---|
107 | * otherwise; descendats take care of the real reading. */
|
---|
108 | virtual int getch();
|
---|
109 | virtual size_t readBytes(uint8_t *buffer, size_t len);
|
---|
110 | /* Return the character back to the front of the stream
|
---|
111 | * after loading it with getch(). Only returning a single
|
---|
112 | * character is supported. */
|
---|
113 | virtual void ungetch(char ch);
|
---|
114 |
|
---|
115 | /* Inherited from class Print. */
|
---|
116 | virtual size_t write(uint8_t ch);
|
---|
117 |
|
---|
118 | /* stream attribute is used only from virtual functions,
|
---|
119 | * therefore an object inheriting aJsonStream may avoid
|
---|
120 | * using streams completely. */
|
---|
121 | Stream *stream_obj;
|
---|
122 | /* Use this accessor for stream retrieval; some subclasses
|
---|
123 | * may use their own stream subclass. */
|
---|
124 | virtual inline Stream *stream() { return stream_obj; }
|
---|
125 |
|
---|
126 | /* bucket is EOF by default. Otherwise, it is a character
|
---|
127 | * to be returned by next getch() - returned by a call
|
---|
128 | * to ungetch(). */
|
---|
129 | int bucket;
|
---|
130 | };
|
---|
131 |
|
---|
132 | /* JSON stream that consumes data from a connection (usually
|
---|
133 | * Ethernet client) until the connection is closed. */
|
---|
134 | class aJsonClientStream : public aJsonStream {
|
---|
135 | public:
|
---|
136 | aJsonClientStream(Client *stream_)
|
---|
137 | : aJsonStream(NULL), client_obj(stream_)
|
---|
138 | {}
|
---|
139 |
|
---|
140 | private:
|
---|
141 | virtual int getch();
|
---|
142 |
|
---|
143 | Client *client_obj;
|
---|
144 | virtual inline Client *stream() { return client_obj; }
|
---|
145 | };
|
---|
146 |
|
---|
147 | /* JSON stream that is bound to input and output string buffer. This is
|
---|
148 | * for internal usage by string-based aJsonClass methods. */
|
---|
149 | /* TODO: Elastic output buffer support. */
|
---|
150 | class aJsonStringStream : public aJsonStream {
|
---|
151 | public:
|
---|
152 | /* Either of inbuf, outbuf can be NULL if you do not care about
|
---|
153 | * particular I/O direction. */
|
---|
154 | aJsonStringStream(char *inbuf_, char *outbuf_ = NULL, size_t outbuf_len_ = 0)
|
---|
155 | : aJsonStream(NULL), inbuf(inbuf_), outbuf(outbuf_), outbuf_len(outbuf_len_)
|
---|
156 | {
|
---|
157 | inbuf_len = inbuf ? strlen(inbuf) : 0;
|
---|
158 | }
|
---|
159 |
|
---|
160 | virtual bool available();
|
---|
161 |
|
---|
162 | private:
|
---|
163 | virtual int getch();
|
---|
164 | virtual size_t write(uint8_t ch);
|
---|
165 |
|
---|
166 | char *inbuf, *outbuf;
|
---|
167 | size_t inbuf_len, outbuf_len;
|
---|
168 | };
|
---|
169 |
|
---|
170 | class aJsonClass {
|
---|
171 | /******************************************************************************
|
---|
172 | * Constructors
|
---|
173 | ******************************************************************************/
|
---|
174 |
|
---|
175 | /******************************************************************************
|
---|
176 | * User API
|
---|
177 | ******************************************************************************/
|
---|
178 | public:
|
---|
179 | // Supply a block of JSON, and this returns a aJson object you can interrogate. Call aJson.deleteItem when finished.
|
---|
180 | aJsonObject* parse(aJsonStream* stream); //Reads from a stream
|
---|
181 | aJsonObject* parse(aJsonStream* stream,char** filter_values); //Read from a file, but only return values include in the char* array filter_values
|
---|
182 | aJsonObject* parse(char *value); //Reads from a string
|
---|
183 | // Render a aJsonObject entity to text for transfer/storage. Free the char* when finished.
|
---|
184 | int print(aJsonObject *item, aJsonStream* stream);
|
---|
185 | char* print(aJsonObject* item);
|
---|
186 | //Renders a aJsonObject directly to a output stream
|
---|
187 | char stream(aJsonObject *item, aJsonStream* stream);
|
---|
188 | // Delete a aJsonObject entity and all sub-entities.
|
---|
189 | void deleteItem(aJsonObject *c);
|
---|
190 |
|
---|
191 | // Returns the number of items in an array (or object).
|
---|
192 | unsigned char getArraySize(aJsonObject *array);
|
---|
193 | // Retrieve item number "item" from array "array". Returns NULL if unsuccessful.
|
---|
194 | aJsonObject* getArrayItem(aJsonObject *array, unsigned char item);
|
---|
195 | // Get item "string" from object. Case insensitive.
|
---|
196 | aJsonObject* getObjectItem(aJsonObject *object, const char *string);
|
---|
197 |
|
---|
198 | // These calls create a aJsonObject item of the appropriate type.
|
---|
199 | aJsonObject* createNull();
|
---|
200 | aJsonObject* createItem(bool b);
|
---|
201 | aJsonObject* createItem(char b);
|
---|
202 | aJsonObject* createItem(int num);
|
---|
203 | aJsonObject* createItem(double num);
|
---|
204 | aJsonObject* createItem(const char *string);
|
---|
205 | aJsonObject* createArray();
|
---|
206 | aJsonObject* createObject();
|
---|
207 |
|
---|
208 | // These utilities create an Array of count items.
|
---|
209 | aJsonObject* createIntArray(int *numbers, unsigned char count);
|
---|
210 | aJsonObject* createFloatArray(double *numbers, unsigned char count);
|
---|
211 | aJsonObject* createDoubleArray(double *numbers, unsigned char count);
|
---|
212 | aJsonObject* createStringArray(const char **strings, unsigned char count);
|
---|
213 |
|
---|
214 | // Append item to the specified array/object.
|
---|
215 | void addItemToArray(aJsonObject *array, aJsonObject *item);
|
---|
216 | void addItemToObject(aJsonObject *object, const char *string,
|
---|
217 | aJsonObject *item);
|
---|
218 | // Append reference to item to the specified array/object. Use this when you want to add an existing aJsonObject to a new aJsonObject, but don't want to corrupt your existing aJsonObject.
|
---|
219 | void addItemReferenceToArray(aJsonObject *array, aJsonObject *item);
|
---|
220 | void addItemReferenceToObject(aJsonObject *object, const char *string,
|
---|
221 | aJsonObject *item);
|
---|
222 |
|
---|
223 | // Remove/Detach items from Arrays/Objects.
|
---|
224 | aJsonObject* detachItemFromArray(aJsonObject *array, unsigned char which);
|
---|
225 | void deleteItemFromArray(aJsonObject *array, unsigned char which);
|
---|
226 | aJsonObject* detachItemFromObject(aJsonObject *object, const char *string);
|
---|
227 | void deleteItemFromObject(aJsonObject *object, const char *string);
|
---|
228 |
|
---|
229 | // Update array items.
|
---|
230 | void replaceItemInArray(aJsonObject *array, unsigned char which,
|
---|
231 | aJsonObject *newitem);
|
---|
232 | void replaceItemInObject(aJsonObject *object, const char *string,
|
---|
233 | aJsonObject *newitem);
|
---|
234 |
|
---|
235 | void addNullToObject(aJsonObject* object, const char* name);
|
---|
236 | void addBooleanToObject(aJsonObject* object, const char* name, bool b);
|
---|
237 | void addNumberToObject(aJsonObject* object, const char* name, int n);
|
---|
238 | void addNumberToObject(aJsonObject* object, const char* name, double n);
|
---|
239 | void addStringToObject(aJsonObject* object, const char* name,
|
---|
240 | const char* s);
|
---|
241 |
|
---|
242 | protected:
|
---|
243 | friend class aJsonStream;
|
---|
244 | static aJsonObject* newItem();
|
---|
245 |
|
---|
246 | private:
|
---|
247 | void suffixObject(aJsonObject *prev, aJsonObject *item);
|
---|
248 |
|
---|
249 | aJsonObject* createReference(aJsonObject *item);
|
---|
250 | };
|
---|
251 |
|
---|
252 | extern aJsonClass aJson;
|
---|
253 |
|
---|
254 | #endif
|
---|