私はいくつかの解決策を見つけました。一般に、「特別な機会のバグのないエスケープ」を提供するboost::property_tree::json_parser::create_escapes
ために、のテンプレートを指定する必要があります。[Ch=Char]
JSON標準では、すべての文字列が「\ uXXXX」エスケープでUTF-16エンコードされていると想定していますが、一部のライブラリは「\xXX」エスケープでUTF-8エンコードをサポートしています。JSONファイルをUTF-8でエンコードできる場合は、0x7Fより高いすべての文字を渡すことができます。witchは元の機能を目的としていました。
を使用する前にこのコードを配置しboost::property_tree::json_parser::write_json
ました。それはから来ていboost_1_49_0/boost/property_tree/detail/json_parser_write.hpp
ます:
namespace boost { namespace property_tree { namespace json_parser
{
// Create necessary escape sequences from illegal characters
template<>
std::basic_string<char> create_escapes(const std::basic_string<char> &s)
{
std::basic_string<char> result;
std::basic_string<char>::const_iterator b = s.begin();
std::basic_string<char>::const_iterator e = s.end();
while (b != e)
{
// This assumes an ASCII superset. But so does everything in PTree.
// We escape everything outside ASCII, because this code can't
// handle high unicode characters.
if (*b == 0x20 || *b == 0x21 || (*b >= 0x23 && *b <= 0x2E) ||
(*b >= 0x30 && *b <= 0x5B) || (*b >= 0x5D && *b <= 0xFF) //it fails here because char are signed
|| (*b >= -0x80 && *b < 0 ) ) // this will pass UTF-8 signed chars
result += *b;
else if (*b == char('\b')) result += char('\\'), result += char('b');
else if (*b == char('\f')) result += char('\\'), result += char('f');
else if (*b == char('\n')) result += char('\\'), result += char('n');
else if (*b == char('\r')) result += char('\\'), result += char('r');
else if (*b == char('/')) result += char('\\'), result += char('/');
else if (*b == char('"')) result += char('\\'), result += char('"');
else if (*b == char('\\')) result += char('\\'), result += char('\\');
else
{
const char *hexdigits = "0123456789ABCDEF";
typedef make_unsigned<char>::type UCh;
unsigned long u = (std::min)(static_cast<unsigned long>(
static_cast<UCh>(*b)),
0xFFFFul);
int d1 = u / 4096; u -= d1 * 4096;
int d2 = u / 256; u -= d2 * 256;
int d3 = u / 16; u -= d3 * 16;
int d4 = u;
result += char('\\'); result += char('u');
result += char(hexdigits[d1]); result += char(hexdigits[d2]);
result += char(hexdigits[d3]); result += char(hexdigits[d4]);
}
++b;
}
return result;
}
} } }
そして私が得る出力:
{
"text": "aáb"
}
また、この関数boost::property_tree::json_parser::a_unicode
には、エスケープされたUnicode文字を符号付き文字に読み取る際に同様の問題があります。