~ubuntu-branches/debian/stretch/opentyrian/stretch

« back to all changes in this revision

Viewing changes to src/cJSON.c

  • Committer: Package Import Robot
  • Author(s): Etienne Millon
  • Date: 2015-03-31 08:48:54 UTC
  • Revision ID: package-import@ubuntu.com-20150331084854-f5a4uoz7uv3vopk6
Tags: upstream-2.1.20130907+dfsg
ImportĀ upstreamĀ versionĀ 2.1.20130907+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  Copyright (c) 2009 Dave Gamble
 
3
  Copyright (c) 2009 The OpenTyrian Development Team
 
4
  
 
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
 
6
  of this software and associated documentation files (the "Software"), to deal
 
7
  in the Software without restriction, including without limitation the rights
 
8
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
9
  copies of the Software, and to permit persons to whom the Software is
 
10
  furnished to do so, subject to the following conditions:
 
11
 
 
12
  The above copyright notice and this permission notice shall be included in
 
13
  all copies or substantial portions of the Software.
 
14
 
 
15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
21
  THE SOFTWARE.
 
22
*/
 
23
 
 
24
// cJSON
 
25
// JSON parser in C.
 
26
 
 
27
#include "cJSON.h"
 
28
#include "mingw_fixes.h"
 
29
 
 
30
#include <assert.h>
 
31
#include <ctype.h>
 
32
#include <float.h>
 
33
#include <limits.h>
 
34
#include <math.h>
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
 
 
39
static void *(*cJSON_malloc)( size_t ) = malloc;
 
40
static void *(*cJSON_realloc)( void *, size_t ) = realloc;
 
41
static void (*cJSON_free)( void *ptr ) = free;
 
42
 
 
43
// helper for compilers without strdup
 
44
static char *cJSON_strdup( const char *str )
 
45
{
 
46
        size_t size = strlen(str) + 1;
 
47
        char *copy = (char *)cJSON_malloc(size);
 
48
        
 
49
        if (copy != NULL)
 
50
                memcpy(copy, str, size);
 
51
        
 
52
        return copy;
 
53
}
 
54
 
 
55
// helper for compilers without strcasecmp
 
56
static int cJSON_strcasecmp( const char *s1, const char *s2 )
 
57
{
 
58
        for(; tolower(*(const unsigned char *)s1) == tolower(*(const unsigned char *)s2); ++s1, ++s2)
 
59
                if (*s1 == 0)
 
60
                        return 0;
 
61
        return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
 
62
}
 
63
 
 
64
// construct empty item
 
65
static cJSON *cJSON_NewItem( cJSON_Type type )
 
66
{
 
67
        cJSON *node = (cJSON *)cJSON_malloc(sizeof(cJSON));
 
68
        
 
69
        if (node != NULL)
 
70
        {
 
71
                node->type = type;
 
72
                node->child = 
 
73
                node->prev =
 
74
                node->next = NULL;
 
75
                
 
76
                node->string = NULL;
 
77
                
 
78
                node->valuestring = NULL;
 
79
                node->valueint =
 
80
                node->valuedouble = 0;
 
81
        }
 
82
        
 
83
        return node;
 
84
}
 
85
 
 
86
// destroy item chain
 
87
void cJSON_Delete( cJSON *item )
 
88
{
 
89
        while (item != NULL)
 
90
        {
 
91
                if (item->child)
 
92
                        cJSON_Delete(item->child);
 
93
                
 
94
                cJSON *next = item->next;
 
95
                
 
96
                if (item->string)
 
97
                        cJSON_free(item->string);
 
98
                if (item->valuestring)
 
99
                        cJSON_free(item->valuestring);
 
100
                cJSON_free(item);
 
101
                
 
102
                item = next;
 
103
        }
 
104
}
 
105
 
 
106
// parser/emitter prototypes
 
107
 
 
108
static const char *parse_value( cJSON *item, const char *in );
 
109
static char *print_value(cJSON *item,int depth);
 
110
 
 
111
static const char *parse_number( cJSON *item, const char *in );
 
112
static char *print_number( cJSON *item );
 
113
 
 
114
static const char *parse_string(cJSON *item,const char *str);
 
115
static char *print_string(cJSON *item);
 
