Commit 55587d6f authored by miloyip@gmail.com's avatar miloyip@gmail.com

Added transcoding support in Writer and PrettyWriter

git-svn-id: https://rapidjson.googlecode.com/svn/trunk@47 c5894555-1306-4e8d-425f-1f6f381ee07c
parent 8bdcd742
...@@ -11,10 +11,10 @@ namespace rapidjson { ...@@ -11,10 +11,10 @@ namespace rapidjson {
\tparam Encoding Encoding of both source strings and output. \tparam Encoding Encoding of both source strings and output.
\tparam Allocator Type of allocator for allocating memory of stack. \tparam Allocator Type of allocator for allocating memory of stack.
*/ */
template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > template<typename Stream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
class PrettyWriter : public Writer<Stream, Encoding, Allocator> { class PrettyWriter : public Writer<Stream, SourceEncoding, TargetEncoding, Allocator> {
public: public:
typedef Writer<Stream, Encoding, Allocator> Base; typedef Writer<Stream, SourceEncoding, TargetEncoding, Allocator> Base;
typedef typename Base::Ch Ch; typedef typename Base::Ch Ch;
//! Constructor //! Constructor
......
...@@ -23,10 +23,10 @@ namespace rapidjson { ...@@ -23,10 +23,10 @@ namespace rapidjson {
\tparam Encoding Encoding of both source strings and output. \tparam Encoding Encoding of both source strings and output.
\implements Handler \implements Handler
*/ */
template<typename Stream, typename Encoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> > template<typename Stream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename Allocator = MemoryPoolAllocator<> >
class Writer { class Writer {
public: public:
typedef typename Encoding::Ch Ch; typedef typename SourceEncoding::Ch Ch;
Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : Writer(Stream& stream, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {} stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) {}
...@@ -166,7 +166,7 @@ protected: ...@@ -166,7 +166,7 @@ protected:
} }
void WriteString(const Ch* str, SizeType length) { void WriteString(const Ch* str, SizeType length) {
static const char hexDigits[] = "0123456789ABCDEF"; static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
static const char escape[256] = { static const char escape[256] = {
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
//0 1 2 3 4 5 6 7 8 9 A B C D E F //0 1 2 3 4 5 6 7 8 9 A B C D E F
...@@ -180,19 +180,22 @@ protected: ...@@ -180,19 +180,22 @@ protected:
}; };
stream_.Put('\"'); stream_.Put('\"');
for (const Ch* p = str; p != str + length; ++p) { GenericStringStream<SourceEncoding> is(str);
if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p]) { while (is.Tell() < length) {
const Ch c = is.Peek();
if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) {
is.Take();
stream_.Put('\\'); stream_.Put('\\');
stream_.Put(escape[(unsigned char)*p]); stream_.Put(escape[(unsigned char)c]);
if (escape[(unsigned char)*p] == 'u') { if (escape[(unsigned char)c] == 'u') {
stream_.Put('0'); stream_.Put('0');
stream_.Put('0'); stream_.Put('0');
stream_.Put(hexDigits[(*p) >> 4]); stream_.Put(hexDigits[(unsigned char)c >> 4]);
stream_.Put(hexDigits[(*p) & 0xF]); stream_.Put(hexDigits[(unsigned char)c & 0xF]);
} }
} }
else else
stream_.Put(*p); Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, stream_);
} }
stream_.Put('\"'); stream_.Put('\"');
} }
......
...@@ -54,3 +54,13 @@ TEST(Writer, String) { ...@@ -54,3 +54,13 @@ TEST(Writer, String) {
TEST_ROUNDTRIP("[\"Hello\\u0000World\"]"); TEST_ROUNDTRIP("[\"Hello\\u0000World\"]");
TEST_ROUNDTRIP("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]"); TEST_ROUNDTRIP("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]");
} }
TEST(Writer, Transcode) {
// UTF8 -> UTF16 -> UTF8
StringStream s("{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3], \"dollar\":\"\x24\", \"cents\":\"\xC2\xA2\", \"euro\":\"\xE2\x82\xAC\", \"gclef\":\"\xF0\x9D\x84\x9E\" } ");
StringBuffer buffer;
Writer<StringBuffer, UTF16<>, UTF8<> > writer(buffer);
GenericReader<UTF8<>, UTF16<> > reader;
reader.Parse<0>(s, writer);
EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3],\"dollar\":\"\x24\",\"cents\":\"\xC2\xA2\",\"euro\":\"\xE2\x82\xAC\",\"gclef\":\"\xF0\x9D\x84\x9E\"}", buffer.GetString());
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment