PageRenderTime 149ms CodeModel.GetById 137ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

/aJSON.h

http://github.com/interactive-matter/aJson
C Header | 254 lines | 136 code | 41 blank | 77 comment | 0 complexity | b180082e910372878210ce2d6ec33732 MD5 | raw file
  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:
 54typedef 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. */
 73class aJsonStream : public Print {
 74public:
 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
103protected:
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. */
134class aJsonClientStream : public aJsonStream {
135public:
136	aJsonClientStream(Client *stream_)
137		: aJsonStream(NULL), client_obj(stream_)
138		{}
139
140private:
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. */
150class aJsonStringStream : public aJsonStream {
151public:
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
162private:
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
170class aJsonClass {
171	/******************************************************************************
172	 * Constructors
173	 ******************************************************************************/
174
175	/******************************************************************************
176	 * User API
177	 ******************************************************************************/
178public:
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
242protected:
243	friend class aJsonStream;
244	static aJsonObject* newItem();
245
246private:
247	void suffixObject(aJsonObject *prev, aJsonObject *item);
248
249	aJsonObject* createReference(aJsonObject *item);
250};
251
252extern aJsonClass aJson;
253
254#endif