json_force_inline void write_escaped_c()

in src/detail/escape_common.hpp [32:84]


json_force_inline void write_escaped_c(char *&out, const char c) {
  static const char HEX[] = "0123456789ABCDEF";
  static const char POPULAR_CONTROL_CHARACTERS[] = {
    'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
    'b', 't', 'n', 'u', 'f', 'r', 'u', 'u',
    'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u',
    'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u'
  };

  // All characters above 0x20 can be written as is, except for ", /. The former
  // is below 0x30 and the latter is at 0x5C. As an optimization, for most
  // simple strings (letters, numbers, some punctuation), check for this first
  // before doing more complicated checks (more expensive checks).
  if (json_likely(uint8_t(c) >= 0x30)) {
    if (json_likely(c != '\\')) {
      *(out++) = c;
    } else {
      *(out++) = '\\';
      *(out++) = c;
    }
    return;
  }

  // In the next step, consider the characters between 0x20 and 0x30, which are
  // different punctuation and special characters. We will write most of them as
  // is, except for ", which is trivially escaped. Note that JSON allows for /
  // to be escaped as well, but most JSON serializers do not.
  if (json_likely(uint8_t(c) >= 0x20)) {
    if (json_likely(c != '"')) {
      *(out++) = c;
    } else {
      *(out++) = '\\';
      *(out++) = c;
    }
    return;
  }

  // Finally handle all control characters (below 0x20). These all need escaping
  // to some degree. There are some "popular" control characters, such as tabs,>
  // newline, and carriage return, with simple escape codes. All other control
  // characters get an escape code on the form \u00xx. Six bytes. Isch.
  const auto control_character = POPULAR_CONTROL_CHARACTERS[int(c)];
  if (json_likely(control_character != 'u')) {
    out[0] = '\\';
    out[1] = control_character;
    out += 2;
  } else {
    memcpy(out, "\\u00", 4);
    out[4] = HEX[(c >> 4)];
    out[5] = HEX[(c & 0x0F)];
    out += 6;
  }
}