- void newline(void) {
- os << "\n";
- for (int i = 0; i < level; ++i)
- os << " ";
- }
-
- void separator(void) {
- if (value) {
- os << ",";
- switch (space) {
- case '\0':
- break;
- case '\n':
- newline();
- break;
- default:
- os << space;
- break;
- }
- } else {
- if (space == '\n') {
- newline();
- }
- }
- }
-
- void escapeAsciiString(const char *str) {
- os << "\"";
-
- const unsigned char *src = (const unsigned char *)str;
- unsigned char c;
- while ((c = *src++)) {
- if ((c == '\"') ||
- (c == '\\')) {
- // escape character
- os << '\\' << (unsigned char)c;
- } else if ((c >= 0x20 && c <= 0x7e) ||
- c == '\t' ||
- c == '\r' ||
- c == '\n') {
- // pass-through character
- os << (unsigned char)c;
- } else {
- assert(0);
- os << "?";
- }
- }
-
- os << "\"";
- }
-
- void escapeUnicodeString(const char *str) {
- os << "\"";
-
- const char *locale = setlocale(LC_CTYPE, "");
- const char *src = str;
- mbstate_t state;
-
- memset(&state, 0, sizeof state);
-
- do {
- // Convert characters one at a time in order to recover from
- // conversion errors
- wchar_t c;
- size_t written = mbsrtowcs(&c, &src, 1, &state);
- if (written == 0) {
- // completed
- break;
- } if (written == (size_t)-1) {
- // conversion error -- skip
- os << "?";
- do {
- ++src;
- } while (*src & 0x80);
- } else if ((c == '\"') ||
- (c == '\\')) {
- // escape character
- os << '\\' << (unsigned char)c;
- } else if ((c >= 0x20 && c <= 0x7e) ||
- c == '\t' ||
- c == '\r' ||
- c == '\n') {
- // pass-through character
- os << (unsigned char)c;
- } else {
- // unicode
- os << "\\u" << std::setfill('0') << std::hex << std::setw(4) << (unsigned)c;
- os << std::dec;
- }
- } while (src);
-
- setlocale(LC_CTYPE, locale);
-
- os << "\"";
- }