in src/kudu/util/debug/trace_event_impl.cc [692:757]
void TraceEvent::AppendValueAsJSON(unsigned char type,
TraceEvent::TraceValue value,
std::string* out) {
switch (type) {
case TRACE_VALUE_TYPE_BOOL:
*out += value.as_bool ? "true" : "false";
break;
case TRACE_VALUE_TYPE_UINT:
SubstituteAndAppend(out, "$0", static_cast<uint64_t>(value.as_uint));
break;
case TRACE_VALUE_TYPE_INT:
SubstituteAndAppend(out, "$0", static_cast<int64_t>(value.as_int));
break;
case TRACE_VALUE_TYPE_DOUBLE: {
// FIXME: base/json/json_writer.cc is using the same code,
// should be made into a common method.
std::string real;
double val = value.as_double;
if (MathLimits<double>::IsFinite(val)) {
real = strings::Substitute("$0", val);
// Ensure that the number has a .0 if there's no decimal or 'e'. This
// makes sure that when we read the JSON back, it's interpreted as a
// real rather than an int.
if (real.find('.') == std::string::npos &&
real.find('e') == std::string::npos &&
real.find('E') == std::string::npos) {
real.append(".0");
}
// The JSON spec requires that non-integer values in the range (-1,1)
// have a zero before the decimal point - ".52" is not valid, "0.52" is.
if (real[0] == '.') {
real.insert(0, "0");
} else if (real.length() > 1 && real[0] == '-' && real[1] == '.') {
// "-.1" bad "-0.1" good
real.insert(1, "0");
}
} else if (MathLimits<double>::IsNaN(val)){
// The JSON spec doesn't allow NaN and Infinity (since these are
// objects in EcmaScript). Use strings instead.
real = "\"NaN\"";
} else if (val < 0) {
real = "\"-Infinity\"";
} else {
real = "\"Infinity\"";
}
SubstituteAndAppend(out, "$0", real);
break;
}
case TRACE_VALUE_TYPE_POINTER:
// JSON only supports double and int numbers.
// So as not to lose bits from a 64-bit pointer, output as a hex string.
StringAppendF(out, "\"0x%" PRIx64 "\"", static_cast<uint64_t>(
reinterpret_cast<intptr_t>(
value.as_pointer)));
break;
case TRACE_VALUE_TYPE_STRING:
case TRACE_VALUE_TYPE_COPY_STRING:
*out += "\"";
JsonEscape(value.as_string ? value.as_string : "NULL", out);
*out += "\"";
break;
default:
LOG(FATAL) << "Don't know how to print this value";
break;
}
}