nmsg 1.1.1
nmsg_json.h
1#ifndef NMSG_JSON_H
2#define NMSG_JSON_H
3
4#include "strbuf.h"
5#include "libmy/my_alloc.h"
6
7static inline void
8num_to_str(int num, int size, char * ptr) {
9 int ndx = size - 1;
10
11 while (size > 0) {
12 int digit = num % 10;
13 ptr[ndx] = '0' + digit;
14 --ndx;
15 --size;
16 num /= 10;
17 }
18}
19
20static inline size_t
21vnum_to_str(uint64_t num, char *ptr) {
22 uint64_t tmp = num;
23 size_t ndx, left, ndigits = 0;
24
25 do {
26 ndigits++;
27 tmp /= 10;
28 } while (tmp != 0);
29
30 left = ndigits;
31 ndx = left - 1;
32 while(left > 0) {
33 int digit = num % 10;
34 ptr[ndx] = '0' + digit;
35 --ndx;
36 --left;
37 num = num/10;
38 }
39
40 ptr[ndigits] = '\0';
41
42 return ndigits;
43}
44
45static inline void
46declare_json_value(struct nmsg_strbuf *sb, const char *name, bool is_first) {
47 if (!is_first) {
48 nmsg_strbuf_append_str(sb, ",\"", 2);
49 } else {
50 nmsg_strbuf_append_str(sb, "\"", 1);
51 }
52
53 nmsg_strbuf_append_str(sb, name, strlen(name));
54 nmsg_strbuf_append_str(sb, "\":", 2);
55}
56
57static inline void
58append_json_value_string(struct nmsg_strbuf *sb, const char *val, size_t vlen) {
59 nmsg_strbuf_append_str(sb, "\"", 1);
60
61 if (vlen == 0)
62 vlen = strlen(val);
63
64 nmsg_strbuf_append_str_json(sb, val, vlen);
65 nmsg_strbuf_append_str(sb, "\"", 1); // guaranteed success x 3
66}
67
68/* More performant variant for when we know data doesn't need to be escaped. */
69static inline void
70append_json_value_string_noescape(struct nmsg_strbuf *sb, const char *val, size_t vlen) {
71 nmsg_strbuf_append_str(sb, "\"", 1);
72
73 if (vlen == 0)
74 vlen = strlen(val);
75
76 nmsg_strbuf_append_str(sb, val, vlen);
77 nmsg_strbuf_append_str(sb, "\"", 1); // guaranteed success x 3
78}
79
80static inline void
81append_json_value_int(struct nmsg_strbuf *sb, uint64_t val) {
82 char numbuf[32];
83 size_t nlen;
84
85 nlen = vnum_to_str(val, numbuf);
86 nmsg_strbuf_append_str(sb, numbuf, nlen); // guaranteed succes
87}
88
89static inline void
90append_json_value_bool(struct nmsg_strbuf *sb, bool val) {
91
92 if (val)
93 nmsg_strbuf_append_str(sb, "true", 4);
94 else
95 nmsg_strbuf_append_str(sb, "false", 5); // guaranteed success
96}
97
98static inline void
99append_json_value_double(struct nmsg_strbuf *sb, double val) {
100 char dubbuf[64], *endp;
101 size_t dlen;
102
103 dlen = snprintf(dubbuf, sizeof(dubbuf), "%.18f", val);
104 dubbuf[sizeof(dubbuf)-1] = 0;
105
106 /* Trim possible trailing numerical zero padding */
107 endp = dubbuf + dlen - 1;
108 while (*endp != '\0' && endp > dubbuf) {
109 if (*endp != '0' || *(endp-1) == '.')
110 break;
111 *endp-- = '\0';
112 dlen--;
113 }
114
115 nmsg_strbuf_append_str(sb, dubbuf, dlen); // guaranteed success
116}
117
118static inline void
119append_json_value_null(struct nmsg_strbuf *sb) {
120 nmsg_strbuf_append_str(sb, "null", 4); // guaranteed success
121}
122
123#endif /* NMSG_JSON_H */