static void write_action(Context* ctx, const WasmAction* action) { write_key(ctx, "action"); wasm_writef(&ctx->json_stream, "{"); write_key(ctx, "type"); if (action->type == WASM_ACTION_TYPE_INVOKE) { write_string(ctx, "invoke"); } else { assert(action->type == WASM_ACTION_TYPE_GET); write_string(ctx, "get"); } write_separator(ctx); if (action->module_var.type != WASM_VAR_TYPE_INDEX) { write_key(ctx, "module"); write_var(ctx, &action->module_var); write_separator(ctx); } if (action->type == WASM_ACTION_TYPE_INVOKE) { write_key(ctx, "field"); write_escaped_string_slice(ctx, action->invoke.name); write_separator(ctx); write_key(ctx, "args"); write_const_vector(ctx, &action->invoke.args); } else { write_key(ctx, "field"); write_escaped_string_slice(ctx, action->get.name); } wasm_writef(&ctx->json_stream, "}"); }
void JsonOut::write(const JsonSerializer &thing) { if (need_separator) { write_separator(); } thing.serialize(*this); need_separator = true; }
void JsonOut::write_null() { if (need_separator) { write_separator(); } stream->write("null", 4); need_separator = true; }
static void write_const(Context* ctx, const WasmConst* const_) { wasm_writef(&ctx->json_stream, "{"); write_key(ctx, "type"); /* Always write the values as strings, even though they may be representable * as JSON numbers. This way the formatting is consistent. */ switch (const_->type) { case WASM_TYPE_I32: write_string(ctx, "i32"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%u\"", const_->u32); break; case WASM_TYPE_I64: write_string(ctx, "i64"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%" PRIu64 "\"", const_->u64); break; case WASM_TYPE_F32: { /* TODO(binji): write as hex float */ write_string(ctx, "f32"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%u\"", const_->f32_bits); break; } case WASM_TYPE_F64: { /* TODO(binji): write as hex float */ write_string(ctx, "f64"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%" PRIu64 "\"", const_->f64_bits); break; } default: assert(0); } wasm_writef(&ctx->json_stream, "}"); }
void JsonOut::write(const double &f) { if (need_separator) { write_separator(); } // format specified in constructor, let's hope it hasn't changed *stream << f; need_separator = true; }
void JsonOut::write(const unsigned long &ul) { if (need_separator) { write_separator(); } // format specified in constructor, let's hope it hasn't changed *stream << ul; need_separator = true; }
static void write_const_vector(Context* ctx, const WasmConstVector* consts) { wasm_writef(&ctx->json_stream, "["); size_t i; for (i = 0; i < consts->size; ++i) { const WasmConst* const_ = &consts->data[i]; write_const(ctx, const_); if (i != consts->size - 1) write_separator(ctx); } wasm_writef(&ctx->json_stream, "]"); }
void JsonOut::write(const bool &b) { if (need_separator) { write_separator(); } if (b) { stream->write("true", 4); } else { stream->write("false", 5); } need_separator = true; }
void JsonOut::start_array() { if (need_separator) { write_separator(); } stream->put('['); if (pretty_print) { indent_level += 1; stream->put('\n'); write_indent(); } need_separator = false; }
void JsonOut::write(const std::bitset<13> &b) { if (need_separator) { write_separator(); } std::string converted = b.to_string(); unsigned char ch; stream->put('"'); for (int i = 0; i < converted.size(); ++i) { ch = converted[i]; stream->put(ch); } stream->put('"'); need_separator = true; }
void JsonOut::write(const std::bitset<13> &b) { if (need_separator) { write_separator(); } std::string converted = b.to_string(); unsigned char ch; stream->put('"'); for (auto &i : converted) { ch = i; stream->put(ch); } stream->put('"'); need_separator = true; }
void JsonOut::write(const std::string &s) { if (need_separator) { write_separator(); } unsigned char ch; stream->put('"'); for (int i = 0; i < s.size(); ++i) { ch = s[i]; if (ch == '"') { stream->write("\\\"", 2); } else if (ch == '\\') { stream->write("\\\\", 2); } else if (ch == '/') { // don't technically need to escape this stream->put('/'); } else if (ch == '\b') { stream->write("\\b", 2); } else if (ch == '\f') { stream->write("\\f", 2); } else if (ch == '\n') { stream->write("\\n", 2); } else if (ch == '\r') { stream->write("\\r", 2); } else if (ch == '\t') { stream->write("\\t", 2); } else if (ch < 0x20) { // convert to "\uxxxx" unicode escape stream->write("\\u00", 4); stream->put((ch < 0x10) ? '0' : '1'); char remainder = ch & 0x0F; if (remainder < 0x0A) { stream->put('0' + remainder); } else { stream->put('A' + (remainder - 0x0A)); } } else { stream->put(ch); } } stream->put('"'); need_separator = true; }
static void list_formatted_write_scalar (st_parameter_dt *dtp, bt type, void *p, int kind, size_t size) { if (dtp->u.p.current_unit == NULL) return; if (dtp->u.p.first_item) { dtp->u.p.first_item = 0; write_char (dtp, ' '); } else { if (type != BT_CHARACTER || !dtp->u.p.char_flag || dtp->u.p.current_unit->delim_status != DELIM_NONE) write_separator (dtp); } switch (type) { case BT_INTEGER: write_integer (dtp, p, kind); break; case BT_LOGICAL: write_logical (dtp, p, kind); break; case BT_CHARACTER: write_character (dtp, p, kind, size); break; case BT_REAL: write_real (dtp, p, kind); break; case BT_COMPLEX: write_complex (dtp, p, kind, size); break; default: internal_error (&dtp->common, "list_formatted_write(): Bad type"); } dtp->u.p.char_flag = (type == BT_CHARACTER); }