Пример #1
0
static void json_writer_value_end(grpc_json_writer* writer) {
  if (writer->container_empty) {
    writer->container_empty = 0;
    if ((writer->indent == 0) || (writer->depth == 0)) return;
    json_writer_output_char(writer, '\n');
  } else {
    json_writer_output_char(writer, ',');
    if (writer->indent == 0) return;
    json_writer_output_char(writer, '\n');
  }
}
Пример #2
0
static void json_writer_output_indent(
    grpc_json_writer* writer) {
  static const char spacesstr[] =
      "                "
      "                "
      "                "
      "                ";

  unsigned spaces = writer->depth * writer->indent;

  if (writer->indent == 0) return;

  if (writer->got_key) {
    json_writer_output_char(writer, ' ');
    return;
  }

  while (spaces >= (sizeof(spacesstr) - 1)) {
    json_writer_output_string_with_len(writer, spacesstr,
                                       sizeof(spacesstr) - 1);
    spaces -= (sizeof(spacesstr) - 1);
  }

  if (spaces == 0) return;

  json_writer_output_string_with_len(
      writer, spacesstr + sizeof(spacesstr) - 1 - spaces, spaces);
}
Пример #3
0
static void json_writer_output_string_with_len(void *userdata, const char *str,
                                               size_t len) {
  size_t i;
  for (i = 0; i < len; i++) {
    json_writer_output_char(userdata, str[i]);
  }
}
Пример #4
0
static void json_writer_escape_utf16(grpc_json_writer* writer, gpr_uint16 utf16) {
  static const char hex[] = "0123456789abcdef";

  json_writer_output_string_with_len(writer, "\\u", 2);
  json_writer_output_char(writer, hex[(utf16 >> 12) & 0x0f]);
  json_writer_output_char(writer, hex[(utf16 >> 8) & 0x0f]);
  json_writer_output_char(writer, hex[(utf16 >> 4) & 0x0f]);
  json_writer_output_char(writer, hex[(utf16) & 0x0f]);
}
Пример #5
0
static void json_writer_escape_string(grpc_json_writer* writer,
                                      const char* string) {
  json_writer_output_char(writer, '"');

  for (;;) {
    gpr_uint8 c = (gpr_uint8)*string++;
    if (c == 0) {
      break;
    } else if ((c >= 32) && (c <= 126)) {
      if ((c == '\\') || (c == '"')) json_writer_output_char(writer, '\\');
      json_writer_output_char(writer, c);
    } else if ((c < 32) || (c == 127)) {
      switch (c) {
        case '\b':
          json_writer_output_string_with_len(writer, "\\b", 2);
          break;
        case '\f':
          json_writer_output_string_with_len(writer, "\\f", 2);
          break;
        case '\n':
          json_writer_output_string_with_len(writer, "\\n", 2);
          break;
        case '\r':
          json_writer_output_string_with_len(writer, "\\r", 2);
          break;
        case '\t':
          json_writer_output_string_with_len(writer, "\\t", 2);
          break;
        default:
          json_writer_escape_utf16(writer, c);
          break;
      }
    } else {
      gpr_uint32 utf32 = 0;
      int extra = 0;
      int i;
      int valid = 1;
      if ((c & 0xe0) == 0xc0) {
        utf32 = c & 0x1f;
        extra = 1;
      } else if ((c & 0xf0) == 0xe0) {
        utf32 = c & 0x0f;
        extra = 2;
      } else if ((c & 0xf8) == 0xf0) {
        utf32 = c & 0x07;
        extra = 3;
      } else {
        break;
      }
      for (i = 0; i < extra; i++) {
        utf32 <<= 6;
        c = *string++;
        /* Breaks out and bail on any invalid UTF-8 sequence, including \0. */
        if ((c & 0xc0) != 0x80) {
          valid = 0;
          break;
        }
        utf32 |= c & 0x3f;
      }
      if (!valid) break;
      /* The range 0xd800 - 0xdfff is reserved by the surrogates ad vitam.
       * Any other range is technically reserved for future usage, so if we
       * don't want the software to break in the future, we have to allow
       * anything else. The first non-unicode character is 0x110000. */
      if (((utf32 >= 0xd800) && (utf32 <= 0xdfff)) ||
          (utf32 >= 0x110000)) break;
      if (utf32 >= 0x10000) {
        /* If utf32 contains a character that is above 0xffff, it needs to be
         * broken down into a utf-16 surrogate pair. A surrogate pair is first
         * a high surrogate, followed by a low surrogate. Each surrogate holds
         * 10 bits of usable data, thus allowing a total of 20 bits of data.
         * The high surrogate marker is 0xd800, while the low surrogate marker
         * is 0xdc00. The low 10 bits of each will be the usable data.
         *
         * After re-combining the 20 bits of data, one has to add 0x10000 to
         * the resulting value, in order to obtain the original character.
         * This is obviously because the range 0x0000 - 0xffff can be written
         * without any special trick.
         *
         * Since 0x10ffff is the highest allowed character, we're working in
         * the range 0x00000 - 0xfffff after we decrement it by 0x10000.
         * That range is exactly 20 bits.
         */
        utf32 -= 0x10000;
        json_writer_escape_utf16(writer, 0xd800 | (utf32 >> 10));
        json_writer_escape_utf16(writer, 0xdc00 | (utf32 & 0x3ff));
      } else {
        json_writer_escape_utf16(writer, utf32);
      }
    }
Пример #6
0
static void json_writer_output_string(void *userdata, const char *str) {
  while (*str) {
    json_writer_output_char(userdata, *str++);
  }
}