/* * dup_json_string -- * Like strdup, but escape any characters that are special for JSON. * The result will be embedded in a JSON string. */ static int dup_json_string(const char *str, char **result) { size_t left, nchars; const char *p; char *q; nchars = 0; for (p = str; *p; p++, nchars++) nchars += __wt_json_unpack_char(*p, NULL, 0, false); q = malloc(nchars + 1); if (q == NULL) return (1); *result = q; left = nchars; for (p = str; *p; p++, nchars++) { nchars = __wt_json_unpack_char(*p, (u_char *)q, left, false); left -= nchars; q += nchars; } *q = '\0'; return (0); }
static size_t __logrec_json_unpack_str(char *dest, size_t destlen, const char *src, size_t srclen) { size_t total; size_t n; total = 0; while (srclen > 0) { n = __wt_json_unpack_char(*src++, (u_char *)dest, destlen, 0); srclen--; if (n > destlen) destlen = 0; else { destlen -= n; dest += n; } total += n; } if (destlen > 0) *dest = '\0'; return (total + 1); }
/* * __json_unpack_put -- * Calculate the size of a packed byte string as formatted for JSON. */ static size_t __json_unpack_put(WT_SESSION_IMPL *session, void *voidpv, u_char *buf, size_t bufsz, WT_CONFIG_ITEM *name) { WT_PACK_VALUE *pv; const u_char *p, *end; size_t s, n; pv = (WT_PACK_VALUE *)voidpv; s = (size_t)snprintf((char *)buf, bufsz, "\"%.*s\" : ", (int)name->len, name->str); if (s <= bufsz) { bufsz -= s; buf += s; } else bufsz = 0; switch (pv->type) { case 'x': return (0); case 's': case 'S': /* Account for '"' quote in front and back. */ s += 2; p = (const u_char *)pv->u.s; if (bufsz > 0) { *buf++ = '"'; bufsz--; } if (pv->type == 's' || pv->havesize) { end = p + pv->size; for (; p < end; p++) { n = __wt_json_unpack_char( *p, buf, bufsz, false); if (n > bufsz) bufsz = 0; else { bufsz -= n; buf += n; } s += n; } } else for (; *p; p++) { n = __wt_json_unpack_char( *p, buf, bufsz, false); if (n > bufsz) bufsz = 0; else { bufsz -= n; buf += n; } s += n; } if (bufsz > 0) *buf++ = '"'; return (s); case 'U': case 'u': s += 2; p = (const u_char *)pv->u.item.data; end = p + pv->u.item.size; if (bufsz > 0) { *buf++ = '"'; bufsz--; } for (; p < end; p++) { n = __wt_json_unpack_char(*p, buf, bufsz, true); if (n > bufsz) bufsz = 0; else { bufsz -= n; buf += n; } s += n; } if (bufsz > 0) *buf++ = '"'; return (s); case 'b': case 'h': case 'i': case 'l': case 'q': return (s + (size_t)snprintf((char *)buf, bufsz, "%" PRId64, pv->u.i)); case 'B': case 't': case 'H': case 'I': case 'L': case 'Q': case 'r': case 'R': return (s + (size_t)snprintf((char *)buf, bufsz, "%" PRId64, pv->u.u)); } __wt_err(session, EINVAL, "unknown pack-value type: %c", (int)pv->type); return ((size_t)-1); }