1
diff --git a/json/reader.inl b/json/reader.inl
2
index fc20833..60c1b93 100644
5
@@ -35,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9
-* unicode character decoding
13
@@ -308,7 +307,7 @@ inline std::string Reader::MatchString(InputStream& inputStream)
17
- inputStream.EOS() == false) // shouldn't have reached the end yet
18
+ inputStream.EOS() == false) // shouldn't have reached the end yet
20
c = inputStream.Get();
22
@@ -320,7 +319,37 @@ inline std::string Reader::MatchString(InputStream& inputStream)
23
case 'n': string.push_back('\n'); break;
24
case 'r': string.push_back('\r'); break;
25
case 't': string.push_back('\t'); break;
26
- case 'u': string.push_back('\u'); break; // TODO: what do we do with this?
27
+ case 'u': { // convert unicode to UTF-8
30
+ // next four characters should be hex
31
+ for (i = 0; i < 4; ++i) {
32
+ c = inputStream.Get();
33
+ if (c >= '0' && c <= '9') {
34
+ x = (x << 4) | (c - '0');
35
+ } else if (c >= 'a' && c <= 'f') {
36
+ x = (x << 4) | (c - 'a' + 10);
37
+ } else if (c >= 'A' && c <= 'F') {
38
+ x = (x << 4) | (c - 'A' + 10);
40
+ std::string sMessage = std::string("Unrecognized hexadecimal character found in string: ") + c;
41
+ throw ScanException(sMessage, inputStream.GetLocation());
47
+ string.push_back(x);
48
+ } else if (x < 0x800) {
49
+ string.push_back(0xc0 | (x >> 6));
50
+ string.push_back(0x80 | (x & 0x3f));
52
+ string.push_back(0xe0 | (x >> 12));
53
+ string.push_back(0x80 | ((x >> 6) & 0x3f));
54
+ string.push_back(0x80 | (x & 0x3f));
59
std::string sMessage = std::string("Unrecognized escape sequence found in string: \\") + c;
60
throw ScanException(sMessage, inputStream.GetLocation());
61
diff --git a/json/writer.inl b/json/writer.inl
62
index b16401b..27226b6 100644
65
@@ -35,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68
* better documentation
69
-* unicode character encoding
73
@@ -122,7 +121,7 @@ inline void Writer::Write_i(const Object& object)
75
inline void Writer::Write_i(const Number& numberElement)
77
- m_ostr << std::setprecision(20) << numberElement.Value();
78
+ m_ostr << std::dec << std::setprecision(20) << numberElement.Value();
81
inline void Writer::Write_i(const Boolean& booleanElement)
82
@@ -139,6 +138,48 @@ inline void Writer::Write_i(const String& stringElement)
84
for (; it != itEnd; ++it)
86
+ // check for UTF-8 unicode encoding
87
+ unsigned char u = static_cast<unsigned char>(*it);
89
+ if ((u & 0xe0) == 0xc0) {
90
+ // two-character sequence
91
+ int x = (*it & 0x1f) << 6;
92
+ if ((it + 1) == itEnd) {
93
+ m_ostr << *it; continue;
95
+ u = static_cast<unsigned char>(*(it + 1));
96
+ if ((u & 0xc0) == 0x80) {
98
+ m_ostr << "\\u" << std::hex << std::setfill('0')
99
+ << std::setw(4) << x;
104
+ } else if ((u & 0xf0) == 0xe0) {
105
+ // three-character sequence
106
+ int x = (u & 0x0f) << 12;
107
+ if ((it + 1) == itEnd) {
108
+ m_ostr << *it; continue;
110
+ u = static_cast<unsigned char>(*(it + 1));
111
+ if ((u & 0xc0) == 0x80) {
112
+ x |= (u & 0x3f) << 6;
113
+ if ((it + 2) == itEnd) {
114
+ m_ostr << *it; continue;
116
+ u = static_cast<unsigned char>(*(it + 2));
117
+ if ((u & 0xc0) == 0x80) {
119
+ m_ostr << "\\u" << std::hex << std::setfill('0')
120
+ << std::setw(4) << x;
130
case '"': m_ostr << "\\\""; break;
131
@@ -148,7 +189,6 @@ inline void Writer::Write_i(const String& stringElement)
132
case '\n': m_ostr << "\\n"; break;
133
case '\r': m_ostr << "\\r"; break;
134
case '\t': m_ostr << "\\t"; break;
135
- case '\u': m_ostr << "\\u"; break; // uh...
136
default: m_ostr << *it; break;