static size_t json_string_format(struct n_buf *nb, const char *s, void *data) { static char esc[] = { ['\0'] = '0', ['\a'] = 'a', ['\b'] = 'b', ['\t'] = 't', ['\n'] = 'n', ['\v'] = 'v', ['\f'] = 'f', ['\r'] = 'r', ['\"'] = '\"', ['\\'] = '\\', }; /* This is probably broken for UNICODE. */ size_t len = 0; len += n_buf_putc(nb, '\"'); for (; *s != 0; s++) { int c = *(const unsigned char *) s; if (!isascii(c)) { len += n_buf_printf(nb, "\\u%04x", (unsigned int) c); } else if (c < sizeof(esc) && esc[c] != 0) { len += n_buf_putc(nb, '\\'); len += n_buf_putc(nb, esc[c]); } else { len += n_buf_putc(nb, c); } } len += n_buf_putc(nb, '\"'); return len; }
static size_t json_format_r(struct n_buf *nb, struct json **j, void *data, int in_object, int in_array) { size_t len = 0; int i; for (i = 0; (*j)->j_type != J_end_V; (*j)++) { if (i > 0) { if (in_array) len += n_buf_putc(nb, ','); else if (in_object) len += n_buf_putc(nb, i % 2 ? ':' : ','); else break; } switch ((*j)->j_type) { case J_init_V: ((*j)->j_u.u_init_V)(); break; case J_array_V: (*j)++; len += n_buf_putc(nb, '['); len += json_format_r(nb, j, data, 0, 1); len += n_buf_putc(nb, ']'); break; case J_object_V: (*j)++; len += n_buf_putc(nb, '{'); len += json_format_r(nb, j, data, 1, 0); len += n_buf_putc(nb, '}'); break; default: len += json_format_1(nb, *j, data); break; } i += ((*j)->j_type != J_init_V); } return len; }
tn_buf *pkguinf_store(const struct pkguinf *pkgu, tn_buf *nbuf, const char *lang) { struct pkguinf_i18n *inf; struct member { char tag; char *value; } members[] = { { PKGUINF_LICENSE, pkgu->license }, { PKGUINF_URL, pkgu->url }, { PKGUINF_VENDOR, pkgu->vendor }, { PKGUINF_BUILDHOST, pkgu->buildhost }, { PKGUINF_DISTRO, pkgu->distro }, { PKGUINF_CHANGELOG, pkgu->changelog }, { 0, NULL } }; n_assert(lang); if (n_str_eq(lang, "C")) { /* skip entries older than year */ time_t since = time(NULL) - 3600 * 24 * 356; int i = 0; while (members[i].tag) { struct member m = members[i++]; const char *value = m.value; if (m.tag == PKGUINF_CHANGELOG) { if (pkgu->changelog && strlen(pkgu->changelog) > 512) value = pkguinf_get_changelog((struct pkguinf*)pkgu, since); } if (value == NULL) continue; n_buf_putc(nbuf, m.tag); n_buf_putc(nbuf, '\0'); n_buf_puts(nbuf, value); n_buf_putc(nbuf, '\0'); } n_buf_putc(nbuf, PKGUINF_TAG_ENDCMN); n_buf_putc(nbuf, '\0'); } if ((inf = n_hash_get(pkgu->_ht, lang))) { n_buf_putc(nbuf, PKGUINF_SUMMARY); n_buf_putc(nbuf, '\0'); n_buf_puts(nbuf, inf->summary); n_buf_putc(nbuf, '\0'); n_buf_putc(nbuf, PKGUINF_DESCRIPTION); n_buf_putc(nbuf, '\0'); n_buf_puts(nbuf, inf->description); n_buf_putc(nbuf, '\0'); } return nbuf; }