116
 
 
117
static const char *parse_array_or_object( cJSON *item, const char *in, cJSON_Type type );
 
118
static char *print_array(cJSON *item,int depth);
 
119
static char *print_object(cJSON *item,int depth);
 
120
 
 
121
static inline const char *parse_array( cJSON *item, const char *in )
 
122
{
 
123
        return parse_array_or_object(item, in, cJSON_Array);
 
124
}
 
125
static inline const char *parse_object( cJSON *item, const char *in )
 
126
{
 
127
        return parse_array_or_object(item, in, cJSON_Object);
 
128
}
 
129
 
 
130
// helper to skip whitespace
 
131
static inline const char *skip_space( const char *str )
 
132
{
 
133
        if (str != NULL)
 
134
                while (isspace(*str))
 
135
                        ++str;
 
136
        return str;
 
137
}
 
138
 
 
139
// parse root of JSON into cJSON item
 
140
cJSON *cJSON_Parse( const char *in )
 
141
{
 
142
        cJSON *item = cJSON_NewItem(cJSON_NULL);
 
143
        
 
144
        if (item != NULL)
 
145
        {
 
146
                if (parse_value(item, skip_space(in)) == NULL)  // if malformed or out-of-memory
 
147
                {
 
148
                        cJSON_Delete(item);
 
149
                        item = NULL;
 
150
                }
 
151
        }
 
152
        
 
153
        return item;
 
154
}
 
155
 
 
156
// emit cJSON item as JSON value
 
157
char *cJSON_Print( cJSON *item )
 
158
{
 
159
        return print_value(item, 0);
 
160
}
 
161
 
 
162
// parse JSON value into cJSON item
 
163
static const char *parse_value( cJSON *item, const char *in )
 
164
{
 
165
        if (in == NULL)
 
166
                return in;
 
167
        
 
168
        if (!strncmp(in, "null", 4))
 
169
        {
 
170
                item->type = cJSON_NULL;
 
171
                return in + 4;
 
172
        }
 
173
        if (!strncmp(in, "false", 5))
 
174
        {
 
175
                item->type = cJSON_False;
 
176
                return in + 5;
 
177
        }
 
178
        if (!strncmp(in, "true", 4))
 
179
        {
 
180
                item->type = cJSON_True;
 
181
                return in + 4;
 
182
        }
 
183
        if (*in == '\"')
 
184
                return parse_string(item, in);
 
185
        if (*in == '-' || (*in >= '0' && *in <= '9'))
 
186
                return parse_number(item, in);
 
187
        if (*in == '[')
 
188
                return parse_array(item, in);
 
189
        if (*in == '{')
 
190
                return parse_object(item, in);
 
191
        
 
192
        return NULL;  // malformed: expected value
 
193
}
 
194
 
 
195
// emit cJSON item as JSON value
 
196
static char *print_value( cJSON *item, int depth )
 
197
{
 
198
        char *out = NULL;
 
199
        
 
200
        switch (item->type)
 
201
        {
 
202
        case cJSON_NULL:
 
203
                out = cJSON_strdup("null");
 
204
                break;
 
205
        case cJSON_False:
 
206
                out = cJSON_strdup("false");
 
207
                break;
 
208
        case cJSON_True:
 
209
                out = cJSON_strdup("true");
 
210
                break;
 
211
        case cJSON_Number:
 
212
                out = print_number(item);
 
213
                break;
 
214
        case cJSON_String:
 
215
                out = print_string(item);
 
216
                break;
 
217
        case cJSON_Array:
 
218
                out = print_array(item, depth);
 
219
                break;
 
220
        case cJSON_Object:
 
221
                out = print_object(item, depth);
 
222
                break;
 
223
        }
 
224
        
 
225
        return out;
 
226
}
 
227
 
 
228
// parse JSON number value into cJSON item
 
229
static const char *parse_number( cJSON *item, const char *in )
 
