Instead of using llvm::raw_ostream::write_escaped (which does not produce valid
JSON strings), implemented custom escaping logic based on the JSON standard,
which only requires that the following characters be escaped:
- Quotation mark (U+0022)
- Reverse solidus (U+005C)
- Control characters (U+0000 to U+001F)
Since these characters all fit within a single UTF8 byte, and will not be
present in a multi-byte UTF8 representation, simply check whether the current
byte needs to be escaped according to those requirements. If the current byte
needs to be escaped, then print out the escaped version of the byte; otherwise,
pass the current byte to the stream directly.
This fixes <rdar://problem/18266570>.
Swift SVN r21892
The swift::json namespace now contains an Output class, which largely mirrors
llvm::yaml::Output. It takes the same approach where there are various traits
structs which dictate how a particular type is output in JSON. (This is separate
from llvm::yaml because, while all JSON is valid YAML, not all YAML is valid
JSON, and customization on how scalar types are output as JSON is necessary.)
Unlike llvm::yaml, there is no equivalent Input class. Since JSON is valid YAML,
llvm::yaml::Input can be used instead.
At some point, the traits structs could likely be merged with llvm::yaml (with
some ability to customize how scalars are output if it's outputting JSON instead
of YAML), but this provides enough of a starting point to allow the driver to
generate parseable output in JSON format.
Part of <rdar://problem/15958329>.
Swift SVN r20870