sink-input: adjust log level of empty-pop operations
[platform/upstream/pulseaudio.git] / src / pulsecore / json.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2016 Arun Raghavan <mail@arunraghavan.net>
5
6   PulseAudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as published
8   by the Free Software Foundation; either version 2.1 of the License,
9   or (at your option) any later version.
10
11   PulseAudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <math.h>
25
26 #include <pulse/xmalloc.h>
27 #include <pulsecore/core-util.h>
28 #include <pulsecore/hashmap.h>
29 #include <pulsecore/json.h>
30 #include <pulsecore/strbuf.h>
31
32 #define MAX_NESTING_DEPTH 20 /* Arbitrary number to make sure we don't have a stack overflow */
33
34 struct pa_json_object {
35     pa_json_type type;
36
37     union {
38         int64_t int_value;
39         double double_value;
40         bool bool_value;
41         char *string_value;
42         pa_hashmap *object_values; /* name -> object */
43         pa_idxset *array_values; /* objects */
44     };
45 };
46
47 /* JSON encoder context type */
48 typedef enum pa_json_context_type {
49     /* Top-level context of empty encoder. JSON element can be added. */
50     PA_JSON_CONTEXT_EMPTY  = 0,
51     /* Top-level context of encoder with an element. JSON element cannot be added. */
52     PA_JSON_CONTEXT_TOP    = 1,
53     /* JSON array context. JSON elements can be added. */
54     PA_JSON_CONTEXT_ARRAY  = 2,
55     /* JSON object context. JSON object members can be added. */
56     PA_JSON_CONTEXT_OBJECT = 3,
57 } pa_json_context_type_t;
58
59 typedef struct encoder_context {
60     pa_json_context_type_t type;
61     int counter;
62     struct encoder_context *next;
63 } encoder_context;
64
65 /* JSON encoder structure, a wrapper for pa_strbuf and encoder context */
66 struct pa_json_encoder {
67     pa_strbuf *buffer;
68     encoder_context *context;
69 };
70
71 static const char* parse_value(const char *str, const char *end, pa_json_object **obj, unsigned int depth);
72
73 static pa_json_object* json_object_new(void) {
74     pa_json_object *obj;
75
76     obj = pa_xnew0(pa_json_object, 1);
77
78     return obj;
79 }
80
81 static bool is_whitespace(char c) {
82     return c == '\t' || c == '\n' || c == '\r' || c == ' ';
83 }
84
85 static bool is_digit(char c) {
86     return c >= '0' && c <= '9';
87 }
88
89 static bool is_end(const char c, const char *end) {
90     if (!end)
91         return c == '\0';
92     else  {
93         while (*end) {
94             if (c == *end)
95                 return true;
96             end++;
97         }
98     }
99
100     return false;
101 }
102
103 static const char* consume_string(const char *str, const char *expect) {
104     while (*expect) {
105         if (*str != *expect)
106             return NULL;
107
108         str++;
109         expect++;
110     }
111
112     return str;
113 }
114
115 static const char* parse_null(const char *str, pa_json_object *obj) {
116     str = consume_string(str, "null");
117
118     if (str)
119         obj->type = PA_JSON_TYPE_NULL;
120
121     return str;
122 }
123
124 static const char* parse_boolean(const char *str, pa_json_object *obj) {
125     const char *tmp;
126
127     tmp = consume_string(str, "true");
128
129     if (tmp) {
130         obj->type = PA_JSON_TYPE_BOOL;
131         obj->bool_value = true;
132     } else {
133         tmp = consume_string(str, "false");
134
135         if (str) {
136             obj->type = PA_JSON_TYPE_BOOL;
137             obj->bool_value = false;
138         }
139     }
140
141     return tmp;
142 }
143
144 static const char* parse_string(const char *str, pa_json_object *obj) {
145     pa_strbuf *buf = pa_strbuf_new();
146
147     str++; /* Consume leading '"' */
148
149     while (*str && *str != '"') {
150         if (*str != '\\') {
151             /* We only accept ASCII printable characters. */
152             if (*str < 0x20 || *str > 0x7E) {
153                 pa_log("Invalid non-ASCII character: 0x%x", (unsigned int) *str);
154                 goto error;
155             }
156
157             /* Normal character, juts consume */
158             pa_strbuf_putc(buf, *str);
159         } else {
160             /* Need to unescape */
161             str++;
162
163             switch (*str) {
164                 case '"':
165                 case '\\':
166                 case '/':
167                     pa_strbuf_putc(buf, *str);
168                     break;
169
170                 case 'b':
171                     pa_strbuf_putc(buf, '\b' /* backspace */);
172                     break;
173
174                 case 'f':
175                     pa_strbuf_putc(buf, '\f' /* form feed */);
176                     break;
177
178                 case 'n':
179                     pa_strbuf_putc(buf, '\n' /* new line */);
180                     break;
181
182                 case 'r':
183                     pa_strbuf_putc(buf, '\r' /* carriage return */);
184                     break;
185
186                 case 't':
187                     pa_strbuf_putc(buf, '\t' /* horizontal tab */);
188                     break;
189
190                 case 'u':
191                     pa_log("Unicode code points are currently unsupported");
192                     goto error;
193
194                 default:
195                     pa_log("Unexpected escape value: %c", *str);
196                     goto error;
197             }
198         }
199
200         str++;
201     }
202
203     if (*str != '"') {
204         pa_log("Failed to parse remainder of string: %s", str);
205         goto error;
206     }
207
208     str++;
209
210     obj->type = PA_JSON_TYPE_STRING;
211     obj->string_value = pa_strbuf_to_string_free(buf);
212
213     return str;
214
215 error:
216     pa_strbuf_free(buf);
217     return NULL;
218 }
219
220 static const char* parse_number(const char *str, pa_json_object *obj) {
221     bool has_fraction = false, has_exponent = false, valid = false;
222     char *candidate = NULL;
223     const char *s = str;
224
225     if (*s == '-')
226         s++;
227
228     if (*s == '0') {
229         valid = true;
230         s++;
231         goto fraction;
232     }
233
234     while (is_digit(*s)) {
235         valid = true;
236         s++;
237     }
238
239 fraction:
240
241     if (!valid) {
242         pa_log("Missing digits while parsing number");
243         goto error;
244     }
245
246     if (*s == '.') {
247         has_fraction = true;
248         s++;
249         valid = false;
250
251         while (is_digit(*s)) {
252             valid = true;
253             s++;
254         }
255
256         if (!valid) {
257             pa_log("No digit after '.' while parsing fraction");
258             goto error;
259         }
260     }
261
262     if (*s == 'e' || *s == 'E') {
263         has_exponent = true;
264         s++;
265         valid = false;
266
267         if (*s == '-' || *s == '+')
268             s++;
269
270         while (is_digit(*s)) {
271             valid = true;
272             s++;
273         }
274
275         if (!valid) {
276             pa_log("No digit in exponent while parsing fraction");
277             goto error;
278         }
279     }
280
281     /* Number format looks good, now try to extract the value.
282      * Here 's' points just after the string which will be consumed. */
283
284     candidate = pa_xstrndup(str, s - str);
285
286     if (has_fraction || has_exponent) {
287         if (pa_atod(candidate, &obj->double_value) < 0) {
288             pa_log("Cannot convert string '%s' to double value", str);
289             goto error;
290         }
291         obj->type = PA_JSON_TYPE_DOUBLE;
292     } else {
293         if (pa_atoi64(candidate, &obj->int_value) < 0) {
294             pa_log("Cannot convert string '%s' to int64_t value", str);
295             goto error;
296         }
297         obj->type = PA_JSON_TYPE_INT;
298     }
299
300     pa_xfree(candidate);
301
302     return s;
303
304 error:
305     pa_xfree(candidate);
306     return NULL;
307 }
308
309 static const char *parse_object(const char *str, pa_json_object *obj, unsigned int depth) {
310     pa_json_object *name = NULL, *value = NULL;
311
312     obj->object_values = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
313                                              pa_xfree, (pa_free_cb_t) pa_json_object_free);
314
315     while (*str != '}') {
316         str++; /* Consume leading '{' or ',' */
317
318         str = parse_value(str, ":", &name, depth + 1);
319         if (!str || pa_json_object_get_type(name) != PA_JSON_TYPE_STRING) {
320             pa_log("Could not parse key for object");
321             goto error;
322         }
323
324         /* Consume the ':' */
325         str++;
326
327         str = parse_value(str, ",}", &value, depth + 1);
328         if (!str) {
329             pa_log("Could not parse value for object");
330             goto error;
331         }
332
333         pa_hashmap_put(obj->object_values, pa_xstrdup(pa_json_object_get_string(name)), value);
334         pa_json_object_free(name);
335
336         name = NULL;
337         value = NULL;
338     }
339
340     /* Drop trailing '}' */
341     str++;
342
343     /* We now know the value was correctly parsed */
344     obj->type = PA_JSON_TYPE_OBJECT;
345
346     return str;
347
348 error:
349     pa_hashmap_free(obj->object_values);
350     obj->object_values = NULL;
351
352     if (name)
353         pa_json_object_free(name);
354     if (value)
355         pa_json_object_free(value);
356
357     return NULL;
358 }
359
360 static const char *parse_array(const char *str, pa_json_object *obj, unsigned int depth) {
361     pa_json_object *value;
362
363     obj->array_values = pa_idxset_new(NULL, NULL);
364
365     while (*str != ']') {
366         str++; /* Consume leading '[' or ',' */
367
368         /* Need to chew up whitespaces as a special case to deal with the
369          * possibility of an empty array */
370         while (is_whitespace(*str))
371             str++;
372
373         if (*str == ']')
374             break;
375
376         str = parse_value(str, ",]", &value, depth + 1);
377         if (!str) {
378             pa_log("Could not parse value for array");
379             goto error;
380         }
381
382         pa_idxset_put(obj->array_values, value, NULL);
383     }
384
385     /* Drop trailing ']' */
386     str++;
387
388     /* We now know the value was correctly parsed */
389     obj->type = PA_JSON_TYPE_ARRAY;
390
391     return str;
392
393 error:
394     pa_idxset_free(obj->array_values, (pa_free_cb_t) pa_json_object_free);
395     obj->array_values = NULL;
396     return NULL;
397 }
398
399 typedef enum {
400     JSON_PARSER_STATE_INIT,
401     JSON_PARSER_STATE_FINISH,
402 } json_parser_state;
403
404 static const char* parse_value(const char *str, const char *end, pa_json_object **obj, unsigned int depth) {
405     json_parser_state state = JSON_PARSER_STATE_INIT;
406     pa_json_object *o;
407
408     pa_assert(str != NULL);
409
410     o = json_object_new();
411
412     if (depth > MAX_NESTING_DEPTH) {
413         pa_log("Exceeded maximum permitted nesting depth of objects (%u)", MAX_NESTING_DEPTH);
414         goto error;
415     }
416
417     while (!is_end(*str, end)) {
418         switch (state) {
419             case JSON_PARSER_STATE_INIT:
420                 if (is_whitespace(*str)) {
421                     str++;
422                 } else if (*str == 'n') {
423                     str = parse_null(str, o);
424                     state = JSON_PARSER_STATE_FINISH;
425                 } else if (*str == 't' || *str == 'f') {
426                     str = parse_boolean(str, o);
427                     state = JSON_PARSER_STATE_FINISH;
428                 } else if (*str == '"') {
429                     str = parse_string(str, o);
430                     state = JSON_PARSER_STATE_FINISH;
431                 } else if (is_digit(*str) || *str == '-') {
432                     str = parse_number(str, o);
433                     state = JSON_PARSER_STATE_FINISH;
434                 } else if (*str == '{') {
435                     str = parse_object(str, o, depth);
436                     state = JSON_PARSER_STATE_FINISH;
437                 } else if (*str == '[') {
438                     str = parse_array(str, o, depth);
439                     state = JSON_PARSER_STATE_FINISH;
440                 } else {
441                     pa_log("Invalid JSON string: %s", str);
442                     goto error;
443                 }
444
445                 if (!str)
446                     goto error;
447
448                 break;
449
450             case JSON_PARSER_STATE_FINISH:
451                 /* Consume trailing whitespaces */
452                 if (is_whitespace(*str)) {
453                     str++;
454                 } else {
455                     goto error;
456                 }
457         }
458     }
459
460     if (pa_json_object_get_type(o) == PA_JSON_TYPE_INIT) {
461         /* We didn't actually get any data */
462         pa_log("No data while parsing json string: '%s' till '%s'", str, pa_strnull(end));
463         goto error;
464     }
465
466     *obj = o;
467
468     return str;
469
470 error:
471     pa_json_object_free(o);
472     return NULL;
473 }
474
475
476 pa_json_object* pa_json_parse(const char *str) {
477     pa_json_object *obj;
478
479     str = parse_value(str, NULL, &obj, 0);
480
481     if (!str) {
482         pa_log("JSON parsing failed");
483         return NULL;
484     }
485
486     if (*str != '\0') {
487         pa_log("Unable to parse complete JSON string, remainder is: %s", str);
488         pa_json_object_free(obj);
489         return NULL;
490     }
491
492     return obj;
493 }
494
495 pa_json_type pa_json_object_get_type(const pa_json_object *obj) {
496     return obj->type;
497 }
498
499 void pa_json_object_free(pa_json_object *obj) {
500
501     switch (pa_json_object_get_type(obj)) {
502         case PA_JSON_TYPE_INIT:
503         case PA_JSON_TYPE_INT:
504         case PA_JSON_TYPE_DOUBLE:
505         case PA_JSON_TYPE_BOOL:
506         case PA_JSON_TYPE_NULL:
507             break;
508
509         case PA_JSON_TYPE_STRING:
510             pa_xfree(obj->string_value);
511             break;
512
513         case PA_JSON_TYPE_OBJECT:
514             pa_hashmap_free(obj->object_values);
515             break;
516
517         case PA_JSON_TYPE_ARRAY:
518             pa_idxset_free(obj->array_values, (pa_free_cb_t) pa_json_object_free);
519             break;
520
521         default:
522             pa_assert_not_reached();
523     }
524
525     pa_xfree(obj);
526 }
527
528 int64_t pa_json_object_get_int(const pa_json_object *o) {
529     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_INT);
530     return o->int_value;
531 }
532
533 double pa_json_object_get_double(const pa_json_object *o) {
534     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_DOUBLE);
535     return o->double_value;
536 }
537
538 bool pa_json_object_get_bool(const pa_json_object *o) {
539     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_BOOL);
540     return o->bool_value;
541 }
542
543 const char* pa_json_object_get_string(const pa_json_object *o) {
544     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_STRING);
545     return o->string_value;
546 }
547
548 const pa_json_object* pa_json_object_get_object_member(const pa_json_object *o, const char *name) {
549     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
550     return pa_hashmap_get(o->object_values, name);
551 }
552
553 const pa_hashmap *pa_json_object_get_object_member_hashmap(const pa_json_object *o) {
554     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_OBJECT);
555     return o->object_values;
556 }
557
558 int pa_json_object_get_array_length(const pa_json_object *o) {
559     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
560     return pa_idxset_size(o->array_values);
561 }
562
563 const pa_json_object* pa_json_object_get_array_member(const pa_json_object *o, int index) {
564     pa_assert(pa_json_object_get_type(o) == PA_JSON_TYPE_ARRAY);
565     return pa_idxset_get_by_index(o->array_values, index);
566 }
567
568 bool pa_json_object_equal(const pa_json_object *o1, const pa_json_object *o2) {
569     int i;
570
571     if (pa_json_object_get_type(o1) != pa_json_object_get_type(o2))
572         return false;
573
574     switch (pa_json_object_get_type(o1)) {
575         case PA_JSON_TYPE_NULL:
576             return true;
577
578         case PA_JSON_TYPE_BOOL:
579             return o1->bool_value == o2->bool_value;
580
581         case PA_JSON_TYPE_INT:
582             return o1->int_value == o2->int_value;
583
584         case PA_JSON_TYPE_DOUBLE:
585             return PA_DOUBLE_IS_EQUAL(o1->double_value, o2->double_value);
586
587         case PA_JSON_TYPE_STRING:
588             return pa_streq(o1->string_value, o2->string_value);
589
590         case PA_JSON_TYPE_ARRAY:
591             if (pa_json_object_get_array_length(o1) != pa_json_object_get_array_length(o2))
592                 return false;
593
594             for (i = 0; i < pa_json_object_get_array_length(o1); i++) {
595                 if (!pa_json_object_equal(pa_json_object_get_array_member(o1, i),
596                             pa_json_object_get_array_member(o2, i)))
597                     return false;
598             }
599
600             return true;
601
602         case PA_JSON_TYPE_OBJECT: {
603             void *state;
604             const char *key;
605             const pa_json_object *v1, *v2;
606
607             if (pa_hashmap_size(o1->object_values) != pa_hashmap_size(o2->object_values))
608                 return false;
609
610             PA_HASHMAP_FOREACH_KV(key, v1, o1->object_values, state) {
611                 v2 = pa_json_object_get_object_member(o2, key);
612                 if (!v2 || !pa_json_object_equal(v1, v2))
613                     return false;
614             }
615
616             return true;
617         }
618
619         default:
620             pa_assert_not_reached();
621     }
622 }
623
624 /* Write functions. The functions are wrapper functions around pa_strbuf,
625  * so that the client does not need to use pa_strbuf directly. */
626
627 static void json_encoder_context_push(pa_json_encoder *encoder, pa_json_context_type_t type) {
628     pa_assert(encoder);
629
630     encoder_context *head = pa_xnew0(encoder_context, 1);
631     head->type = type;
632     head->next = encoder->context;
633     encoder->context = head;
634 }
635
636 /* Returns type of context popped off encoder context stack. */
637 static pa_json_context_type_t json_encoder_context_pop(pa_json_encoder *encoder) {
638     encoder_context *head;
639     pa_json_context_type_t type;
640
641     pa_assert(encoder);
642     pa_assert(encoder->context);
643
644     type = encoder->context->type;
645
646     head = encoder->context->next;
647     pa_xfree(encoder->context);
648     encoder->context = head;
649
650     return type;
651 }
652
653 pa_json_encoder *pa_json_encoder_new(void) {
654     pa_json_encoder *encoder;
655
656     encoder = pa_xnew(pa_json_encoder, 1);
657     encoder->buffer = pa_strbuf_new();
658
659     encoder->context = NULL;
660     json_encoder_context_push(encoder, PA_JSON_CONTEXT_EMPTY);
661
662     return encoder;
663 }
664
665 void pa_json_encoder_free(pa_json_encoder *encoder) {
666     pa_json_context_type_t type;
667     pa_assert(encoder);
668
669     /* should have exactly one encoder context left at this point */
670     pa_assert(encoder->context);
671     type = json_encoder_context_pop(encoder);
672     pa_assert(encoder->context == NULL);
673
674     pa_assert(type == PA_JSON_CONTEXT_TOP || type == PA_JSON_CONTEXT_EMPTY);
675     if (type == PA_JSON_CONTEXT_EMPTY)
676         pa_log_warn("JSON encoder is empty.");
677
678     if (encoder->buffer)
679         pa_strbuf_free(encoder->buffer);
680
681     pa_xfree(encoder);
682 }
683
684 char *pa_json_encoder_to_string_free(pa_json_encoder *encoder) {
685     char *result;
686
687     pa_assert(encoder);
688
689     result = pa_strbuf_to_string_free(encoder->buffer);
690
691     encoder->buffer = NULL;
692     pa_json_encoder_free(encoder);
693
694     return result;
695 }
696
697 static void json_encoder_insert_delimiter(pa_json_encoder *encoder) {
698     pa_assert(encoder);
699
700     if (encoder->context->counter++)
701         pa_strbuf_putc(encoder->buffer, ',');
702 }
703
704 /* Escapes p to create valid JSON string.
705  * The caller has to free the returned string. */
706 static char *pa_json_escape(const char *p) {
707     const char *s;
708     char *out_string, *output;
709     int char_count = strlen(p);
710
711     /* Maximum number of characters in output string
712      * including trailing 0. */
713     char_count = 2 * char_count + 1;
714
715     /* allocate output string */
716     out_string = pa_xmalloc(char_count);
717     output = out_string;
718
719     /* write output string */
720     for (s = p; *s; ++s) {
721         switch (*s) {
722             case '"':
723                 *output++ = '\\';
724                 *output++ = '"';
725                 break;
726             case '\\':
727                 *output++ = '\\';
728                 *output++ = '\\';
729                 break;
730             case '\b':
731                 *output++ = '\\';
732                 *output++ = 'b';
733                 break;
734
735             case '\f':
736                 *output++ = '\\';
737                 *output++ = 'f';
738                 break;
739
740             case '\n':
741                 *output++ = '\\';
742                 *output++ = 'n';
743                 break;
744
745             case '\r':
746                 *output++ = '\\';
747                 *output++ = 'r';
748                 break;
749
750             case '\t':
751                 *output++ = '\\';
752                 *output++ = 't';
753                 break;
754             default:
755                 if (*s < 0x20 || *s > 0x7E) {
756                     pa_log("Invalid non-ASCII character: 0x%x", (unsigned int) *s);
757                     pa_xfree(out_string);
758                     return NULL;
759                 }
760                 *output++ = *s;
761                 break;
762         }
763     }
764
765     *output = 0;
766
767     return out_string;
768 }
769
770 static void json_write_string_escaped(pa_json_encoder *encoder, const char *value) {
771     char *escaped_value;
772
773     pa_assert(encoder);
774
775     escaped_value = pa_json_escape(value);
776     pa_strbuf_printf(encoder->buffer, "\"%s\"", escaped_value);
777     pa_xfree(escaped_value);
778 }
779
780 /* Writes an opening curly brace */
781 void pa_json_encoder_begin_element_object(pa_json_encoder *encoder) {
782     pa_assert(encoder);
783     pa_assert(encoder->context->type != PA_JSON_CONTEXT_TOP);
784
785     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
786         encoder->context->type = PA_JSON_CONTEXT_TOP;
787
788     json_encoder_insert_delimiter(encoder);
789     pa_strbuf_putc(encoder->buffer, '{');
790
791     json_encoder_context_push(encoder, PA_JSON_CONTEXT_OBJECT);
792 }
793
794 /* Writes an opening curly brace */
795 void pa_json_encoder_begin_member_object(pa_json_encoder *encoder, const char *name) {
796     pa_assert(encoder);
797     pa_assert(encoder->context);
798     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
799     pa_assert(name && name[0]);
800
801     json_encoder_insert_delimiter(encoder);
802
803     json_write_string_escaped(encoder, name);
804     pa_strbuf_putc(encoder->buffer, ':');
805
806     pa_strbuf_putc(encoder->buffer, '{');
807
808     json_encoder_context_push(encoder, PA_JSON_CONTEXT_OBJECT);
809 }
810
811 /* Writes a closing curly brace */
812 void pa_json_encoder_end_object(pa_json_encoder *encoder) {
813     pa_json_context_type_t type;
814     pa_assert(encoder);
815
816     type = json_encoder_context_pop(encoder);
817     pa_assert(type == PA_JSON_CONTEXT_OBJECT);
818
819     pa_strbuf_putc(encoder->buffer, '}');
820 }
821
822 /* Writes an opening bracket */
823 void pa_json_encoder_begin_element_array(pa_json_encoder *encoder) {
824     pa_assert(encoder);
825     pa_assert(encoder->context);
826     pa_assert(encoder->context->type != PA_JSON_CONTEXT_TOP);
827
828     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
829         encoder->context->type = PA_JSON_CONTEXT_TOP;
830
831     json_encoder_insert_delimiter(encoder);
832     pa_strbuf_putc(encoder->buffer, '[');
833
834     json_encoder_context_push(encoder, PA_JSON_CONTEXT_ARRAY);
835 }
836
837 /* Writes member name and an opening bracket */
838 void pa_json_encoder_begin_member_array(pa_json_encoder *encoder, const char *name) {
839     pa_assert(encoder);
840     pa_assert(encoder->context);
841     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
842     pa_assert(name && name[0]);
843
844     json_encoder_insert_delimiter(encoder);
845
846     json_write_string_escaped(encoder, name);
847     pa_strbuf_putc(encoder->buffer, ':');
848
849     pa_strbuf_putc(encoder->buffer, '[');
850
851     json_encoder_context_push(encoder, PA_JSON_CONTEXT_ARRAY);
852 }
853
854 /* Writes a closing bracket */
855 void pa_json_encoder_end_array(pa_json_encoder *encoder) {
856     pa_json_context_type_t type;
857     pa_assert(encoder);
858
859     type = json_encoder_context_pop(encoder);
860     pa_assert(type == PA_JSON_CONTEXT_ARRAY);
861
862     pa_strbuf_putc(encoder->buffer, ']');
863 }
864
865 void pa_json_encoder_add_element_string(pa_json_encoder *encoder, const char *value) {
866     pa_assert(encoder);
867     pa_assert(encoder->context);
868     pa_assert(encoder->context->type == PA_JSON_CONTEXT_EMPTY || encoder->context->type == PA_JSON_CONTEXT_ARRAY);
869
870     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
871         encoder->context->type = PA_JSON_CONTEXT_TOP;
872
873     json_encoder_insert_delimiter(encoder);
874
875     json_write_string_escaped(encoder, value);
876 }
877
878 void pa_json_encoder_add_member_string(pa_json_encoder *encoder, const char *name, const char *value) {
879     pa_assert(encoder);
880     pa_assert(encoder->context);
881     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
882     pa_assert(name && name[0]);
883
884     json_encoder_insert_delimiter(encoder);
885
886     json_write_string_escaped(encoder, name);
887
888     pa_strbuf_putc(encoder->buffer, ':');
889
890     /* Null value is written as empty element */
891     if (!value)
892         value = "";
893
894     json_write_string_escaped(encoder, value);
895 }
896
897 static void json_write_null(pa_json_encoder *encoder) {
898     pa_assert(encoder);
899
900     pa_strbuf_puts(encoder->buffer, "null");
901 }
902
903 void pa_json_encoder_add_element_null(pa_json_encoder *encoder) {
904     pa_assert(encoder);
905     pa_assert(encoder->context);
906     pa_assert(encoder->context->type == PA_JSON_CONTEXT_EMPTY || encoder->context->type == PA_JSON_CONTEXT_ARRAY);
907
908     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
909         encoder->context->type = PA_JSON_CONTEXT_TOP;
910
911     json_encoder_insert_delimiter(encoder);
912
913     json_write_null(encoder);
914 }
915
916 void pa_json_encoder_add_member_null(pa_json_encoder *encoder, const char *name) {
917     pa_assert(encoder);
918     pa_assert(encoder->context);
919     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
920     pa_assert(name && name[0]);
921
922     json_encoder_insert_delimiter(encoder);
923
924     json_write_string_escaped(encoder, name);
925     pa_strbuf_putc(encoder->buffer, ':');
926
927     json_write_null(encoder);
928 }
929
930 static void json_write_bool(pa_json_encoder *encoder, bool value) {
931     pa_assert(encoder);
932
933     pa_strbuf_puts(encoder->buffer, value ? "true" : "false");
934 }
935
936 void pa_json_encoder_add_element_bool(pa_json_encoder *encoder, bool value) {
937     pa_assert(encoder);
938     pa_assert(encoder->context);
939     pa_assert(encoder->context->type == PA_JSON_CONTEXT_EMPTY || encoder->context->type == PA_JSON_CONTEXT_ARRAY);
940
941     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
942         encoder->context->type = PA_JSON_CONTEXT_TOP;
943
944     json_encoder_insert_delimiter(encoder);
945
946     json_write_bool(encoder, value);
947 }
948
949 void pa_json_encoder_add_member_bool(pa_json_encoder *encoder, const char *name, bool value) {
950     pa_assert(encoder);
951     pa_assert(encoder->context);
952     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
953     pa_assert(name && name[0]);
954
955     json_encoder_insert_delimiter(encoder);
956
957     json_write_string_escaped(encoder, name);
958
959     pa_strbuf_putc(encoder->buffer, ':');
960
961     json_write_bool(encoder, value);
962 }
963
964 static void json_write_int(pa_json_encoder *encoder, int64_t value) {
965     pa_assert(encoder);
966
967     pa_strbuf_printf(encoder->buffer, "%"PRId64, value);
968 }
969
970 void pa_json_encoder_add_element_int(pa_json_encoder *encoder, int64_t value) {
971     pa_assert(encoder);
972     pa_assert(encoder->context);
973     pa_assert(encoder->context->type == PA_JSON_CONTEXT_EMPTY || encoder->context->type == PA_JSON_CONTEXT_ARRAY);
974
975     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
976         encoder->context->type = PA_JSON_CONTEXT_TOP;
977
978     json_encoder_insert_delimiter(encoder);
979
980     json_write_int(encoder, value);
981 }
982
983 void pa_json_encoder_add_member_int(pa_json_encoder *encoder, const char *name, int64_t value) {
984     pa_assert(encoder);
985     pa_assert(encoder->context);
986     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
987     pa_assert(name && name[0]);
988
989     json_encoder_insert_delimiter(encoder);
990
991     json_write_string_escaped(encoder, name);
992
993     pa_strbuf_putc(encoder->buffer, ':');
994
995     json_write_int(encoder, value);
996 }
997
998 static void json_write_double(pa_json_encoder *encoder, double value, int precision) {
999     pa_assert(encoder);
1000     pa_strbuf_printf(encoder->buffer, "%.*f",  precision, value);
1001 }
1002
1003 void pa_json_encoder_add_element_double(pa_json_encoder *encoder, double value, int precision) {
1004     pa_assert(encoder);
1005     pa_assert(encoder->context);
1006     pa_assert(encoder->context->type == PA_JSON_CONTEXT_EMPTY || encoder->context->type == PA_JSON_CONTEXT_ARRAY);
1007
1008     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
1009         encoder->context->type = PA_JSON_CONTEXT_TOP;
1010
1011     json_encoder_insert_delimiter(encoder);
1012
1013     json_write_double(encoder, value, precision);
1014 }
1015
1016 void pa_json_encoder_add_member_double(pa_json_encoder *encoder, const char *name, double value, int precision) {
1017     pa_assert(encoder);
1018     pa_assert(encoder->context);
1019     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
1020     pa_assert(name && name[0]);
1021
1022     json_encoder_insert_delimiter(encoder);
1023
1024     json_write_string_escaped(encoder, name);
1025
1026     pa_strbuf_putc(encoder->buffer, ':');
1027
1028     json_write_double(encoder, value, precision);
1029 }
1030
1031 static void json_write_raw(pa_json_encoder *encoder, const char *raw_string) {
1032     pa_assert(encoder);
1033     pa_strbuf_puts(encoder->buffer, raw_string);
1034 }
1035
1036 void pa_json_encoder_add_element_raw_json(pa_json_encoder *encoder, const char *raw_json_string) {
1037     pa_assert(encoder);
1038     pa_assert(encoder->context);
1039     pa_assert(encoder->context->type == PA_JSON_CONTEXT_EMPTY || encoder->context->type == PA_JSON_CONTEXT_ARRAY);
1040
1041     if (encoder->context->type == PA_JSON_CONTEXT_EMPTY)
1042         encoder->context->type = PA_JSON_CONTEXT_TOP;
1043
1044     json_encoder_insert_delimiter(encoder);
1045
1046     json_write_raw(encoder, raw_json_string);
1047 }
1048
1049 void pa_json_encoder_add_member_raw_json(pa_json_encoder *encoder, const char *name, const char *raw_json_string) {
1050     pa_assert(encoder);
1051     pa_assert(encoder->context);
1052     pa_assert(encoder->context->type == PA_JSON_CONTEXT_OBJECT);
1053     pa_assert(name && name[0]);
1054
1055     json_encoder_insert_delimiter(encoder);
1056
1057     json_write_string_escaped(encoder, name);
1058
1059     pa_strbuf_putc(encoder->buffer, ':');
1060
1061     json_write_raw(encoder, raw_json_string);
1062 }