230
{
 
231
        double n = 0;
 
232
        int sign = 1, decimal_shift = 0;
 
233
        int exponent_sign = 1, exponent = 0;
 
234
        
 
235
        if (*in == '-')
 
236
                sign = -1, ++in;
 
237
        
 
238
        // integer part
 
239
        if (*in == '0')
 
240
                ++in;
 
241
        else if (*in >= '1' && *in <= '9')
 
242
                do
 
243
                        n = (n * 10.0) + (*(in++) - '0');
 
244
                while (*in >= '0' && *in <= '9');
 
245
        
 
246
        // fractional part
 
247
        if (*in == '.')
 
248
        {
 
249
                ++in;
 
250
                
 
251
                while (*in >= '0' && *in <= '9')
 
252
                        n = (n * 10.0) + (*(in++) - '0'), decimal_shift--;
 
253
        }
 
254
        
 
255
        // exponent part
 
256
        if (*in == 'e' || *in == 'E')
 
257
        {
 
258
                ++in;
 
259
                
 
260
                if (*in == '+')
 
261
                        ++in;
 
262
                else if (*in == '-')
 
263
                        exponent_sign = -1, ++in;
 
264
                
 
265
                while (*in >= '0' && *in <= '9')
 
266
                        exponent = (exponent * 10) + (*(in++) - '0');
 
267
        }
 
268
        
 
269
        // number = +/- number.fraction * (10 ^ +/- exponent)
 
270
        n = sign * n * pow(10.0, decimal_shift + exponent_sign * exponent);
 
271
        
 
272
        item->valuedouble = n;
 
273
        item->valueint = n;
 
274
        item->type = cJSON_Number;
 
275
        
 
276
        return in;
 
277
}
 
278
 
 
279
// emit string containing numeric value of cJSON item
 
280
static char *print_number( cJSON *item )
 
281
{
 
282
        char *str = (char *)cJSON_malloc(DBL_DIG + 10);
 
283
        snprintf(str, DBL_DIG + 10, "%.*g", DBL_DIG, item->valuedouble);
 
284
        return str;
 
285
}
 
286
 
 
287
// Parse the input text into an unescaped cstring, and populate item.
 
288
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
 
289
static const char *parse_string(cJSON *item,const char *str)
 
290
{
 
291
        const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc;
 
292
        if (*str!='\"') return 0;       // not a string!
 
293
        
 
294
        while (*ptr!='\"' && *ptr>31 && ++len) if (*ptr++ == '\\') ptr++;       // skip escaped quotes.
 
295
        
 
296
        out=(char*)cJSON_malloc(len+1); // This is how long we need for the string, roughly.
 
297
        if (!out) return 0;
 
298
        
 
299
        ptr=str+1;ptr2=out;
 
300
        while (*ptr!='\"' && *ptr>31)
 
301
        {
 
302
                if (*ptr!='\\') *ptr2++=*ptr++;
 
303
                else
 
304
                {
 
305
                        ptr++;
 
306
                        switch (*ptr)
 
307
                        {
 
308
                                case 'b': *ptr2++='\b'; break;
 
309
                                case 'f': *ptr2++='\f'; break;
 
310
                                case 'n': *ptr2++='\n'; break;
 
311
                                case 'r': *ptr2++='\r'; break;
 
312
                                case 't': *ptr2++='\t'; break;
 
313
                                case 'u':        // transcode utf16 to utf8. DOES NOT SUPPORT SURROGATE PAIRS CORRECTLY.
 
314
                                        sscanf(ptr+1,"%4x",&uc);        // get the unicode char.
 
315
                                        len=3;if (uc<0x80) len=1;else if (uc<0x800) len=2;ptr2+=len;
 
316
                                        
 
317
                                        switch (len) {
 
318
                                                case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
 
319
                                                case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
 
320
                                                case 1: *--ptr2 =(uc | firstByteMark[len]);
 
321
                                        }
 
322
                                        ptr2+=len;ptr+=4;
 
323
                                        break;
 
324
                                default:  *ptr2++=*ptr; break;
 
325
                        }
 
326
                        ptr++;
 
327
                }
 
328
        }
 
329
        *ptr2=0;
 
330
        if (*ptr=='\"') ptr++;
 
331
        item->valuestring=out;
 
332
        item->type=cJSON_String;
 
333
        return ptr;
 
334
}
 
335
 
 
336
// Render the cstring provided to an escaped version that can be printed.
 
337
static char *print_string_ptr(const char *str)
 
