/** * Prints a string to an autobuffer, using JSON escape rules * @param out pointer to output buffer * @param txt string to print * @param delimiter true if string must be enclosed in quotation marks * @return -1 if an error happened, 0 otherwise */ static int _json_printvalue(struct autobuf *out, const char *txt, bool delimiter) { const char *ptr; bool unprintable; if (delimiter) { if (abuf_puts(out, "\"") < 0) { return -1; } } else if (*txt == 0) { abuf_puts(out, "0"); } ptr = txt; while (*ptr) { unprintable = !str_char_is_printable(*ptr); if (unprintable || *ptr == '\\' || *ptr == '\"') { if (ptr != txt) { if (abuf_memcpy(out, txt, ptr - txt) < 0) { return -1; } } if (unprintable) { if (abuf_appendf(out, "\\u00%02x", (unsigned char)(*ptr++)) < 0) { return -1; } } else { if (abuf_appendf(out, "\\%c", *ptr++) < 0) { return -1; } } txt = ptr; } else { ptr++; } } if (abuf_puts(out, txt) < 0) { return -1; } if (delimiter) { if (abuf_puts(out, "\"") < 0) { return -1; } } return 0; }
/** * Printable is defined as all ascii characters >= 32 except * 127 and 255. * @param value stringpointer * @return true if string only contains printable characters, * false otherwise */ bool str_is_printable(const char *value) { const unsigned char *_value; _value = (const unsigned char *)value; while (*_value) { if (!str_char_is_printable(*_value)) { return false; } _value++; } return true; }