338
{
 
339
        const char *ptr;char *ptr2,*out;int len=0;
 
340
        
 
341
        ptr=str;while (*ptr && ++len) {if (*ptr<32 || *ptr=='\"' || *ptr=='\\') len++;ptr++;}
 
342
        
 
343
        out=(char*)cJSON_malloc(len+3);
 
344
        ptr2=out;ptr=str;
 
345
        *ptr2++='\"';
 
346
        while (*ptr)
 
347
        {
 
348
                if (*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
 
349
                else
 
350
                {
 
351
                        *ptr2++='\\';
 
352
                        switch (*ptr++)
 
353
                        {
 
354
                                case '\\':      *ptr2++='\\';   break;
 
355
                                case '\"':      *ptr2++='\"';   break;
 
356
                                case '\b':      *ptr2++='b';    break;
 
357
                                case '\f':      *ptr2++='f';    break;
 
358
                                case '\n':      *ptr2++='n';    break;
 
359
                                case '\r':      *ptr2++='r';    break;
 
360
                                case '\t':      *ptr2++='t';    break;
 
361
                                default: ptr2--;        break;  // eviscerate with prejudice.
 
362
                        }
 
363
                }
 
364
        }
 
365
        *ptr2++='\"';*ptr2++=0;
 
366
        return out;
 
367
}
 
368
// Invote print_string_ptr (which is useful) on an item.
 
369
static char *print_string(cJSON *item)
 
370
{
 
371
        return (item->valuestring != NULL) ? print_string_ptr(item->valuestring) : cJSON_strdup("");
 
372
}
 
373
 
 
374
// parse JSON array/object into cJSON item chain
 
375
static const char *parse_array_or_object( cJSON *const item, const char *in, cJSON_Type type )
 
376
{
 
377
        assert(type == cJSON_Array || type == cJSON_Object);
 
378
        
 
379
        const char opening = (type == cJSON_Object) ? '{' : '[',
 
380
                   closing = (type == cJSON_Object) ? '}' : ']';
 
381
        
 
382
        if (*in != opening)  // not an array/object!
 
383
                return NULL;
 
384
        else
 
385
                in = skip_space(++in);
 
386
        
 
387
        item->type = type;
 
388
        
 
389
        if (*in == closing)  // empty array/object
 
390
                return ++in;
 
391
        
 
392
        cJSON *prev_child = NULL;
 
393
        for (; ; )
 
394
        {
 
395
                cJSON *child = cJSON_NewItem(cJSON_NULL);
 
396
                if (child == NULL)  // memory fail
 
397
                        return NULL;
 
398
                
 
399
                if (prev_child == NULL)
 
400
                {
 
401
                        // attach first child to parent
 
402
                        item->child = child;
 
403
                }
 
404
                else
 
405
                {
 
406
                        // attach other children to older sibling
 
407
                        prev_child->next = child;
 
408
                        child->prev = prev_child;
 
409
                }
 
410
                
 
411
                if (type == cJSON_Object)
 
412
                {
 
413
                        // object children have identifier string
 
414
                        
 
415
                        in = skip_space(parse_string(child, skip_space(in)));
 
416
                        if (in == NULL)  // malformed or memory fail
 
417
                                return NULL;
 
418
                        
 
419
                        // parse_string parses into the item's value; we can use it to parse the identifier string, we just have to move the results
 
420
                        child->string = child->valuestring;
 
421
                        child->valuestring = NULL;
 
422
                        
 
423
                        if (*in != ':')  // malformed
 
424
                                return NULL;
 
425
                        else
 
426
                                ++in;
 
427
                }
 
428
                
 
429
                in = skip_space(parse_value(child, skip_space(in)));
 
430
                if (in == NULL)  // malformed or memory fail
 
431
                        return NULL;
 
432
                
 
433
                prev_child = child;
 
434
                
 
435
                if (*in == ',')
 
436
                        ++in;
 
437
                else
 
438
                        break;
 
439
        }
 
440
        
 
441
        if (*in == closing)  // end of array/object
 
442
                return ++in;
 
443
        
 
444
        return NULL;  // malformed
 
445
}
 
446
 
 
447
// Render an array to text
 
448
static char *print_array(cJSON *item,int depth)
 
449
{
 
450
        char *out, *ptr;
 
451
        size_t len = 3;  // minimum needed to print empty array
 
452
        
 
453
        ptr = out = (char*)cJSON_malloc(len);
 
454
        
 
455
        strcpy(ptr, "[");
 
456
        ptr += 1;
 
457
        
 
458
        cJSON *child = item->child;
 
459
        
 
460
        while (child)
 
461
        {
 
462
                char *ret = print_value(child, depth + 1);
 
463
                if (!ret)
 
464
                {
 
465
                        cJSON_free(out);
 
466
                        return NULL;
 
467
                }
 
468
                size_t ret_len = strlen(ret);
 
469
                
 
470
                len += ret_len + 2;
 
471
                ptr = out = (char*)cJSON_realloc(out, len);
 
472
                ptr += strlen(out);
 
473
                
 
474
                strcpy(ptr, ret);  // strcat(out, ret);
 
475
                ptr += ret_len;
 
476
                
 
477
                cJSON_free(ret);
 
478
                
 
479
                if (child->next)
 
480
                {
 
481
                        strcpy(ptr, ", ");  // strcat(out, ", ");
 
482
                        ptr += 2;
 
483
                }
 
484
                
 
485
                child = child->next;
 
486
        }
 
487
        
 
488
        strcpy(ptr, "]");  // strcat(out, "]");
 
489
        
 
490
        return out;
 
491
}
 
492
 
 
493
// Render an object to text.
 
494
static char *print_object(cJSON *item,int depth)
 
495
{
 
496
        char *out, *ptr;
 
497
        size_t len = 4 + depth;  // minimum needed to print empty object
 
498
        
 
499
        ++depth;
 
500
        
 
501
        ptr = out = (char*)cJSON_malloc(len);
 
502
        
 
503
        strcpy(ptr, "{\n");
 
504
        ptr += 2;
 
505
        
 
506
        cJSON *child = item->child;
 
507
        
 
508
        while (child)
 
509
        {
 
510
                char *str = print_string_ptr(child->string);
 
511
                if (!str)
 
512
                {
 
513
                        cJSON_free(out);
 
514
                        return NULL;
 
515
                }
 
516
                size_t str_len = strlen(str);
 
517
                
 
518
                char *ret = print_value(child, depth);
 
519
                if (!ret)
 
520
                {
 
521
                        cJSON_free(str);
 
522
                        cJSON_free(out);
 
523
                        return NULL;
 
524
                }
 
525
                size_t ret_len = strlen(ret);
 
526
                
 
527
                len += depth + str_len + ret_len + 4;
 
528
                out = (char*)cJSON_realloc(out, len);
 
529
                ptr = out + strlen(out);
 
530
                
 
531
                for (int i = 0; i < depth; ++i)
 
532
                        *(ptr++) = '\t';
 
533
                
 
534
                strcpy(ptr, str);  // strcat(out, str);
 
535
                ptr += str_len;
 
536
                
 
537
                cJSON_free(str);
 
538
                
 
539
                strcpy(ptr, ":\t");  // strcat(out, ":\t");
 
540
                ptr += 2;
 
541
                
 
542
                strcpy(ptr, ret);  // strcat(out, ret);
 
543
                ptr += ret_len;
 
544
                
 
545
                cJSON_free(ret);
 
546
                
 
547
                if (child->next)
 
548
                {
 
549
                        strcpy(ptr, ",\n");  // strcat(out, ",\n");
 
550
                        ptr += 2;
 
551
                }
 
552
                else
 
553
                {
 
554
                        strcpy(ptr, "\n");  // strcat(out, "\n");
 
555
                        ptr += 1;
 
556
                }
 
557
                
 
558
                child = child->next;
 
559
        }
 
560
        
 
561
        --depth;
 
562
        
 
563
        for (int i = 0; i < depth; ++i)
 
564
                *(ptr++) = '\t';
 
565
        
 
566
        strcpy(ptr, "}");  // strcat(out, "}");
 
567
        
 
568
        return out;
 
569
}
 
570
 
 
571
// Get Array size/item / object item.
 
572
int cJSON_GetArraySize( cJSON *array )
 
573
{
 
574
        int size = 0;
 
575
        cJSON *item = array->child;
 
576
        while (item != NULL)
 
577
                item = item->next, ++size;
 
578
        return size;
 
579
}
 
580
cJSON *cJSON_GetArrayItem( cJSON *array, int index )
 
581
{
 
582
        cJSON *item = array->child;
 
583
        while (item != NULL && index > 0)
 
584
                item = item->next, --index;
 
585
        return item;
 
586
}
 
587
cJSON *cJSON_GetObjectItem( cJSON *object, const char *string)
 
588
{
 
589
        cJSON *item=object->child;
 
590
        while (item != NULL && cJSON_strcasecmp(item->string, string) != 0)
 
591
                item = item->next;
 
592
        return item;
 
593
}
 
594
 
 
595
cJSON *cJSON_CreateOrGetObjectItem( cJSON *object, const char *string )
 
596
{
 
597
        cJSON *child = cJSON_GetObjectItem(object, string);
 
598
        if (child == NULL)
 
599
                cJSON_AddItemToObject(object, string, child = cJSON_CreateNull());
 
600
        
 
601
        return child;
 
602
}
 
603
 
 
604
// Utility for array list handling.
 
605
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
 
606
 
 
607
// Add item to array/object.
 
608
void   cJSON_AddItemToArray(cJSON *array, cJSON *item)                                          {cJSON *c=array->child;if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
 
609
void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)      {if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
 
610
 
 
611
// remove all items from array/object
 
612
void cJSON_ClearArray( cJSON *array )
 
613
{
 
614
        cJSON_Delete(array->child);
 
615
        array->child = NULL;
 
616
}
 
617
 
 
618
// create basic types
 
619
 
 
620
cJSON *cJSON_CreateNull( void )
 
621
{
 
622
        return cJSON_NewItem(cJSON_NULL);
 
623
}
 
624
cJSON *cJSON_CreateBoolean( bool value )
 
625
{
 
626
        return cJSON_NewItem(value ? cJSON_True : cJSON_False);
 
627
}
 
628
cJSON *cJSON_CreateNumber( double value )
 
629
{
 
630
        cJSON *item = cJSON_NewItem(cJSON_Number);
 
631
        item->valueint = item->valuedouble = value;
 
632
        return item;
 
633
}
 
634
cJSON *cJSON_CreateString( const char *value )
 
635
{
 
636
        cJSON *item = cJSON_NewItem(cJSON_String);
 
637
        item->valuestring = cJSON_strdup(value);
 
638
        return item;
 
639
}
 
640
cJSON *cJSON_CreateArray( void )
 
641
{
 
642
        return cJSON_NewItem(cJSON_Array);
 
643
}
 
644
cJSON *cJSON_CreateObject( void )
 
645
{
 
646
        return cJSON_NewItem(cJSON_Object);
 
647
}
 
648
 
 
649
void cJSON_ForceType( cJSON *item, cJSON_Type type )
 
650
{
 
651
        if (item->type != type)
 
652
        {
 
653
                cJSON_Delete(item->child);
 
654
                item->child = NULL;
 
655
                
 
656
                item->type = type;
 
657
        }
 
658
}
 
659
 
 
660
void cJSON_SetBoolean( cJSON *item, bool value )
 
661
{
 
662
        cJSON_ForceType(item, value ? cJSON_True : cJSON_False);
 
663
}
 
664
void cJSON_SetNumber( cJSON *item, double value )
 
665
{
 
666
        cJSON_ForceType(item, cJSON_Number);
 
667
        item->valueint = item->valuedouble = value;
 
668
}
 
669
void cJSON_SetString( cJSON *item, const char *value )
 
670
{
 
671
        cJSON_ForceType(item, cJSON_String);
 
672
        cJSON_free(item->valuestring);
 
673
        item->valuestring = cJSON_strdup(value);
 
674
}
 
675
 
 
676
// Create Arrays:
 
677
cJSON *cJSON_CreateIntArray(int *numbers,int count)                             {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
 
678
cJSON *cJSON_CreateFloatArray(float *numbers,int count)                 {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
 
679
cJSON *cJSON_CreateDoubleArray(double *numbers,int count)               {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
 
680
cJSON *cJSON_CreateStringArray(const char **strings,int count)  {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}